From 9c115ccc40951328898763d0c5184dc83dc69a8b Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sun, 30 Oct 2011 23:01:24 +0000 Subject: [PATCH 001/147] Blender Conference Feature Request by Jonathan: * Made "V3D_BGPIC_EXPANDED" true per default, so when you add a new background image, you don't have to expand the UI to select the image. --- source/blender/editors/space_view3d/view3d_edit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 99f11554aa6..ea8db17daf0 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2946,6 +2946,7 @@ static BGpic *background_image_add(bContext *C) bgpic->iuser.fie_ima= 2; bgpic->iuser.ok= 1; bgpic->view= 0; /* 0 for all */ + bgpic->flag |= V3D_BGPIC_EXPANDED; BLI_addtail(&v3d->bgpicbase, bgpic); From d3f63bf54cb214fc7cb67b8741dc21fc67b5937a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 31 Oct 2011 00:03:18 +0000 Subject: [PATCH 002/147] Another Bconf Feature Request. :) Some UI and code cleanup for the "Symmetry" panel in sculpt mode. * Made X, Y, Z Buttons toggle buttons, as the other X,Y,Z in the "Options" panel above in sculpt mode, for consistency. --- .../startup/bl_ui/space_view3d_toolbar.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index a78992d4a07..13f34fa6647 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -985,18 +985,14 @@ class VIEW3D_PT_sculpt_symmetry(PaintPanel, Panel): sculpt = context.tool_settings.sculpt - split = layout.split() - - col = split.column() + col = layout.column(align=True) col.label(text="Mirror:") - col.prop(sculpt, "use_symmetry_x", text="X") - col.prop(sculpt, "use_symmetry_y", text="Y") - col.prop(sculpt, "use_symmetry_z", text="Z") - - split.prop(sculpt, "radial_symmetry", text="Radial") - - layout.separator() - + row = col.row() + row.prop(sculpt, "use_symmetry_x", text="X", toggle=True) + row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True) + row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True) + + layout.column().prop(sculpt, "radial_symmetry", text="Radial") layout.prop(sculpt, "use_symmetry_feather", text="Feather") From dc1b3d88b821db1316c85be5f48a60107796b651 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Oct 2011 00:23:42 +0000 Subject: [PATCH 003/147] fix [#29098] File save dialog cannot handle extra periods in file name --- source/blender/blenkernel/intern/image.c | 2 +- source/blender/blenlib/BLI_path_util.h | 1 + source/blender/blenlib/intern/path_util.c | 45 +++++++++++++++---- .../windowmanager/intern/wm_operators.c | 5 ++- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 8bce7515695..9aeacb9d7fa 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -981,7 +981,7 @@ int BKE_add_image_extension(char *string, int imtype) || (G.have_quicktime && BLI_testextensie_array(string, imb_ext_image_qt))) { return BLI_replace_extension(string, FILE_MAX, extension); } else { - strcat(string, extension); + return BLI_ensure_extension(string, FILE_MAX, extension); return TRUE; } diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index dd4bc868ab0..68bb1a7280d 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -102,6 +102,7 @@ int BLI_testextensie(const char *str, const char *ext); int BLI_testextensie_array(const char *str, const char **ext_array); int BLI_testextensie_glob(const char *str, const char *ext_fnmatch); int BLI_replace_extension(char *path, size_t maxlen, const char *ext); +int BLI_ensure_extension(char *path, size_t maxlen, const char *ext); void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len); int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len); void BLI_newname(char * name, int add); diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index e03a7baca0c..bbb62db58f2 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1397,22 +1397,51 @@ int BLI_testextensie_glob(const char *str, const char *ext_fnmatch) int BLI_replace_extension(char *path, size_t maxlen, const char *ext) { + size_t path_len= strlen(path); + size_t ext_len= strlen(ext); size_t a; - for(a=strlen(path); a>0; a--) { - if(path[a-1] == '.' || path[a-1] == '/' || path[a-1] == '\\') { - a--; + for(a= path_len - 1; a >= 0; a--) { + if (ELEM3(path[a], '.', '/', '\\')) { break; } } - - if(path[a] != '.') - a= strlen(path); - if(a + strlen(ext) >= maxlen) + if(a + ext_len >= maxlen) return 0; - strcpy(path+a, ext); + memcpy(path+a, ext, ext_len + 1); + return 1; +} + +/* strip's trailing '.'s and adds the extension only when needed */ +int BLI_ensure_extension(char *path, size_t maxlen, const char *ext) +{ + size_t path_len= strlen(path); + size_t ext_len= strlen(ext); + size_t a; + + /* first check the extension is alread there */ + if ( (ext_len <= path_len) && + (strcmp(path + (path_len - ext_len), ext) == 0)) + { + return 1; + } + + for(a= path_len - 1; a >= 0; a--) { + if (path[a] == '.') { + path[a]= '\0'; + } + else { + break; + } + } + a++; + + if(a + ext_len >= maxlen) + return 0; + + memcpy(path+a, ext, ext_len + 1); return 1; } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 32d4ba857e6..acd5df79982 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1949,7 +1949,10 @@ static int blend_save_check(bContext *UNUSED(C), wmOperator *op) { char filepath[FILE_MAX]; RNA_string_get(op->ptr, "filepath", filepath); - if(BLI_replace_extension(filepath, sizeof(filepath), ".blend")) { + if(!BLO_has_bfile_extension(filepath)) { + /* some users would prefer BLI_replace_extension(), + * we keep getting knit-picking bug reports about this - campbell */ + BLI_ensure_extension(filepath, FILE_MAX, ".blend"); RNA_string_set(op->ptr, "filepath", filepath); return TRUE; } From 65b92d820af238f5ad694ecff07181f076590ccd Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 31 Oct 2011 00:35:14 +0000 Subject: [PATCH 004/147] Sculpt UI: * Code cleanup. --- .../startup/bl_ui/space_view3d_toolbar.py | 59 +++++++------------ 1 file changed, 20 insertions(+), 39 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 13f34fa6647..168405c2279 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -711,19 +711,14 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel): if context.sculpt_object: #XXX duplicated from properties_texture.py - col.separator() - col.label(text="Brush Mapping:") - row = col.row(align=True) - row.prop(tex_slot, "map_mode", expand=True) + col.row().prop(tex_slot, "map_mode", expand=True) col.separator() col = layout.column() col.active = tex_slot.map_mode in {'FIXED'} col.label(text="Angle:") - - col = layout.column() if not brush.use_anchor and brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'} and tex_slot.map_mode in {'FIXED'}: col.prop(brush, "texture_angle_source_random", text="") else: @@ -740,47 +735,33 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel): #col.prop(brush, "use_rake", toggle=True, icon='PARTICLEMODE', text="") col = layout.column() - col.prop(tex_slot, "angle", text="") col.active = tex_slot.map_mode in {'FIXED', 'TILED'} - + col.prop(tex_slot, "angle", text="") + #col = layout.column() #col.prop(brush, "use_random_rotation") #col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'} split = layout.split() + split.prop(tex_slot, "offset") + split.prop(tex_slot, "scale") - col = split.column() - col.prop(tex_slot, "offset") - - col = split.column() - - col.prop(tex_slot, "scale") - - col = layout.column() - - row = col.row(align=True) - row.label(text="Sample Bias:") - row = col.row(align=True) - row.prop(brush, "texture_sample_bias", slider=True, text="") - - row = col.row(align=True) - row.label(text="Overlay:") - row.active = tex_slot.map_mode in {'FIXED', 'TILED'} - - row = col.row(align=True) - - col = row.column() - - if brush.use_texture_overlay: - col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF') - else: - col.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON') - + col = layout.column(align=True) + col.label(text="Sample Bias:") + col.prop(brush, "texture_sample_bias", slider=True, text="") + + col = layout.column(align=True) col.active = tex_slot.map_mode in {'FIXED', 'TILED'} - - col = row.column() - col.prop(brush, "texture_overlay_alpha", text="Alpha") - col.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay + col.label(text="Overlay:") + + row = col.row() + if brush.use_texture_overlay: + row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF') + else: + row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON') + sub = row.row() + sub.active = tex_slot.map_mode in {'FIXED', 'TILED'} and brush.use_texture_overlay + sub.prop(brush, "texture_overlay_alpha", text="Alpha") class VIEW3D_PT_tools_brush_tool(PaintPanel, Panel): From 9905094f5da957f7c4ae14ed9ce6e043e5b30ac3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Oct 2011 01:50:04 +0000 Subject: [PATCH 005/147] fix own error r41191 getting id property string lengths. --- release/scripts/startup/bl_operators/wm.py | 28 ++----------------- .../startup/bl_ui/space_view3d_toolbar.py | 8 +++--- source/blender/python/generic/IDProp.c | 18 ++++++------ 3 files changed, 15 insertions(+), 39 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 1e469275e77..aa661b76512 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1179,31 +1179,7 @@ class WM_OT_copy_prev_settings(Operator): return {'CANCELLED'} -class WM_OT_blenderplayer_start(Operator): - '''Launches the Blenderplayer with the current blendfile''' - bl_idname = "wm.blenderplayer_start" - bl_label = "Start" - - import os - blender_bin_path = bpy.app.binary_path - blender_bin_dir = os.path.dirname(blender_bin_path) - ext = os.path.splitext(blender_bin_path)[-1] - player_path = os.path.join(blender_bin_dir, 'blenderplayer' + ext) - - def execute(self, context): - import sys - import subprocess - import os - if sys.platform == 'darwin': - self.player_path = os.path.join(self.blender_bin_dir, '../../../blenderplayer.app/Contents/MacOS/blenderplayer') - - filepath = bpy.app.tempdir + "game.blend" - bpy.ops.wm.save_as_mainfile(filepath=filepath, check_existing=False, copy=True) - subprocess.call([self.player_path, filepath]) - return {'FINISHED'} - - class WM_OT_keyconfig_test(Operator): "Test keyconfig for conflicts" bl_idname = "wm.keyconfig_test" @@ -1395,9 +1371,9 @@ class WM_OT_keyitem_add(Operator): km = context.keymap if km.is_modal: - km.keymap_items.new_modal("", 'A', 'PRESS') #~ kmi + km.keymap_items.new_modal("", 'A', 'PRESS') else: - km.keymap_items.new("none", 'A', 'PRESS') #~ kmi + km.keymap_items.new("none", 'A', 'PRESS') # clear filter and expand keymap so we can see the newly added item if context.space_data.filter_text != "": diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 168405c2279..4a5fcfd4c49 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -737,7 +737,7 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel): col = layout.column() col.active = tex_slot.map_mode in {'FIXED', 'TILED'} col.prop(tex_slot, "angle", text="") - + #col = layout.column() #col.prop(brush, "use_random_rotation") #col.active = (not brush.use_rake) and (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'SNAKE_HOOK', 'THUMB', 'ROTATE'}) and tex_slot.map_mode in {'FIXED'} @@ -749,11 +749,11 @@ class VIEW3D_PT_tools_brush_texture(PaintPanel, Panel): col = layout.column(align=True) col.label(text="Sample Bias:") col.prop(brush, "texture_sample_bias", slider=True, text="") - + col = layout.column(align=True) col.active = tex_slot.map_mode in {'FIXED', 'TILED'} col.label(text="Overlay:") - + row = col.row() if brush.use_texture_overlay: row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF') @@ -972,7 +972,7 @@ class VIEW3D_PT_sculpt_symmetry(PaintPanel, Panel): row.prop(sculpt, "use_symmetry_x", text="X", toggle=True) row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True) row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True) - + layout.column().prop(sculpt, "radial_symmetry", text="Radial") layout.prop(sculpt, "use_symmetry_feather", text="Feather") diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c index 7aa5ed61203..076b4811d07 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/IDProp.c @@ -65,9 +65,9 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop ) switch ( prop->type ) { case IDP_STRING: #ifdef USE_STRING_COERCE - return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len); + return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); #else - return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len); + return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); #endif case IDP_INT: return PyLong_FromLong( (long)prop->data.val ); @@ -483,9 +483,9 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) switch (prop->type) { case IDP_STRING: #ifdef USE_STRING_COERCE - return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len); + return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1); #else - return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len); + return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1); #endif break; case IDP_FLOAT: @@ -625,11 +625,11 @@ static PyObject *BPy_IDGroup_IterItems(BPy_IDProperty *self) } /* utility function */ -static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len) +static void BPy_IDGroup_CorrectListLen(IDProperty *prop, PyObject *seq, int len, const char *func) { int j; - printf("ID Property Error found and corrected in BPy_IDGroup_GetKeys/Values/Items!\n"); + printf("%s: ID Property Error found and corrected!\n", func); /*fill rest of list with valid references to None*/ for (j=len; jlen; j++) { @@ -654,7 +654,7 @@ PyObject *BPy_Wrap_GetKeys(IDProperty *prop) for (; loop; loop=loop->next, i++) {} if (i != prop->len) { /* if the loop didnt finish, we know the length is wrong */ - BPy_IDGroup_CorrectListLen(prop, seq, i); + BPy_IDGroup_CorrectListLen(prop, seq, i, __func__); Py_DECREF(seq); /*free the list*/ /*call self again*/ return BPy_Wrap_GetKeys(prop); @@ -674,7 +674,7 @@ PyObject *BPy_Wrap_GetValues(ID *id, IDProperty *prop) } if (i != prop->len) { - BPy_IDGroup_CorrectListLen(prop, seq, i); + BPy_IDGroup_CorrectListLen(prop, seq, i, __func__); Py_DECREF(seq); /*free the list*/ /*call self again*/ return BPy_Wrap_GetValues(id, prop); @@ -697,7 +697,7 @@ PyObject *BPy_Wrap_GetItems(ID *id, IDProperty *prop) } if (i != prop->len) { - BPy_IDGroup_CorrectListLen(prop, seq, i); + BPy_IDGroup_CorrectListLen(prop, seq, i, __func__); Py_DECREF(seq); /*free the list*/ /*call self again*/ return BPy_Wrap_GetItems(id, prop); From 797d2bbd8894462d19f0eda4d9bf818e477f7112 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Oct 2011 06:13:20 +0000 Subject: [PATCH 006/147] use_verify option to defvert_sync_mapped and defvert_sync was flipped, also minor edits to defvert_verify_index() - no functional change. --- source/blender/blenkernel/intern/deform.c | 26 +++++++++++------------ source/blender/editors/mesh/editface.c | 1 - source/blender/python/BPY_extern.h | 18 +++++----------- 3 files changed, 18 insertions(+), 27 deletions(-) diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index a9610023775..83eda860510 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -104,8 +104,8 @@ void defvert_sync (MDeformVert *dvert_r, const MDeformVert *dvert, int use_verif MDeformWeight *dw; for(i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { MDeformWeight *dw_r; - if(use_verify) dw_r= defvert_find_index(dvert_r, dw->def_nr); - else dw_r= defvert_verify_index(dvert_r, dw->def_nr); + if(use_verify) dw_r= defvert_verify_index(dvert_r, dw->def_nr); + else dw_r= defvert_find_index(dvert_r, dw->def_nr); if(dw_r) { dw_r->weight= dw->weight; @@ -123,8 +123,8 @@ void defvert_sync_mapped (MDeformVert *dvert_r, const MDeformVert *dvert, const for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++) { if (dw->def_nr < flip_map_len) { MDeformWeight *dw_r; - if(use_verify) dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]); - else dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]); + if(use_verify) dw_r= defvert_verify_index(dvert_r, flip_map[dw->def_nr]); + else dw_r= defvert_find_index(dvert_r, flip_map[dw->def_nr]); if(dw_r) { dw_r->weight= dw->weight; @@ -487,25 +487,25 @@ MDeformWeight *defvert_verify_index(MDeformVert *dv, const int defgroup) MDeformWeight *newdw; /* do this check always, this function is used to check for it */ - if(!dv || defgroup<0) + if(!dv || defgroup < 0) return NULL; - newdw = defvert_find_index(dv, defgroup); + newdw= defvert_find_index(dv, defgroup); if(newdw) return newdw; - newdw = MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); - if(dv->dw) { + newdw= MEM_callocN(sizeof(MDeformWeight)*(dv->totweight+1), "deformWeight"); + if (dv->dw) { memcpy(newdw, dv->dw, sizeof(MDeformWeight)*dv->totweight); MEM_freeN(dv->dw); } - dv->dw=newdw; - - dv->dw[dv->totweight].weight=0.0f; - dv->dw[dv->totweight].def_nr=defgroup; + dv->dw= newdw; + newdw += dv->totweight; + newdw->weight= 0.0f; + newdw->def_nr= defgroup; /* Group index */ dv->totweight++; - return dv->dw+(dv->totweight-1); + return newdw; } diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 279657e71c2..02d20e64bc3 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -346,7 +346,6 @@ void paintface_select_linked(bContext *UNUSED(C), Object *ob, int UNUSED(mval[2] paintface_flush_flags(ob); } -/* note: caller needs to run paintface_flush_flags(ob) after this */ void paintface_deselect_all_visible(Object *ob, int action, short flush_flags) { Mesh *me; diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index c43a2520bb8..d8ddcd593a8 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -20,7 +20,10 @@ * * The Original Code was in: source/blender/bpython/include/BPY_extern.h * - * Contributor(s): Michel Selten, Willian P. Germano, Chris Keith + * Contributor(s): Michel Selten, + * Willian P. Germano, + * Chris Keith, + * Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ @@ -39,14 +42,10 @@ struct ID; /* DNA_ID.h */ struct Object; /* DNA_object_types.h */ struct ChannelDriver; /* DNA_anim_types.h */ struct ListBase; /* DNA_listBase.h */ -struct SpaceText; /* DNA_space_types.h */ -struct ScrArea; /* DNA_screen_types.h */ -struct bScreen; /* DNA_screen_types.h */ struct bConstraint; /* DNA_constraint_types.h */ struct bPythonConstraint; /* DNA_constraint_types.h */ struct bConstraintOb; /* DNA_constraint_types.h */ struct bConstraintTarget; /* DNA_constraint_types.h*/ -struct BPyMenu; struct bContext; struct bContextDataResult; struct ReportList; @@ -61,16 +60,9 @@ void BPY_pyconstraint_target(struct bPythonConstraint *con, struct bConstraintTa void BPY_pyconstraint_update(struct Object *owner, struct bConstraint *con); int BPY_is_pyconstraint(struct Text *text); // void BPY_free_pyconstraint_links(struct Text *text); -// + void BPY_python_start(int argc, const char **argv); void BPY_python_end(void); -// void init_syspath(int first_time); -// void syspath_append(char *dir); -// void BPY_rebuild_syspath(void); -// int BPY_path_update(void); -// -// int BPY_Err_getLinenumber(void); -// const char *BPY_Err_getFilename(void); /* 2.5 UI Scripts */ int BPY_filepath_exec(struct bContext *C, const char *filepath, struct ReportList *reports); From 2ceeaf97218d5a73815cc67e0f2eed298c9e5ca2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Oct 2011 07:17:35 +0000 Subject: [PATCH 007/147] fix [#29089] Faces created for "rims" by solidify modifier have incorrect visibility --- source/blender/modifiers/intern/MOD_solidify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 8d47ad28a86..b8e95ad4c51 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -626,7 +626,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); #endif - origindex[numFaces * 2 + i]= ORIGINDEX_NONE; + origindex[numFaces * 2 + i]= fidx; } #ifdef SOLIDIFY_SIDE_NORMALS From 9c801a6d855f4c376a8dcc0e84ff035d09b47ce9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 31 Oct 2011 09:52:43 +0000 Subject: [PATCH 008/147] Correction to own commit r41169 --- build_files/scons/config/darwin-config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/scons/config/darwin-config.py b/build_files/scons/config/darwin-config.py index deb3d01febd..38c8dca6cd2 100644 --- a/build_files/scons/config/darwin-config.py +++ b/build_files/scons/config/darwin-config.py @@ -336,7 +336,7 @@ else: # some flags shuffling for different OS versions if MAC_MIN_VERS == '10.3': - CCFLAGS = ['-fuse-cxa-atexit'] + CFLAGS + CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS LLIBS.append('crt3.o') From a664e779ac8be0f926221d4c064394f9b3b6a801 Mon Sep 17 00:00:00 2001 From: Jens Verwiebe Date: Mon, 31 Oct 2011 12:31:48 +0000 Subject: [PATCH 009/147] OSX: make ZOOM-gesture on trackpads half the speed, added comment for experimental all-time-trackpad assumption --- intern/ghost/intern/GHOST_SystemCocoa.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 7a6c0a02043..9dc3dd3f30b 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -578,7 +578,7 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() if (strstr(rstring,"MacBookAir") || (strstr(rstring,"MacBook") && (rstring[strlen(rstring)-3]>='5') && (rstring[strlen(rstring)-3]<='9'))) m_hasMultiTouchTrackpad = true; - else m_hasMultiTouchTrackpad = true; + else m_hasMultiTouchTrackpad = true; // experimental, changes only MagicMouse behaviour (zoom->pan) but enables MagicTrackpad for all Macs free( rstring ); rstring = NULL; @@ -1610,7 +1610,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x, y; window->clientToScreenIntern(mousePos.x, mousePos.y, x, y); pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, x, y, - [event magnification]*250.0 + 0.1, 0)); + [event magnification]*125.0 + 0.1, 0)); } break; From 56421d869dd080c0c3e715736dbc6de6e03526e5 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 31 Oct 2011 14:08:14 +0000 Subject: [PATCH 010/147] Fix: selecting with z-buffer hiding did not work when graphics card settings enabled antialiasing, overriding application settings. The fix for this got lost when the FSAA option was added and later disabled again. Added it back now, and also disable AA for UI widgets since it makes them look too blurry, they already do their own AA. --- source/blender/editors/interface/interface.c | 9 +++++++++ source/blender/editors/space_view3d/view3d_draw.c | 11 +++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 5b27fe88b4b..a6316dc0e9e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -962,6 +962,7 @@ void uiDrawBlock(const bContext *C, uiBlock *block) ARegion *ar; uiBut *but; rcti rect; + int multisample_enabled; /* get menu region or area region */ ar= CTX_wm_menu(C); @@ -971,6 +972,11 @@ void uiDrawBlock(const bContext *C, uiBlock *block) if(!block->endblock) uiEndBlock(C, block); + /* disable AA, makes widgets too blurry */ + multisample_enabled= glIsEnabled(GL_MULTISAMPLE_ARB); + if(multisample_enabled) + glDisable(GL_MULTISAMPLE_ARB); + /* we set this only once */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1015,6 +1021,9 @@ void uiDrawBlock(const bContext *C, uiBlock *block) glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); + + if(multisample_enabled) + glEnable(GL_MULTISAMPLE_ARB); ui_draw_links(block); } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 32e553262e2..6b5e7792e85 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1226,6 +1226,7 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) { RegionView3D *rv3d= ar->regiondata; struct Base *base = scene->basact; + int multisample_enabled; rcti winrct; BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); @@ -1252,8 +1253,13 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if(v3d->drawtype > OB_WIRE) v3d->zbuf= TRUE; + /* dithering and AA break color coding, so disable */ glDisable(GL_DITHER); + multisample_enabled= glIsEnabled(GL_MULTISAMPLE_ARB); + if(multisample_enabled) + glDisable(GL_MULTISAMPLE_ARB); + region_scissor_winrct(ar, &winrct); glScissor(winrct.xmin, winrct.ymin, winrct.xmax - winrct.xmin, winrct.ymax - winrct.ymin); @@ -1272,9 +1278,8 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) G.f |= G_BACKBUFSEL; - if(base && (base->lay & v3d->lay)) { + if(base && (base->lay & v3d->lay)) draw_object_backbufsel(scene, v3d, rv3d, base->object); - } v3d->flag &= ~V3D_INVALID_BACKBUF; ar->swap= 0; /* mark invalid backbuf for wm draw */ @@ -1283,6 +1288,8 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) v3d->zbuf= FALSE; glDisable(GL_DEPTH_TEST); glEnable(GL_DITHER); + if(multisample_enabled) + glEnable(GL_MULTISAMPLE_ARB); if(rv3d->rflag & RV3D_CLIPPING) view3d_clr_clipping(); From bdb279ec5b4f8537bc30a54bef814bd47f2aef1e Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 31 Oct 2011 16:44:24 +0000 Subject: [PATCH 011/147] Fix crash in texture nodes, when no derivatives available, other nodes already did this check. --- .../blender/nodes/texture/nodes/node_texture_texture.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c index 2d543470342..1b8eb3aabc6 100644 --- a/source/blender/nodes/texture/nodes/node_texture_texture.c +++ b/source/blender/nodes/texture/nodes/node_texture_texture.c @@ -54,8 +54,14 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor float co[3], dxt[3], dyt[3]; copy_v3_v3(co, p->co); - copy_v3_v3(dxt, p->dxt); - copy_v3_v3(dyt, p->dyt); + if (p->osatex) { + copy_v3_v3(dxt, p->dxt); + copy_v3_v3(dyt, p->dyt); + } + else { + zero_v3(dxt); + zero_v3(dyt); + } if(node->custom2 || node->need_exec==0) { /* this node refers to its own texture tree! */ From 4e0d8ccf9619f72fb6cbca1d18647f9dff1f0d73 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 31 Oct 2011 17:00:59 +0000 Subject: [PATCH 012/147] Fix #29084: material/texture nodes crash introduced in 2.60, execdata is being lazely created but this wasn't done in a thread safe way. --- source/blender/blenlib/BLI_threads.h | 1 + source/blender/blenlib/intern/threads.c | 5 +++++ source/blender/nodes/shader/node_shader_tree.c | 11 +++++++++-- source/blender/nodes/texture/node_texture_tree.c | 11 +++++++++-- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 00d8131d813..8826e9a9936 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -70,6 +70,7 @@ int BLI_system_thread_count(void); /* gets the number of threads the system can #define LOCK_CUSTOM1 3 #define LOCK_RCACHE 4 #define LOCK_OPENGL 5 +#define LOCK_NODES 6 void BLI_lock_thread(int type); void BLI_unlock_thread(int type); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index c049ab85546..7b156a3ac52 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -113,6 +113,7 @@ static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t mainid; static int thread_levels= 0; /* threads can be invoked inside threads */ @@ -347,6 +348,8 @@ void BLI_lock_thread(int type) pthread_mutex_lock(&_rcache_lock); else if (type==LOCK_OPENGL) pthread_mutex_lock(&_opengl_lock); + else if (type==LOCK_NODES) + pthread_mutex_lock(&_nodes_lock); } void BLI_unlock_thread(int type) @@ -363,6 +366,8 @@ void BLI_unlock_thread(int type) pthread_mutex_unlock(&_rcache_lock); else if(type==LOCK_OPENGL) pthread_mutex_unlock(&_opengl_lock); + else if(type==LOCK_NODES) + pthread_mutex_unlock(&_nodes_lock); } /* Mutex Locks */ diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index cc8e1619570..a83b32097df 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -212,8 +212,15 @@ void ntreeShaderExecTree(bNodeTree *ntree, ShadeInput *shi, ShadeResult *shr) /* each material node has own local shaderesult, with optional copying */ memset(shr, 0, sizeof(ShadeResult)); - if (!exec) - exec = ntree->execdata = ntreeShaderBeginExecTree(ntree, 1); + /* ensure execdata is only initialized once */ + if (!exec) { + BLI_lock_thread(LOCK_NODES); + if(!ntree->execdata) + ntree->execdata = ntreeShaderBeginExecTree(ntree, 1); + BLI_unlock_thread(LOCK_NODES); + + exec = ntree->execdata; + } nts= ntreeGetThreadStack(exec, shi->thread); ntreeExecThreadNodes(exec, nts, &scd, shi->thread); diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 78792956684..5e5d44540dc 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -232,8 +232,15 @@ int ntreeTexExecTree( data.mtex= mtex; data.shi= shi; - if (!exec) - exec = ntreeTexBeginExecTree(nodes, 1); + /* ensure execdata is only initialized once */ + if (!exec) { + BLI_lock_thread(LOCK_NODES); + if(!nodes->execdata) + ntreeTexBeginExecTree(nodes, 1); + BLI_unlock_thread(LOCK_NODES); + + exec= nodes->execdata; + } nts= ntreeGetThreadStack(exec, thread); ntreeExecThreadNodes(exec, nts, &data, thread); From a5959e767e1fce78fa1876e8791667a377ac51f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 00:34:09 +0000 Subject: [PATCH 013/147] hopefully fix problem with cmake on osx (older gcc version) --- CMakeLists.txt | 2 ++ build_files/cmake/macros.cmake | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcec149eda8..f421c2c9395 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1255,6 +1255,8 @@ if(CMAKE_COMPILER_IS_GNUCC) # flags to undo strict flags ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations) + ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter) + ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable) elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index f767376d122..10f89797754 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -413,8 +413,7 @@ macro(remove_strict_flags) remove_cc_flag("-Werror") # negate flags implied by '-Wall' - add_cc_flag("-Wno-unused-parameter") - add_cc_flag("-Wno-unused-but-set-variable") + add_cc_flag("${CC_REMOVE_STRICT_FLAGS}") endif() if(MSVC) From e4896c999f412ecb05b68b1bffa25e5eec924514 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 02:24:40 +0000 Subject: [PATCH 014/147] name qtcreator projects based on branch names (if svn is found and its a branch), was too confusing with multiple IDE's open calling all projects 'Blender'. --- build_files/cmake/cmake_qtcreator_project.py | 23 +++++++++++++++----- build_files/cmake/project_info.py | 20 +++++++++++++++++ 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/build_files/cmake/cmake_qtcreator_project.py b/build_files/cmake/cmake_qtcreator_project.py index fc5c00ec2ec..a89bcd01523 100755 --- a/build_files/cmake/cmake_qtcreator_project.py +++ b/build_files/cmake/cmake_qtcreator_project.py @@ -40,6 +40,7 @@ from project_info import (SIMPLE_PROJECTFILE, is_py, cmake_advanced_info, cmake_compiler_defines, + project_name_get, ) import os @@ -59,7 +60,8 @@ def create_qtc_project_main(): f.write("\n".join(files_rel)) f = open(os.path.join(PROJECT_DIR, "%s.includes" % PROJECT_NAME), 'w') - f.write("\n".join(sorted(list(set(os.path.dirname(f) for f in files_rel if is_c_header(f)))))) + f.write("\n".join(sorted(list(set(os.path.dirname(f) + for f in files_rel if is_c_header(f)))))) qtc_prj = os.path.join(PROJECT_DIR, "%s.creator" % PROJECT_NAME) f = open(qtc_prj, 'w') @@ -73,10 +75,16 @@ def create_qtc_project_main(): includes, defines = cmake_advanced_info() # for some reason it doesnt give all internal includes - includes = list(set(includes) | set(os.path.dirname(f) for f in files_rel if is_c_header(f))) + includes = list(set(includes) | set(os.path.dirname(f) + for f in files_rel if is_c_header(f))) includes.sort() - PROJECT_NAME = "Blender" + if 0: + PROJECT_NAME = "Blender" + else: + # be tricky, get the project name from SVN if we can! + PROJECT_NAME = project_name_get(SOURCE_DIR) + FILE_NAME = PROJECT_NAME.lower() f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') f.write("\n".join(files_rel)) @@ -93,7 +101,7 @@ def create_qtc_project_main(): f.write("// ADD PREDEFINED MACROS HERE!\n") defines_final = [("#define %s %s" % item) for item in defines] if sys.platform != "win32": - defines_final += cmake_compiler_defines() # defines from the compiler + defines_final += cmake_compiler_defines() f.write("\n".join(defines_final)) print("Blender project file written to: %s" % qtc_prj) @@ -106,7 +114,12 @@ def create_qtc_project_python(): files_rel.sort() # --- qtcreator specific, simple format - PROJECT_NAME = "Blender_Python" + if 0: + PROJECT_NAME = "Blender_Python" + else: + # be tricky, get the project name from SVN if we can! + PROJECT_NAME = project_name_get(SOURCE_DIR) + "_Python" + FILE_NAME = PROJECT_NAME.lower() f = open(os.path.join(PROJECT_DIR, "%s.files" % FILE_NAME), 'w') f.write("\n".join(files_rel)) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index 8e813d39b64..da1f2087f4f 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -41,6 +41,7 @@ __all__ = ( "is_py", "cmake_advanced_info", "cmake_compiler_defines", + "project_name_get" ) import sys @@ -215,3 +216,22 @@ def cmake_compiler_defines(): os.remove(temp_c) os.remove(temp_def) return lines + + +def project_name_get(path, fallback="Blender", prefix="Blender_"): + if not os.path.isdir(os.path.join(path, ".svn")): + return fallback + + import subprocess + info = subprocess.Popen(["svn", "info", path], + stdout=subprocess.PIPE).communicate()[0].decode() + + for l in info.split("\n"): + l = l.strip() + if l.startswith("URL"): + # https://svn.blender.org/svnroot/bf-blender/branches/bmesh/blender + # --> bmesh + if "/branches/" in l: + return prefix + l.rsplit("/branches/", 1)[-1].split("/", 1)[0] + return fallback + From f3f3a42566810185f22752428931c4d7584a67be Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 04:19:21 +0000 Subject: [PATCH 015/147] use math functions for mesh subdivide smooth (easier to follow for bmesh, no functional changes). --- source/blender/editors/mesh/editmesh_tools.c | 48 +++++++------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 5455bf966ef..54b46cc14a6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1456,11 +1456,11 @@ void MESH_OT_delete(wmOperatorType *ot) /* calculates offset for co, based on fractal, sphere or smooth settings */ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int beauty, float perc) { - float vec1[3], fac; + float tvec[3], fac; if(beauty & B_SMOOTH) { - /* we calculate an offset vector vec1[], to be added to *co */ - float len, fac, nor[3], nor1[3], nor2[3]; + /* we calculate an offset vector tvec[], to be added to *co */ + float len, nor[3], nor1[3], nor2[3]; sub_v3_v3v3(nor, edge->v1->co, edge->v2->co); len= 0.5f*normalize_v3(nor); @@ -1469,43 +1469,31 @@ static void alter_co(float *co, EditEdge *edge, float smooth, float fractal, int copy_v3_v3(nor2, edge->v2->no); /* cosine angle */ - fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ; - - vec1[0]= fac*nor1[0]; - vec1[1]= fac*nor1[1]; - vec1[2]= fac*nor1[2]; + fac= dot_v3v3(nor, nor1); + mul_v3_v3fl(tvec, nor1, fac); /* cosine angle */ - fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ; - - vec1[0]+= fac*nor2[0]; - vec1[1]+= fac*nor2[1]; - vec1[2]+= fac*nor2[2]; + fac= -dot_v3v3(nor, nor2); + madd_v3_v3fl(tvec, nor2, fac); /* falloff for multi subdivide */ smooth *= sqrtf(fabs(1.0f - 2.0f*fabsf(0.5f-perc))); - vec1[0]*= smooth*len; - vec1[1]*= smooth*len; - vec1[2]*= smooth*len; + mul_v3_fl(tvec, smooth * len); - co[0] += vec1[0]; - co[1] += vec1[1]; - co[2] += vec1[2]; + add_v3_v3(co, tvec); } else if(beauty & B_SPHERE) { /* subdivide sphere */ normalize_v3(co); - co[0]*= smooth; - co[1]*= smooth; - co[2]*= smooth; + mul_v3_fl(co, smooth); } if(beauty & B_FRACTAL) { fac= fractal*len_v3v3(edge->v1->co, edge->v2->co); - vec1[0]= fac*(float)(0.5-BLI_drand()); - vec1[1]= fac*(float)(0.5-BLI_drand()); - vec1[2]= fac*(float)(0.5-BLI_drand()); - add_v3_v3(co, vec1); + tvec[0]= fac*(float)(0.5-BLI_drand()); + tvec[1]= fac*(float)(0.5-BLI_drand()); + tvec[2]= fac*(float)(0.5-BLI_drand()); + add_v3_v3(co, tvec); } } @@ -1517,9 +1505,7 @@ static EditVert *subdivide_edge_addvert(EditMesh *em, EditEdge *edge, float smoo EditVert *ev; float co[3]; - co[0] = (edge->v2->co[0]-edge->v1->co[0])*percent + edge->v1->co[0]; - co[1] = (edge->v2->co[1]-edge->v1->co[1])*percent + edge->v1->co[1]; - co[2] = (edge->v2->co[2]-edge->v1->co[2])*percent + edge->v1->co[2]; + interp_v3_v3v3(co, edge->v1->co, edge->v2->co, percent); /* offset for smooth or sphere or fractal */ alter_co(co, edge, smooth, fractal, beauty, percent); @@ -1543,9 +1529,7 @@ static EditVert *subdivide_edge_addvert(EditMesh *em, EditEdge *edge, float smoo EM_data_interp_from_verts(em, edge->v1, edge->v2, ev, percent); /* normal */ - ev->no[0] = (edge->v2->no[0]-edge->v1->no[0])*percent + edge->v1->no[0]; - ev->no[1] = (edge->v2->no[1]-edge->v1->no[1])*percent + edge->v1->no[1]; - ev->no[2] = (edge->v2->no[2]-edge->v1->no[2])*percent + edge->v1->no[2]; + interp_v3_v3v3(ev->no, edge->v1->no, edge->v2->no, percent); normalize_v3(ev->no); return ev; From e3f03d72b6e0a24a2c87e94c68c5f6452ad91e94 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 06:26:55 +0000 Subject: [PATCH 016/147] added path traversal flag - BPATH_TRAVERSE_SKIP_MULTIFILE, so path manipulation functions dont run multiple times on the same path in the case of sequence strips where the one directory is used as the base for many images. --- source/blender/blenkernel/BKE_library.h | 1 + source/blender/blenkernel/intern/action.c | 5 +---- source/blender/blenkernel/intern/armature.c | 3 +-- source/blender/blenkernel/intern/blender.c | 2 +- source/blender/blenkernel/intern/brush.c | 3 +-- source/blender/blenkernel/intern/curve.c | 5 +---- source/blender/blenkernel/intern/image.c | 3 +-- source/blender/blenkernel/intern/lattice.c | 3 +-- source/blender/blenkernel/intern/library.c | 19 +++++++++++++++++-- source/blender/blenkernel/intern/material.c | 3 +-- source/blender/blenkernel/intern/mball.c | 3 +-- source/blender/blenkernel/intern/mesh.c | 3 +-- source/blender/blenkernel/intern/object.c | 10 +++------- source/blender/blenkernel/intern/particle.c | 3 +-- source/blender/blenkernel/intern/speaker.c | 3 +-- source/blender/blenkernel/intern/texture.c | 3 +-- source/blender/blenkernel/intern/world.c | 3 +-- source/blender/blenlib/BLI_bpath.h | 10 +++++++--- source/blender/blenlib/intern/bpath.c | 5 +++++ 19 files changed, 47 insertions(+), 43 deletions(-) diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index e2033915caa..9130cac6cd6 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -49,6 +49,7 @@ void *alloc_libblock(struct ListBase *lb, short type, const char *name); void *copy_libblock(void *rt); void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action); +void BKE_id_lib_local_paths(struct Main *bmain, struct ID *id); void id_lib_extern(struct ID *id); void BKE_library_filepath_set(struct Library *lib, const char *filepath); void id_us_plus(struct ID *id); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 2a1794fe2fc..944f7c6a0b6 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -146,13 +146,10 @@ void make_local_action(bAction *act) id_clear_lib_data(bmain, &act->id); } else if (mlac.is_local && mlac.is_lib) { - char *bpath_user_data[2]= {bmain->name, act->id.lib->filepath}; - mlac.actn= copy_action(act); mlac.actn->id.us= 0; - /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &mlac.actn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &mlac.actn->id); BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac); } diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 9fba18dd7cf..e9a19b50a81 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -157,12 +157,11 @@ void make_local_armature(bArmature *arm) id_clear_lib_data(bmain, &arm->id); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, arm->id.lib->filepath}; bArmature *armn= copy_armature(arm); armn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &armn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &armn->id); for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data == arm) { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 6e343e874f1..d68b0b361d1 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -172,7 +172,7 @@ static void clean_paths(Main *main) { Scene *scene; - bpath_traverse_main(main, clean_paths_visit_cb, 0, NULL); + bpath_traverse_main(main, clean_paths_visit_cb, BPATH_TRAVERSE_SKIP_MULTIFILE, NULL); for(scene= main->scene.first; scene; scene= scene->id.next) { BLI_clean(scene->r.pic); diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 10f056e9b78..e78b89441c9 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -224,13 +224,12 @@ void make_local_brush(Brush *brush) } } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, brush->id.lib->filepath}; Brush *brushn= copy_brush(brush); brushn->id.us= 1; /* only keep fake user */ brushn->id.flag |= LIB_FAKEUSER; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &brushn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &brush->id); for(scene= bmain->scene.first; scene; scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 13b1da22449..5d2180fe702 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -273,13 +273,10 @@ void make_local_curve(Curve *cu) extern_local_curve(cu); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, cu->id.lib->filepath}; Curve *cun= copy_curve(cu); cun->id.us= 0; - - /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &cun->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &cun->id); for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==cu) { diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 9aeacb9d7fa..08440849a4e 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -385,13 +385,12 @@ void make_local_image(struct Image *ima) extern_local_image(ima); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, ima->id.lib->filepath}; Image *iman= copy_image(ima); iman->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &iman->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &iman->id); tex= bmain->tex.first; while(tex) { diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 9a528b54143..47878242604 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -271,12 +271,11 @@ void make_local_lattice(Lattice *lt) id_clear_lib_data(bmain, <->id); } else if(is_local && is_lib) { - char *bath_user_data[2]= {bmain->name, lt->id.lib->filepath}; Lattice *ltn= copy_lattice(lt); ltn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, <n->id, bpath_relocate_visitor, 0, bath_user_data); + BKE_id_lib_local_paths(bmain, <n->id); for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==lt) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 9d8acc44e88..35b50730a31 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -127,6 +127,21 @@ /* ************* general ************************ */ + +/* this has to be called from each make_local_* func, we could call + * from id_make_local() but then the make local functions would not be self + * contained. + * also note that the id _must_ have a library - campbell */ +void BKE_id_lib_local_paths(Main *bmain, ID *id) +{ + char *bpath_user_data[2]= {bmain->name, (id)->lib->filepath}; + + bpath_traverse_id(bmain, id, + bpath_relocate_visitor, + BPATH_TRAVERSE_SKIP_MULTIFILE, + bpath_user_data); +} + void id_lib_extern(ID *id) { if(id) { @@ -1252,8 +1267,8 @@ int new_id(ListBase *lb, ID *id, const char *tname) don't have other library users. */ void id_clear_lib_data(Main *bmain, ID *id) { - char *bpath_user_data[2]= {bmain->name, id->lib->filepath}; - bpath_traverse_id(bmain, id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, id); + id->lib= NULL; id->flag= LIB_LOCAL; new_id(which_libbase(bmain, GS(id->name)), id, NULL); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 2ad3da9f3a0..7be3514e0f2 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -364,13 +364,12 @@ void make_local_material(Material *ma) } /* Both user and local, so copy. */ else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, ma->id.lib->filepath}; Material *man= copy_material(ma); man->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &man->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &man->id); /* do objects */ ob= bmain->object.first; diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 98646bd2faa..327306b32ee 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -174,12 +174,11 @@ void make_local_mball(MetaBall *mb) extern_local_mball(mb); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, mb->id.lib->filepath}; MetaBall *mbn= copy_mball(mb); mbn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &mbn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &mbn->id); for(ob= G.main->object.first; ob; ob= ob->id.next) { if(ob->data == mb) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 6f66e189dcf..4a8bc34cdf7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -298,13 +298,12 @@ void make_local_mesh(Mesh *me) expand_local_mesh(me); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, me->id.lib->filepath}; Mesh *men= copy_mesh(me); men->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &men->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &men->id); for(ob= bmain->object.first; ob; ob= ob->id.next) { if(me == ob->data) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 0d0552cf3b3..635e0744aa1 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -772,13 +772,12 @@ void make_local_camera(Camera *cam) id_clear_lib_data(bmain, &cam->id); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, cam->id.lib->filepath}; Camera *camn= copy_camera(cam); camn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &camn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &camn->id); for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data == cam) { @@ -939,13 +938,11 @@ void make_local_lamp(Lamp *la) id_clear_lib_data(bmain, &la->id); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, la->id.lib->filepath}; Lamp *lan= copy_lamp(la); lan->id.us= 0; - /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &lan->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &lan->id); ob= bmain->object.first; while(ob) { @@ -1486,13 +1483,12 @@ void make_local_object(Object *ob) extern_local_object(ob); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, ob->id.lib->filepath}; Object *obn= copy_object(ob); obn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &obn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &obn->id); sce= bmain->scene.first; while(sce) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index a1ed0862336..7678da1c7c4 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3632,13 +3632,12 @@ void make_local_particlesettings(ParticleSettings *part) expand_local_particlesettings(part); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, part->id.lib->filepath}; ParticleSettings *partn= psys_copy_settings(part); partn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &partn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &partn->id); /* do objects */ for(ob= bmain->object.first; ob; ob= ob->id.next) { diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index d5788d7a748..018c7a197ff 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -106,12 +106,11 @@ void make_local_speaker(Speaker *spk) id_clear_lib_data(bmain, &spk->id); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, spk->id.lib->filepath}; Speaker *spkn= copy_speaker(spk); spkn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &spkn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &spkn->id); ob= bmain->object.first; while(ob) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index e3713b1e177..d3bd7d7b766 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -897,13 +897,12 @@ void make_local_texture(Tex *tex) extern_local_texture(tex); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, tex->id.lib->filepath}; Tex *texn= copy_texture(tex); texn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &texn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &texn->id); ma= bmain->mat.first; while(ma) { diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 4d7a7c9a262..5797c6c3f15 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -176,12 +176,11 @@ void make_local_world(World *wrld) id_clear_lib_data(bmain, &wrld->id); } else if(is_local && is_lib) { - char *bpath_user_data[2]= {bmain->name, wrld->id.lib->filepath}; World *wrldn= copy_world(wrld); wrldn->id.us= 0; /* Remap paths of new ID using old library as base. */ - bpath_traverse_id(bmain, &wrldn->id, bpath_relocate_visitor, 0, bpath_user_data); + BKE_id_lib_local_paths(bmain, &wrldn->id); for(sce= bmain->scene.first; sce; sce= sce->id.next) { if(sce->world == wrld) { diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 89ba4b2675e..e850db5a171 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -48,9 +48,13 @@ void bpath_traverse_id_list(struct Main *bmain, struct ListBase *lb, BPathVisito void bpath_traverse_main(struct Main *bmain, BPathVisitor visit_cb, const int flag, void *userdata); int bpath_relocate_visitor(void *oldbasepath, char *path_dst, const char *path_src); -#define BPATH_TRAVERSE_ABS (1<<0) /* convert paths to absolute */ -#define BPATH_TRAVERSE_SKIP_LIBRARY (1<<2) /* skip library paths */ -#define BPATH_TRAVERSE_SKIP_PACKED (1<<3) /* skip packed data */ +#define BPATH_TRAVERSE_ABS (1<<0) /* convert paths to absolute */ +#define BPATH_TRAVERSE_SKIP_LIBRARY (1<<2) /* skip library paths */ +#define BPATH_TRAVERSE_SKIP_PACKED (1<<3) /* skip packed data */ +#define BPATH_TRAVERSE_SKIP_MULTIFILE (1<<4) /* skip paths where a single dir is used with an array of files, eg. + * sequence strip images and pointcache. in this case only use the first + * file, this is needed for directory manipulation functions which might + * otherwise modify the same directory multiple times */ /* high level funcs */ diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index b7fe7ef5efd..259b25e67dd 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -499,6 +499,11 @@ void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int fla int len= MEM_allocN_len(se) / sizeof(*se); int i; + if (flag & BPATH_TRAVERSE_SKIP_MULTIFILE) { + /* only operate on one path */ + len= MIN2(1, len); + } + for(i= 0; i < len; i++, se++) { rewrite_path_fixed_dirfile(seq->strip->dir, se->name, visit_cb, absbase, bpath_user_data); } From bcdcbb65c159cc16b222fc5381e806a6b4f03fb0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 06:45:36 +0000 Subject: [PATCH 017/147] macro to check if an object type supports vgroups --- source/blender/blenkernel/intern/constraint.c | 2 +- source/blender/blenkernel/intern/key.c | 2 +- source/blender/editors/object/object_vgroup.c | 5 ++--- source/blender/makesdna/DNA_object_types.h | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index c244c26ad7f..aebf3198cf4 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -703,7 +703,7 @@ static void default_get_tarmat (bConstraint *con, bConstraintOb *UNUSED(cob), bC ct->type = CONSTRAINT_OBTYPE_BONE; \ ct->rotOrder= (pchan) ? (pchan->rotmode) : EULER_ORDER_DEFAULT; \ }\ - else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) { \ + else if (OB_TYPE_SUPPORT_VGROUP(ct->tar->type) && (ct->subtarget[0])) { \ ct->type = CONSTRAINT_OBTYPE_VERT; \ ct->rotOrder = EULER_ORDER_DEFAULT; \ } \ diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 0a467142f74..6d095117136 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1381,7 +1381,7 @@ float *do_ob_key(Scene *scene, Object *ob) ob->shapenr= 1; } - if(ELEM(ob->type, OB_MESH, OB_LATTICE)) { + if (OB_TYPE_SUPPORT_VGROUP(ob->type)) { float *weights= get_weights_array(ob, kb->vgroup); cp_key(0, tot, tot, out, key, actkb, kb, weights, 0); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d4ee68f8b72..ce6730ab1ed 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -99,8 +99,7 @@ int ED_vgroup_object_is_edit_mode(Object *ob) bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name) { bDeformGroup *defgroup; - - if(!ob || !ELEM(ob->type, OB_MESH, OB_LATTICE)) + if(!ob || !OB_TYPE_SUPPORT_VGROUP(ob->type)) return NULL; defgroup = MEM_callocN(sizeof(bDeformGroup), "add deformGroup"); @@ -2013,7 +2012,7 @@ static int vertex_group_poll(bContext *C) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; ID *data= (ob)? ob->data: NULL; - return (ob && !ob->id.lib && ELEM(ob->type, OB_MESH, OB_LATTICE) && data && !data->lib); + return (ob && !ob->id.lib && OB_TYPE_SUPPORT_VGROUP(ob->type) && data && !data->lib); } static int vertex_group_poll_edit(bContext *C) diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 19eff756ce1..38daf8bae28 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -321,6 +321,7 @@ typedef struct DupliObject { /* check if the object type supports materials */ #define OB_TYPE_SUPPORT_MATERIAL(_type) ((_type) >= OB_MESH && (_type) <= OB_MBALL) +#define OB_TYPE_SUPPORT_VGROUP(_type) (ELEM(_type, OB_MESH, OB_LATTICE)) /* partype: first 4 bits: type */ #define PARTYPE 15 From 2ad80bf3bb807a5d433406794becb6aaafd415f9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 08:11:55 +0000 Subject: [PATCH 018/147] vertex group mirror - now works in vertex select + weight paint mode. - added option not to mirror all vertex groups. --- release/scripts/startup/bl_ui/space_view3d.py | 1 + .../startup/bl_ui/space_view3d_toolbar.py | 1 + source/blender/blenkernel/BKE_deform.h | 1 + source/blender/blenkernel/intern/deform.c | 42 +++++- source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/object/object_vgroup.c | 129 ++++++++++++++---- 6 files changed, 147 insertions(+), 29 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 1170bce2c14..dceab4a72e8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1086,6 +1086,7 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_normalize_all", text="Normalize All") layout.operator("object.vertex_group_normalize", text="Normalize") + layout.operator("object.vertex_group_mirror", text="Mirror") layout.operator("object.vertex_group_invert", text="Invert") layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 4a5fcfd4c49..14774c2215a 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1036,6 +1036,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.active = ob.vertex_groups.active is not None col.operator("object.vertex_group_normalize_all", text="Normalize All") col.operator("object.vertex_group_normalize", text="Normalize") + col.operator("object.vertex_group_mirror", text="Mirror") col.operator("object.vertex_group_invert", text="Invert") col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 84a6517fd52..71814799050 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -45,6 +45,7 @@ struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup); struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name); int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg); int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default); +int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, int use_default, int defgroup); int defgroup_flip_index(struct Object *ob, int index, int use_default); int defgroup_name_index(struct Object *ob, const char *name); void defgroup_unique_name(struct bDeformGroup *dg, struct Object *ob); diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 83eda860510..0c3c78f6eef 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -257,17 +257,19 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg) /* note, must be freed */ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) { - bDeformGroup *dg; int totdg= *flip_map_len= BLI_countlist(&ob->defbase); if(totdg==0) { return NULL; } else { + bDeformGroup *dg; char name[sizeof(dg->name)]; int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); - memset(map, -1, totdg * sizeof(int)); + for (i=0; i < totdg; i++) { + map[i]= -1; + } for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { if(map[i] == -1) { /* may be calculated previously */ @@ -276,7 +278,7 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) if(use_default) map[i]= i; - flip_side_name(name, dg->name, 0); + flip_side_name(name, dg->name, FALSE); if(strcmp(name, dg->name)) { flip_num= defgroup_name_index(ob, name); if(flip_num >= 0) { @@ -290,6 +292,40 @@ int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default) } } +/* note, must be freed */ +int *defgroup_flip_map_single(Object *ob, int *flip_map_len, int use_default, int defgroup) +{ + int totdg= *flip_map_len= BLI_countlist(&ob->defbase); + + if(totdg==0) { + return NULL; + } + else { + bDeformGroup *dg; + char name[sizeof(dg->name)]; + int i, flip_num, *map= MEM_mallocN(totdg * sizeof(int), __func__); + + for (i=0; i < totdg; i++) { + if (use_default) map[i]= i; + else map[i]= -1; + } + + dg= BLI_findlink(&ob->defbase, defgroup); + + flip_side_name(name, dg->name, FALSE); + if(strcmp(name, dg->name)) { + flip_num= defgroup_name_index(ob, name); + + if(flip_num >= 0) { + map[defgroup]= flip_num; + map[flip_num]= defgroup; + } + } + + return map; + } +} + int defgroup_flip_index(Object *ob, int index, int use_default) { bDeformGroup *dg= BLI_findlink(&ob->defbase, index); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 5d1e02a6cab..414ca671ef2 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -209,7 +209,7 @@ void ED_vgroup_select_by_name(struct Object *ob, const char *name); int ED_vgroup_data_create(struct ID *id); int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); -void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups); +void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups); int ED_vgroup_object_is_edit_mode(struct Object *ob); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index ce6730ab1ed..a59ca5ad954 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -1527,14 +1527,32 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single) static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, const char sel, const char sel_mirr, const int *flip_map, const int flip_map_len, - const short mirror_weights, const short flip_vgroups) + const short mirror_weights, const short flip_vgroups, + const short all_vgroups, const int act_vgroup) { BLI_assert(sel || sel_mirr); if(sel_mirr && sel) { /* swap */ - if(mirror_weights) - SWAP(MDeformVert, *dvert, *dvert_mirr); + if(mirror_weights) { + if (all_vgroups) { + SWAP(MDeformVert, *dvert, *dvert_mirr); + } + else { + MDeformWeight *dw= defvert_find_index(dvert, act_vgroup); + MDeformWeight *dw_mirr= defvert_find_index(dvert_mirr, act_vgroup); + + if (dw || dw_mirr) { + if (dw_mirr == NULL) + dw_mirr= defvert_verify_index(dvert_mirr, act_vgroup); + if (dw == NULL) + dw= defvert_verify_index(dvert, act_vgroup); + + SWAP(float, dw->weight, dw_mirr->weight); + } + } + } + if(flip_vgroups) { defvert_flip(dvert, flip_map, flip_map_len); defvert_flip(dvert_mirr, flip_map, flip_map_len); @@ -1554,52 +1572,109 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, } } -void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups) +/* TODO, vgroup locking */ +/* TODO, face masking */ +void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups) { -#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, flip_map_len, mirror_weights, flip_vgroups) + +#define VGROUP_MIRR_OP \ + dvert_mirror_op(dvert, dvert_mirr, \ + sel, sel_mirr, \ + flip_map, flip_map_len, \ + mirror_weights, flip_vgroups, \ + all_vgroups, act_vgroup \ + ) EditVert *eve, *eve_mirr; MDeformVert *dvert, *dvert_mirr; short sel, sel_mirr; int *flip_map, flip_map_len; + const int act_vgroup= ob->actdef > 0 ? ob->actdef-1 : 0; if(mirror_weights==0 && flip_vgroups==0) return; - flip_map= defgroup_flip_map(ob, &flip_map_len, FALSE); + flip_map= all_vgroups ? + defgroup_flip_map(ob, &flip_map_len, FALSE) : + defgroup_flip_map_single(ob, &flip_map_len, FALSE, act_vgroup); /* only the active group */ if(ob->type == OB_MESH) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); + if (em) { + if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { + MEM_freeN(flip_map); + return; + } - if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { - MEM_freeN(flip_map); - return; + EM_cache_x_mirror_vert(ob, em); + + /* Go through the list of editverts and assign them */ + for(eve=em->verts.first; eve; eve=eve->next){ + if((eve_mirr=eve->tmp.v)) { + sel= eve->f & SELECT; + sel_mirr= eve_mirr->f & SELECT; + + if((sel || sel_mirr) && (eve != eve_mirr)) { + dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); + dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT); + if(dvert && dvert_mirr) { + VGROUP_MIRR_OP; + } + } + + eve->tmp.v= eve_mirr->tmp.v= NULL; + } + } + + BKE_mesh_end_editmesh(me, em); } + else { + /* object mode / weight paint */ + MVert *mv, *mv_mirr; + int vidx, vidx_mirr; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; - EM_cache_x_mirror_vert(ob, em); + if (me->dvert == NULL) { + MEM_freeN(flip_map); + return; + } - /* Go through the list of editverts and assign them */ - for(eve=em->verts.first; eve; eve=eve->next){ - if((eve_mirr=eve->tmp.v)) { - sel= eve->f & SELECT; - sel_mirr= eve_mirr->f & SELECT; + if (!use_vert_sel) { + sel= sel_mirr= TRUE; + } + + /* tag verts we have used */ + for(vidx= 0, mv= me->mvert; vidx < me->totvert; vidx++, mv++) { + mv->flag &= ~ME_VERT_TMP_TAG; + } + + for(vidx= 0, mv= me->mvert; vidx < me->totvert; vidx++, mv++) { + if ( ((mv->flag & ME_VERT_TMP_TAG) == 0) && + ((vidx_mirr= mesh_get_x_mirror_vert(ob, vidx)) != -1) && + (vidx != vidx_mirr) && + ((((mv_mirr= me->mvert + vidx_mirr)->flag) & ME_VERT_TMP_TAG) == 0)) + { + + if (use_vert_sel) { + sel= mv->flag & SELECT; + sel_mirr= mv_mirr->flag & SELECT; + } + + if (sel || sel_mirr) { + dvert= &me->dvert[vidx]; + dvert_mirr= &me->dvert[vidx_mirr]; - if((sel || sel_mirr) && (eve != eve_mirr)) { - dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); - dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT); - if(dvert && dvert_mirr) { VGROUP_MIRR_OP; } - } - eve->tmp.v= eve_mirr->tmp.v= NULL; + mv->flag |= ME_VERT_TMP_TAG; + mv_mirr->flag |= ME_VERT_TMP_TAG; + } } } - - BKE_mesh_end_editmesh(me, em); } else if (ob->type == OB_LATTICE) { Lattice *lt= ob->data; @@ -2508,7 +2583,10 @@ static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr,"mirror_weights"), RNA_boolean_get(op->ptr,"flip_group_names")); + ED_vgroup_mirror(ob, + RNA_boolean_get(op->ptr,"mirror_weights"), + RNA_boolean_get(op->ptr,"flip_group_names"), + RNA_boolean_get(op->ptr,"all_groups")); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); @@ -2526,7 +2604,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) "flipping when both sides are selected otherwise copy from unselected"; /* api callbacks */ - ot->poll= vertex_group_poll_edit; + ot->poll= vertex_group_poll; ot->exec= vertex_group_mirror_exec; /* flags */ @@ -2535,6 +2613,7 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) /* properties */ RNA_def_boolean(ot->srna, "mirror_weights", TRUE, "Mirror Weights", "Mirror weights"); RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Groups", "Flip vertex group names"); + RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Mirror all vertex groups weights"); } From dd8a575c22db8b6e1a78610115cf7e369f26ae0c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 09:47:19 +0000 Subject: [PATCH 019/147] correct header, for some reason gcc doesnt warn about this --- source/blender/blenkernel/BKE_deform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 71814799050..3e643fe961c 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -58,7 +58,7 @@ float defvert_array_find_weight_safe(const struct MDeformVert *dvert, int index void defvert_copy(struct MDeformVert *dvert_r, const struct MDeformVert *dvert); void defvert_sync(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, int use_verify); -void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, const int flip_map_len, int use_verify); +void defvert_sync_mapped(struct MDeformVert *dvert_r, const struct MDeformVert *dvert, const int *flip_map, const int flip_map_len, const int use_verify); void defvert_remap (struct MDeformVert *dvert, int *map); void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len); void defvert_normalize(struct MDeformVert *dvert); From 4b48a5a497136e6839474a7089e9674fe31b1fc9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 1 Nov 2011 11:00:08 +0000 Subject: [PATCH 020/147] Fix #29101: 2D Tilt on Bezier Curve Bug? Changing tilt for 2D curves doesn't really hurt, just makes things not so clear tosee what's going on because you're changing value which isn't used at all for 2D curves. Disallwo to run TRANSFORM_OT_tilt operator for 2D curves. Also made a correct fix for incorrect shortcut for tilt in 3D viewport toolbar, it was really confusing to have almost the same operators (TRANSFORM_OT_tilt and TRANSFORM_OT_transform with mode=tilt) in keymap. Better to use tilt operator in toolbar. --- release/scripts/startup/bl_ui/space_view3d_toolbar.py | 2 +- source/blender/editors/curve/curve_ops.c | 1 - source/blender/editors/include/ED_screen.h | 1 + source/blender/editors/screen/screen_ops.c | 11 +++++++++++ source/blender/editors/transform/transform_ops.c | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 14774c2215a..9518ccb5f80 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -209,7 +209,7 @@ class VIEW3D_PT_tools_curveedit(View3DPanel, Panel): col.operator("transform.resize", text="Scale") col = layout.column(align=True) - col.operator("transform.transform", text="Tilt").mode = 'TILT' + col.operator("transform.tilt", text="Tilt") col.operator("transform.transform", text="Shrink/Fatten").mode = 'CURVE_SHRINKFATTEN' col = layout.column(align=True) diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index be6b322e6b4..95f3bb55ba5 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -223,7 +223,6 @@ void ED_keymap_curve(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_tilt", TKEY, KM_PRESS, KM_CTRL, 0); - RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", TFM_TILT); RNA_enum_set(WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_CURVE_SHRINKFATTEN); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index f92ee724f6f..05537004927 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -159,6 +159,7 @@ int ED_operator_editmesh_view3d(struct bContext *C); int ED_operator_editmesh_region_view3d(struct bContext *C); int ED_operator_editarmature(struct bContext *C); int ED_operator_editcurve(struct bContext *C); +int ED_operator_editcurve_3d(struct bContext *C); int ED_operator_editsurf(struct bContext *C); int ED_operator_editsurfcurve(struct bContext *C); int ED_operator_editsurfcurve_region_view3d(struct bContext *C); diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 0a7e3a2763a..171adc8d89a 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -406,6 +406,17 @@ int ED_operator_editcurve(bContext *C) return 0; } +int ED_operator_editcurve_3d(bContext *C) +{ + Object *obedit= CTX_data_edit_object(C); + if(obedit && obedit->type==OB_CURVE) { + Curve *cu= (Curve *)obedit->data; + + return (cu->flag&CU_3D) && (NULL != cu->editnurb); + } + return 0; +} + int ED_operator_editsurf(bContext *C) { Object *obedit= CTX_data_edit_object(C); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 2d3c1d80d8d..f926f442830 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -610,7 +610,7 @@ void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->exec = transform_exec; ot->modal = transform_modal; ot->cancel = transform_cancel; - ot->poll = ED_operator_editcurve; + ot->poll = ED_operator_editcurve_3d; RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2); From d55298ee3c67dfa2044759bcff01929465ef1b18 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 1 Nov 2011 14:51:44 +0000 Subject: [PATCH 021/147] Fix #29109: bpy.ops.render.render() with scene parameter missed compositing, previous bugfix needed a bit more refining. --- source/blender/editors/render/render_internal.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 2f0958371f9..9c38b1ce98f 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -223,20 +223,26 @@ static int screen_render_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); SceneRenderLayer *srl= NULL; - Render *re= RE_NewRender(scene->id.name); + Render *re; Image *ima; View3D *v3d= CTX_wm_view3d(C); Main *mainp= CTX_data_main(C); - unsigned int lay= (v3d)? v3d->lay: scene->lay; + unsigned int lay; const short is_animation= RNA_boolean_get(op->ptr, "animation"); const short is_write_still= RNA_boolean_get(op->ptr, "write_still"); struct Object *camera_override= v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; + /* custom scene and single layer re-render */ + screen_render_scene_layer_set(op, mainp, &scene, &srl); + if(!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.imtype)) { BKE_report(op->reports, RPT_ERROR, "Can't write a single file with an animation format selected"); return OPERATOR_CANCELLED; } + re= RE_NewRender(scene->id.name); + lay= (v3d)? v3d->lay: scene->lay; + G.afbreek= 0; RE_test_break_cb(re, NULL, (int (*)(void *)) blender_test_break); @@ -252,9 +258,6 @@ static int screen_render_exec(bContext *C, wmOperator *op) RE_SetReports(re, op->reports); - /* custom scene and single layer re-render */ - screen_render_scene_layer_set(op, mainp, &scene, &srl); - if(is_animation) RE_BlenderAnim(re, mainp, scene, camera_override, lay, scene->r.sfra, scene->r.efra, scene->r.frame_step); else From 2241eaddf55f87306c10053b263e62ca95f4ce3a Mon Sep 17 00:00:00 2001 From: Andrew Wiggin Date: Tue, 1 Nov 2011 17:06:10 +0000 Subject: [PATCH 022/147] Reverting r41409 (broken fix for #29089) r41409 can cause a crash if you delete a face of a mesh that has subsurf & solidify modifiers active --- source/blender/modifiers/intern/MOD_solidify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index b8e95ad4c51..8d47ad28a86 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -626,7 +626,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); #endif - origindex[numFaces * 2 + i]= fidx; + origindex[numFaces * 2 + i]= ORIGINDEX_NONE; } #ifdef SOLIDIFY_SIDE_NORMALS From c70cde6f94884f67cc9d4fb0546a50d2a7f96f65 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 1 Nov 2011 17:43:30 +0000 Subject: [PATCH 023/147] Fix #29124: Modifying mesh with mirror and solidify modifiers crashes blender It is corrected fix for #29089 (svn rev 41409). That fix wasn't correct because it used to set face number from derived mesh on which solidify is applying which isn't correct for case of constructive modifiers applied on base mesh before solidify modifier. Actually nothing special should be performed here to set needed original index because of ORIGINDEX layer is getting copyed automatically when when copying faces. --- source/blender/modifiers/intern/MOD_solidify.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 8d47ad28a86..347af0066c6 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -626,7 +626,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); #endif - origindex[numFaces * 2 + i]= ORIGINDEX_NONE; } #ifdef SOLIDIFY_SIDE_NORMALS From 785de4cbfc424fb095ed549f6d9e733014224a51 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Tue, 1 Nov 2011 18:27:09 +0000 Subject: [PATCH 024/147] == Cleanup of SpaceImasel == * removed struct for SpaceType and all usages * SPACE_IMASEL in enum nees to be kept to identify it in old files * it is replaces with SPACE_EMPTY on load, which is overridden by SPACE_INFO which has same struct members * also removed theme settings --- source/blender/blenloader/BLO_readfile.h | 1 - source/blender/blenloader/intern/readfile.c | 64 +------------------- source/blender/blenloader/intern/writefile.c | 4 -- source/blender/editors/interface/resources.c | 16 ----- source/blender/makesdna/DNA_space_types.h | 64 +------------------- source/blender/makesdna/DNA_userdef_types.h | 1 - source/blender/makesrna/intern/rna_space.c | 3 - source/blender/python/simple_enum_gen.py | 2 +- 8 files changed, 5 insertions(+), 150 deletions(-) diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 1777979c3ab..38925ea5238 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -44,7 +44,6 @@ struct MemFile; struct ReportList; struct Scene; struct SpaceFile; -struct SpaceImaSel; struct UserDef; struct bContext; struct BHead; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 16da7321524..bb068ac80eb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4927,15 +4927,6 @@ static void lib_link_screen(FileData *fd, Main *main) sfile->folders_prev= NULL; sfile->folders_next= NULL; } - else if(sl->spacetype==SPACE_IMASEL) { - SpaceImaSel *simasel= (SpaceImaSel *)sl; - - simasel->files = NULL; - simasel->returnfunc= NULL; - simasel->menup= NULL; - simasel->pupmenu= NULL; - simasel->img= NULL; - } else if(sl->spacetype==SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)sl; bDopeSheet *ads= &saction->ads; @@ -5160,12 +5151,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) SpaceFile *sfile= (SpaceFile *)sl; sfile->op= NULL; } - else if(sl->spacetype==SPACE_IMASEL) { - SpaceImaSel *simasel= (SpaceImaSel *)sl; - if (simasel->files) { - //XXX BIF_filelist_freelib(simasel->files); - } - } else if(sl->spacetype==SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)sl; @@ -6749,11 +6734,11 @@ static void do_versions_windowmanager_2_50(bScreen *screen) area_add_window_regions(sa, sa->spacedata.first, &sa->regionbase); - /* space imageselect is depricated */ + /* space imageselect is deprecated */ for(sl= sa->spacedata.first; sl; sl= sl->next) { if(sl->spacetype==SPACE_IMASEL) - sl->spacetype= SPACE_INFO; /* spacedata then matches */ - } + sl->spacetype= SPACE_EMPTY; /* spacedata then matches */ + } /* it seems to be possible in 2.5 to have this saved, filewindow probably */ sa->butspacetype= sa->spacetype; @@ -9243,49 +9228,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for(ima= main->image.first; ima; ima= ima->id.next) { ima->preview = NULL; } - - /* repair imasel space - completely reworked */ - for(sc= main->screen.first; sc; sc= sc->id.next) { - ScrArea *sa; - sa= sc->areabase.first; - while(sa) { - SpaceLink *sl; - - for (sl= sa->spacedata.first; sl; sl= sl->next) { - if(sl->spacetype==SPACE_IMASEL) { - SpaceImaSel *simasel= (SpaceImaSel*) sl; - simasel->blockscale= 0.7f; - /* view 2D */ - simasel->v2d.tot.xmin= -10.0f; - simasel->v2d.tot.ymin= -10.0f; - simasel->v2d.tot.xmax= (float)sa->winx + 10.0f; - simasel->v2d.tot.ymax= (float)sa->winy + 10.0f; - simasel->v2d.cur.xmin= 0.0f; - simasel->v2d.cur.ymin= 0.0f; - simasel->v2d.cur.xmax= (float)sa->winx; - simasel->v2d.cur.ymax= (float)sa->winy; - simasel->v2d.min[0]= 1.0; - simasel->v2d.min[1]= 1.0; - simasel->v2d.max[0]= 32000.0f; - simasel->v2d.max[1]= 32000.0f; - simasel->v2d.minzoom= 0.5f; - simasel->v2d.maxzoom= 1.21f; - simasel->v2d.scroll= 0; - simasel->v2d.keepzoom= V2D_LIMITZOOM|V2D_KEEPASPECT; - simasel->v2d.keeptot= 0; - simasel->prv_h = 96; - simasel->prv_w = 96; - simasel->flag = 7; /* ??? elubie */ - BLI_strncpy (simasel->dir, U.textudir, sizeof(simasel->dir)); /* TON */ - simasel->file[0]= '\0'; - - simasel->returnfunc = NULL; - simasel->title[0] = 0; - } - } - sa = sa->next; - } - } } /* add point caches */ diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f0f5ab283a6..18807f911ed 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2205,10 +2205,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) if(sima->cumap) write_curvemapping(wd, sima->cumap); } - else if(sl->spacetype==SPACE_IMASEL) { - // XXX: depreceated... do we still want to keep this? - writestruct(wd, DATA, "SpaceImaSel", 1, sl); - } else if(sl->spacetype==SPACE_TEXT) { writestruct(wd, DATA, "SpaceText", 1, sl); } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index d3a5c6691ef..4318feca737 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -129,9 +129,6 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case SPACE_IMAGE: ts= &btheme->tima; break; - case SPACE_IMASEL: - ts= &btheme->timasel; - break; case SPACE_TEXT: ts= &btheme->text; break; @@ -533,7 +530,6 @@ static void ui_theme_init_new(bTheme *btheme) ui_theme_init_new_do(&btheme->tnla); ui_theme_init_new_do(&btheme->tseq); ui_theme_init_new_do(&btheme->tima); - ui_theme_init_new_do(&btheme->timasel); ui_theme_init_new_do(&btheme->text); ui_theme_init_new_do(&btheme->toops); ui_theme_init_new_do(&btheme->ttime); @@ -731,18 +727,6 @@ void ui_theme_init_default(void) SETCOL(btheme->tima.editmesh_active, 255, 255, 255, 128); SETCOLF(btheme->tima.preview_back, 0.45, 0.45, 0.45, 1.0); - /* space imageselect */ - btheme->timasel= btheme->tv3d; - SETCOL(btheme->timasel.active, 195, 195, 195, 255); /* active tile */ - SETCOL(btheme->timasel.grid, 94, 94, 94, 255); /* active file text */ - SETCOL(btheme->timasel.back, 110, 110, 110, 255); - SETCOL(btheme->timasel.shade1, 94, 94, 94, 255); /* bar */ - SETCOL(btheme->timasel.shade2, 172, 172, 172, 255); /* sliders */ - SETCOL(btheme->timasel.hilite, 17, 27, 60, 100); /* selected tile */ - SETCOL(btheme->timasel.text, 0, 0, 0, 255); - SETCOL(btheme->timasel.text_hi, 255, 255, 255, 255); - SETCOL(btheme->timasel.panel, 132, 132, 132, 255); - /* space text */ btheme->text= btheme->tv3d; SETCOL(btheme->text.back, 153, 153, 153, 255); diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 3b5ecbe59d8..d21db85b1f3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -432,68 +432,6 @@ typedef struct SpaceLogic { struct bGPdata *gpd; /* grease-pencil data */ } SpaceLogic; -/* note, this entire struct isnt used anymore!, - * may remove some day - campbell */ -typedef struct SpaceImaSel { - SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ - int spacetype; - float blockscale; - - short blockhandler[8]; - - View2D v2d; /* deprecated, copied to region */ - - struct FileList *files; - - /* specific stuff for drawing */ - char title[24]; - char dir[240]; - char file[80]; - - short type, menu, flag, sort; - - void *curfont; - int active_file; - - int numtilesx; - int numtilesy; - - int selstate; - - struct rcti viewrect; - struct rcti bookmarkrect; - - float scrollpos; /* current position of scrollhandle */ - float scrollheight; /* height of the scrollhandle */ - float scrollarea; /* scroll region, scrollpos is from 0 to scrollarea */ - - float aspect; - unsigned short retval; /* event */ - - short ipotype; - - short filter; - short active_bookmark; - short pad, pad1; - - /* view settings */ - short prv_w; - short prv_h; - - /* one day we'll add unions to dna */ - void (*returnfunc)(char *); - void (*returnfunc_event)(unsigned short); - void (*returnfunc_args)(char *, void *, void *); - - void *arg1, *arg2; - short *menup; /* pointer to menu result or ID browsing */ - char *pupmenu; /* optional menu in header */ - - struct ImBuf *img; -} SpaceImaSel; - - typedef struct ConsoleLine { struct ConsoleLine *next, *prev; @@ -947,7 +885,7 @@ enum { SPACE_INFO, SPACE_SEQ, SPACE_TEXT, - SPACE_IMASEL, + SPACE_IMASEL, /* deprecated */ SPACE_SOUND, SPACE_ACTION, SPACE_NLA, diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index a3934618582..4859268d477 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -273,7 +273,6 @@ typedef struct bTheme { ThemeSpace tnla; ThemeSpace tseq; ThemeSpace tima; - ThemeSpace timasel; ThemeSpace text; ThemeSpace toops; ThemeSpace ttime; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 29a2723182b..58ed9c50df5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -60,7 +60,6 @@ EnumPropertyItem space_type_items[] = { {SPACE_INFO, "INFO", 0, "Info", ""}, {SPACE_SEQ, "SEQUENCE_EDITOR", 0, "Sequence Editor", ""}, {SPACE_TEXT, "TEXT_EDITOR", 0, "Text Editor", ""}, - //{SPACE_IMASEL, "IMAGE_BROWSER", 0, "Image Browser", ""}, {SPACE_SOUND, "AUDIO_WINDOW", 0, "Audio Window", ""}, {SPACE_ACTION, "DOPESHEET_EDITOR", 0, "DopeSheet Editor", ""}, {SPACE_NLA, "NLA_EDITOR", 0, "NLA Editor", ""}, @@ -152,8 +151,6 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) return &RNA_SpaceSequenceEditor; case SPACE_TEXT: return &RNA_SpaceTextEditor; - //case SPACE_IMASEL: - // return &RNA_SpaceImageBrowser; /*case SPACE_SOUND: return &RNA_SpaceAudioWindow;*/ case SPACE_ACTION: diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py index bc7a2df9fb6..1455747cdbb 100644 --- a/source/blender/python/simple_enum_gen.py +++ b/source/blender/python/simple_enum_gen.py @@ -29,7 +29,7 @@ defs = """ SPACE_INFO, SPACE_SEQ, SPACE_TEXT, - SPACE_IMASEL, + SPACE_IMASEL, #Deprecated SPACE_SOUND, SPACE_ACTION, SPACE_NLA, From ea2f7c907c5de85b34c2c0a87bf4dd0a347004d3 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 1 Nov 2011 19:48:45 +0000 Subject: [PATCH 025/147] == Removal of SpaceSound == * Removed old, unused Space Sound space * Removed data struct and Theme settings * Old files with an open Audio window will be loaded as Info Space --- source/blender/blenloader/intern/readfile.c | 26 +- source/blender/blenloader/intern/writefile.c | 3 - source/blender/editors/CMakeLists.txt | 1 - source/blender/editors/SConscript | 1 - .../blender/editors/animation/anim_markers.c | 6 +- source/blender/editors/include/ED_space_api.h | 1 - source/blender/editors/interface/resources.c | 25 +- source/blender/editors/screen/screen_ops.c | 2 +- source/blender/editors/space_api/spacetypes.c | 1 - .../editors/space_sound/CMakeLists.txt | 43 --- source/blender/editors/space_sound/SConscript | 9 - .../editors/space_sound/sound_header.c | 127 --------- .../editors/space_sound/sound_intern.h | 42 --- .../blender/editors/space_sound/space_sound.c | 266 ------------------ source/blender/makesdna/DNA_space_types.h | 18 +- source/blender/makesdna/DNA_userdef_types.h | 3 +- source/blender/makesrna/intern/rna_space.c | 3 - source/blender/makesrna/intern/rna_userdef.c | 32 --- source/blender/python/simple_enum_gen.py | 2 +- 19 files changed, 23 insertions(+), 588 deletions(-) delete mode 100644 source/blender/editors/space_sound/CMakeLists.txt delete mode 100644 source/blender/editors/space_sound/SConscript delete mode 100644 source/blender/editors/space_sound/sound_header.c delete mode 100644 source/blender/editors/space_sound/sound_intern.h delete mode 100644 source/blender/editors/space_sound/space_sound.c diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bb068ac80eb..4700a41d003 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4990,11 +4990,6 @@ static void lib_link_screen(FileData *fd, Main *main) } } } - else if(sl->spacetype==SPACE_SOUND) { - SpaceSound *ssound= (SpaceSound *)sl; - - ssound->sound= newlibadr_us(fd, sc->id.lib, ssound->sound); - } else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; @@ -5217,11 +5212,6 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) } } } - else if(sl->spacetype==SPACE_SOUND) { - SpaceSound *ssound= (SpaceSound *)sl; - - ssound->sound= restore_pointer_by_name(newmain, (ID *)ssound->sound, 1); - } else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; @@ -6609,16 +6599,6 @@ static void area_add_window_regions(ScrArea *sa, SpaceLink *sl, ListBase *lb) //ar->v2d.flag |= V2D_IS_INITIALISED; break; } - case SPACE_SOUND: - { - SpaceSound *ssound= (SpaceSound *)sl; - memcpy(&ar->v2d, &ssound->v2d, sizeof(View2D)); - - ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); - ar->v2d.scroll |= (V2D_SCROLL_LEFT); - //ar->v2d.flag |= V2D_IS_INITIALISED; - break; - } case SPACE_NLA: { SpaceNla *snla= (SpaceNla *)sl; @@ -6740,6 +6720,12 @@ static void do_versions_windowmanager_2_50(bScreen *screen) sl->spacetype= SPACE_EMPTY; /* spacedata then matches */ } + /* space sound is deprecated */ + for(sl= sa->spacedata.first; sl; sl= sl->next) { + if(sl->spacetype==SPACE_SOUND) + sl->spacetype= SPACE_EMPTY; /* spacedata then matches */ + } + /* it seems to be possible in 2.5 to have this saved, filewindow probably */ sa->butspacetype= sa->spacetype; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 18807f911ed..4640fa0fe04 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2216,9 +2216,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) else if(sl->spacetype==SPACE_ACTION) { writestruct(wd, DATA, "SpaceAction", 1, sl); } - else if(sl->spacetype==SPACE_SOUND) { - writestruct(wd, DATA, "SpaceSound", 1, sl); - } else if(sl->spacetype==SPACE_NLA){ SpaceNla *snla= (SpaceNla *)sl; diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 16c0d4a2c79..7b7d11bd487 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -46,7 +46,6 @@ if(WITH_BLENDER) add_subdirectory(space_outliner) add_subdirectory(space_script) add_subdirectory(space_sequencer) - add_subdirectory(space_sound) add_subdirectory(space_text) add_subdirectory(space_time) add_subdirectory(space_userpref) diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index e8159bdf03f..a1b766ec2be 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -25,7 +25,6 @@ SConscript(['datafiles/SConscript', 'space_outliner/SConscript', 'space_time/SConscript', 'space_view3d/SConscript', - 'space_sound/SConscript', 'space_action/SConscript', 'space_nla/SConscript', 'space_script/SConscript', diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 5345fcd756d..4a359acabd9 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -777,7 +777,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) fac= ((float)(evt->x - mm->firstx)*dx); - if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) + if (mm->slink->spacetype == SPACE_TIME) apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1*FPS, 0); else apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/); @@ -796,7 +796,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) if (totmark==1) { /* we print current marker value */ - if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) { + if (mm->slink->spacetype == SPACE_TIME) { SpaceTime *stime= (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) BLI_snprintf(str, sizeof(str), "Marker %d offset %d", selmarker->frame, offs); @@ -816,7 +816,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) } else { /* we only print the offset */ - if (ELEM(mm->slink->spacetype, SPACE_TIME, SPACE_SOUND)) { + if (mm->slink->spacetype == SPACE_TIME) { SpaceTime *stime= (SpaceTime *)mm->slink; if (stime->flag & TIME_DRAWFRAMES) BLI_snprintf(str, sizeof(str), "Marker offset %d ", offs); diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h index 5c42dfc5d05..8e445ab1cee 100644 --- a/source/blender/editors/include/ED_space_api.h +++ b/source/blender/editors/include/ED_space_api.h @@ -46,7 +46,6 @@ void ED_spacetype_node(void); void ED_spacetype_buttons(void); void ED_spacetype_info(void); void ED_spacetype_file(void); -void ED_spacetype_sound(void); void ED_spacetype_action(void); void ED_spacetype_nla(void); void ED_spacetype_script(void); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 4318feca737..921a1879bb7 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -135,9 +135,6 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case SPACE_OUTLINER: ts= &btheme->toops; break; - case SPACE_SOUND: - ts= &btheme->tsnd; - break; case SPACE_INFO: ts= &btheme->tinfo; break; @@ -525,7 +522,6 @@ static void ui_theme_init_new(bTheme *btheme) ui_theme_init_new_do(&btheme->tfile); ui_theme_init_new_do(&btheme->tipo); ui_theme_init_new_do(&btheme->tinfo); - ui_theme_init_new_do(&btheme->tsnd); ui_theme_init_new_do(&btheme->tact); ui_theme_init_new_do(&btheme->tnla); ui_theme_init_new_do(&btheme->tseq); @@ -762,15 +758,11 @@ void ui_theme_init_default(void) SETCOL(btheme->tconsole.console_error, 220, 96, 96, 255); SETCOL(btheme->tconsole.console_cursor, 220, 96, 96, 255); - - /* space sound */ - btheme->tsnd= btheme->tv3d; - SETCOLF(btheme->tsnd.back, 0.45, 0.45, 0.45, 1.0); - SETCOLF(btheme->tsnd.grid, 0.36, 0.36, 0.36, 1.0); - SETCOL(btheme->tsnd.shade1, 173, 173, 173, 255); // sliders - /* space time */ - btheme->ttime= btheme->tsnd; // same as sound space + btheme->ttime= btheme->tv3d; + SETCOLF(btheme->ttime.back, 0.45, 0.45, 0.45, 1.0); + SETCOLF(btheme->ttime.grid, 0.36, 0.36, 0.36, 1.0); + SETCOL(btheme->ttime.shade1, 173, 173, 173, 255); // sliders /* space node, re-uses syntax color storage */ btheme->tnode= btheme->tv3d; @@ -785,7 +777,6 @@ void ui_theme_init_default(void) /* space logic */ btheme->tlogic= btheme->tv3d; SETCOL(btheme->tlogic.back, 100, 100, 100, 255); - } @@ -1177,7 +1168,11 @@ void init_userdef_do_versions(void) for(btheme= U.themes.first; btheme; btheme= btheme->next) { /* check for alpha==0 is safe, then color was never set */ if(btheme->ttime.back[3]==0) { - btheme->ttime = btheme->tsnd; // copy from sound + // copied from ui_theme_init_default + btheme->ttime= btheme->tv3d; + SETCOLF(btheme->ttime.back, 0.45, 0.45, 0.45, 1.0); + SETCOLF(btheme->ttime.grid, 0.36, 0.36, 0.36, 1.0); + SETCOL(btheme->ttime.shade1, 173, 173, 173, 255); // sliders } if(btheme->text.syntaxn[3]==0) { SETCOL(btheme->text.syntaxn, 0, 0, 200, 255); /* Numbers Blue*/ @@ -1304,7 +1299,7 @@ void init_userdef_do_versions(void) SETCOL(btheme->tact.cframe, 0x60, 0xc0, 0x40, 255); SETCOL(btheme->tnla.cframe, 0x60, 0xc0, 0x40, 255); SETCOL(btheme->tseq.cframe, 0x60, 0xc0, 0x40, 255); - SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255); + //SETCOL(btheme->tsnd.cframe, 0x60, 0xc0, 0x40, 255); Not needed anymore SETCOL(btheme->ttime.cframe, 0x60, 0xc0, 0x40, 255); } } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 171adc8d89a..e86dd8dbde3 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -192,7 +192,7 @@ int ED_operator_animview_active(bContext *C) { if(ED_operator_areaactive(C)) { SpaceLink *sl= (SpaceLink *)CTX_wm_space_data(C); - if (sl && (ELEM6(sl->spacetype, SPACE_SEQ, SPACE_SOUND, SPACE_ACTION, SPACE_NLA, SPACE_IPO, SPACE_TIME))) + if (sl && (ELEM5(sl->spacetype, SPACE_SEQ, SPACE_ACTION, SPACE_NLA, SPACE_IPO, SPACE_TIME))) return TRUE; } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 99ab356ac5f..905f7bc80b6 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -81,7 +81,6 @@ void ED_spacetypes_init(void) ED_spacetype_buttons(); ED_spacetype_info(); ED_spacetype_file(); - ED_spacetype_sound(); ED_spacetype_action(); ED_spacetype_nla(); ED_spacetype_script(); diff --git a/source/blender/editors/space_sound/CMakeLists.txt b/source/blender/editors/space_sound/CMakeLists.txt deleted file mode 100644 index ae605760975..00000000000 --- a/source/blender/editors/space_sound/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -# ***** 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. -# -# Contributor(s): Jacques Beaurain. -# -# ***** END GPL LICENSE BLOCK ***** - -set(INC - ../include - ../../blenkernel - ../../blenlib - ../../blenloader - ../../makesdna - ../../makesrna - ../../windowmanager - ../../../../intern/guardedalloc -) - -set(INC_SYS - ${GLEW_INCLUDE_PATH} -) - -set(SRC - sound_header.c - space_sound.c - - sound_intern.h -) - -blender_add_lib(bf_editor_space_sound "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/space_sound/SConscript b/source/blender/editors/space_sound/SConscript deleted file mode 100644 index d76fb7939ea..00000000000 --- a/source/blender/editors/space_sound/SConscript +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/python -Import ('env') - -sources = env.Glob('*.c') - -incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../makesrna ../../imbuf' -incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include ../../blenloader' - -env.BlenderLib ( 'bf_editors_space_sound', sources, Split(incs), [], libtype=['core'], priority=[75] ) diff --git a/source/blender/editors/space_sound/sound_header.c b/source/blender/editors/space_sound/sound_header.c deleted file mode 100644 index 6e2010c0c63..00000000000 --- a/source/blender/editors/space_sound/sound_header.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * ***** 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. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_sound/sound_header.c - * \ingroup spsnd - */ - - -#include -#include - - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - - -#include "BKE_context.h" - -#include "ED_screen.h" -#include "ED_types.h" -#include "ED_util.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "sound_intern.h" - - -/* ************************ header area region *********************** */ - -static void do_viewmenu(bContext *UNUSED(C), void *UNUSED(arg), int UNUSED(event)) -{ - -} - -static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *UNUSED(arg)) -{ - ScrArea *curarea= CTX_wm_area(C); - uiBlock *block; - short yco= 0, menuwidth=120; - - block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP); - uiBlockSetButmFunc(block, do_viewmenu, NULL); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - - if(curarea->headertype==HEADERTOP) { - uiBlockSetDirection(block, UI_DOWN); - } - else { - uiBlockSetDirection(block, UI_TOP); - uiBlockFlipOrder(block); - } - - uiTextBoundsBlock(block, 50); - uiEndBlock(C, block); - - return block; -} - -static void do_sound_buttons(bContext *UNUSED(C), void *UNUSED(arg), int event) -{ - switch(event) { - } -} - - -void sound_header_buttons(const bContext *C, ARegion *ar) -{ - ScrArea *sa= CTX_wm_area(C); - uiBlock *block; - int xco, yco= 3; - - block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS); - uiBlockSetHandleFunc(block, do_sound_buttons, NULL); - - xco= ED_area_header_standardbuttons(C, block, yco); - - if((sa->flag & HEADER_NO_PULLDOWN)==0) { - int xmax; - - xmax= GetButStringLength("View"); - uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C), - "View", xco, yco-2, xmax-3, UI_UNIT_Y, ""); - xco+=UI_UNIT_X+xmax; - } - - uiBlockSetEmboss(block, UI_EMBOSS); - - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, xco+UI_UNIT_X+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); - - uiEndBlock(C, block); - uiDrawBlock(C, block); -} - - diff --git a/source/blender/editors/space_sound/sound_intern.h b/source/blender/editors/space_sound/sound_intern.h deleted file mode 100644 index 88891ff4913..00000000000 --- a/source/blender/editors/space_sound/sound_intern.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ***** 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. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_sound/sound_intern.h - * \ingroup spsnd - */ - -#ifndef ED_SOUND_INTERN_H -#define ED_SOUND_INTERN_H - -/* internal exports only */ - - -/* sound_header.c */ -void sound_header_buttons(const bContext *C, ARegion *ar); - - -#endif /* ED_SOUND_INTERN_H */ - diff --git a/source/blender/editors/space_sound/space_sound.c b/source/blender/editors/space_sound/space_sound.c deleted file mode 100644 index 83d1b5b06c2..00000000000 --- a/source/blender/editors/space_sound/space_sound.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * ***** 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. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_sound/space_sound.c - * \ingroup spsnd - */ - - -#include -#include - -#include "DNA_scene_types.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" - -#include "BKE_context.h" -#include "BKE_screen.h" - -#include "ED_space_api.h" -#include "ED_screen.h" - -#include "BIF_gl.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "UI_resources.h" -#include "UI_view2d.h" - - -#include "sound_intern.h" // own include - -/* ******************** default callbacks for sound space ***************** */ - -static SpaceLink *sound_new(const bContext *UNUSED(C)) -{ - ARegion *ar; - SpaceSound *ssound; - - ssound= MEM_callocN(sizeof(SpaceSound), "initsound"); - ssound->spacetype= SPACE_SOUND; - - /* header */ - ar= MEM_callocN(sizeof(ARegion), "header for sound"); - - BLI_addtail(&ssound->regionbase, ar); - ar->regiontype= RGN_TYPE_HEADER; - ar->alignment= RGN_ALIGN_BOTTOM; - - /* main area */ - ar= MEM_callocN(sizeof(ARegion), "main area for sound"); - - BLI_addtail(&ssound->regionbase, ar); - ar->regiontype= RGN_TYPE_WINDOW; - - ar->v2d.tot.xmin= -4.0f; - ar->v2d.tot.ymin= -4.0f; - ar->v2d.tot.xmax= 250.0f; - ar->v2d.tot.ymax= 255.0f; - - ar->v2d.cur.xmin= -4.0f; - ar->v2d.cur.ymin= -4.0f; - ar->v2d.cur.xmax= 50.0f; - ar->v2d.cur.ymax= 255.0f; - - ar->v2d.min[0]= 1.0f; - ar->v2d.min[1]= 259.0f; - - ar->v2d.max[0]= MAXFRAMEF; - ar->v2d.max[1]= 259.0f; - - ar->v2d.minzoom= 0.1f; - ar->v2d.maxzoom= 10.0f; - - ar->v2d.scroll = (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); - ar->v2d.scroll |= (V2D_SCROLL_LEFT); - ar->v2d.keepzoom= 0; - ar->v2d.keeptot= 0; - ar->v2d.keepzoom = V2D_LOCKZOOM_Y; - - - return (SpaceLink *)ssound; -} - -/* not spacelink itself */ -static void sound_free(SpaceLink *UNUSED(sl)) -{ -// SpaceSound *ssound= (SpaceSound*) sl; - - -} - - -/* spacetype; init callback */ -static void sound_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) -{ - -} - -static SpaceLink *sound_duplicate(SpaceLink *sl) -{ - SpaceSound *ssoundn= MEM_dupallocN(sl); - - /* clear or remove stuff from old */ - - return (SpaceLink *)ssoundn; -} - - - -/* add handlers, stuff you only do once or on area/region changes */ -static void sound_main_area_init(wmWindowManager *wm, ARegion *ar) -{ - wmKeyMap *keymap; - - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); - - /* own keymap */ - keymap= WM_keymap_find(wm->defaultconf, "Sound", SPACE_SOUND, 0); - WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); -} - -static void sound_main_area_draw(const bContext *C, ARegion *ar) -{ - /* draw entirely, view changes should be handled here */ - // SpaceSound *ssound= (SpaceSound*)CTX_wm_space_data(C); - View2D *v2d= &ar->v2d; - - /* clear and setup matrix */ - UI_ThemeClearColor(TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); - - UI_view2d_view_ortho(v2d); - - /* data... */ - - - /* reset view matrix */ - UI_view2d_view_restore(C); - - /* scrollers? */ -} - -static void sound_operatortypes(void) -{ - -} - -static void sound_keymap(struct wmKeyConfig *UNUSED(keyconf)) -{ - -} - -/* add handlers, stuff you only do once or on area/region changes */ -static void sound_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) -{ - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); -} - -static void sound_header_area_draw(const bContext *C, ARegion *ar) -{ - float col[3]; - - /* clear */ - if(ED_screen_area_active(C)) - UI_GetThemeColor3fv(TH_HEADER, col); - else - UI_GetThemeColor3fv(TH_HEADERDESEL, col); - - glClearColor(col[0], col[1], col[2], 0.0); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(&ar->v2d); - - sound_header_buttons(C, ar); - - /* restore view matrix? */ - UI_view2d_view_restore(C); -} - -static void sound_main_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) -{ - /* context changes */ -} - -/* only called once, from space/spacetypes.c */ -void ED_spacetype_sound(void) -{ - SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype sound"); - ARegionType *art; - - st->spaceid= SPACE_SOUND; - strncpy(st->name, "Sound", BKE_ST_MAXNAME); - - st->new= sound_new; - st->free= sound_free; - st->init= sound_init; - st->duplicate= sound_duplicate; - st->operatortypes= sound_operatortypes; - st->keymap= sound_keymap; - - /* regions: main window */ - art= MEM_callocN(sizeof(ARegionType), "spacetype sound region"); - art->regionid = RGN_TYPE_WINDOW; - art->init= sound_main_area_init; - art->draw= sound_main_area_draw; - art->listener= sound_main_area_listener; - art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES; - - BLI_addhead(&st->regiontypes, art); - - /* regions: header */ - art= MEM_callocN(sizeof(ARegionType), "spacetype sound region"); - art->regionid = RGN_TYPE_HEADER; - art->prefsizey= HEADERY; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; - - art->init= sound_header_area_init; - art->draw= sound_header_area_draw; - - BLI_addhead(&st->regiontypes, art); - - /* regions: channels */ - art= MEM_callocN(sizeof(ARegionType), "spacetype sound region"); - art->regionid = RGN_TYPE_CHANNELS; - art->prefsizex= 80; - art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; - -// art->init= sound_channel_area_init; -// art->draw= sound_channel_area_draw; - - BLI_addhead(&st->regiontypes, art); - - - BKE_spacetype_register(st); -} - diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index d21db85b1f3..a92075c32e3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -483,22 +483,6 @@ typedef struct SpaceUserPref { } SpaceUserPref; -typedef struct SpaceSound { - struct SpaceLink *next, *prev; - ListBase regionbase; /* storage of regions for inactive spaces */ - int spacetype; - float blockscale; - struct ScrArea *area; - - View2D v2d; - - struct bSound *sound; - short mode, sndnr; - short xof, yof; - short flag, lock; - int pad2; -} SpaceSound; - /* view3d Now in DNA_view3d_types.h */ @@ -886,7 +870,7 @@ enum { SPACE_SEQ, SPACE_TEXT, SPACE_IMASEL, /* deprecated */ - SPACE_SOUND, + SPACE_SOUND, /* Deprecated */ SPACE_ACTION, SPACE_NLA, SPACE_SCRIPT, diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4859268d477..8dd00f4ac08 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -267,8 +267,7 @@ typedef struct bTheme { ThemeSpace tv3d; ThemeSpace tfile; ThemeSpace tipo; - ThemeSpace tinfo; - ThemeSpace tsnd; + ThemeSpace tinfo; ThemeSpace tact; ThemeSpace tnla; ThemeSpace tseq; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 58ed9c50df5..19acc51feed 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -60,7 +60,6 @@ EnumPropertyItem space_type_items[] = { {SPACE_INFO, "INFO", 0, "Info", ""}, {SPACE_SEQ, "SEQUENCE_EDITOR", 0, "Sequence Editor", ""}, {SPACE_TEXT, "TEXT_EDITOR", 0, "Text Editor", ""}, - {SPACE_SOUND, "AUDIO_WINDOW", 0, "Audio Window", ""}, {SPACE_ACTION, "DOPESHEET_EDITOR", 0, "DopeSheet Editor", ""}, {SPACE_NLA, "NLA_EDITOR", 0, "NLA Editor", ""}, {SPACE_SCRIPT, "SCRIPTS_WINDOW", 0, "Scripts Window", ""}, @@ -151,8 +150,6 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) return &RNA_SpaceSequenceEditor; case SPACE_TEXT: return &RNA_SpaceTextEditor; - /*case SPACE_SOUND: - return &RNA_SpaceAudioWindow;*/ case SPACE_ACTION: return &RNA_SpaceDopeSheetEditor; case SPACE_NLA: diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 898ee2b2623..5c4838c8842 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1451,37 +1451,6 @@ static void rna_def_userdef_theme_space_time(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); } -static void rna_def_userdef_theme_space_sound(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - /* space_sound */ - - srna= RNA_def_struct(brna, "ThemeAudioWindow", NULL); - RNA_def_struct_sdna(srna, "ThemeSpace"); - RNA_def_struct_ui_text(srna, "Theme Audio Window", "Theme settings for the Audio Window"); - - rna_def_userdef_theme_spaces_main(srna, SPACE_SOUND); - - prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Grid", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "shade1"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Window Sliders", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); - - prop= RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); - RNA_def_property_float_sdna(prop, NULL, "cframe"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Current Frame", ""); - RNA_def_property_update(prop, 0, "rna_userdef_update"); -} - static void rna_def_userdef_theme_space_image(BlenderRNA *brna) { StructRNA *srna; @@ -1956,7 +1925,6 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna) rna_def_userdef_theme_space_info(brna); rna_def_userdef_theme_space_userpref(brna); rna_def_userdef_theme_space_console(brna); - rna_def_userdef_theme_space_sound(brna); rna_def_userdef_theme_space_logic(brna); rna_def_userdef_theme_colorset(brna); rna_def_userdef_themes(brna); diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py index 1455747cdbb..f01b7011e4f 100644 --- a/source/blender/python/simple_enum_gen.py +++ b/source/blender/python/simple_enum_gen.py @@ -30,7 +30,7 @@ defs = """ SPACE_SEQ, SPACE_TEXT, SPACE_IMASEL, #Deprecated - SPACE_SOUND, + SPACE_SOUND, #Deprecated SPACE_ACTION, SPACE_NLA, SPACE_SCRIPT, From 32b34d631ab2f7d2a28b2f6055618f549eb691fe Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 1 Nov 2011 20:14:58 +0000 Subject: [PATCH 026/147] Space types: * Some cleanup, removed references to already deleted *_header.c files. * Marked SpaceScript as deprecated and removed header. Will keep space for now though, as some script operators are there and Campbell might want to re-use the space later. --- .../editors/space_graph/graph_intern.h | 4 - .../editors/space_image/image_intern.h | 3 - source/blender/editors/space_nla/nla_intern.h | 5 - .../editors/space_outliner/outliner_intern.h | 3 - .../editors/space_script/CMakeLists.txt | 1 - .../editors/space_script/script_header.c | 120 ------------------ .../editors/space_script/script_intern.h | 4 - .../blender/editors/space_time/time_intern.h | 3 - source/blender/makesdna/DNA_space_types.h | 2 +- source/blender/makesrna/intern/rna_space.c | 3 - source/blender/makesrna/intern/rna_userdef.c | 2 +- source/blender/python/simple_enum_gen.py | 2 +- 12 files changed, 3 insertions(+), 149 deletions(-) delete mode 100644 source/blender/editors/space_script/script_header.c diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index d0efdefe5a5..bc4fa398221 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -56,10 +56,6 @@ void graph_draw_channel_names(struct bContext *C, struct bAnimContext *ac, struc void graph_draw_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar, struct View2DGrid *grid, short sel); void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, struct ARegion *ar); -/* ***************************************** */ -/* graph_header.c */ -void graph_header_buttons(const bContext *C, struct ARegion *ar); - /* ***************************************** */ /* graph_select.c */ diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 051926bf689..4310b5dbae8 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -51,9 +51,6 @@ struct ARegion *image_has_scope_region(struct ScrArea *sa); extern const char *image_context_dir[]; /* doc access */ -/* image_header.c */ -void image_header_buttons(const struct bContext *C, struct ARegion *ar); - void IMAGE_OT_toolbox(struct wmOperatorType *ot); /* image_draw.c */ diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h index ec2e22e65fa..00c16d68f36 100644 --- a/source/blender/editors/space_nla/nla_intern.h +++ b/source/blender/editors/space_nla/nla_intern.h @@ -50,11 +50,6 @@ void NLA_OT_properties(wmOperatorType *ot); void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar); void draw_nla_channel_list(bContext *C, bAnimContext *ac, ARegion *ar); -/* **************************************** */ -/* nla_header.c */ - -void nla_header_buttons(const bContext *C, ARegion *ar); - /* **************************************** */ /* nla_select.c */ diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h index 215ab508ab6..4065b3e2e0b 100644 --- a/source/blender/editors/space_outliner/outliner_intern.h +++ b/source/blender/editors/space_outliner/outliner_intern.h @@ -229,7 +229,4 @@ void OUTLINER_OT_action_set(struct wmOperatorType *ot); void outliner_operatortypes(void); void outliner_keymap(struct wmKeyConfig *keyconf); -/* outliner_header.c */ -void outliner_header_buttons(const struct bContext *C, struct ARegion *ar); - #endif /* ED_OUTLINER_INTERN_H */ diff --git a/source/blender/editors/space_script/CMakeLists.txt b/source/blender/editors/space_script/CMakeLists.txt index fb88d81ddf6..00f8df299e2 100644 --- a/source/blender/editors/space_script/CMakeLists.txt +++ b/source/blender/editors/space_script/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC_SYS set(SRC script_edit.c - script_header.c script_ops.c space_script.c diff --git a/source/blender/editors/space_script/script_header.c b/source/blender/editors/space_script/script_header.c deleted file mode 100644 index 8354dc1e996..00000000000 --- a/source/blender/editors/space_script/script_header.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * ***** 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. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_script/script_header.c - * \ingroup spscript - */ - - -#include -#include - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - - -#include "BKE_context.h" - -#include "ED_screen.h" -#include "ED_types.h" -#include "ED_util.h" - -#include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "script_intern.h" - -/* ************************ header area region *********************** */ - -static void do_viewmenu(bContext *UNUSED(C), void *UNUSED(arg), int UNUSED(event)) -{ - -} - -static uiBlock *dummy_viewmenu(bContext *C, ARegion *ar, void *UNUSED(arg)) -{ - ScrArea *curarea= CTX_wm_area(C); - uiBlock *block; - short yco= 0, menuwidth=120; - - block= uiBeginBlock(C, ar, "dummy_viewmenu", UI_EMBOSSP); - uiBlockSetButmFunc(block, do_viewmenu, NULL); - - uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20, - menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); - - if(curarea->headertype==HEADERTOP) { - uiBlockSetDirection(block, UI_DOWN); - } - else { - uiBlockSetDirection(block, UI_TOP); - uiBlockFlipOrder(block); - } - - uiTextBoundsBlock(block, 50); - uiEndBlock(C, block); - - return block; -} - -static void do_script_buttons(bContext *UNUSED(C), void *UNUSED(arg), int UNUSED(event)) -{ - //switch(event) { - //} -} - - -void script_header_buttons(const bContext *C, ARegion *ar) -{ - ScrArea *sa= CTX_wm_area(C); - uiBlock *block; - int xco, yco= 3; - - block= uiBeginBlock(C, ar, "header buttons", UI_EMBOSS); - uiBlockSetHandleFunc(block, do_script_buttons, NULL); - - xco= ED_area_header_standardbuttons(C, block, yco); - - if((sa->flag & HEADER_NO_PULLDOWN)==0) { - int xmax; - - xmax= GetButStringLength("View"); - uiDefPulldownBut(block, dummy_viewmenu, CTX_wm_area(C), - "View", xco, yco-2, xmax-3, UI_UNIT_Y, ""); - xco+=UI_UNIT_X+xmax; - } - - uiBlockSetEmboss(block, UI_EMBOSS); - - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, xco+UI_UNIT_X+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin); - - uiEndBlock(C, block); - uiDrawBlock(C, block); -} - - diff --git a/source/blender/editors/space_script/script_intern.h b/source/blender/editors/space_script/script_intern.h index a3565d070eb..98e9699079b 100644 --- a/source/blender/editors/space_script/script_intern.h +++ b/source/blender/editors/space_script/script_intern.h @@ -33,10 +33,6 @@ /* internal exports only */ - -/* script_header.c */ -void script_header_buttons(const bContext *C, ARegion *ar); - /* script_ops.c */ void script_operatortypes(void); void script_keymap(struct wmKeyConfig *keyconf); diff --git a/source/blender/editors/space_time/time_intern.h b/source/blender/editors/space_time/time_intern.h index 094b0bc9e86..a345d00bd74 100644 --- a/source/blender/editors/space_time/time_intern.h +++ b/source/blender/editors/space_time/time_intern.h @@ -40,8 +40,5 @@ struct wmWindowManager; void time_operatortypes(void); void time_keymap(struct wmKeyConfig *keyconf); -/* time_header.c */ -void time_header_buttons(const bContext *C, ARegion *ar); - #endif /* ED_TIME_INTERN_H */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index a92075c32e3..37c2ea56e76 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -873,7 +873,7 @@ enum { SPACE_SOUND, /* Deprecated */ SPACE_ACTION, SPACE_NLA, - SPACE_SCRIPT, + SPACE_SCRIPT, /* Deprecated */ SPACE_TIME, SPACE_NODE, SPACE_LOGIC, diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 19acc51feed..51faccc0d6c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -62,7 +62,6 @@ EnumPropertyItem space_type_items[] = { {SPACE_TEXT, "TEXT_EDITOR", 0, "Text Editor", ""}, {SPACE_ACTION, "DOPESHEET_EDITOR", 0, "DopeSheet Editor", ""}, {SPACE_NLA, "NLA_EDITOR", 0, "NLA Editor", ""}, - {SPACE_SCRIPT, "SCRIPTS_WINDOW", 0, "Scripts Window", ""}, {SPACE_TIME, "TIMELINE", 0, "Timeline", ""}, {SPACE_NODE, "NODE_EDITOR", 0, "Node Editor", ""}, {SPACE_LOGIC, "LOGIC_EDITOR", 0, "Logic Editor", ""}, @@ -154,8 +153,6 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) return &RNA_SpaceDopeSheetEditor; case SPACE_NLA: return &RNA_SpaceNLA; - /*case SPACE_SCRIPT: - return &RNA_SpaceScriptsWindow;*/ case SPACE_TIME: return &RNA_SpaceTimeline; case SPACE_NODE: diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 5c4838c8842..fc9c8a241c6 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1392,7 +1392,7 @@ static void rna_def_userdef_theme_space_logic(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - /* space_buts */ + /* space_logic */ srna= RNA_def_struct(brna, "ThemeLogicEditor", NULL); RNA_def_struct_sdna(srna, "ThemeSpace"); diff --git a/source/blender/python/simple_enum_gen.py b/source/blender/python/simple_enum_gen.py index f01b7011e4f..ec2eead522c 100644 --- a/source/blender/python/simple_enum_gen.py +++ b/source/blender/python/simple_enum_gen.py @@ -33,7 +33,7 @@ defs = """ SPACE_SOUND, #Deprecated SPACE_ACTION, SPACE_NLA, - SPACE_SCRIPT, + SPACE_SCRIPT, #Deprecated SPACE_TIME, SPACE_NODE, SPACEICONMAX From 27ffb5556a8bf879f8b29b86f16b4964f092c3d2 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 1 Nov 2011 22:21:21 +0000 Subject: [PATCH 027/147] Bugfix for [#29055] node editor / texture node / scale node * Node Vector sockets, don't have a PROP_FACTOR any longer. --- source/blender/nodes/texture/nodes/node_texture_scale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/texture/nodes/node_texture_scale.c b/source/blender/nodes/texture/nodes/node_texture_scale.c index fbca9be068c..f42b3addc91 100644 --- a/source/blender/nodes/texture/nodes/node_texture_scale.c +++ b/source/blender/nodes/texture/nodes/node_texture_scale.c @@ -35,7 +35,7 @@ static bNodeSocketTemplate inputs[]= { { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f }, - { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 0.0f, -10.0f, 10.0f, PROP_FACTOR }, + { SOCK_VECTOR, 1, "Scale", 1.0f, 1.0f, 1.0f, 0.0f, -10.0f, 10.0f, PROP_XYZ }, { -1, 0, "" } }; From d7de4d28dd5c0042e80e5dc585b35e3808c4e0a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 22:51:10 +0000 Subject: [PATCH 028/147] quiet some warnings. --- build_files/cmake/cmake_consistency_check_config.py | 6 +++--- source/blender/blenfont/intern/blf_lang.c | 2 +- source/blender/blenkernel/intern/smoke.c | 7 ++++++- source/blender/blenloader/intern/readfile.c | 1 - 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/build_files/cmake/cmake_consistency_check_config.py b/build_files/cmake/cmake_consistency_check_config.py index 86f51273ff5..a6215b40ae8 100644 --- a/build_files/cmake/cmake_consistency_check_config.py +++ b/build_files/cmake/cmake_consistency_check_config.py @@ -29,8 +29,8 @@ IGNORE = ( "source/blender/imbuf/intern/imbuf_cocoa.m", "extern/recastnavigation/Recast/Source/RecastLog.cpp", "extern/recastnavigation/Recast/Source/RecastTimer.cpp", - "entern/audaspace/SRC/AUD_SRCResampleFactory.cpp", - "entern/audaspace/SRC/AUD_SRCResampleReader.cpp", + "intern/audaspace/SRC/AUD_SRCResampleFactory.cpp", + "intern/audaspace/SRC/AUD_SRCResampleReader.cpp", "extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h", "extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h", @@ -44,7 +44,7 @@ IGNORE = ( "extern/eltopo/common/meshes/ObjLoader.hpp", "extern/eltopo/common/meshes/TriangleIndex.hpp", "extern/eltopo/common/meshes/meshloader.h", - "extern/eltopo/eltopo3d/broadphase_blenderbvh.h" + "extern/eltopo/eltopo3d/broadphase_blenderbvh.h", "extern/recastnavigation/Recast/Include/RecastLog.h", "extern/recastnavigation/Recast/Include/RecastTimer.h", "intern/audaspace/SRC/AUD_SRCResampleFactory.h", diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index 9548febab27..3bce3878d72 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -120,7 +120,7 @@ void BLF_lang_set(const char *str) const char *short_locale; int ok= 1; #if defined (_WIN32) && !defined(FREE_WINDOWS) - char *long_locale = locales[ 2 * U.language]; + const char *long_locale = locales[ 2 * U.language]; #endif if((U.transopts&USER_DOTRANSLATE)==0) diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index ac2a840c95a..7174126a00c 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -77,6 +77,8 @@ #include "BKE_smoke.h" +#ifdef WITH_SMOKE + #ifdef _WIN32 #include #include @@ -131,12 +133,13 @@ struct SmokeModifierData; #define TRI_UVOFFSET (1./4.) -#ifdef WITH_SMOKE /* forward declerations */ static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int correct); static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); + #else /* WITH_SMOKE */ + /* Stubs to use when smoke is disabled */ struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } @@ -146,9 +149,11 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(s void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} long long smoke_get_mem_req(int UNUSED(xres), int UNUSED(yres), int UNUSED(zres), int UNUSED(amplify)) { return 0; } void smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) {} + #endif /* WITH_SMOKE */ #ifdef WITH_SMOKE + static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 4700a41d003..bdc25836a5d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -9124,7 +9124,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if(main->versionfile <= 245) { Scene *sce; - bScreen *sc; Object *ob; Image *ima; Lamp *la; From 90a19ce57893642263a0b91eed96ba1a710d44af Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 1 Nov 2011 23:01:57 +0000 Subject: [PATCH 029/147] fix [#29120] project painting error --- release/scripts/startup/bl_operators/image.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/startup/bl_operators/image.py b/release/scripts/startup/bl_operators/image.py index 790c22d57d0..8c12a6442f7 100644 --- a/release/scripts/startup/bl_operators/image.py +++ b/release/scripts/startup/bl_operators/image.py @@ -192,6 +192,8 @@ class ProjectEdit(Operator): image_new.file_format = 'PNG' image_new.save() + filepath_final = bpy.path.abspath(filepath_final) + try: bpy.ops.image.external_edit(filepath=filepath_final) except RuntimeError as re: From b60f60453b6b70950257b269574aa51f00d55511 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 2 Nov 2011 00:17:37 +0000 Subject: [PATCH 030/147] Function convertViewVec() contained some piece of code duplicated four times, pulled out into separate function and cleaned up a bit. Should be no functional changes. Review link: http://codereview.appspot.com/5308073/ --- source/blender/editors/transform/transform.c | 63 +++++++------------- 1 file changed, 22 insertions(+), 41 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 9c1d5adcd1b..759fefba438 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -118,10 +118,22 @@ void setTransformViewMatrices(TransInfo *t) calculateCenter2D(t); } +static void convertViewVec2D(View2D *v2d, float *vec, int dx, int dy) +{ + float divx, divy; + + divx= v2d->mask.xmax - v2d->mask.xmin; + divy= v2d->mask.ymax - v2d->mask.ymin; + + vec[0]= (v2d->cur.xmax - v2d->cur.xmin) * dx / divx; + vec[1]= (v2d->cur.ymax - v2d->cur.ymin) * dy / divy; + vec[2]= 0.0f; +} + void convertViewVec(TransInfo *t, float *vec, int dx, int dy) { - if (t->spacetype==SPACE_VIEW3D) { - if (t->ar->regiontype == RGN_TYPE_WINDOW) { + if(t->spacetype==SPACE_VIEW3D) { + if(t->ar->regiontype == RGN_TYPE_WINDOW) { float mval_f[2]; mval_f[0]= dx; mval_f[1]= dy; @@ -129,50 +141,19 @@ void convertViewVec(TransInfo *t, float *vec, int dx, int dy) } } else if(t->spacetype==SPACE_IMAGE) { - View2D *v2d = t->view; - float divx, divy, aspx, aspy; + float aspx, aspy; + + convertViewVec2D(t->view, vec, dx, dy); ED_space_image_uv_aspect(t->sa->spacedata.first, &aspx, &aspy); - - divx= v2d->mask.xmax-v2d->mask.xmin; - divy= v2d->mask.ymax-v2d->mask.ymin; - - vec[0]= aspx*(v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - vec[1]= aspy*(v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; - vec[2]= 0.0f; + vec[0]*= aspx; + vec[1]*= aspy; } else if(ELEM(t->spacetype, SPACE_IPO, SPACE_NLA)) { - View2D *v2d = t->view; - float divx, divy; - - divx= v2d->mask.xmax-v2d->mask.xmin; - divy= v2d->mask.ymax-v2d->mask.ymin; - - vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx) / (divx); - vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy) / (divy); - vec[2]= 0.0f; + convertViewVec2D(t->view, vec, dx, dy); } - else if(t->spacetype==SPACE_NODE) { - View2D *v2d = &t->ar->v2d; - float divx, divy; - - divx= v2d->mask.xmax-v2d->mask.xmin; - divy= v2d->mask.ymax-v2d->mask.ymin; - - vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; - vec[2]= 0.0f; - } - else if(t->spacetype==SPACE_SEQ) { - View2D *v2d = &t->ar->v2d; - float divx, divy; - - divx= v2d->mask.xmax-v2d->mask.xmin; - divy= v2d->mask.ymax-v2d->mask.ymin; - - vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; - vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; - vec[2]= 0.0f; + else if(ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { + convertViewVec2D(&t->ar->v2d, vec, dx, dy); } } From 43e297c0c0cd18b0a9666fa55a4dc9411911ef24 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Nov 2011 00:51:21 +0000 Subject: [PATCH 031/147] minor cleanup for weightpaint fill - SCE_SELECT_FACE and SCE_SELECT_VERTEX are mutually exclusive, use a macro to get a single value from them. - was allocating an array for no reason. --- .../editors/sculpt_paint/paint_vertex.c | 106 +++++++----------- source/blender/makesdna/DNA_mesh_types.h | 8 ++ 2 files changed, 50 insertions(+), 64 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 3e2c4666528..57f926b0612 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -387,37 +387,16 @@ void vpaint_fill(Object *ob, unsigned int paintcol) /* fills in the selected faces with the current weight and vertex group */ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) { - Mesh *me; + Mesh *me= ob->data; + MFace *mf; MDeformWeight *dw, *uw; - int *indexar; - unsigned int index; int vgroup, vgroup_mirror= -1; - int selected; - - int use_vert_sel; + unsigned int index; - me= ob->data; - if(me==NULL || me->totface==0 || me->dvert==NULL || !me->mface) return; - - selected= (me->editflag & ME_EDIT_PAINT_MASK); - - use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; + /* mutually exclusive, could be made into a */ + const short paint_selmode= ME_EDIT_PAINT_SEL_MODE(me); - indexar= get_indexarray(me); - - if(selected) { - MFace *mf; - for(index=0, mf= me->mface; indextotface; index++, mf++) { - if((mf->flag & ME_FACE_SEL)==0) - indexar[index]= 0; - else - indexar[index]= index+1; - } - } - else { - for(index=0; indextotface; index++) - indexar[index]= index+1; - } + if(me->totface==0 || me->dvert==NULL || !me->mface) return; vgroup= ob->actdef-1; @@ -428,47 +407,47 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) copy_wpaint_prev(wp, me->dvert, me->totvert); - for(index=0; indextotface; index++) { - if(indexar[index] && indexar[index]<=me->totface) { - MFace *mf= &me->mface[indexar[index]-1]; - unsigned int fidx= mf->v4 ? 3:2; + for(index=0, mf= me->mface; index < me->totface; index++, mf++) { + unsigned int fidx= mf->v4 ? 3:2; - do { - unsigned int vidx= *(&mf->v1 + fidx); + if ((paint_selmode == SCE_SELECT_FACE) && !(mf->flag & ME_FACE_SEL)) { + continue; + } - if(!me->dvert[vidx].flag) { - if(use_vert_sel && !(me->mvert[vidx].flag & SELECT)) { - continue; - } + do { + unsigned int vidx= *(&mf->v1 + fidx); - dw= defvert_verify_index(&me->dvert[vidx], vgroup); - if(dw) { - uw= defvert_verify_index(wp->wpaint_prev+vidx, vgroup); - uw->weight= dw->weight; /* set the undo weight */ - dw->weight= paintweight; - - if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, vidx); - if(j>=0) { - /* copy, not paint again */ - if(vgroup_mirror != -1) { - dw= defvert_verify_index(me->dvert+j, vgroup_mirror); - uw= defvert_verify_index(wp->wpaint_prev+j, vgroup_mirror); - } else { - dw= defvert_verify_index(me->dvert+j, vgroup); - uw= defvert_verify_index(wp->wpaint_prev+j, vgroup); - } - uw->weight= dw->weight; /* set the undo weight */ - dw->weight= paintweight; - } - } - } - me->dvert[vidx].flag= 1; + if(!me->dvert[vidx].flag) { + if((paint_selmode == SCE_SELECT_VERTEX) && !(me->mvert[vidx].flag & SELECT)) { + continue; } + dw= defvert_verify_index(&me->dvert[vidx], vgroup); + if(dw) { + uw= defvert_verify_index(wp->wpaint_prev+vidx, vgroup); + uw->weight= dw->weight; /* set the undo weight */ + dw->weight= paintweight; - } while (fidx--); - } + if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ + int j= mesh_get_x_mirror_vert(ob, vidx); + if(j>=0) { + /* copy, not paint again */ + if(vgroup_mirror != -1) { + dw= defvert_verify_index(me->dvert+j, vgroup_mirror); + uw= defvert_verify_index(wp->wpaint_prev+j, vgroup_mirror); + } else { + dw= defvert_verify_index(me->dvert+j, vgroup); + uw= defvert_verify_index(wp->wpaint_prev+j, vgroup); + } + uw->weight= dw->weight; /* set the undo weight */ + dw->weight= paintweight; + } + } + } + me->dvert[vidx].flag= 1; + } + + } while (fidx--); } { @@ -477,8 +456,7 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) dv->flag= 0; } } - - MEM_freeN(indexar); + copy_wpaint_prev(wp, NULL, 0); DAG_id_tag_update(&me->id, 0); diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index ece6c84b0e8..bb67b46a7e5 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -125,6 +125,14 @@ typedef struct TFace { #define ME_EDIT_MIRROR_TOPO (1 << 4) #define ME_EDIT_VERT_SEL (1 << 5) +/* we cant have both flags enabled at once, + * flags defined in DNA_scene_types.h */ +#define ME_EDIT_PAINT_SEL_MODE(_me) ( \ + (_me->editflag & ME_EDIT_PAINT_MASK) ? SCE_SELECT_FACE : \ + (_me->editflag & ME_EDIT_VERT_SEL) ? SCE_SELECT_VERTEX : \ + 0 \ + ) + /* me->flag */ /* #define ME_ISDONE 1 */ #define ME_DEPRECATED 2 From e29aa363f21b945404b9e7e3702d67432236c067 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Nov 2011 09:13:04 +0000 Subject: [PATCH 032/147] new math function: Quaternion.to_axis_angle(). add in safety checks for inf/nan values which could happen in some cases. --- .../python/mathutils/mathutils_Quaternion.c | 94 +++++++++++++++---- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index 7eb39509e6b..f892c25f67e 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -39,6 +39,7 @@ #define QUAT_SIZE 4 static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObject *self); +static void quat__axis_angle_sanitize(float axis[3], float *angle); static PyObject *Quaternion_copy(QuaternionObject *self); //-----------------------------METHODS------------------------------ @@ -141,6 +142,39 @@ static PyObject *Quaternion_to_matrix(QuaternionObject *self) return newMatrixObject(mat, 3, 3, Py_NEW, NULL); } +//----------------------------Quaternion.toMatrix()------------------ +PyDoc_STRVAR(Quaternion_to_axis_angle_doc, +".. method:: to_axis_angle()\n" +"\n" +" Return the axis, angle representation of the quaternion.\n" +"\n" +" :return: axis, angle.\n" +" :rtype: (:class:`Vector`, float) pair\n" +); +static PyObject *Quaternion_to_axis_angle(QuaternionObject *self) +{ + PyObject *ret; + + float tquat[4]; + + float axis[3]; + float angle; + + if (BaseMath_ReadCallback(self) == -1) + return NULL; + + normalize_qt_qt(tquat, self->quat); + quat_to_axis_angle(axis, &angle, tquat); + + quat__axis_angle_sanitize(axis, &angle); + + ret= PyTuple_New(2); + PyTuple_SET_ITEM(ret, 0, newVectorObject(axis, 3, Py_NEW, NULL)); + PyTuple_SET_ITEM(ret, 1, PyFloat_FromDouble(angle)); + return ret; +} + + //----------------------------Quaternion.cross(other)------------------ PyDoc_STRVAR(Quaternion_cross_doc, ".. method:: cross(other)\n" @@ -881,12 +915,18 @@ static PyObject *Quaternion_getMagnitude(QuaternionObject *self, void *UNUSED(cl static PyObject *Quaternion_getAngle(QuaternionObject *self, void *UNUSED(closure)) { float tquat[4]; + float angle; if (BaseMath_ReadCallback(self) == -1) return NULL; normalize_qt_qt(tquat, self->quat); - return PyFloat_FromDouble(2.0f * (saacos(tquat[0]))); + + angle= 2.0f * saacos(tquat[0]); + + quat__axis_angle_sanitize(NULL, &angle); + + return PyFloat_FromDouble(angle); } static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UNUSED(closure)) @@ -895,7 +935,7 @@ static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UN float len; float axis[3], angle_dummy; - double angle; + float angle; if (BaseMath_ReadCallback(self) == -1) return -1; @@ -913,13 +953,7 @@ static int Quaternion_setAngle(QuaternionObject *self, PyObject *value, void *UN angle= angle_wrap_rad(angle); - /* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */ - if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[2], 0.0f, 10) - ) { - axis[0] = 1.0f; - } + quat__axis_angle_sanitize(axis, &angle); axis_angle_to_quat(self->quat, axis, angle); mul_qt_fl(self->quat, len); @@ -935,21 +969,15 @@ static PyObject *Quaternion_getAxisVec(QuaternionObject *self, void *UNUSED(clos float tquat[4]; float axis[3]; - float angle; + float angle_dummy; if (BaseMath_ReadCallback(self) == -1) return NULL; normalize_qt_qt(tquat, self->quat); - quat_to_axis_angle(axis, &angle, tquat); + quat_to_axis_angle(axis, &angle_dummy, tquat); - /* If the axis of rotation is 0,0,0 set it to 1,0,0 - for zero-degree rotations */ - if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && - EXPP_FloatsAreEqual(axis[2], 0.0f, 10) - ) { - axis[0] = 1.0f; - } + quat__axis_angle_sanitize(axis, NULL); return (PyObject *) newVectorObject(axis, 3, Py_NEW, NULL); } @@ -971,6 +999,8 @@ static int Quaternion_setAxisVec(QuaternionObject *self, PyObject *value, void * if (mathutils_array_parse(axis, 3, 3, value, "quat.axis = other") == -1) return -1; + quat__axis_angle_sanitize(axis, &angle); + axis_angle_to_quat(self->quat, axis, angle); mul_qt_fl(self->quat, len); @@ -1029,6 +1059,33 @@ static PyObject *quat__apply_to_copy(PyNoArgsFunction quat_func, QuaternionObjec } } +/* axis vector suffers from precission errors, use this function to ensure */ +static void quat__axis_angle_sanitize(float axis[3], float *angle) +{ + if (axis) { + if ( !finite(axis[0]) || + !finite(axis[1]) || + !finite(axis[2])) + { + axis[0]= 1.0f; + axis[1]= 0.0f; + axis[2]= 0.0f; + } + else if ( EXPP_FloatsAreEqual(axis[0], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[1], 0.0f, 10) && + EXPP_FloatsAreEqual(axis[2], 0.0f, 10) + ) { + axis[0] = 1.0f; + } + } + + if (angle) { + if (!finite(*angle)) { + *angle= 0.0f; + } + } +} + //-----------------------METHOD DEFINITIONS ---------------------- static struct PyMethodDef Quaternion_methods[] = { /* in place only */ @@ -1048,6 +1105,7 @@ static struct PyMethodDef Quaternion_methods[] = { /* return converted representation */ {"to_euler", (PyCFunction) Quaternion_to_euler, METH_VARARGS, Quaternion_to_euler_doc}, {"to_matrix", (PyCFunction) Quaternion_to_matrix, METH_NOARGS, Quaternion_to_matrix_doc}, + {"to_axis_angle", (PyCFunction) Quaternion_to_axis_angle, METH_NOARGS, Quaternion_to_axis_angle_doc}, /* operation between 2 or more types */ {"cross", (PyCFunction) Quaternion_cross, METH_O, Quaternion_cross_doc}, From 3d35e004d35faf45968c0cead7d758a5599a2bcc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 12:18:51 +0000 Subject: [PATCH 033/147] Related to #29092: make the working of the Mist Intensity option more clear in the user interface. --- release/scripts/startup/bl_ui/properties_world.py | 2 +- source/blender/makesrna/intern/rna_world.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 71ee03296a0..23f35d6d1e9 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -227,7 +227,7 @@ class WORLD_PT_mist(WorldButtonsPanel, Panel): split = layout.split() col = split.column() - col.prop(world.mist_settings, "intensity", slider=True) + col.prop(world.mist_settings, "intensity") col.prop(world.mist_settings, "start") col = split.column() diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 22570460093..d07050eaab5 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -393,7 +393,7 @@ static void rna_def_world_mist(BlenderRNA *brna) prop= RNA_def_property(srna, "intensity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "misi"); RNA_def_property_range(prop, 0, 1); - RNA_def_property_ui_text(prop, "Intensity", "Intensity of the mist effect"); + RNA_def_property_ui_text(prop, "Minimum", "Overall minimum intensity of the mist effect"); RNA_def_property_update(prop, 0, "rna_World_update"); prop= RNA_def_property(srna, "start", PROP_FLOAT, PROP_DISTANCE); From 79a389ee3711f0528c33e5aeb4b2a202e5e44b38 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 13:36:28 +0000 Subject: [PATCH 034/147] RenderEngine: add .is_animation and .is_preview properties to detect if it's an animation or preview render that is being done. --- source/blender/makesrna/intern/rna_render.c | 9 ++++++++- source/blender/render/extern/include/RE_engine.h | 7 +++++++ source/blender/render/intern/include/render_types.h | 1 + source/blender/render/intern/source/external_engine.c | 5 +++++ source/blender/render/intern/source/pipeline.c | 4 ++++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 1498d161209..9b53b477c52 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -251,9 +251,16 @@ static void rna_def_render_engine(BlenderRNA *brna) prop= RNA_def_string(func, "message", "", 0, "Report Message", ""); RNA_def_property_flag(prop, PROP_REQUIRED); - /* registration */ RNA_define_verify_sdna(0); + prop= RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_ANIMATION); + + prop= RNA_def_property(srna, "is_preview", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_PREVIEW); + + /* registration */ + prop= RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "type->idname"); RNA_def_property_flag(prop, PROP_REGISTER|PROP_NEVER_CLAMP); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 1326ed495ec..344ef301f4c 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -46,11 +46,16 @@ struct Scene; /* External Engine */ +/* RenderEngineType.flag */ #define RE_INTERNAL 1 #define RE_GAME 2 #define RE_USE_PREVIEW 4 #define RE_USE_POSTPROCESS 8 +/* RenderEngine.flag */ +#define RE_ENGINE_ANIMATION 1 +#define RE_ENGINE_PREVIEW 2 + extern ListBase R_engines; typedef struct RenderEngineType { @@ -70,6 +75,8 @@ typedef struct RenderEngineType { typedef struct RenderEngine { RenderEngineType *type; + int flag; + struct Render *re; ListBase fullresult; } RenderEngine; diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index aa2dd29814e..ae4e55b9b88 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -601,6 +601,7 @@ typedef struct LampRen { #define R_NEED_TANGENT 16 #define R_BAKE_TRACE 32 #define R_BAKING 64 +#define R_ANIMATION 128 /* vlakren->flag (vlak = face in dutch) char!!! */ #define R_SMOOTH 1 diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index a4d1e502f13..a6214329d0e 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -265,6 +265,11 @@ int RE_engine_render(Render *re, int do_all) engine = RE_engine_create(type); engine->re= re; + if(re->flag & R_ANIMATION) + engine->flag |= RE_ENGINE_ANIMATION; + if(re->r.scemode & R_PREVIEWBUTS) + engine->flag |= RE_ENGINE_PREVIEW; + if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0) scene_update_for_newframe(re->main, re->scene, re->lay); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 64b36c1fd12..8d72be1684c 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -3085,6 +3085,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri /* is also set by caller renderwin.c */ G.rendering= 1; + re->flag |= R_ANIMATION; + if(BKE_imtype_is_movie(scene->r.imtype)) if(!mh->start_movie(scene, &re->r, re->rectx, re->recty, re->reports)) G.afbreek= 1; @@ -3193,6 +3195,8 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri scene->r.cfra= cfrao; + re->flag &= ~R_ANIMATION; + /* UGLY WARNING */ G.rendering= 0; } From aa363800b0826b4299bf999001d13530554f2ec1 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 2 Nov 2011 14:28:16 +0000 Subject: [PATCH 035/147] World Stars: * Remove remaining star color code, was unused. Marked as deprecated in DNA. --- source/blender/blenkernel/intern/ipo.c | 9 +-------- source/blender/makesdna/DNA_world_types.h | 2 +- source/blender/makesrna/intern/rna_world.c | 7 ------- 3 files changed, 2 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 85e00bcea06..034f4a96879 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -703,14 +703,7 @@ static const char *world_adrcodes_to_paths (int adrcode, int *array_index) return "mist.start"; case WO_MISTHI: return "mist.height"; - - /* Star Color is unused -- recommend removal */ - /* case WO_STAR_R: - *array_index= 0; return "stars.color"; - case WO_STAR_G: - *array_index= 1; return "stars.color"; - case WO_STAR_B: - *array_index= 2; return "stars.color"; */ + case WO_STAR_R: case WO_STAR_G: case WO_STAR_B: diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 500851e23b8..18e175129c1 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -95,7 +95,7 @@ typedef struct World { float misi, miststa, mistdist, misthi; - float starr, starg, starb, stark; + float starr, starg, starb, stark; /* Deprecated */ float starsize, starmindist; float stardist, starcolnoise; diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index d07050eaab5..ba769a8d7fc 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -461,13 +461,6 @@ static void rna_def_world_stars(BlenderRNA *brna) RNA_def_property_range(prop, 0, 1); RNA_def_property_ui_text(prop, "Color Randomization", "Randomize star colors"); RNA_def_property_update(prop, 0, "rna_World_stars_update"); - - /* unused - prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "starr"); - RNA_def_property_array(prop, 3); - RNA_def_property_ui_text(prop, "Color", "Stars color"); - RNA_def_property_update(prop, 0, "rna_World_update");*/ } void RNA_def_world(BlenderRNA *brna) From e07389ccb86ea6f1f10e74bbea2ff27db8c0a748 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 14:33:14 +0000 Subject: [PATCH 036/147] RenderEngine: steps towards implementation of this proposal: http://wiki.blender.org/index.php/Dev:2.6/Source/Render/RenderEngineAPI * RenderEngine is now a persistent python object that exists and retains properties as long as a frame is being rendered. This is mostly useful now that more than one callback will be added. * Added update() callback that should ideally be used to export the scene, leaving only the rendering to the render() callback. This is not required to be used at this point, but separating this will make things more thread safe later on. * Added tag_redraw() and tag_update() functions that will be used for viewport rendering. * Internal change: status text is now retained after update_status calls. --- source/blender/makesrna/intern/rna_render.c | 62 ++++++++++++++++--- .../blender/render/extern/include/RE_engine.h | 5 ++ .../render/intern/source/external_engine.c | 32 ++++++++-- 3 files changed, 88 insertions(+), 11 deletions(-) diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 9b53b477c52..8f928313840 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -48,12 +48,39 @@ #include "BKE_context.h" #include "BKE_report.h" -/* RenderEngine */ +/* RenderEngine Callbacks */ + +void engine_tag_redraw(RenderEngine *engine) +{ + engine->flag |= RE_ENGINE_DO_DRAW; +} + +void engine_tag_update(RenderEngine *engine) +{ + engine->flag |= RE_ENGINE_DO_UPDATE; +} + +static void engine_update(RenderEngine *engine, Main *bmain, Scene *scene) +{ + extern FunctionRNA rna_RenderEngine_update_func; + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= &rna_RenderEngine_update_func; + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "data", &bmain); + RNA_parameter_set_lookup(&list, "scene", &scene); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} static void engine_render(RenderEngine *engine, struct Scene *scene) { extern FunctionRNA rna_RenderEngine_render_func; - PointerRNA ptr; ParameterList list; FunctionRNA *func; @@ -87,7 +114,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine= {NULL}; PointerRNA dummyptr; - int have_function[1]; + int have_function[2]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type= &dummyet; @@ -122,13 +149,20 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo et->ext.free= free; RNA_struct_blender_type_set(et->ext.srna, et); - et->render= (have_function[0])? engine_render: NULL; + et->update= (have_function[0])? engine_update: NULL; + et->render= (have_function[1])? engine_render: NULL; BLI_addtail(&R_engines, et); return et->ext.srna; } +static void **rna_RenderEngine_instance(PointerRNA *ptr) +{ + RenderEngine *engine = ptr->data; + return &engine->py_instance; +} + static StructRNA* rna_RenderEngine_refine(PointerRNA *ptr) { RenderEngine *engine= (RenderEngine*)ptr->data; @@ -203,14 +237,28 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_struct_sdna(srna, "RenderEngine"); RNA_def_struct_ui_text(srna, "Render Engine", "Render engine"); RNA_def_struct_refine_func(srna, "rna_RenderEngine_refine"); - RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", NULL); + RNA_def_struct_register_funcs(srna, "rna_RenderEngine_register", "rna_RenderEngine_unregister", "rna_RenderEngine_instance"); + + /* final render callbacks */ + func= RNA_def_function(srna, "update", NULL); + RNA_def_function_ui_description(func, "Export scene data for render"); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_pointer(func, "data", "BlendData", "", ""); + RNA_def_pointer(func, "scene", "Scene", "", ""); - /* render */ func= RNA_def_function(srna, "render", NULL); RNA_def_function_ui_description(func, "Render scene into an image"); - RNA_def_function_flag(func, FUNC_REGISTER); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); RNA_def_pointer(func, "scene", "Scene", "", ""); + /* tag for redraw */ + RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); + RNA_def_function_ui_description(func, "Request redraw for viewport rendering"); + + /* tag for update */ + RNA_def_function(srna, "tag_update", "engine_tag_update"); + RNA_def_function_ui_description(func, "Request update call for viewport rendering"); + func= RNA_def_function(srna, "begin_result", "RE_engine_begin_result"); prop= RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX); RNA_def_property_flag(prop, PROP_REQUIRED); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index 344ef301f4c..b848dc26681 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -55,6 +55,8 @@ struct Scene; /* RenderEngine.flag */ #define RE_ENGINE_ANIMATION 1 #define RE_ENGINE_PREVIEW 2 +#define RE_ENGINE_DO_DRAW 4 +#define RE_ENGINE_DO_UPDATE 8 extern ListBase R_engines; @@ -66,6 +68,7 @@ typedef struct RenderEngineType { char name[64]; int flag; + void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene); void (*render)(struct RenderEngine *engine, struct Scene *scene); /* RNA integration */ @@ -74,11 +77,13 @@ typedef struct RenderEngineType { typedef struct RenderEngine { RenderEngineType *type; + void *py_instance; int flag; struct Render *re; ListBase fullresult; + char *text; } RenderEngine; RenderEngine *RE_engine_create(RenderEngineType *type); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index a6214329d0e..9d48e257154 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -61,7 +61,7 @@ static RenderEngineType internal_render_type = { NULL, NULL, "BLENDER_RENDER", "Blender Render", RE_INTERNAL, - NULL, + NULL, NULL, {NULL, NULL, NULL}}; #ifdef WITH_GAMEENGINE @@ -69,7 +69,7 @@ static RenderEngineType internal_render_type = { static RenderEngineType internal_game_type = { NULL, NULL, "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME, - NULL, + NULL, NULL, {NULL, NULL, NULL}}; #endif @@ -125,6 +125,15 @@ RenderEngine *RE_engine_create(RenderEngineType *type) void RE_engine_free(RenderEngine *engine) { +#ifdef WITH_PYTHON + if(engine->py_instance) { + BPY_DECREF(engine->py_instance); + } +#endif + + if(engine->text) + MEM_freeN(engine->text); + MEM_freeN(engine); } @@ -216,6 +225,19 @@ void RE_engine_update_stats(RenderEngine *engine, const char *stats, const char re->i.infostr= NULL; re->i.statstr= NULL; } + + /* set engine text */ + if(engine->text) { + MEM_freeN(engine->text); + engine->text= NULL; + } + + if(stats && stats[0] && info && info[0]) + engine->text= BLI_sprintfN("%s | %s", stats, info); + else if(info && info[0]) + engine->text= BLI_strdup(info); + else if(stats && stats[0]) + engine->text= BLI_strdup(stats); } void RE_engine_update_progress(RenderEngine *engine, float progress) @@ -273,8 +295,10 @@ int RE_engine_render(Render *re, int do_all) if((re->r.scemode & (R_NO_FRAME_UPDATE|R_PREVIEWBUTS))==0) scene_update_for_newframe(re->main, re->scene, re->lay); - type->render(engine, re->scene); - + if(type->update) + type->update(engine, re->main, re->scene); + if(type->render) + type->render(engine, re->scene); free_render_result(&engine->fullresult, engine->fullresult.first); From e1594ebb3c52f573a8a6c90f3d30acfb3de6e8a5 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 2 Nov 2011 14:36:21 +0000 Subject: [PATCH 037/147] World Mist * Removed some more unused stuff and marked as deprecated. --- source/blender/makesdna/DNA_world_types.h | 2 +- source/blender/makesrna/intern/rna_world.c | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 18e175129c1..2bc384b98a7 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -182,7 +182,7 @@ typedef struct World { #define WOMAP_HORIZ 2 #define WOMAP_ZENUP 4 #define WOMAP_ZENDOWN 8 -#define WOMAP_MIST 16 +#define WOMAP_MIST 16 /* Deprecated */ /* flag */ #define WO_DS_EXPAND (1<<0) diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index ba769a8d7fc..21ab9d9c845 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -161,11 +161,6 @@ static void rna_def_world_mtex(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Zenith Down", "Affect the color of the zenith below"); RNA_def_property_update(prop, 0, "rna_World_update"); - /* unused - prop= RNA_def_property(srna, "map_mist", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mapto", WOMAP_MIST); - RNA_def_property_ui_text(prop, "Mist", "Causes the texture to affect the intensity of the mist");*/ - prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "texco"); RNA_def_property_enum_items(prop, texco_items); From 11d05b379dfceb3d927d75a4be8c25d500f827ef Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 2 Nov 2011 15:35:16 +0000 Subject: [PATCH 038/147] Small sculpt cleanup Since frontface() is always called with tex_strength(), moved the call to frontface() into tex_strength (required a few new normal parameters.) --- source/blender/editors/sculpt_paint/sculpt.c | 70 ++++++++++++++------ 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0b009dba651..d4df1628b83 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -405,7 +405,8 @@ static int sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float loca } } -static float frontface(Brush *brush, float sculpt_normal[3], short no[3], float fno[3]) +static float frontface(Brush *brush, const float sculpt_normal[3], + const short no[3], const float fno[3]) { if (brush->flag & BRUSH_FRONTFACE) { float dot; @@ -655,7 +656,11 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather) } /* Return a multiplier for brush strength on a particular vertex. */ -static float tex_strength(SculptSession *ss, Brush *br, float *point, const float len) +static float tex_strength(SculptSession *ss, Brush *br, float point[3], + const float len, + const float sculpt_normal[3], + const short vno[3], + const float fno[3]) { MTex *mtex = &br->mtex; float avg= 1; @@ -742,7 +747,10 @@ static float tex_strength(SculptSession *ss, Brush *br, float *point, const floa avg += br->texture_sample_bias; - avg *= brush_curve_strength(br, len, ss->cache->radius); /* Falloff curve */ + /* Falloff curve */ + avg *= brush_curve_strength(br, len, ss->cache->radius); + + avg *= frontface(br, sculpt_normal, vno, fno); return avg; } @@ -980,7 +988,8 @@ static void do_mesh_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *node, BLI_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, ss->cache->view_normal, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + ss->cache->view_normal, vd.no, vd.fno); float avg[3], val[3]; neighbor_average(ss, avg, vd.vert_indices[vd.i]); @@ -1073,7 +1082,8 @@ static void do_multires_smooth_brush(Sculpt *sd, SculptSession *ss, PBVHNode *no fno= data[index].no; if(sculpt_brush_test(&test, co)) { - const float fade = bstrength*tex_strength(ss, brush, co, test.dist)*frontface(brush, ss->cache->view_normal, NULL, fno); + const float fade = bstrength*tex_strength(ss, brush, co, test.dist, + ss->cache->view_normal, NULL, fno); float *avg, val[3]; float n; @@ -1169,9 +1179,9 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test(&test, vd.co)) { - //if(sculpt_brush_test_cyl(&test, vd.co, ss->cache->location, area_normal)) { /* offset vertex */ - float fade = tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, area_normal, vd.no, vd.fno); + float fade = tex_strength(ss, brush, vd.co, test.dist, + area_normal, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -1225,7 +1235,8 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { /* offset vertex */ - const float fade = tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, area_normal, vd.no, vd.fno); + const float fade = tex_strength(ss, brush, vd.co, test.dist, + area_normal, vd.no, vd.fno); float val1[3]; float val2[3]; @@ -1266,7 +1277,8 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { - float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, ss->cache->view_normal, vd.no, vd.fno); + float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + ss->cache->view_normal, vd.no, vd.fno); float val[3]; sub_v3_v3v3(val, test.location, vd.co); @@ -1326,7 +1338,8 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, origco[vd.i])) { - const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist)*frontface(brush, an, origno[vd.i], NULL); + const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, + an, origno[vd.i], NULL); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1367,7 +1380,8 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1416,7 +1430,8 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1464,7 +1479,8 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, origco[vd.i])) { - const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist)*frontface(brush, an, origno[vd.i], NULL); + const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, + an, origno[vd.i], NULL); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1510,7 +1526,8 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, origco[vd.i])) { - const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist)*frontface(brush, an, origno[vd.i], NULL); + const float fade = bstrength*tex_strength(ss, brush, origco[vd.i], test.dist, + an, origno[vd.i], NULL); mul_v3_m3v3(proxy[vd.i], m, origco[vd.i]); sub_v3_v3(proxy[vd.i], origco[vd.i]); @@ -1564,7 +1581,8 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, origco[vd.i])) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, area_normal, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + area_normal, vd.no, vd.fno); float *disp= &layer_disp[vd.i]; float val[3]; @@ -1615,7 +1633,8 @@ static void do_inflate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if(sculpt_brush_test(&test, vd.co)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist)*frontface(brush, ss->cache->view_normal, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, test.dist, + ss->cache->view_normal, vd.no, vd.fno); float val[3]; if(vd.fno) copy_v3_v3(val, vd.fno); @@ -1947,7 +1966,8 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist))*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist), + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2020,7 +2040,9 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist))*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, + sqrt(test.dist), + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2111,7 +2133,9 @@ static void do_clay_tubes_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, ss->cache->radius*test.dist)*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, + ss->cache->radius*test.dist, + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2172,7 +2196,9 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist))*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, + sqrt(test.dist), + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], val, fade); @@ -2233,7 +2259,9 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod sub_v3_v3v3(val, intr, vd.co); if (plane_trim(ss->cache, brush, val)) { - const float fade = bstrength*tex_strength(ss, brush, vd.co, sqrt(test.dist))*frontface(brush, an, vd.no, vd.fno); + const float fade = bstrength*tex_strength(ss, brush, vd.co, + sqrt(test.dist), + an, vd.no, vd.fno); mul_v3_v3fl(proxy[vd.i], val, fade); From bdc029a193affd1672da340ae0a8287e8c299356 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 2 Nov 2011 15:58:56 +0000 Subject: [PATCH 039/147] Toolbar UI code: * More cleanup. --- .../startup/bl_ui/space_view3d_toolbar.py | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 9518ccb5f80..d8ef991e68f 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -481,12 +481,9 @@ class VIEW3D_PT_tools_brush(PaintPanel, Panel): col.template_ID_preview(settings, "brush", new="brush.add", rows=3, cols=8) # Particle Mode # - - # XXX This needs a check if psys is editable. if context.particle_edit_object: tool = settings.tool - # XXX Select Particle System layout.column().prop(settings, "tool", expand=True) if tool != 'NONE': @@ -825,13 +822,11 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel): if brush.use_anchor: col.separator() - row = col.row() - row.prop(brush, "use_edge_to_edge", "Edge To Edge") + col.prop(brush, "use_edge_to_edge", "Edge To Edge") if brush.use_airbrush: col.separator() - row = col.row() - row.prop(brush, "rate", text="Rate", slider=True) + col.prop(brush, "rate", text="Rate", slider=True) if brush.use_space: col.separator() @@ -857,8 +852,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel): row.prop(brush, "use_pressure_jitter", toggle=True, text="") else: - row = col.row() - row.prop(brush, "use_airbrush") + col.prop(brush, "use_airbrush") row = col.row() row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor) @@ -867,8 +861,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel): col.separator() if not image_paint: - row = col.row() - row.prop(brush, "use_smooth_stroke") + col.prop(brush, "use_smooth_stroke") col = layout.column() col.active = brush.use_smooth_stroke @@ -879,9 +872,7 @@ class VIEW3D_PT_tools_brush_stroke(PaintPanel, Panel): col = layout.column() col.active = (not brush.use_anchor) and (brush.sculpt_tool not in {'GRAB', 'THUMB', 'ROTATE', 'SNAKE_HOOK'}) - - row = col.row() - row.prop(brush, "use_space") + col.prop(brush, "use_space") row = col.row() row.active = brush.use_space @@ -1011,14 +1002,10 @@ class VIEW3D_PT_tools_brush_appearance(PaintPanel, Panel): else: col.prop(brush, "cursor_color_add", text="Color") - col = layout.column() - col.label(text="Icon:") - - row = col.row(align=True) - row.prop(brush, "use_custom_icon") + col = layout.column(align=True) + col.prop(brush, "use_custom_icon") if brush.use_custom_icon: - row = col.row(align=True) - row.prop(brush, "icon_filepath", text="") + col.prop(brush, "icon_filepath", text="") # ********** default tools for weight-paint **************** From 42ce1d5943195ed0d83ed225f50b7e8614d085a5 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Wed, 2 Nov 2011 16:02:01 +0000 Subject: [PATCH 040/147] Sculpt cleanup Replace a use of bglMats in sculpt with ED_view3d_* functions(). --- source/blender/editors/sculpt_paint/sculpt.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index d4df1628b83..c26a4d52a9e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -208,7 +208,8 @@ typedef struct StrokeCache { int first_time; /* Beginning of stroke may do some things special */ - bglMats *mats; + /* from ED_view3d_ob_project_mat_get() */ + float projection_mat[4][4]; /* Clean this up! */ ViewContext *vc; @@ -678,7 +679,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], } else if(ss->texcache) { float rotation = -mtex->rot; - float x, y, point_2d[3]; + float symm_point[3], point_2d[2]; + float x, y; float radius; /* if the active area is being applied for symmetry, flip it @@ -686,12 +688,13 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], position in order to project it. This insures that the brush texture will be oriented correctly. */ - flip_coord(point_2d, point, ss->cache->mirror_symmetry_pass); + flip_coord(symm_point, point, ss->cache->mirror_symmetry_pass); if (ss->cache->radial_symmetry_pass) - mul_m4_v3(ss->cache->symm_rot_mat_inv, point_2d); + mul_m4_v3(ss->cache->symm_rot_mat_inv, symm_point); - projectf(ss->cache->mats, point_2d, point_2d); + ED_view3d_project_float(ss->cache->vc->ar, symm_point, point_2d, + ss->cache->projection_mat); /* if fixed mode, keep coordinates relative to mouse */ if(mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) { @@ -2810,8 +2813,6 @@ static void sculpt_cache_free(StrokeCache *cache) { if(cache->face_norms) MEM_freeN(cache->face_norms); - if(cache->mats) - MEM_freeN(cache->mats); MEM_freeN(cache); } @@ -2910,8 +2911,8 @@ static void sculpt_update_cache_invariants(bContext* C, Sculpt *sd, SculptSessio cache->brush = brush; - cache->mats = MEM_callocN(sizeof(bglMats), "sculpt bglMats"); - view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, cache->mats); + /* cache projection matrix */ + ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat); ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal); /* Initialize layer brush displacements and persistent coords */ From a59f7e02f8c8b2527e6a23e440ca61a9b9992373 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 2 Nov 2011 16:19:57 +0000 Subject: [PATCH 041/147] Projection Paint UI: * Code cleanup, much better to understand what is going on there now. * Stencil menu was mis aligned, fixed it for UI beauty. :) --- .../startup/bl_ui/space_view3d_toolbar.py | 61 ++++++++----------- 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index d8ef991e68f..591191321ee 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1120,53 +1120,46 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): use_projection = ipaint.use_projection col = layout.column() - sub = col.column() - sub.active = use_projection - sub.prop(ipaint, "use_occlude") - sub.prop(ipaint, "use_backface_culling") + col.active = use_projection + col.prop(ipaint, "use_occlude") + col.prop(ipaint, "use_backface_culling") + + row = layout.row() + row.active = (use_projection) + row.prop(ipaint, "use_normal_falloff") + + sub = row.row() + sub.active = (ipaint.use_normal_falloff) + sub.prop(ipaint, "normal_angle", text="") split = layout.split() + + split.active = (use_projection) + split.prop(ipaint, "use_stencil_layer", text="Stencil") - col = split.column() - col.active = (use_projection) - col.prop(ipaint, "use_normal_falloff") + row = split.row() + row.active = (ipaint.use_stencil_layer) + row.menu("VIEW3D_MT_tools_projectpaint_stencil", text=mesh.uv_texture_stencil.name) + row.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA') - col = split.column() - col.active = (ipaint.use_normal_falloff and use_projection) - col.prop(ipaint, "normal_angle", text="") - - col = layout.column(align=False) - row = col.row() - row.active = (use_projection) - row.prop(ipaint, "use_stencil_layer", text="Stencil") - - row2 = row.row(align=False) - row2.active = (use_projection and ipaint.use_stencil_layer) - row2.menu("VIEW3D_MT_tools_projectpaint_stencil", text=mesh.uv_texture_stencil.name) - row2.prop(ipaint, "invert_stencil", text="", icon='IMAGE_ALPHA') - - col = layout.column() - sub = col.column() - row = sub.row() + row = layout.row() row.active = (settings.brush.image_tool == 'CLONE') - row.prop(ipaint, "use_clone_layer", text="Layer") row.menu("VIEW3D_MT_tools_projectpaint_clone", text=mesh.uv_texture_clone.name) - sub = col.column() - sub.prop(ipaint, "seam_bleed") - - col.label(text="External Editing") + layout.prop(ipaint, "seam_bleed") + + col = layout.column() + col.label(text="External Editing:") + row = col.split(align=True, percentage=0.55) row.operator("image.project_edit", text="Quick Edit") row.operator("image.project_apply", text="Apply") - row = col.row(align=True) - row.prop(ipaint, "screen_grab_size", text="") - sub = col.column() - sub.operator("paint.project_image", text="Apply Camera Image") + col.row().prop(ipaint, "screen_grab_size", text="") - sub.operator("image.save_dirty", text="Save All Edited") + col.operator("paint.project_image", text="Apply Camera Image") + col.operator("image.save_dirty", text="Save All Edited") class VIEW3D_PT_imagepaint_options(PaintPanel): From 97a0ae3e1b7eea3c069da8c6d3c7a3535734059d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 18:20:53 +0000 Subject: [PATCH 042/147] RenderEngine api: support for viewport rendering, details here: http://wiki.blender.org/index.php/Dev:2.6/Source/Render/RenderEngineAPI * This adds a Rendered draw type in the 3D view, only available when the render engine implements the view_draw callback. * 3D view now stores a pointer to a RenderEngine. * view_draw() callback will do OpenGL drawing instead of the viewport. * view_update() callback is called after depsgraph updates. --- source/blender/blenloader/intern/readfile.c | 21 +++- source/blender/editors/include/ED_render.h | 2 + source/blender/editors/render/render_update.c | 103 +++++++++++++++++- .../blender/editors/space_view3d/drawobject.c | 13 ++- .../editors/space_view3d/space_view3d.c | 8 ++ .../editors/space_view3d/view3d_draw.c | 71 +++++++++++- source/blender/makesdna/DNA_object_types.h | 5 +- source/blender/makesdna/DNA_view3d_types.h | 6 +- source/blender/makesrna/intern/rna_render.c | 49 ++++++++- source/blender/makesrna/intern/rna_scene.c | 10 +- source/blender/makesrna/intern/rna_space.c | 50 ++++++++- .../blender/render/extern/include/RE_engine.h | 3 + .../render/intern/source/external_engine.c | 4 +- source/blender/windowmanager/intern/wm_draw.c | 41 +++++-- .../windowmanager/intern/wm_event_system.c | 6 +- .../bad_level_call_stubs/stubs.c | 3 + 16 files changed, 363 insertions(+), 32 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index bdc25836a5d..b1a31820f54 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -140,6 +140,8 @@ #include "BLO_readfile.h" #include "BLO_undofile.h" +#include "RE_engine.h" + #include "readfile.h" #include "PIL_time.h" @@ -5089,6 +5091,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) if(sl->spacetype==SPACE_VIEW3D) { View3D *v3d= (View3D*) sl; BGpic *bgpic; + ARegion *ar; if(v3d->scenelock) v3d->camera= NULL; /* always get from scene */ @@ -5124,6 +5127,15 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) /* not very nice, but could help */ if((v3d->layact & v3d->lay)==0) v3d->layact= v3d->lay; + /* free render engines for now */ + for(ar= sa->regionbase.first; ar; ar= ar->next) { + RegionView3D *rv3d= ar->regiondata; + + if(rv3d && rv3d->render_engine) { + RE_engine_free(rv3d->render_engine); + rv3d->render_engine= NULL; + } + } } else if(sl->spacetype==SPACE_IPO) { SpaceIpo *sipo= (SpaceIpo *)sl; @@ -5262,6 +5274,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) rv3d->depths= NULL; rv3d->ri= NULL; + rv3d->render_engine= NULL; rv3d->sms= NULL; rv3d->smooth_timer= NULL; } @@ -5403,6 +5416,10 @@ static void direct_link_screen(FileData *fd, bScreen *sc) v3d->afterdraw_xray.first= v3d->afterdraw_xray.last= NULL; v3d->afterdraw_xraytransp.first= v3d->afterdraw_xraytransp.last= NULL; v3d->properties_storage= NULL; + + /* render can be quite heavy, set to wire on load */ + if(v3d->drawtype == OB_RENDER) + v3d->drawtype = OB_WIRE; view3d_split_250(v3d, &sl->regionbase); } @@ -10696,7 +10713,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) Object *ob=main->object.first; while (ob) { /* shaded mode disabled for now */ - if (ob->dt == OB_SHADED) ob->dt = OB_TEXTURE; + if (ob->dt == OB_MATERIAL) ob->dt = OB_TEXTURE; ob=ob->id.next; } } @@ -10711,7 +10728,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) for(sl= sa->spacedata.first; sl; sl= sl->next) { if(sl->spacetype==SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - if (v3d->drawtype == OB_SHADED) v3d->drawtype = OB_SOLID; + if (v3d->drawtype == OB_MATERIAL) v3d->drawtype = OB_SOLID; } } } diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 651c298ad5e..8c0fa3a89a3 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -44,6 +44,8 @@ void ED_operatortypes_render(void); /* render_shading.c */ void ED_render_id_flush_update(struct Main *bmain, struct ID *id); +void ED_render_engine_changed(struct Main *bmain); +void ED_render_engine_update_tagged(struct bContext *C, struct Main *bmain); /* render_preview.c */ diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index e80c3d85670..c4ce69557ad 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -56,11 +56,110 @@ #include "GPU_material.h" +#include "RE_engine.h" + #include "ED_node.h" #include "ED_render.h" #include "render_intern.h" // own include +/***************************** Render Engines ********************************/ + +void ED_render_engine_update_tagged(bContext *C, Main *bmain) +{ + /* viewport rendering update on data changes, happens after depsgraph + * updates if there was any change. context is set to the 3d view */ + bScreen *sc, *prev_sc= CTX_wm_screen(C); + ScrArea *sa, *prev_sa= CTX_wm_area(C); + ARegion *ar, *prev_ar= CTX_wm_region(C); + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + RenderEngine *engine; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + engine= rv3d->render_engine; + + if(engine && (engine->flag & RE_ENGINE_DO_UPDATE)) { + CTX_wm_screen_set(C, sc); + CTX_wm_area_set(C, sa); + CTX_wm_region_set(C, ar); + + engine->flag &= ~RE_ENGINE_DO_UPDATE; + engine->type->view_update(engine, C); + } + } + } + } + + CTX_wm_screen_set(C, prev_sc); + CTX_wm_area_set(C, prev_sa); + CTX_wm_region_set(C, prev_ar); +} + +void ED_render_engine_changed(Main *bmain) +{ + /* on changing the render engine type, clear all running render engines */ + bScreen *sc; + ScrArea *sa; + ARegion *ar; + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + + if(rv3d->render_engine) { + RE_engine_free(rv3d->render_engine); + rv3d->render_engine= NULL; + } + } + } + } +} + +static void tag_render_engines(Main *bmain) +{ + /* tag running render engines for update later on */ + bScreen *sc; + ScrArea *sa; + ARegion *ar; + + for(sc=bmain->screen.first; sc; sc=sc->id.next) { + for(sa=sc->areabase.first; sa; sa=sa->next) { + if(sa->spacetype != SPACE_VIEW3D) + continue; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d; + + if(ar->regiontype != RGN_TYPE_WINDOW) + continue; + + rv3d= ar->regiondata; + if(rv3d->render_engine) + rv3d->render_engine->flag |= RE_ENGINE_DO_UPDATE; + } + } + } +} + /***************************** Updates *********************************** * ED_render_id_flush_update gets called from DAG_id_tag_update, to do * * editor level updates when the ID changes. when these ID blocks are in * @@ -220,8 +319,10 @@ static void scene_changed(Main *bmain, Scene *UNUSED(scene)) void ED_render_id_flush_update(Main *bmain, ID *id) { - if(!id) + if(!id) { + tag_render_engines(bmain); return; + } switch(GS(id->name)) { case ID_MA: diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index a6424b183d1..593537f82d0 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -104,7 +104,7 @@ /* this condition has been made more complex since editmode can draw textures */ #define CHECK_OB_DRAWTEXTURE(vd, dt) \ -((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ + ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX)) static void draw_bounding_volume(Scene *scene, Object *ob); @@ -2696,8 +2696,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D totface = dm->getNumFaces(dm); /* vertexpaint, faceselect wants this, but it doesnt work for shaded? */ - if(dt!=OB_SHADED) - glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); + glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW); // Unwanted combination. if (is_paint_sel) draw_wire = 0; @@ -2814,7 +2813,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D dm->drawLooseEdges(dm); } } - else if(dt==OB_SHADED) { + else if(dt==OB_PAINT) { if(ob==OBACT) { if(ob && ob->mode & OB_MODE_WEIGHT_PAINT) { /* enforce default material settings */ @@ -5955,7 +5954,9 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } /* maximum drawtype */ - dt= MIN2(v3d->drawtype, ob->dt); + dt= v3d->drawtype; + if(dt==OB_RENDER) dt= OB_SOLID; + dt= MIN2(dt, ob->dt); if(v3d->zbuf==0 && dt>OB_WIRE) dt= OB_WIRE; dtx= 0; @@ -5970,7 +5971,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) dt= OB_SOLID; } else { - dt= OB_SHADED; + dt= OB_PAINT; } glEnable(GL_DEPTH_TEST); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index f868cda485f..ef806cb8881 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -56,6 +56,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "RE_engine.h" #include "RNA_access.h" @@ -344,6 +345,9 @@ static SpaceLink *view3d_duplicate(SpaceLink *sl) v3do->lay= v3dn->localvd->lay; v3do->lay &= 0xFFFFFF; } + + if(v3dn->drawtype == OB_RENDER) + v3dn->drawtype = OB_SOLID; /* copy or clear inside new stuff */ @@ -549,6 +553,9 @@ static void view3d_main_area_free(ARegion *ar) if(rv3d->ri) { // XXX BIF_view3d_previewrender_free(rv3d); } + + if(rv3d->render_engine) + RE_engine_free(rv3d->render_engine); if(rv3d->depths) { if(rv3d->depths->depths) MEM_freeN(rv3d->depths->depths); @@ -573,6 +580,7 @@ static void *view3d_main_area_duplicate(void *poin) new->depths= NULL; new->ri= NULL; + new->render_engine= NULL; new->gpd= NULL; new->sms= NULL; new->smooth_timer= NULL; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 6b5e7792e85..96031a7b3d3 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -62,6 +62,7 @@ #include "BKE_screen.h" #include "BKE_unit.h" +#include "RE_engine.h" #include "RE_pipeline.h" // make_stars #include "IMB_imbuf_types.h" @@ -2518,6 +2519,62 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLF_draw_default_ascii(22, ar->winy-17, 0.0f, printable, sizeof(printable)-1); } +static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar) +{ + Scene *scene= CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d= CTX_wm_region_view3d(C); + RenderEngineType *type; + + if(!rv3d->render_engine) { + type= RE_engines_find(scene->r.engine); + + if(!(type->view_update && type->view_draw)) + return 0; + + rv3d->render_engine= RE_engine_create(type); + type->view_update(rv3d->render_engine, C); + } + + view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + ED_region_pixelspace(ar); + + type= rv3d->render_engine->type; + type->view_draw(rv3d->render_engine, C); + + return 1; +} + +static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar) +{ + rcti rect; + const int header_height = 18; + + if(!rv3d->render_engine || !rv3d->render_engine->text) + return; + + /* background box */ + rect= ar->winrct; + rect.xmin= 0; + rect.ymin= ar->winrct.ymax - ar->winrct.ymin - header_height; + rect.xmax= ar->winrct.xmax - ar->winrct.xmin; + rect.ymax= ar->winrct.ymax - ar->winrct.ymin; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glColor4f(0.0f, 0.0f, 0.0f, 0.25f); + glRecti(rect.xmin, rect.ymin, rect.xmax+1, rect.ymax+1); + glDisable(GL_BLEND); + + /* text */ + UI_ThemeColor(TH_TEXT_HI); + UI_DrawString(12, rect.ymin + 5, rv3d->render_engine->text); +} + /* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) { @@ -2728,6 +2785,11 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha else draw_view_icon(rv3d); + if(rv3d->render_engine) { + view3d_main_area_draw_engine_info(rv3d, ar); + return; + } + if((U.uiflag & USER_SHOW_FPS) && screen->animtimer) { draw_viewport_fps(scene, ar); } @@ -2755,9 +2817,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); const char *grid_unit= NULL; - view3d_main_area_draw_objects(C, ar, &grid_unit); - - ED_region_pixelspace(ar); + /* draw viewport using external renderer? */ + if(!(v3d->drawtype == OB_RENDER && view3d_main_area_draw_engine(C, ar))) { + /* draw viewport using opengl */ + view3d_main_area_draw_objects(C, ar, &grid_unit); + ED_region_pixelspace(ar); + } view3d_main_area_draw_info(C, ar, grid_unit); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 38daf8bae28..3e17d7f4942 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -385,8 +385,11 @@ typedef struct DupliObject { #define OB_BOUNDBOX 1 #define OB_WIRE 2 #define OB_SOLID 3 -#define OB_SHADED 4 +#define OB_MATERIAL 4 #define OB_TEXTURE 5 +#define OB_RENDER 6 + +#define OB_PAINT 100 /* temporary used in draw code */ /* dtx: flags, char! */ #define OB_AXIS 2 diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index d94d4318725..aaf4186945e 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -39,6 +39,7 @@ struct SpaceLink; struct Base; struct BoundBox; struct RenderInfo; +struct RenderEngine; struct bGPdata; struct SmoothViewStore; struct wmTimer; @@ -115,6 +116,7 @@ typedef struct RegionView3D { struct RegionView3D *localvd; /* allocated backup of its self while in localview */ struct RenderInfo *ri; + struct RenderEngine *render_engine; struct ViewDepths *depths; /* animated smooth view */ @@ -164,8 +166,8 @@ typedef struct View3D { int layact; /** - * The drawing mode for the 3d display. Set to OB_WIRE, OB_SOLID, - * OB_SHADED or OB_TEXTURE */ + * The drawing mode for the 3d display. Set to OB_BOUNDBOX, OB_WIRE, OB_SOLID, + * OB_TEXTURE, OB_MATERIAL or OB_RENDER */ short drawtype; short ob_centre_cursor; /* optional bool for 3d cursor to define center */ short scenelock, around; diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 8f928313840..2ed06516c55 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -95,6 +95,40 @@ static void engine_render(RenderEngine *engine, struct Scene *scene) RNA_parameter_list_free(&list); } +static void engine_view_update(RenderEngine *engine, const struct bContext *context) +{ + extern FunctionRNA rna_RenderEngine_view_update_func; + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= &rna_RenderEngine_view_update_func; + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &context); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + +static void engine_view_draw(RenderEngine *engine, const struct bContext *context) +{ + extern FunctionRNA rna_RenderEngine_view_draw_func; + PointerRNA ptr; + ParameterList list; + FunctionRNA *func; + + RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr); + func= &rna_RenderEngine_view_draw_func; + + RNA_parameter_list_create(&list, &ptr, func); + RNA_parameter_set_lookup(&list, "context", &context); + engine->type->ext.call(NULL, &ptr, func, &list); + + RNA_parameter_list_free(&list); +} + /* RenderEngine registration */ static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type) @@ -114,7 +148,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo RenderEngineType *et, dummyet = {NULL}; RenderEngine dummyengine= {NULL}; PointerRNA dummyptr; - int have_function[2]; + int have_function[4]; /* setup dummy engine & engine type to store static properties in */ dummyengine.type= &dummyet; @@ -151,6 +185,8 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo et->update= (have_function[0])? engine_update: NULL; et->render= (have_function[1])? engine_render: NULL; + et->view_update= (have_function[2])? engine_view_update: NULL; + et->view_draw= (have_function[3])? engine_view_draw: NULL; BLI_addtail(&R_engines, et); @@ -251,6 +287,17 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); RNA_def_pointer(func, "scene", "Scene", "", ""); + /* viewport render callbacks */ + func= RNA_def_function(srna, "view_update", NULL); + RNA_def_function_ui_description(func, "Update on data changes for viewport render"); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_pointer(func, "context", "Context", "", ""); + + func= RNA_def_function(srna, "view_draw", NULL); + RNA_def_function_ui_description(func, "Draw viewport render"); + RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL); + RNA_def_pointer(func, "context", "Context", "", ""); + /* tag for redraw */ RNA_def_function(srna, "tag_redraw", "engine_tag_redraw"); RNA_def_function_ui_description(func, "Request redraw for viewport rendering"); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7bdaa0a512f..ce62550feeb 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -40,6 +40,7 @@ #include "BLI_math.h" /* Include for Bake Options */ +#include "RE_engine.h" #include "RE_pipeline.h" #ifdef WITH_QUICKTIME @@ -55,6 +56,8 @@ #include #endif +#include "ED_render.h" + #include "WM_api.h" #include "WM_types.h" @@ -773,6 +776,11 @@ static int rna_RenderSettings_engine_get(PointerRNA *ptr) return 0; } +static void rna_RenderSettings_engine_update(Main *bmain, Scene *UNUSED(unused), PointerRNA *UNUSED(ptr)) +{ + ED_render_engine_changed(bmain); +} + static void rna_Scene_glsl_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { Scene *scene= (Scene*)ptr->id.data; @@ -3212,7 +3220,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, "rna_RenderSettings_engine_get", "rna_RenderSettings_engine_set", "rna_RenderSettings_engine_itemf"); RNA_def_property_ui_text(prop, "Engine", "Engine to use for rendering"); - RNA_def_property_update(prop, NC_WINDOW, NULL); + RNA_def_property_update(prop, NC_WINDOW, "rna_RenderSettings_engine_update"); prop= RNA_def_property(srna, "has_multiple_engines", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_multiple_engines_get", NULL); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 51faccc0d6c..5c494a3337f 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -47,6 +47,9 @@ #include "WM_api.h" #include "WM_types.h" +#include "RE_engine.h" +#include "RE_pipeline.h" + #include "RNA_enum_types.h" EnumPropertyItem space_type_items[] = { @@ -98,8 +101,8 @@ EnumPropertyItem viewport_shade_items[] = { {OB_BOUNDBOX, "BOUNDBOX", ICON_BBOX, "Bounding Box", "Display the object's local bounding boxes only"}, {OB_WIRE, "WIREFRAME", ICON_WIRE, "Wireframe", "Display the object as wire edges"}, {OB_SOLID, "SOLID", ICON_SOLID, "Solid", "Display the object solid, lit with default OpenGL lights"}, - //{OB_SHADED, "SHADED", ICON_SMOOTH, "Shaded", "Display the object solid, with preview shading interpolated at vertices"}, {OB_TEXTURE, "TEXTURED", ICON_POTATO, "Textured", "Display the object solid, with face-assigned textures"}, + {OB_RENDER, "RENDERED", ICON_SMOOTH, "Rendered", "Display render preview"}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -313,6 +316,25 @@ static void rna_SpaceView3D_layer_update(Main *bmain, Scene *UNUSED(scene), Poin DAG_on_visible_update(bmain, FALSE); } +static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + View3D *v3d= (View3D*)(ptr->data); + ScrArea *sa= rna_area_from_space(ptr); + + if(v3d->drawtype != OB_RENDER) { + ARegion *ar; + + for(ar=sa->regionbase.first; ar; ar=ar->next) { + RegionView3D *rv3d = ar->regiondata; + + if(rv3d && rv3d->render_engine) { + RE_engine_free(rv3d->render_engine); + rv3d->render_engine= NULL; + } + } + } +} + static void rna_SpaceView3D_pivot_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { if (U.uiflag & USER_LOCKAROUND) { @@ -423,6 +445,29 @@ static void rna_RegionView3D_view_matrix_set(PointerRNA *ptr, const float *value ED_view3d_from_m4((float (*)[4])values, rv3d->ofs, rv3d->viewquat, &rv3d->dist); } +static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free) +{ + Scene *scene = ((bScreen*)ptr->id.data)->scene; + RenderEngineType *type = RE_engines_find(scene->r.engine); + + EnumPropertyItem *item= NULL; + int totitem= 0; + + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_BOUNDBOX); + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_WIRE); + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_SOLID); + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_TEXTURE); + + if(type->view_draw) { + RNA_enum_items_add_value(&item, &totitem, viewport_shade_items, OB_RENDER); + } + + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; +} + /* Space Image Editor */ static PointerRNA rna_SpaceImageEditor_uvedit_get(PointerRNA *ptr) @@ -1227,8 +1272,9 @@ static void rna_def_space_view3d(BlenderRNA *brna) prop= RNA_def_property(srna, "viewport_shade", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "drawtype"); RNA_def_property_enum_items(prop, viewport_shade_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_SpaceView3D_viewport_shade_itemf"); RNA_def_property_ui_text(prop, "Viewport Shading", "Method to display/shade objects in the 3D View"); - RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, "rna_SpaceView3D_viewport_shade_update"); prop= RNA_def_property(srna, "local_view", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "localvd"); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index b848dc26681..ef6c8a37b2e 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -71,6 +71,9 @@ typedef struct RenderEngineType { void (*update)(struct RenderEngine *engine, struct Main *bmain, struct Scene *scene); void (*render)(struct RenderEngine *engine, struct Scene *scene); + void (*view_update)(struct RenderEngine *engine, const struct bContext *context); + void (*view_draw)(struct RenderEngine *engine, const struct bContext *context); + /* RNA integration */ ExtensionRNA ext; } RenderEngineType; diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 9d48e257154..b37da67f743 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -61,7 +61,7 @@ static RenderEngineType internal_render_type = { NULL, NULL, "BLENDER_RENDER", "Blender Render", RE_INTERNAL, - NULL, NULL, + NULL, NULL, NULL, NULL, {NULL, NULL, NULL}}; #ifdef WITH_GAMEENGINE @@ -69,7 +69,7 @@ static RenderEngineType internal_render_type = { static RenderEngineType internal_game_type = { NULL, NULL, "BLENDER_GAME", "Blender Game", RE_INTERNAL|RE_GAME, - NULL, NULL, + NULL, NULL, NULL, NULL, {NULL, NULL, NULL}}; #endif diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 8261198ef78..389049d9e59 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -55,6 +55,8 @@ #include "GPU_draw.h" #include "GPU_extensions.h" +#include "RE_engine.h" + #include "WM_api.h" #include "WM_types.h" #include "wm.h" @@ -113,6 +115,19 @@ static int wm_area_test_invalid_backbuf(ScrArea *sa) return 1; } +static void wm_region_test_render_do_draw(ScrArea *sa, ARegion *ar) +{ + if(sa->spacetype == SPACE_VIEW3D) { + RegionView3D *rv3d = ar->regiondata; + RenderEngine *engine = (rv3d)? rv3d->render_engine: NULL; + + if(engine && (engine->flag & RE_ENGINE_DO_DRAW)) { + ar->do_draw = 1; + engine->flag &= ~RE_ENGINE_DO_DRAW; + } + } +} + /********************** draw all **************************/ /* - reference method, draw all each time */ @@ -205,7 +220,7 @@ static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) for(sa= screen->areabase.first; sa; sa= sa->next) for(ar= sa->regionbase.first; ar; ar= ar->next) if(ar->swinid && !wm_area_test_invalid_backbuf(sa)) - ED_region_tag_redraw(ar); + ED_region_tag_redraw(ar); /* flush overlapping regions */ if(screen->regionbase.first) { @@ -662,13 +677,28 @@ static int wm_draw_update_test_window(wmWindow *win) { ScrArea *sa; ARegion *ar; + int do_draw= 0; for(ar= win->screen->regionbase.first; ar; ar= ar->next) { if(ar->do_draw_overlay) { wm_tag_redraw_overlay(win, ar); ar->do_draw_overlay= 0; } + if(ar->swinid && ar->do_draw) + do_draw= 1; } + + for(sa= win->screen->areabase.first; sa; sa= sa->next) { + for(ar=sa->regionbase.first; ar; ar= ar->next) { + wm_region_test_render_do_draw(sa, ar); + + if(ar->swinid && ar->do_draw) + do_draw = 1; + } + } + + if(do_draw) + return 1; if(win->screen->do_refresh) return 1; @@ -681,15 +711,6 @@ static int wm_draw_update_test_window(wmWindow *win) if(win->screen->do_draw_drag) return 1; - for(ar= win->screen->regionbase.first; ar; ar= ar->next) - if(ar->swinid && ar->do_draw) - return 1; - - for(sa= win->screen->areabase.first; sa; sa= sa->next) - for(ar=sa->regionbase.first; ar; ar= ar->next) - if(ar->swinid && ar->do_draw) - return 1; - return 0; } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 65e65450167..0e22ccd05a7 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -59,6 +59,7 @@ #include "ED_fileselect.h" #include "ED_info.h" +#include "ED_render.h" #include "ED_screen.h" #include "ED_view3d.h" #include "ED_util.h" @@ -311,6 +312,7 @@ void wm_event_do_notifiers(bContext *C) /* XXX make lock in future, or separated derivedmesh users in scene */ if(!G.rendering) { /* depsgraph & animation: update tagged datablocks */ + Main *bmain = CTX_data_main(C); /* copied to set's in scene_update_tagged_recursive() */ win->screen->scene->customdata_mask= win_combine_v3d_datamask; @@ -318,7 +320,9 @@ void wm_event_do_notifiers(bContext *C) /* XXX, hack so operators can enforce datamasks [#26482], gl render */ win->screen->scene->customdata_mask |= win->screen->scene->customdata_mask_modal; - scene_update_tagged(CTX_data_main(C), win->screen->scene); + scene_update_tagged(bmain, win->screen->scene); + + ED_render_engine_update_tagged(C, bmain); } } diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 1dbed479d40..306a24f9adf 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -72,6 +72,7 @@ struct Object; struct PBVHNode; struct Render; struct RenderEngine; +struct RenderEngineType; struct RenderLayer; struct RenderResult; struct ScrArea; @@ -194,6 +195,7 @@ struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBu void ED_screen_set_scene(struct bContext *C, struct Scene *scene){} void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype){} +void ED_render_engine_changed(struct Main *bmain) {} struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob){return (struct PTCacheEdit *) NULL;} void PE_current_changed(struct Scene *scene, struct Object *ob){} @@ -387,6 +389,7 @@ void RE_engines_exit() {} void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) {} ListBase R_engines = {NULL, NULL}; void RE_engine_free(struct RenderEngine *engine) {} +struct RenderEngineType *RE_engines_find(const char *idname) {} /* python */ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} From 30f1f28a8af3b393608b5869512a8823111294ad Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 18:55:32 +0000 Subject: [PATCH 043/147] Nodes: add support for shader nodes on world and lamps, in addition to materials. The internal render engine does not support them, and they are not accesible in the UI yet, but cycles will use them. --- release/scripts/startup/bl_ui/space_node.py | 2 +- source/blender/blenkernel/intern/anim_sys.c | 6 +- source/blender/blenkernel/intern/object.c | 13 +++ source/blender/blenkernel/intern/world.c | 20 +++- source/blender/blenloader/intern/readfile.c | 26 ++++++ source/blender/blenloader/intern/writefile.c | 12 +++ source/blender/editors/include/ED_node.h | 2 +- .../blender/editors/render/render_preview.c | 24 +++++ source/blender/editors/render/render_update.c | 2 + source/blender/editors/space_node/node_draw.c | 10 +- source/blender/editors/space_node/node_edit.c | 93 ++++++++++++++----- .../blender/editors/space_node/space_node.c | 26 +++++- source/blender/makesdna/DNA_lamp_types.h | 12 ++- source/blender/makesdna/DNA_space_types.h | 6 ++ source/blender/makesdna/DNA_world_types.h | 6 +- source/blender/makesrna/intern/rna_lamp.c | 21 +++++ source/blender/makesrna/intern/rna_material.c | 11 ++- source/blender/makesrna/intern/rna_nodetree.c | 7 +- source/blender/makesrna/intern/rna_object.c | 1 - source/blender/makesrna/intern/rna_space.c | 11 +++ source/blender/makesrna/intern/rna_world.c | 22 +++++ .../blender/nodes/shader/node_shader_tree.c | 19 +++- .../blender/nodes/shader/node_shader_util.c | 2 + 23 files changed, 303 insertions(+), 51 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 708017ba749..2b2cc505f1f 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -42,7 +42,7 @@ class NODE_HT_header(Header): layout.prop(snode, "tree_type", text="", expand=True) - if snode.tree_type == 'MATERIAL': + if snode.tree_type == 'SHADER': if id_from: layout.template_ID(id_from, "active_material", new="material.new") if snode_id: diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 13abf18e20c..981c20d6165 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -43,9 +43,11 @@ #include "BLI_utildefines.h" #include "DNA_anim_types.h" +#include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" +#include "DNA_world_types.h" #include "BKE_animsys.h" #include "BKE_action.h" @@ -2291,7 +2293,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime) EVAL_ANIM_NODETREE_IDS(main->tex.first, Tex, ADT_RECALC_ANIM); /* lamps */ - EVAL_ANIM_IDS(main->lamp.first, ADT_RECALC_ANIM); + EVAL_ANIM_NODETREE_IDS(main->lamp.first, Lamp, ADT_RECALC_ANIM); /* materials */ EVAL_ANIM_NODETREE_IDS(main->mat.first, Material, ADT_RECALC_ANIM); @@ -2331,7 +2333,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime) EVAL_ANIM_IDS(main->object.first, 0); /* worlds */ - EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM); + EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM); /* scenes */ EVAL_ANIM_NODETREE_IDS(main->scene.first, Scene, ADT_RECALC_ANIM); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 635e0744aa1..a5edd569bc2 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -86,6 +86,7 @@ #include "BKE_mesh.h" #include "BKE_mball.h" #include "BKE_modifier.h" +#include "BKE_node.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -877,6 +878,9 @@ Lamp *copy_lamp(Lamp *la) } lan->curfalloff = curvemapping_copy(la->curfalloff); + + if(la->nodetree) + lan->nodetree= ntreeCopyTree(la->nodetree); if(la->preview) lan->preview = BKE_previewimg_copy(la->preview); @@ -903,6 +907,9 @@ Lamp *localize_lamp(Lamp *la) lan->curfalloff = curvemapping_copy(la->curfalloff); + if(la->nodetree) + lan->nodetree= ntreeLocalize(la->nodetree); + lan->preview= NULL; return lan; @@ -978,6 +985,12 @@ void free_lamp(Lamp *la) BKE_free_animdata((ID *)la); curvemapping_free(la->curfalloff); + + /* is no lib link block, but lamp extension */ + if(la->nodetree) { + ntreeFreeTree(la->nodetree); + MEM_freeN(la->nodetree); + } BKE_previewimg_free(&la->preview); BKE_icon_delete(&la->id); diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 5797c6c3f15..c7d2763774d 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -42,12 +42,14 @@ #include "BLI_utildefines.h" #include "BLI_bpath.h" -#include "BKE_world.h" -#include "BKE_library.h" #include "BKE_animsys.h" #include "BKE_global.h" -#include "BKE_main.h" #include "BKE_icons.h" +#include "BKE_library.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_world.h" void free_world(World *wrld) { @@ -63,6 +65,12 @@ void free_world(World *wrld) BKE_free_animdata((ID *)wrld); + /* is no lib link block, but world extension */ + if(wrld->nodetree) { + ntreeFreeTree(wrld->nodetree); + MEM_freeN(wrld->nodetree); + } + BKE_icon_delete((struct ID*)wrld); wrld->id.icon_id = 0; } @@ -119,6 +127,9 @@ World *copy_world(World *wrld) id_us_plus((ID *)wrldn->mtex[a]->tex); } } + + if(wrld->nodetree) + wrldn->nodetree= ntreeCopyTree(wrld->nodetree); if(wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview); @@ -143,6 +154,9 @@ World *localize_world(World *wrld) } } + if(wrld->nodetree) + wrldn->nodetree= ntreeLocalize(wrld->nodetree); + wrldn->preview= NULL; return wrldn; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b1a31820f54..15f5b49dd24 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2182,6 +2182,7 @@ static void lib_verify_nodetree(Main *main, int UNUSED(open)) for(ntree= main->nodetree.first; ntree; ntree= ntree->id.next) if (ntree->update) ntreeUpdateTree(ntree); + for (i=0; i < NUM_NTREE_TYPES; ++i) { ntreetype= ntreeGetType(i); if (ntreetype && ntreetype->foreach_nodetree) @@ -2507,6 +2508,9 @@ static void lib_link_lamp(FileData *fd, Main *main) } la->ipo= newlibadr_us(fd, la->id.lib, la->ipo); // XXX depreceated - old animation system + + if(la->nodetree) + lib_link_ntree(fd, &la->id, la->nodetree); la->id.flag -= LIB_NEEDLINK; } @@ -2528,6 +2532,10 @@ static void direct_link_lamp(FileData *fd, Lamp *la) la->curfalloff= newdataadr(fd, la->curfalloff); if(la->curfalloff) direct_link_curvemapping(fd, la->curfalloff); + + la->nodetree= newdataadr(fd, la->nodetree); + if(la->nodetree) + direct_link_nodetree(fd, la->nodetree); la->preview = direct_link_preview_image(fd, la->preview); } @@ -2670,6 +2678,9 @@ static void lib_link_world(FileData *fd, Main *main) mtex->object= newlibadr(fd, wrld->id.lib, mtex->object); } } + + if(wrld->nodetree) + lib_link_ntree(fd, &wrld->id, wrld->nodetree); wrld->id.flag -= LIB_NEEDLINK; } @@ -2687,6 +2698,11 @@ static void direct_link_world(FileData *fd, World *wrld) for(a=0; amtex[a]= newdataadr(fd, wrld->mtex[a]); } + + wrld->nodetree= newdataadr(fd, wrld->nodetree); + if(wrld->nodetree) + direct_link_nodetree(fd, wrld->nodetree); + wrld->preview = direct_link_preview_image(fd, wrld->preview); } @@ -5004,6 +5020,10 @@ static void lib_link_screen(FileData *fd, Main *main) if(snode->id) { if(GS(snode->id->name)==ID_MA) snode->nodetree= ((Material *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_WO) + snode->nodetree= ((World *)snode->id)->nodetree; + else if(GS(snode->id->name)==ID_LA) + snode->nodetree= ((Lamp *)snode->id)->nodetree; else if(GS(snode->id->name)==ID_SCE) snode->nodetree= ((Scene *)snode->id)->nodetree; else if(GS(snode->id->name)==ID_TE) @@ -12723,6 +12743,9 @@ static void expand_lamp(FileData *fd, Main *mainvar, Lamp *la) if (la->adt) expand_animdata(fd, mainvar, la->adt); + + if(la->nodetree) + expand_nodetree(fd, mainvar, la->nodetree); } static void expand_lattice(FileData *fd, Main *mainvar, Lattice *lt) @@ -12750,6 +12773,9 @@ static void expand_world(FileData *fd, Main *mainvar, World *wrld) if (wrld->adt) expand_animdata(fd, mainvar, wrld->adt); + + if(wrld->nodetree) + expand_nodetree(fd, mainvar, wrld->nodetree); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 4640fa0fe04..1e0ef4a6a16 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1857,6 +1857,12 @@ static void write_worlds(WriteData *wd, ListBase *idbase) for(a=0; amtex[a]) writestruct(wd, DATA, "MTex", 1, wrld->mtex[a]); } + + /* nodetree is integral part of lamps, no libdata */ + if(wrld->nodetree) { + writestruct(wd, DATA, "bNodeTree", 1, wrld->nodetree); + write_nodetree(wd, wrld->nodetree); + } write_previews(wd, wrld->preview); } @@ -1886,6 +1892,12 @@ static void write_lamps(WriteData *wd, ListBase *idbase) if(la->curfalloff) write_curvemapping(wd, la->curfalloff); + /* nodetree is integral part of lamps, no libdata */ + if(la->nodetree) { + writestruct(wd, DATA, "bNodeTree", 1, la->nodetree); + write_nodetree(wd, la->nodetree); + } + write_previews(wd, la->preview); } diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index b6cb59e2f4a..18bb4975da9 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -51,7 +51,7 @@ void ED_node_changed_update(struct ID *id, struct bNode *node); void ED_node_generic_update(struct Main *bmain, struct bNodeTree *ntree, struct bNode *node); /* node_edit.c */ -void ED_node_shader_default(struct Material *ma); +void ED_node_shader_default(struct Scene *scene, struct ID *id); void ED_node_composit_default(struct Scene *sce); void ED_node_texture_default(struct Tex *tex); void ED_node_link_intersect_test(struct ScrArea *sa, int test); diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 49bdb103139..9da160948cc 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -420,6 +420,12 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre base->object->data= la; } } + + if(la && la->nodetree && sp->pr_method==PR_NODE_RENDER) { + /* two previews, they get copied by wmJob */ + ntreeInitPreview(origla->nodetree, sp->sizex, sp->sizey); + ntreeInitPreview(la->nodetree, sp->sizex, sp->sizey); + } } else if(id_type==ID_WO) { World *wrld= NULL, *origwrld= (World *)id; @@ -432,6 +438,12 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre sce->lay= 1<world= wrld; + + if(wrld && wrld->nodetree && sp->pr_method==PR_NODE_RENDER) { + /* two previews, they get copied by wmJob */ + ntreeInitPreview(wrld->nodetree, sp->sizex, sp->sizey); + ntreeInitPreview(origwrld->nodetree, sp->sizex, sp->sizey); + } } return sce; @@ -566,6 +578,18 @@ static void shader_preview_updatejob(void *spv) if(sp->texcopy && tex->nodetree && sp->texcopy->nodetree) ntreeLocalSync(sp->texcopy->nodetree, tex->nodetree); } + else if( GS(sp->id->name) == ID_WO) { + World *wrld= (World *)sp->id; + + if(sp->worldcopy && wrld->nodetree && sp->worldcopy->nodetree) + ntreeLocalSync(sp->worldcopy->nodetree, wrld->nodetree); + } + else if( GS(sp->id->name) == ID_LA) { + Lamp *la= (Lamp *)sp->id; + + if(sp->lampcopy && la->nodetree && sp->lampcopy->nodetree) + ntreeLocalSync(sp->lampcopy->nodetree, la->nodetree); + } } } } diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index c4ce69557ad..72ea79fae7e 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -234,6 +234,7 @@ static void texture_changed(Main *bmain, Tex *tex) /* find lamps */ for(la=bmain->lamp.first; la; la=la->id.next) { if(mtex_use_tex(la->mtex, MAX_MTEX, tex)); + else if(la->nodetree && nodes_use_tex(la->nodetree, tex)); else continue; BKE_icon_changed(BKE_icon_getid(&la->id)); @@ -242,6 +243,7 @@ static void texture_changed(Main *bmain, Tex *tex) /* find worlds */ for(wo=bmain->world.first; wo; wo=wo->id.next) { if(mtex_use_tex(wo->mtex, MAX_MTEX, tex)); + else if(wo->nodetree && nodes_use_tex(wo->nodetree, tex)); else continue; BKE_icon_changed(BKE_icon_getid(&wo->id)); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index fd7a6ee21fd..c2a2f319c28 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -36,11 +36,13 @@ #include "MEM_guardedalloc.h" #include "DNA_node_types.h" +#include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_space_types.h" #include "DNA_screen_types.h" +#include "DNA_world_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -97,7 +99,13 @@ void ED_node_changed_update(ID *id, bNode *node) if(treetype==NTREE_SHADER) { DAG_id_tag_update(id, 0); - WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, id); + + if(GS(id->name) == ID_MA) + WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, id); + else if(GS(id->name) == ID_LA) + WM_main_add_notifier(NC_LAMP|ND_LIGHTING_DRAW, id); + else if(GS(id->name) == ID_WO) + WM_main_add_notifier(NC_WORLD|ND_WORLD_DRAW, id); } else if(treetype==NTREE_COMPOSIT) { nodeUpdate(edittree, node); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 4c98028644a..c1e50c112fa 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -39,11 +39,13 @@ #include "MEM_guardedalloc.h" #include "DNA_ID.h" -#include "DNA_object_types.h" +#include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" +#include "DNA_object_types.h" #include "DNA_particle_types.h" #include "DNA_scene_types.h" +#include "DNA_world_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -267,36 +269,61 @@ bNode *node_tree_get_editgroup(bNodeTree *nodetree) /* assumes nothing being done in ntree yet, sets the default in/out node */ /* called from shading buttons or header */ -void ED_node_shader_default(Material *ma) +void ED_node_shader_default(Scene *UNUSED(scene), ID *id) { bNode *in, *out; bNodeSocket *fromsock, *tosock; + bNodeTree *ntree; bNodeTemplate ntemp; + int output_type, shader_type; - /* but lets check it anyway */ - if(ma->nodetree) { - if (G.f & G_DEBUG) - printf("error in shader initialize\n"); - return; + ntree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0); + + switch(GS(id->name)) { + case ID_MA: { + Material *ma= (Material*)id; + ma->nodetree = ntree; + + output_type = SH_NODE_OUTPUT; + shader_type = SH_NODE_MATERIAL; + break; + } + case ID_WO: { + World *wo= (World*)id; + wo->nodetree = ntree; + + output_type = SH_NODE_OUTPUT; + shader_type = SH_NODE_MATERIAL; + break; + } + case ID_LA: { + Lamp *la= (Lamp*)id; + la->nodetree = ntree; + + output_type = SH_NODE_OUTPUT; + shader_type = SH_NODE_MATERIAL; + break; + } + default: + printf("ED_node_shader_default called on wrong ID type.\n"); + return; } - ma->nodetree= ntreeAddTree("Shader Nodetree", NTREE_SHADER, 0); - - ntemp.type = SH_NODE_OUTPUT; - out= nodeAddNode(ma->nodetree, &ntemp); + ntemp.type = output_type; + out= nodeAddNode(ntree, &ntemp); out->locx= 300.0f; out->locy= 300.0f; - ntemp.type = SH_NODE_MATERIAL; - in= nodeAddNode(ma->nodetree, &ntemp); + ntemp.type = shader_type; + in= nodeAddNode(ntree, &ntemp); in->locx= 10.0f; in->locy= 300.0f; - nodeSetActive(ma->nodetree, in); + nodeSetActive(ntree, in); /* only a link from color to color */ fromsock= in->outputs.first; tosock= out->inputs.first; - nodeAddLink(ma->nodetree, in, fromsock, out, tosock); + nodeAddLink(ntree, in, fromsock, out, tosock); - ntreeUpdateTree(ma->nodetree); + ntreeUpdateTree(ntree); } /* assumes nothing being done in ntree yet, sets the default in/out node */ @@ -387,6 +414,14 @@ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *tre *ntree= ((Material*)id)->nodetree; if(treetype) *treetype= NTREE_SHADER; } + else if(idtype == ID_LA) { + *ntree= ((Lamp*)id)->nodetree; + if(treetype) *treetype= NTREE_SHADER; + } + else if(idtype == ID_WO) { + *ntree= ((World*)id)->nodetree; + if(treetype) *treetype= NTREE_SHADER; + } else if(idtype == ID_SCE) { *ntree= ((Scene*)id)->nodetree; if(treetype) *treetype= NTREE_COMPOSIT; @@ -428,11 +463,25 @@ void snode_set_context(SpaceNode *snode, Scene *scene) if(snode->treetype==NTREE_SHADER) { /* need active object, or we allow pinning... */ - if(ob) { - Material *ma= give_current_material(ob, ob->actcol); - if(ma) { - snode->from= &ob->id; - snode->id= &ma->id; + if(snode->shaderfrom == SNODE_SHADER_OBJECT) { + if(ob) { + if(ob->type == OB_LAMP) { + snode->from= &ob->id; + snode->id= ob->data; + } + else { + Material *ma= give_current_material(ob, ob->actcol); + if(ma) { + snode->from= &ob->id; + snode->id= &ma->id; + } + } + } + } + else { /* SNODE_SHADER_WORLD */ + if(scene->world) { + snode->from= NULL; + snode->id= &scene->world->id; } } } @@ -526,7 +575,7 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) /* tree specific activate calls */ if(ntree->type==NTREE_SHADER) { /* when we select a material, active texture is cleared, for buttons */ - if(node->id && GS(node->id->name)==ID_MA) + if(node->id && ELEM3(GS(node->id->name), ID_MA, ID_LA, ID_WO)) nodeClearActiveID(ntree, ID_TE); if(node->type==SH_NODE_OUTPUT) { diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index 35b8666f274..1a808e8ee5f 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -32,10 +32,12 @@ #include #include +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" -#include "DNA_material_types.h" #include "DNA_scene_types.h" +#include "DNA_world_types.h" #include "MEM_guardedalloc.h" @@ -268,9 +270,21 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa) if(snode->nodetree) { if(snode->treetype==NTREE_SHADER) { - Material *ma= (Material *)snode->id; - if(ma->use_nodes) - ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + if(GS(snode->id->name) == ID_MA) { + Material *ma= (Material *)snode->id; + if(ma->use_nodes) + ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + } + else if(GS(snode->id->name) == ID_LA) { + Lamp *la= (Lamp *)snode->id; + if(la->use_nodes) + ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + } + else if(GS(snode->id->name) == ID_WO) { + World *wo= (World *)snode->id; + if(wo->use_nodes) + ED_preview_shader_job(C, sa, snode->id, NULL, NULL, 100, 100, PR_NODE_RENDER); + } } else if(snode->treetype==NTREE_COMPOSIT) { Scene *scene= (Scene *)snode->id; @@ -426,6 +440,10 @@ static void node_region_listener(ARegion *ar, wmNotifier *wmn) case NC_NODE: ED_region_tag_redraw(ar); break; + case NC_OBJECT: + if(wmn->data==ND_OB_SHADING) + ED_region_tag_redraw(ar); + break; case NC_ID: if(wmn->action == NA_RENAME) ED_region_tag_redraw(ar); diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index e36573473f3..91930f5766e 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -37,10 +37,11 @@ #define MAX_MTEX 18 #endif -struct MTex; -struct CurveMapping; struct AnimData; +struct bNodeTree; +struct CurveMapping; struct Ipo; +struct MTex; typedef struct Lamp { ID id; @@ -98,11 +99,14 @@ typedef struct Lamp { struct Ipo *ipo; // XXX depreceated... old animation system struct MTex *mtex[18]; /* MAX_MTEX */ - short pr_texture; - char pad6[6]; + short pr_texture, use_nodes; + char pad6[4]; /* preview */ struct PreviewImage *preview; + + /* nodes */ + struct bNodeTree *nodetree; } Lamp; /* **************** LAMP ********************* */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 37c2ea56e76..0c7943ce056 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -400,7 +400,9 @@ typedef struct SpaceNode { struct bNodeTree *nodetree, *edittree; int treetype; /* treetype: as same nodetree->type */ short texfrom; /* texfrom object, world or brush */ + short shaderfrom; /* shader from object or world */ short recalc; /* currently on 0/1, for auto compo */ + short pad[3]; ListBase linkdrag; /* temporary data for modal linking operator */ struct bGPdata *gpd; /* grease-pencil data */ @@ -418,6 +420,10 @@ typedef struct SpaceNode { #define SNODE_TEX_WORLD 1 #define SNODE_TEX_BRUSH 2 +/* snode->shaderfrom */ +#define SNODE_SHADER_OBJECT 0 +#define SNODE_SHADER_WORLD 1 + typedef struct SpaceLogic { SpaceLink *next, *prev; ListBase regionbase; /* storage of regions for inactive spaces */ diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 2bc384b98a7..0c455022db4 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -34,6 +34,7 @@ #include "DNA_ID.h" struct AnimData; +struct bNodeTree; struct Ipo; struct MTex; @@ -120,11 +121,14 @@ typedef struct World { struct Ipo *ipo; // XXX depreceated... old animation system struct MTex *mtex[18]; /* MAX_MTEX */ - short pr_texture, pad[3]; + short pr_texture, use_nodes, pad[2]; /* previews */ struct PreviewImage *preview; + /* nodes */ + struct bNodeTree *nodetree; + } World; /* **************** WORLD ********************* */ diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c index 572559546c8..629711fcf96 100644 --- a/source/blender/makesrna/intern/rna_lamp.c +++ b/source/blender/makesrna/intern/rna_lamp.c @@ -46,6 +46,7 @@ #include "BKE_main.h" #include "BKE_texture.h" +#include "ED_node.h" #include "WM_api.h" #include "WM_types.h" @@ -145,6 +146,15 @@ static void rna_Lamp_spot_size_set(PointerRNA *ptr, float value) la->spotsize= RAD2DEGF(value); } +static void rna_Lamp_use_nodes_update(Main *blain, Scene *scene, PointerRNA *ptr) +{ + Lamp *la= (Lamp*)ptr->data; + + if(la->use_nodes && la->nodetree==NULL) + ED_node_shader_default(scene, &la->id); + + rna_Lamp_update(blain, scene, ptr); +} #else @@ -366,6 +376,17 @@ static void rna_def_lamp(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "mode", LA_NO_DIFF); RNA_def_property_ui_text(prop, "Diffuse", "Lamp does diffuse shading"); RNA_def_property_update(prop, 0, "rna_Lamp_update"); + + /* nodes */ + prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); + RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based lamps"); + + prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the lamp"); + RNA_def_property_update(prop, 0, "rna_Lamp_use_nodes_update"); /* common */ rna_def_animdata_common(srna); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 990d3b89bce..57770be57eb 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -269,13 +269,14 @@ static void rna_Material_use_specular_ramp_set(PointerRNA *ptr, int value) ma->ramp_spec= add_colorband(0); } -static void rna_Material_use_nodes_set(PointerRNA *ptr, int value) +static void rna_Material_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr) { Material *ma= (Material*)ptr->data; - ma->use_nodes= value; if(ma->use_nodes && ma->nodetree==NULL) - ED_node_shader_default(ma); + ED_node_shader_default(scene, &ma->id); + + rna_Material_update(bmain, scene, ptr); } static EnumPropertyItem *rna_Material_texture_coordinates_itemf(bContext *UNUSED(C), PointerRNA *ptr, @@ -1954,9 +1955,9 @@ void RNA_def_material(BlenderRNA *brna) prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Material_use_nodes_set"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the material"); - RNA_def_property_update(prop, 0, "rna_Material_update"); + RNA_def_property_update(prop, 0, "rna_Material_use_nodes_update"); prop= RNA_def_property(srna, "active_node_material", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Material"); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 96c23effdfb..1445cf3b537 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -56,7 +56,7 @@ #include "MEM_guardedalloc.h" EnumPropertyItem nodetree_type_items[] = { - {NTREE_SHADER, "MATERIAL", ICON_MATERIAL, "Material", "Material nodes" }, + {NTREE_SHADER, "SHADER", ICON_MATERIAL, "Shader", "Shader nodes" }, {NTREE_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture nodes" }, {NTREE_COMPOSIT, "COMPOSITING", ICON_RENDERLAYERS, "Compositing", "Compositing nodes" }, {0, NULL, 0, NULL, NULL} @@ -189,7 +189,7 @@ static StructRNA *rna_NodeTree_refine(struct PointerRNA *ptr) case NTREE_TEXTURE: return &RNA_TextureNodeTree; default: - return &RNA_UnknownType; + return &RNA_NodeTree; } } @@ -232,6 +232,8 @@ static StructRNA *rna_NodeSocket_refine(PointerRNA *ptr) case SOCK_RGBA: return &RNA_NodeSocketRGBA; break; + case SOCK_SHADER: + return &RNA_NodeSocketShader; } #undef SUBTYPE @@ -2998,6 +3000,7 @@ void RNA_def_nodetree(BlenderRNA *brna) #undef SUBTYPE rna_def_node_socket_subtype(brna, SOCK_BOOLEAN, 0, "NodeSocketBoolean", "Boolean Node Socket"); rna_def_node_socket_subtype(brna, SOCK_RGBA, 0, "NodeSocketRGBA", "RGBA Node Socket"); + rna_def_node_socket_subtype(brna, SOCK_SHADER, 0, "NodeSocketShader", "Shader Closure Node Socket"); rna_def_node(brna); rna_def_node_link(brna); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f0ba435954b..137eebe6397 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1793,7 +1793,6 @@ static void rna_def_object(BlenderRNA *brna) {OB_BOUNDBOX, "BOUNDS", 0, "Bounds", "Draw the bounding box of the object"}, {OB_WIRE, "WIRE", 0, "Wire", "Draw the object as a wireframe"}, {OB_SOLID, "SOLID", 0, "Solid", "Draw the object as a solid (if solid drawing is enabled in the viewport)"}, - // disabled {OB_SHADED, "SHADED", 0, "Shaded", ""}, {OB_TEXTURE, "TEXTURED", 0, "Textured", "Draw the object with textures (if textures are enabled in the viewport)"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 5c494a3337f..0dc4ca343fe 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -2505,6 +2505,11 @@ static void rna_def_space_node(BlenderRNA *brna) {SNODE_TEX_BRUSH, "BRUSH", ICON_BRUSH_DATA, "Brush", "Edit texture nodes from Brush"}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem shader_type_items[] = { + {SNODE_SHADER_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Edit shader nodes from Object"}, + {SNODE_SHADER_WORLD, "WORLD", ICON_WORLD_DATA, "World", "Edit shader nodes from World"}, + {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem backdrop_channels_items[] = { {0, "COLOR", ICON_IMAGE_RGB, "Color", "Draw image with RGB colors"}, {SNODE_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, "Color and Alpha", @@ -2528,6 +2533,12 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Type", "Type of data to take texture from"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); + prop= RNA_def_property(srna, "shader_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "shaderfrom"); + RNA_def_property_enum_items(prop, shader_type_items); + RNA_def_property_ui_text(prop, "Shader Type", "Type of data to take shader from"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_NODE, NULL); + prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "ID", "Datablock whose nodes are being edited"); diff --git a/source/blender/makesrna/intern/rna_world.c b/source/blender/makesrna/intern/rna_world.c index 21ab9d9c845..d421aff7157 100644 --- a/source/blender/makesrna/intern/rna_world.c +++ b/source/blender/makesrna/intern/rna_world.c @@ -46,6 +46,8 @@ #include "BKE_main.h" #include "BKE_texture.h" +#include "ED_node.h" + #include "WM_api.h" static PointerRNA rna_World_lighting_get(PointerRNA *ptr) @@ -119,6 +121,15 @@ static void rna_World_stars_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po WM_main_add_notifier(NC_WORLD|ND_WORLD_STARS, wo); } +static void rna_World_use_nodes_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + World *wrld= (World*)ptr->data; + + if(wrld->use_nodes && wrld->nodetree==NULL) + ED_node_shader_default(scene, &wrld->id); + + rna_World_update(bmain, scene, ptr); +} #else @@ -552,6 +563,17 @@ void RNA_def_world(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_World_stars_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Stars", "World stars settings"); + /* nodes */ + prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); + RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node based worlds"); + + prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Use Nodes", "Use shader nodes to render the world"); + RNA_def_property_update(prop, 0, "rna_World_use_nodes_update"); + rna_def_lighting(brna); rna_def_world_mist(brna); rna_def_world_stars(brna); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index a83b32097df..d0ae17914ca 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -32,8 +32,10 @@ #include +#include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" +#include "DNA_world_types.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -56,11 +58,20 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) { Material *ma; - for(ma= main->mat.first; ma; ma= ma->id.next) { - if(ma->nodetree) { + Lamp *la; + World *wo; + + for(ma= main->mat.first; ma; ma= ma->id.next) + if(ma->nodetree) func(calldata, &ma->id, ma->nodetree); - } - } + + for(la= main->lamp.first; la; la= la->id.next) + if(la->nodetree) + func(calldata, &la->id, la->nodetree); + + for(wo= main->world.first; wo; wo= wo->id.next) + if(wo->nodetree) + func(calldata, &wo->id, wo->nodetree); } static void local_sync(bNodeTree *localtree, bNodeTree *ntree) diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 3b0211a53ee..1acb04c9b41 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -205,6 +205,8 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) gs->type= GPU_VEC3; else if (type == SOCK_RGBA) gs->type= GPU_VEC4; + else if (type == SOCK_SHADER) + gs->type= GPU_VEC4; else gs->type= GPU_NONE; From ac52c79cb19ac85e06651a7b9af2e54efcd45a97 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 19:24:30 +0000 Subject: [PATCH 044/147] RenderEngine/Nodes: system to check for shading nodes compatibility * Scene.use_shading_nodes property to check if RenderEngine is using new shading nodes system, and RenderEngine.bl_use_shading_nodes to set this. * Add mechanism for tagging nodes as being compatible with the old/new system. --- release/scripts/startup/bl_ui/space_node.py | 13 ++++++--- release/scripts/startup/bl_ui/space_view3d.py | 9 ++++--- source/blender/blenkernel/BKE_node.h | 8 +++++- source/blender/blenkernel/BKE_scene.h | 2 ++ source/blender/blenkernel/intern/node.c | 7 ++++- source/blender/blenkernel/intern/scene.c | 9 +++++++ .../blender/editors/render/render_shading.c | 26 ++++++++++++++---- .../blender/editors/space_node/node_header.c | 27 ++++++++++++++----- source/blender/makesrna/intern/rna_render.c | 4 +++ source/blender/makesrna/intern/rna_scene.c | 11 ++++++++ source/blender/nodes/intern/node_common.c | 1 + .../nodes/shader/nodes/node_shader_camera.c | 1 + .../nodes/shader/nodes/node_shader_curves.c | 2 ++ .../nodes/shader/nodes/node_shader_dynamic.c | 2 ++ .../nodes/shader/nodes/node_shader_geom.c | 1 + .../shader/nodes/node_shader_hueSatVal.c | 1 + .../nodes/shader/nodes/node_shader_invert.c | 1 + .../nodes/shader/nodes/node_shader_mapping.c | 1 + .../nodes/shader/nodes/node_shader_material.c | 2 ++ .../nodes/shader/nodes/node_shader_math.c | 1 + .../nodes/shader/nodes/node_shader_mixRgb.c | 1 + .../nodes/shader/nodes/node_shader_normal.c | 1 + .../nodes/shader/nodes/node_shader_output.c | 1 + .../nodes/shader/nodes/node_shader_rgb.c | 1 + .../shader/nodes/node_shader_sepcombRGB.c | 2 ++ .../nodes/shader/nodes/node_shader_squeeze.c | 1 + .../nodes/shader/nodes/node_shader_texture.c | 1 + .../nodes/shader/nodes/node_shader_valToRgb.c | 2 ++ .../nodes/shader/nodes/node_shader_value.c | 1 + .../nodes/shader/nodes/node_shader_vectMath.c | 1 + .../blender/render/extern/include/RE_engine.h | 1 + 31 files changed, 121 insertions(+), 21 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 2b2cc505f1f..69766b54e97 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -27,6 +27,7 @@ class NODE_HT_header(Header): def draw(self, context): layout = self.layout + scene = context.scene snode = context.space_data snode_id = snode.id id_from = snode.id_from @@ -43,10 +44,14 @@ class NODE_HT_header(Header): layout.prop(snode, "tree_type", text="", expand=True) if snode.tree_type == 'SHADER': - if id_from: - layout.template_ID(id_from, "active_material", new="material.new") - if snode_id: - layout.prop(snode_id, "use_nodes") + if scene.render.use_shading_nodes: + layout.prop(snode, "shader_type", text="", expand=True) + + if not scene.render.use_shading_nodes or snode.shader_type == 'OBJECT': + if id_from: + layout.template_ID(id_from, "active_material", new="material.new") + if snode_id: + layout.prop(snode_id, "use_nodes") elif snode.tree_type == 'TEXTURE': layout.prop(snode, "texture_type", text="", expand=True) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index dceab4a72e8..07c860fca31 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2143,10 +2143,11 @@ class VIEW3D_PT_view3d_display(Panel): subsub.active = scene.unit_settings.system == 'NONE' subsub.prop(view, "grid_subdivisions", text="Subdivisions") - col = layout.column() - col.label(text="Shading:") - col.prop(gs, "material_mode", text="") - col.prop(view, "show_textured_solid") + if not scene.render.use_shading_nodes: + col = layout.column() + col.label(text="Shading:") + col.prop(gs, "material_mode", text="") + col.prop(view, "show_textured_solid") layout.separator() diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index a819a464d3f..7509205e968 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -130,7 +130,7 @@ typedef struct bNodeType { char name[32]; float width, minwidth, maxwidth; float height, minheight, maxheight; - short nclass, flag; + short nclass, flag, compatibility; /* templates for static sockets */ bNodeSocketTemplate *inputs, *outputs; @@ -230,8 +230,13 @@ typedef struct bNodeType { #define NODE_CLASS_PARTICLES 25 #define NODE_CLASS_TRANSFORM 30 #define NODE_CLASS_COMBINE 31 +#define NODE_CLASS_SHADER 40 #define NODE_CLASS_LAYOUT 100 +/* nodetype->compatibility */ +#define NODE_OLD_SHADING 1 +#define NODE_NEW_SHADING 2 + /* enum values for input/output */ #define SOCK_IN 1 #define SOCK_OUT 2 @@ -388,6 +393,7 @@ void node_type_exec_new(struct bNodeType *ntype, void (*newexecfunc)(void *data, int thread, struct bNode *, void *nodedata, struct bNodeStack **, struct bNodeStack **)); void node_type_gpu(struct bNodeType *ntype, int (*gpufunc)(struct GPUMaterial *mat, struct bNode *node, struct GPUNodeStack *in, struct GPUNodeStack *out)); void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMaterial *mat, struct bNode *node, void *nodedata, struct GPUNodeStack *in, struct GPUNodeStack *out)); +void node_type_compatibility(struct bNodeType *ntype, short compatibility); /* ************** COMMON NODES *************** */ diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 5c214b2892a..45ee6fd4ebd 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -98,6 +98,8 @@ int get_render_child_particle_number(struct RenderData *r, int num); int get_render_shadow_samples(struct RenderData *r, int samples); float get_render_aosss_error(struct RenderData *r, float error); +int scene_use_new_shading_nodes(struct Scene *scene); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 824e59a82c5..f35f034387b 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -43,10 +43,11 @@ #include #include +#include "DNA_action_types.h" #include "DNA_anim_types.h" #include "DNA_node_types.h" +#include "DNA_node_types.h" #include "DNA_scene_types.h" -#include "DNA_action_types.h" #include "BLI_string.h" #include "BLI_math.h" @@ -1751,6 +1752,10 @@ void node_type_gpu_ext(struct bNodeType *ntype, int (*gpuextfunc)(struct GPUMate ntype->gpuextfunc = gpuextfunc; } +void node_type_compatibility(struct bNodeType *ntype, short compatibility) +{ + ntype->compatibility = compatibility; +} static bNodeType *is_nodetype_registered(ListBase *typelist, int type) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 6b3786663df..c902bee80a8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -72,6 +72,8 @@ #include "BKE_sound.h" +#include "RE_engine.h" + //XXX #include "BIF_previewrender.h" //XXX #include "BIF_editseq.h" @@ -1127,3 +1129,10 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base) return NULL; } + +int scene_use_new_shading_nodes(Scene *scene) +{ + RenderEngineType *type= RE_engines_find(scene->r.engine); + return (type->flag & RE_USE_SHADING_NODES); +} + diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index 35d679146fe..80c54d970b4 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -26,7 +26,6 @@ * \ingroup edrend */ - #include #include @@ -76,6 +75,7 @@ #include "ED_curve.h" #include "ED_mesh.h" +#include "ED_node.h" #include "ED_render.h" #include "ED_screen.h" @@ -363,16 +363,24 @@ void OBJECT_OT_material_slot_copy(wmOperatorType *ot) static int new_material_exec(bContext *C, wmOperator *UNUSED(op)) { + Scene *scene= CTX_data_scene(C); Material *ma= CTX_data_pointer_get_type(C, "material", &RNA_Material).data; PointerRNA ptr, idptr; PropertyRNA *prop; /* add or copy material */ - if(ma) + if(ma) { ma= copy_material(ma); - else + } + else { ma= add_material("Material"); + if(scene_use_new_shading_nodes(scene)) { + ED_node_shader_default(scene, &ma->id); + ma->use_nodes= 1; + } + } + /* hook into UI */ uiIDContextProperty(C, &ptr, &prop); @@ -455,16 +463,24 @@ void TEXTURE_OT_new(wmOperatorType *ot) static int new_world_exec(bContext *C, wmOperator *UNUSED(op)) { + Scene *scene= CTX_data_scene(C); World *wo= CTX_data_pointer_get_type(C, "world", &RNA_World).data; PointerRNA ptr, idptr; PropertyRNA *prop; /* add or copy world */ - if(wo) + if(wo) { wo= copy_world(wo); - else + } + else { wo= add_world("World"); + if(scene_use_new_shading_nodes(scene)) { + ED_node_shader_default(scene, &wo->id); + wo->use_nodes= 1; + } + } + /* hook into UI */ uiIDContextProperty(C, &ptr, &prop); diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 68f5dd6bf14..42b5dafa3e1 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -46,9 +46,10 @@ #include "BKE_context.h" #include "BKE_global.h" -#include "BKE_screen.h" -#include "BKE_node.h" #include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_scene.h" +#include "BKE_screen.h" #include "RNA_access.h" @@ -168,10 +169,11 @@ static int node_tree_has_type(int treetype, int nodetype) static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) { Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); bNodeTree *ntree; int nodeclass= GET_INT_FROM_POINTER(arg_nodeclass); - int event; + int event, compatibility= 0; ntree = snode->nodetree; @@ -179,6 +181,13 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) uiItemS(layout); return; } + + if(ntree->type == NTREE_SHADER) { + if(scene_use_new_shading_nodes(scene)) + compatibility= NODE_NEW_SHADING; + else + compatibility= NODE_OLD_SHADING; + } if (nodeclass==NODE_CLASS_GROUP) { bNodeTree *ngroup; @@ -210,14 +219,16 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) uiLayoutSetFunc(layout, do_node_add_static, NULL); for (ntype=ntreeGetType(ntree->type)->node_types.first; ntype; ntype=ntype->next) { - if(ntype->nclass==nodeclass && ntype->name) - uiItemV(layout, ntype->name, 0, ntype->type); + if (ntype->nclass==nodeclass && ntype->name) + if (!compatibility || (ntype->compatibility & compatibility)) + uiItemV(layout, ntype->name, 0, ntype->type); } } } static void node_menu_add(const bContext *C, Menu *menu) { + Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); uiLayout *layout= menu->layout; @@ -227,11 +238,15 @@ static void node_menu_add(const bContext *C, Menu *menu) if(snode->treetype==NTREE_SHADER) { uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); + if(scene_use_new_shading_nodes(scene)) { + uiItemMenuF(layout, IFACE_("Shader"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_SHADER)); + uiItemMenuF(layout, IFACE_("Texture"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE)); + } uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); uiItemMenuF(layout, IFACE_("Vector"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); - uiItemMenuF(layout, IFACE_("Dynamic"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC)); + //uiItemMenuF(layout, IFACE_("Dynamic"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC)); uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT)); } else if(snode->treetype==NTREE_COMPOSIT) { diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index 2ed06516c55..530d162b1fe 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -372,6 +372,10 @@ static void rna_def_render_engine(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "type->flag", RE_USE_POSTPROCESS); RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + prop= RNA_def_property(srna, "bl_use_shading_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_SHADING_NODES); + RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL); + RNA_define_verify_sdna(1); } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index ce62550feeb..63fce2d9edb 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -838,6 +838,12 @@ static int rna_RenderSettings_multiple_engines_get(PointerRNA *UNUSED(ptr)) return (BLI_countlist(&R_engines) > 1); } +static int rna_RenderSettings_use_shading_nodes_get(PointerRNA *ptr) +{ + Scene *scene= (Scene*)ptr->id.data; + return scene_use_new_shading_nodes(scene); +} + static int rna_RenderSettings_use_game_engine_get(PointerRNA *ptr) { RenderData *rd= (RenderData*)ptr->data; @@ -3227,6 +3233,11 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Multiple Engines", "More than one rendering engine is available"); + prop= RNA_def_property(srna, "use_shading_nodes", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_shading_nodes_get", NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Use Shading Nodes", "Active render engine uses new shading nodes system"); + prop= RNA_def_property(srna, "use_game_engine", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_funcs(prop, "rna_RenderSettings_use_game_engine_get", NULL); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index c43c1b36a84..11dcf44a288 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -980,6 +980,7 @@ void register_node_type_frame(ListBase *lb) node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT, NODE_BACKGROUND); node_type_size(ntype, 150, 100, 0); + node_type_compatibility(ntype, NODE_OLD_SHADING|NODE_NEW_SHADING); ntype->needs_free = 1; nodeRegisterType(lb, ntype); diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c index 15332bfa066..c7882a6e0e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_camera.c +++ b/source/blender/nodes/shader/nodes/node_shader_camera.c @@ -62,6 +62,7 @@ void register_node_type_sh_camera(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_CAMERA, "Camera Data", NODE_CLASS_INPUT, 0); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_camera_out); node_type_size(&ntype, 95, 95, 120); node_type_storage(&ntype, "node_camera", NULL, NULL); diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c index 9c441e45656..7ac05bb28bf 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.c +++ b/source/blender/nodes/shader/nodes/node_shader_curves.c @@ -74,6 +74,7 @@ void register_node_type_sh_curve_vec(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_CURVE_VEC, "Vector Curves", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_curve_vec_in, sh_node_curve_vec_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_vec); @@ -128,6 +129,7 @@ void register_node_type_sh_curve_rgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_CURVE_RGB, "RGB Curves", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_curve_rgb_in, sh_node_curve_rgb_out); node_type_size(&ntype, 200, 140, 320); node_type_init(&ntype, node_shader_init_curve_rgb); diff --git a/source/blender/nodes/shader/nodes/node_shader_dynamic.c b/source/blender/nodes/shader/nodes/node_shader_dynamic.c index d41ddecbab3..51ddb865c54 100644 --- a/source/blender/nodes/shader/nodes/node_shader_dynamic.c +++ b/source/blender/nodes/shader/nodes/node_shader_dynamic.c @@ -766,6 +766,7 @@ void register_node_type_sh_dynamic(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, NODE_OPTIONS, NULL, NULL); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_size(&ntype, 150, 60, 300); node_type_init(&ntype, node_dynamic_init_cb); node_type_storage(&ntype, "NodeScriptDict", node_dynamic_free_storage_cb, node_dynamic_copy_cb); @@ -781,6 +782,7 @@ void register_node_type_sh_dynamic(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, NODE_DYNAMIC, "Dynamic", NODE_CLASS_OP_DYNAMIC, 0); + node_type_compatibility(&ntype, NODE_OLD_SHADING); nodeRegisterType(lb, &ntype); } diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c index 1b073f6415b..dedc25092c1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geom.c +++ b/source/blender/nodes/shader/nodes/node_shader_geom.c @@ -139,6 +139,7 @@ void register_node_type_sh_geom(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_GEOMETRY, "Geometry", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_geom_out); node_type_size(&ntype, 120, 80, 160); node_type_init(&ntype, node_shader_init_geometry); diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c index db717c48a88..7fb31d80ffc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c +++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c @@ -85,6 +85,7 @@ void register_node_type_sh_hue_sat(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_HUE_SAT, "Hue Saturation Value", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_hue_sat_in, sh_node_hue_sat_out); node_type_size(&ntype, 150, 80, 250); node_type_exec(&ntype, node_shader_exec_hue_sat); diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c index 44d26bfff4e..066ff14a870 100644 --- a/source/blender/nodes/shader/nodes/node_shader_invert.c +++ b/source/blender/nodes/shader/nodes/node_shader_invert.c @@ -77,6 +77,7 @@ void register_node_type_sh_invert(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_INVERT, "Invert", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_invert_in, sh_node_invert_out); node_type_size(&ntype, 90, 80, 100); node_type_exec(&ntype, node_shader_exec_invert); diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index 7ec30952ea1..862c52187dc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -91,6 +91,7 @@ void register_node_type_sh_mapping(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_MAPPING, "Mapping", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_mapping_in, sh_node_mapping_out); node_type_size(&ntype, 240, 160, 320); node_type_init(&ntype, node_shader_init_mapping); diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index 408b7b0ea48..f93928d8884 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -305,6 +305,7 @@ void register_node_type_sh_material(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_MATERIAL, "Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_material_in, sh_node_material_out); node_type_size(&ntype, 120, 80, 240); node_type_init(&ntype, node_shader_init_material); @@ -320,6 +321,7 @@ void register_node_type_sh_material_ext(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_MATERIAL_EXT, "Extended Material", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_material_ext_in, sh_node_material_ext_out); node_type_size(&ntype, 120, 80, 240); node_type_init(&ntype, node_shader_init_material); diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c index 6faad500793..13ee1f79fe6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -241,6 +241,7 @@ void register_node_type_sh_math(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_MATH, "Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_math_in, sh_node_math_out); node_type_size(&ntype, 120, 110, 160); node_type_label(&ntype, node_math_label); diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c index 463146ec59c..7aed6bce4c4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c @@ -78,6 +78,7 @@ void register_node_type_sh_mix_rgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_MIX_RGB, "Mix", NODE_CLASS_OP_COLOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_mix_rgb_in, sh_node_mix_rgb_out); node_type_size(&ntype, 100, 60, 150); node_type_label(&ntype, node_blend_label); diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c index 0038570c5b1..c23c6d328cf 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal.c @@ -84,6 +84,7 @@ void register_node_type_sh_normal(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_NORMAL, "Normal", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_normal_in, sh_node_normal_out); node_type_init(&ntype, node_shader_init_normal); node_type_exec(&ntype, node_shader_exec_normal); diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c index 98a23534f90..ea7fae8f961 100644 --- a/source/blender/nodes/shader/nodes/node_shader_output.c +++ b/source/blender/nodes/shader/nodes/node_shader_output.c @@ -83,6 +83,7 @@ void register_node_type_sh_output(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_OUTPUT, "Output", NODE_CLASS_OUTPUT, NODE_PREVIEW); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_output_in, NULL); node_type_size(&ntype, 80, 60, 200); node_type_exec(&ntype, node_shader_exec_output); diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb.c b/source/blender/nodes/shader/nodes/node_shader_rgb.c index db2e9905a01..1a0b4ea616b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_rgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_rgb.c @@ -71,6 +71,7 @@ void register_node_type_sh_rgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_RGB, "RGB", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_rgb_out); node_type_init(&ntype, node_shader_init_rgb); node_type_size(&ntype, 140, 80, 140); diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c index 77d8cdf033a..4f409bb3ec1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c +++ b/source/blender/nodes/shader/nodes/node_shader_sepcombRGB.c @@ -61,6 +61,7 @@ void register_node_type_sh_seprgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_SEPRGB, "Separate RGB", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_seprgb_in, sh_node_seprgb_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_shader_exec_seprgb); @@ -100,6 +101,7 @@ void register_node_type_sh_combrgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_COMBRGB, "Combine RGB", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_combrgb_in, sh_node_combrgb_out); node_type_size(&ntype, 80, 40, 140); node_type_exec(&ntype, node_shader_exec_combrgb); diff --git a/source/blender/nodes/shader/nodes/node_shader_squeeze.c b/source/blender/nodes/shader/nodes/node_shader_squeeze.c index ec2c1860597..16a9ae8aedc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_squeeze.c +++ b/source/blender/nodes/shader/nodes/node_shader_squeeze.c @@ -67,6 +67,7 @@ void register_node_type_sh_squeeze(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_SQUEEZE, "Squeeze Value", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_squeeze_in, sh_node_squeeze_out); node_type_size(&ntype, 120, 110, 160); node_type_storage(&ntype, "node_squeeze", NULL, NULL); diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index 199af9a69a9..588cdc1da83 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -136,6 +136,7 @@ void register_node_type_sh_texture(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_TEXTURE, "Texture", NODE_CLASS_INPUT, NODE_OPTIONS|NODE_PREVIEW); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_texture_in, sh_node_texture_out); node_type_size(&ntype, 120, 80, 240); node_type_exec(&ntype, node_shader_exec_texture); diff --git a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c index bc418a7c416..4d41e62b242 100644 --- a/source/blender/nodes/shader/nodes/node_shader_valToRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_valToRgb.c @@ -76,6 +76,7 @@ void register_node_type_sh_valtorgb(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_VALTORGB, "ColorRamp", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_valtorgb_in, sh_node_valtorgb_out); node_type_size(&ntype, 240, 200, 300); node_type_init(&ntype, node_shader_init_valtorgb); @@ -116,6 +117,7 @@ void register_node_type_sh_rgbtobw(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_RGBTOBW, "RGB to BW", NODE_CLASS_CONVERTOR, 0); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_rgbtobw_in, sh_node_rgbtobw_out); node_type_size(&ntype, 80, 40, 120); node_type_exec(&ntype, node_shader_exec_rgbtobw); diff --git a/source/blender/nodes/shader/nodes/node_shader_value.c b/source/blender/nodes/shader/nodes/node_shader_value.c index 95ee54e225d..4a8aa6c9cf4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_value.c +++ b/source/blender/nodes/shader/nodes/node_shader_value.c @@ -71,6 +71,7 @@ void register_node_type_sh_value(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_VALUE, "Value", NODE_CLASS_INPUT, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, NULL, sh_node_value_out); node_type_init(&ntype, node_shader_init_value); node_type_size(&ntype, 80, 50, 120); diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c index 4282b40cb4d..b3f995dcdce 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c +++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c @@ -135,6 +135,7 @@ void register_node_type_sh_vect_math(ListBase *lb) static bNodeType ntype; node_type_base(&ntype, SH_NODE_VECT_MATH, "Vector Math", NODE_CLASS_CONVERTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_OLD_SHADING); node_type_socket_templates(&ntype, sh_node_vect_math_in, sh_node_vect_math_out); node_type_size(&ntype, 80, 75, 140); node_type_label(&ntype, node_vect_math_label); diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h index ef6c8a37b2e..e521479bbcd 100644 --- a/source/blender/render/extern/include/RE_engine.h +++ b/source/blender/render/extern/include/RE_engine.h @@ -51,6 +51,7 @@ struct Scene; #define RE_GAME 2 #define RE_USE_PREVIEW 4 #define RE_USE_POSTPROCESS 8 +#define RE_USE_SHADING_NODES 16 /* RenderEngine.flag */ #define RE_ENGINE_ANIMATION 1 From 723e129252f82cc81faa8834a68c79e4439ee8fa Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 2 Nov 2011 20:56:52 +0000 Subject: [PATCH 045/147] Depsgraph/Python: callbacks and properties to detect datablock changes * Adds two new python handlers: scene_update_pre() and scene_update_post() These run before and after Blender does a scene update on making modifications to the scene. * Datablocks now have an is_updated property. This will be set to true in the above callbacks if the datablock was tagged to be updated. This works for the most common datablocks used for rendering: object, material, world, lamsp, texture, mesh, curve. * Datablock collections also have an is_updated property. If this is set, it means one datablock of this type was added, removed or modified. It's also useful as a quick check to avoid looping over all datablocks. * RenderEngine.view_update() can also check these properties, for interactive viewport rendering. http://wiki.blender.org/index.php/Dev:2.6/Source/Render/UpdateAPI --- source/blender/blenkernel/BKE_depsgraph.h | 6 + source/blender/blenkernel/BKE_scene.h | 2 + source/blender/blenkernel/intern/depsgraph.c | 127 ++++++++++++-- source/blender/blenkernel/intern/scene.c | 14 ++ source/blender/blenlib/BLI_callbacks.h | 2 + source/blender/editors/object/object_add.c | 1 + source/blender/editors/object/object_edit.c | 2 + source/blender/makesdna/DNA_ID.h | 1 + source/blender/makesrna/intern/rna_ID.c | 10 ++ source/blender/makesrna/intern/rna_main_api.c | 158 ++++++++++++++++++ source/blender/makesrna/intern/rna_object.c | 2 + .../blender/makesrna/intern/rna_scene_api.c | 1 + .../blender/python/intern/bpy_app_handlers.c | 2 + .../windowmanager/intern/wm_event_system.c | 2 + 14 files changed, 314 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 59b7712a5a4..0b0637fb42a 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -120,6 +120,12 @@ void DAG_ids_flush_update(struct Main *bmain, int time); void DAG_id_tag_update(struct ID *id, short flag); /* flush all tagged updates */ void DAG_ids_flush_tagged(struct Main *bmain); + /* check and clear ID recalc flags */ +void DAG_ids_check_recalc(struct Main *bmain); +void DAG_ids_clear_recalc(struct Main *bmain); + /* test if any of this id type is tagged for update */ +void DAG_id_type_tag(struct Main *bmain, short idtype); +int DAG_id_type_tagged(struct Main *bmain, short idtype); /* (re)-create dependency graph for armature pose */ void DAG_pose_sort(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 45ee6fd4ebd..4806a288cee 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -88,6 +88,8 @@ int scene_check_setscene(struct Main *bmain, struct Scene *sce); float BKE_curframe(struct Scene *scene); void scene_update_tagged(struct Main *bmain, struct Scene *sce); +void scene_clear_tagged(struct Main *bmain, struct Scene *sce); + void scene_update_for_newframe(struct Main *bmain, struct Scene *sce, unsigned int lay); void scene_add_render_layer(struct Scene *sce); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index c9df8a135fe..9d51571346f 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1761,9 +1761,22 @@ void DAG_scene_sort(Main *bmain, Scene *sce) sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */ } +static void lib_id_recalc_tag(Main *bmain, ID *id) +{ + id->flag |= LIB_ID_RECALC; + bmain->id_tag_update[id->name[0]] = 1; +} + +static void lib_id_recalc_data_tag(Main *bmain, ID *id) +{ + id->flag |= LIB_ID_RECALC_DATA; + bmain->id_tag_update[id->name[0]] = 1; +} + /* node was checked to have lasttime != curtime and is if type ID_OB */ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) { + Main *bmain= G.main; DagAdjList *itA; Object *ob, *obc; int oldflag, changed=0; @@ -1789,20 +1802,24 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) if(itA->type & DAG_RL_OB_OB) { //printf("ob %s changes ob %s\n", ob->id.name, obc->id.name); obc->recalc |= OB_RECALC_OB; + lib_id_recalc_tag(bmain, &obc->id); } if(itA->type & DAG_RL_OB_DATA) { //printf("ob %s changes obdata %s\n", ob->id.name, obc->id.name); obc->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &obc->id); } } if(ob->recalc & OB_RECALC_DATA) { if(itA->type & DAG_RL_DATA_OB) { //printf("obdata %s changes ob %s\n", ob->id.name, obc->id.name); obc->recalc |= OB_RECALC_OB; + lib_id_recalc_tag(bmain, &obc->id); } if(itA->type & DAG_RL_DATA_DATA) { //printf("obdata %s changes obdata %s\n", ob->id.name, obc->id.name); obc->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &obc->id); } } if(oldflag!=obc->recalc) changed= 1; @@ -1833,6 +1850,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime) if(itA->type & (DAG_RL_OB_DATA|DAG_RL_DATA_DATA)) { // printf("parent %s changes ob %s\n", ob->id.name, obc->id.name); obc->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &obc->id); } } } @@ -1872,6 +1890,7 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime) /* node was checked to have lasttime != curtime , and is of type ID_OB */ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int reset) { + Main *bmain= G.main; DagAdjList *itA; Object *ob; @@ -1883,8 +1902,10 @@ static void flush_pointcache_reset(Scene *scene, DagNode *node, int curtime, int ob= (Object*)(itA->node->ob); if(reset || (ob->recalc & OB_RECALC_ALL)) { - if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) + if(BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH)) { ob->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &ob->id); + } flush_pointcache_reset(scene, itA->node, curtime, 1); } @@ -2001,8 +2022,10 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho ob= (Object*)(itA->node->ob); if(ob->recalc & OB_RECALC_ALL) { - if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) + if(BKE_ptcache_object_reset(sce, ob, PTCACHE_RESET_DEPSGRAPH)) { ob->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &ob->id); + } flush_pointcache_reset(sce, itA->node, lasttime, 1); } @@ -2204,6 +2227,12 @@ static void dag_object_time_update_flags(Object *ob) } } } + + if(ob->recalc & OB_RECALC_OB) + lib_id_recalc_tag(G.main, &ob->id); + if(ob->recalc & OB_RECALC_DATA) + lib_id_recalc_data_tag(G.main, &ob->id); + } /* flag all objects that need recalc, for changes in time for example */ /* do_time: make this optional because undo resets objects to their animated locations without this */ @@ -2362,6 +2391,9 @@ void DAG_on_visible_update(Main *bmain, const short do_time) DAG_scene_update_flags(bmain, scene, lay, do_time); scene->lay_updated |= lay; } + + /* hack to get objects updating on layer changes */ + DAG_id_type_tag(bmain, ID_OB); } static void dag_id_flush_update__isDependentTexture(void *userData, Object *UNUSED(ob), ID **idpoin) @@ -2408,6 +2440,7 @@ static void dag_id_flush_update(Scene *sce, ID *id) for(obt=bmain->object.first; obt; obt= obt->id.next) { if(!(ob && obt == ob) && obt->data == id) { obt->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &obt->id); BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); } } @@ -2421,8 +2454,10 @@ static void dag_id_flush_update(Scene *sce, ID *id) data.is_dependent= 0; modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data); - if (data.is_dependent) + if (data.is_dependent) { obt->recalc |= OB_RECALC_DATA; + lib_id_recalc_data_tag(bmain, &obt->id); + } /* particle settings can use the texture as well */ if(obt->particlesystem.first) { @@ -2435,7 +2470,8 @@ static void dag_id_flush_update(Scene *sce, ID *id) mtex = *mtexp; if(mtex && mtex->tex == (Tex*)id) { obt->recalc |= OB_RECALC_DATA; - + lib_id_recalc_data_tag(bmain, &obt->id); + if(mtex->mapto & PAMAP_INIT) psys->recalc |= PSYS_RECALC_RESET; if(mtex->mapto & PAMAP_CHILD) @@ -2455,6 +2491,8 @@ static void dag_id_flush_update(Scene *sce, ID *id) Key *key= ob_get_key(obt); if(!(ob && obt == ob) && ((ID *)key == id)) { obt->flag |= (OB_RECALC_OB|OB_RECALC_DATA); + lib_id_recalc_tag(bmain, &obt->id); + lib_id_recalc_data_tag(bmain, &obt->id); BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); } } @@ -2479,7 +2517,7 @@ void DAG_ids_flush_tagged(Main *bmain) ListBase *lbarray[MAX_LIBARRAY]; Scene *sce; unsigned int lay; - int a, have_tag = 0; + int a, do_flush = 0; dag_current_scene_layers(bmain, &sce, &lay); @@ -2497,25 +2535,66 @@ void DAG_ids_flush_tagged(Main *bmain) looping over all ID's in case there are no tags */ if(id && bmain->id_tag_update[id->name[0]]) { for(; id; id=id->next) { - if(id->flag & LIB_ID_RECALC) { + if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA)) { dag_id_flush_update(sce, id); - id->flag &= ~LIB_ID_RECALC; + do_flush = 1; } } - - have_tag = 1; } } - if(have_tag) { - /* clear tags */ - memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update)); - - /* flush changes to other objects */ + /* flush changes to other objects */ + if(do_flush) DAG_scene_flush_update(bmain, sce, lay, 0); +} + +void DAG_ids_check_recalc(Main *bmain) +{ + ListBase *lbarray[MAX_LIBARRAY]; + int a; + + /* loop over all ID types */ + a = set_listbasepointers(bmain, lbarray); + + while(a--) { + ListBase *lb = lbarray[a]; + ID *id = lb->first; + + /* we tag based on first ID type character to avoid + looping over all ID's in case there are no tags */ + if(id && bmain->id_tag_update[id->name[0]]) { + /* do editors update */ + dag_editors_update(bmain, NULL); + return; + } } } + +void DAG_ids_clear_recalc(Main *bmain) +{ + ListBase *lbarray[MAX_LIBARRAY]; + int a; + + /* loop over all ID types */ + a = set_listbasepointers(bmain, lbarray); + + while(a--) { + ListBase *lb = lbarray[a]; + ID *id = lb->first; + + /* we tag based on first ID type character to avoid + looping over all ID's in case there are no tags */ + if(id && bmain->id_tag_update[id->name[0]]) { + for(; id; id=id->next) + if(id->flag & (LIB_ID_RECALC|LIB_ID_RECALC_DATA)) + id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); + } + } + + memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update)); +} + void DAG_id_tag_update(ID *id, short flag) { Main *bmain= G.main; @@ -2523,8 +2602,14 @@ void DAG_id_tag_update(ID *id, short flag) if(id==NULL) return; /* tag ID for update */ - id->flag |= LIB_ID_RECALC; - bmain->id_tag_update[id->name[0]] = 1; + if(flag) { + if(flag & OB_RECALC_OB) + lib_id_recalc_tag(bmain, id); + if(flag & (OB_RECALC_DATA|PSYS_RECALC)) + lib_id_recalc_data_tag(bmain, id); + } + else + lib_id_recalc_tag(bmain, id); /* flag is for objects and particle systems */ if(flag) { @@ -2556,6 +2641,16 @@ void DAG_id_tag_update(ID *id, short flag) } } +void DAG_id_type_tag(struct Main *bmain, short idtype) +{ + bmain->id_tag_update[((char*)&idtype)[0]] = 1; +} + +int DAG_id_type_tagged(Main *bmain, short idtype) +{ + return bmain->id_tag_update[((char*)&idtype)[0]]; +} + #if 0 // UNUSED /* recursively descends tree, each node only checked once */ /* node is checked to be of type object */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index c902bee80a8..b25120c0fff 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -992,6 +992,8 @@ void scene_update_tagged(Main *bmain, Scene *scene) { DAG_ids_flush_tagged(bmain); + BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE); + scene->physics_settings.quick_cache_step= 0; /* update all objects: drivers, matrices, displists, etc. flags set @@ -1011,10 +1013,19 @@ void scene_update_tagged(Main *bmain, Scene *scene) if (scene->physics_settings.quick_cache_step) BKE_ptcache_quick_cache_all(bmain, scene); + DAG_ids_check_recalc(bmain); + + BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST); + /* in the future this should handle updates for all datablocks, not only objects and scenes. - brecht */ } +void scene_clear_tagged(Main *bmain, Scene *UNUSED(scene)) +{ + DAG_ids_clear_recalc(bmain); +} + /* applies changes right away, does all sets too */ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) { @@ -1039,6 +1050,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) * so dont call within 'scene_update_tagged_recursive' */ DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still + BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_PRE); + /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that * settings stored nestled within a hierarchy (i.e. settings in a Texture block @@ -1052,6 +1065,7 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) scene_update_tagged_recursive(bmain, sce, sce); /* keep this last */ + BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_POST); BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_POST); } diff --git a/source/blender/blenlib/BLI_callbacks.h b/source/blender/blenlib/BLI_callbacks.h index 5322ce04a2e..7e4fad54cda 100644 --- a/source/blender/blenlib/BLI_callbacks.h +++ b/source/blender/blenlib/BLI_callbacks.h @@ -47,6 +47,8 @@ typedef enum { BLI_CB_EVT_LOAD_POST, BLI_CB_EVT_SAVE_PRE, BLI_CB_EVT_SAVE_POST, + BLI_CB_EVT_SCENE_UPDATE_PRE, + BLI_CB_EVT_SCENE_UPDATE_POST, BLI_CB_EVT_TOT } eCbEvent; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 452e7e4857c..7ff233fa609 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -863,6 +863,7 @@ void OBJECT_OT_group_instance_add(wmOperatorType *ot) /* note: now unlinks constraints as well */ void ED_base_object_free_and_unlink(Main *bmain, Scene *scene, Base *base) { + DAG_id_type_tag(bmain, ID_OB); BLI_remlink(&scene->base, base); free_libblock_us(&bmain->object, base->object); if(scene->basact==base) scene->basact= NULL; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 04272b48d51..d3473225095 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -145,6 +145,7 @@ static int object_hide_view_clear_exec(bContext *C, wmOperator *UNUSED(op)) } } if (changed) { + DAG_id_type_tag(bmain, ID_OB); DAG_scene_sort(bmain, scene); WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); } @@ -197,6 +198,7 @@ static int object_hide_view_set_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (changed) { + DAG_id_type_tag(bmain, ID_OB); DAG_scene_sort(bmain, scene); WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, CTX_data_scene(C)); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index d2c7d49e5f9..6f2933d154b 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -235,6 +235,7 @@ typedef struct PreviewImage { #define LIB_PRE_EXISTING 2048 /* runtime */ #define LIB_ID_RECALC 4096 +#define LIB_ID_RECALC_DATA 8192 #ifdef __cplusplus } diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 194c3e8d18e..e4692d32338 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -486,6 +486,16 @@ static void rna_def_ID(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); RNA_def_property_ui_text(prop, "Tag", "Tools can use this to tag data (initial state is undefined)"); + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_ID_RECALC); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Is Updated", "Datablock is tagged for recalculation"); + + prop= RNA_def_property(srna, "is_updated_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", LIB_ID_RECALC_DATA); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Is Updated Data", "Datablock data is tagged for recalculation"); + prop= RNA_def_property(srna, "library", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "lib"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 3f7cdf8d204..1b80e33b40c 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -62,6 +62,7 @@ #include "BKE_particle.h" #include "BKE_font.h" #include "BKE_node.h" +#include "BKE_depsgraph.h" #include "BKE_speaker.h" #include "DNA_armature_types.h" @@ -548,6 +549,33 @@ void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); } void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); } +static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); } +static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); } +static int rna_Main_objects_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_OB); } +static int rna_Main_materials_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MA); } +static int rna_Main_node_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_NT); } +static int rna_Main_meshes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_ME); } +static int rna_Main_lamps_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LA); } +static int rna_Main_libraries_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LI); } +static int rna_Main_screens_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCR); } +static int rna_Main_window_managers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WM); } +static int rna_Main_images_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_IM); } +static int rna_Main_lattices_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_LT); } +static int rna_Main_curves_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CU); } +static int rna_Main_metaballs_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_MB); } +static int rna_Main_fonts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_VF); } +static int rna_Main_textures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TE); } +static int rna_Main_brushes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_BR); } +static int rna_Main_worlds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_WO); } +static int rna_Main_groups_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GR); } +static int rna_Main_texts_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_TXT); } +static int rna_Main_speakers_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SPK); } +static int rna_Main_sounds_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SO); } +static int rna_Main_armatures_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AR); } +static int rna_Main_actions_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_AC); } +static int rna_Main_particles_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_PA); } +static int rna_Main_gpencil_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_GD); } + #else void RNA_api_main(StructRNA *srna) @@ -574,6 +602,7 @@ void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataCameras"); srna= RNA_def_struct(brna, "BlendDataCameras", NULL); @@ -597,6 +626,10 @@ void RNA_def_main_cameras(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_cameras_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_cameras_is_updated_get", NULL); } void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop) @@ -604,6 +637,7 @@ void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataScenes"); srna= RNA_def_struct(brna, "BlendDataScenes", NULL); @@ -623,6 +657,10 @@ void RNA_def_main_scenes(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Remove a scene from the current blendfile"); parm= RNA_def_pointer(func, "scene", "Scene", "", "Scene to remove"); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_scenes_is_updated_get", NULL); } void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop) @@ -630,6 +668,7 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataObjects"); srna= RNA_def_struct(brna, "BlendDataObjects", NULL); @@ -657,6 +696,10 @@ void RNA_def_main_objects(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_objects_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_objects_is_updated_get", NULL); } void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop) @@ -664,6 +707,7 @@ void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataMaterials"); srna= RNA_def_struct(brna, "BlendDataMaterials", NULL); @@ -687,12 +731,17 @@ void RNA_def_main_materials(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_materials_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_materials_is_updated_get", NULL); } void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; static EnumPropertyItem node_nodetree_items[] = { {0, "SHADER", 0, "Shader", ""}, @@ -724,12 +773,17 @@ void RNA_def_main_node_groups(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_node_groups_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_node_groups_is_updated_get", NULL); } void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataMeshes"); srna= RNA_def_struct(brna, "BlendDataMeshes", NULL); @@ -753,12 +807,17 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_meshes_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_meshes_is_updated_get", NULL); } void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataLamps"); srna= RNA_def_struct(brna, "BlendDataLamps", NULL); @@ -784,6 +843,10 @@ void RNA_def_main_lamps(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_lamps_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_lamps_is_updated_get", NULL); } void RNA_def_main_libraries(BlenderRNA *brna, PropertyRNA *cprop) @@ -791,6 +854,7 @@ void RNA_def_main_libraries(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataLibraries"); srna= RNA_def_struct(brna, "BlendDataLibraries", NULL); @@ -800,6 +864,10 @@ void RNA_def_main_libraries(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_libraries_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_libraries_is_updated_get", NULL); } void RNA_def_main_screens(BlenderRNA *brna, PropertyRNA *cprop) @@ -807,6 +875,7 @@ void RNA_def_main_screens(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataScreens"); srna= RNA_def_struct(brna, "BlendDataScreens", NULL); @@ -816,6 +885,10 @@ void RNA_def_main_screens(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_screens_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_screens_is_updated_get", NULL); } void RNA_def_main_window_managers(BlenderRNA *brna, PropertyRNA *cprop) @@ -823,6 +896,7 @@ void RNA_def_main_window_managers(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataWindowManagers"); srna= RNA_def_struct(brna, "BlendDataWindowManagers", NULL); @@ -832,12 +906,17 @@ void RNA_def_main_window_managers(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_window_managers_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_window_managers_is_updated_get", NULL); } void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataImages"); srna= RNA_def_struct(brna, "BlendDataImages", NULL); @@ -876,6 +955,10 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_images_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_images_is_updated_get", NULL); } void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop) @@ -883,6 +966,7 @@ void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataLattices"); srna= RNA_def_struct(brna, "BlendDataLattices", NULL); @@ -906,12 +990,17 @@ void RNA_def_main_lattices(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_lattices_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_lattices_is_updated_get", NULL); } void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataCurves"); srna= RNA_def_struct(brna, "BlendDataCurves", NULL); @@ -937,12 +1026,17 @@ void RNA_def_main_curves(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_curves_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_curves_is_updated_get", NULL); } void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataMetaBalls"); srna= RNA_def_struct(brna, "BlendDataMetaBalls", NULL); @@ -966,12 +1060,17 @@ void RNA_def_main_metaballs(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_metaballs_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_metaballs_is_updated_get", NULL); } void RNA_def_main_fonts(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataFonts"); srna= RNA_def_struct(brna, "BlendDataFonts", NULL); @@ -996,12 +1095,17 @@ void RNA_def_main_fonts(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_fonts_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_fonts_is_updated_get", NULL); } void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataTextures"); srna= RNA_def_struct(brna, "BlendDataTextures", NULL); @@ -1027,12 +1131,17 @@ void RNA_def_main_textures(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_textures_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_textures_is_updated_get", NULL); } void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataBrushes"); srna= RNA_def_struct(brna, "BlendDataBrushes", NULL); @@ -1056,6 +1165,10 @@ void RNA_def_main_brushes(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_brushes_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_brushes_is_updated_get", NULL); } void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop) @@ -1063,6 +1176,7 @@ void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataWorlds"); srna= RNA_def_struct(brna, "BlendDataWorlds", NULL); @@ -1086,6 +1200,10 @@ void RNA_def_main_worlds(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_worlds_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_worlds_is_updated_get", NULL); } void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop) @@ -1093,6 +1211,7 @@ void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataGroups"); srna= RNA_def_struct(brna, "BlendDataGroups", NULL); @@ -1115,6 +1234,10 @@ void RNA_def_main_groups(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_groups_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_groups_is_updated_get", NULL); } void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop) @@ -1122,6 +1245,7 @@ void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataSpeakers"); srna= RNA_def_struct(brna, "BlendDataSpeakers", NULL); @@ -1145,6 +1269,10 @@ void RNA_def_main_speakers(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_speakers_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_speakers_is_updated_get", NULL); } void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop) @@ -1152,6 +1280,7 @@ void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataTexts"); srna= RNA_def_struct(brna, "BlendDataTexts", NULL); @@ -1184,6 +1313,10 @@ void RNA_def_main_texts(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_texts_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_texts_is_updated_get", NULL); } void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop) @@ -1191,6 +1324,7 @@ void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataSounds"); srna= RNA_def_struct(brna, "BlendDataSounds", NULL); @@ -1202,6 +1336,10 @@ void RNA_def_main_sounds(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_sounds_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_sounds_is_updated_get", NULL); } void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop) @@ -1209,6 +1347,7 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataArmatures"); srna= RNA_def_struct(brna, "BlendDataArmatures", NULL); @@ -1232,12 +1371,17 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_armatures_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_armatures_is_updated_get", NULL); } void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataActions"); srna= RNA_def_struct(brna, "BlendDataActions", NULL); @@ -1261,12 +1405,17 @@ void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_actions_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_actions_is_updated_get", NULL); } void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataParticles"); srna= RNA_def_struct(brna, "BlendDataParticles", NULL); @@ -1290,6 +1439,10 @@ void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_particles_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_particles_is_updated_get", NULL); } void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) @@ -1297,6 +1450,7 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) StructRNA *srna; FunctionRNA *func; PropertyRNA *parm; + PropertyRNA *prop; RNA_def_property_srna(cprop, "BlendDataGreasePencils"); srna= RNA_def_struct(brna, "BlendDataGreasePencils", NULL); @@ -1306,6 +1460,10 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) func= RNA_def_function(srna, "tag", "rna_Main_gpencil_tag"); parm= RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + + prop= RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL); } #endif diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 137eebe6397..0fa63671951 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -286,6 +286,8 @@ static void rna_Object_layer_update__internal(Main *bmain, Scene *scene, Base *b else { DAG_scene_sort(bmain, scene); } + + DAG_id_type_tag(bmain, ID_OB); } static void rna_Object_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c index 345ebb2cd80..250c61ed5f4 100644 --- a/source/blender/makesrna/intern/rna_scene_api.c +++ b/source/blender/makesrna/intern/rna_scene_api.c @@ -69,6 +69,7 @@ static void rna_Scene_frame_set(Scene *scene, int frame, float subframe) static void rna_Scene_update_tagged(Scene *scene) { scene_update_tagged(G.main, scene); + scene_clear_tagged(G.main, scene); } static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, char *name) diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 7008aeda074..e7f74569f1a 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -47,6 +47,8 @@ static PyStructSequence_Field app_cb_info_fields[]= { {(char *)"load_post", NULL}, {(char *)"save_pre", NULL}, {(char *)"save_post", NULL}, + {(char *)"scene_update_pre", NULL}, + {(char *)"scene_update_post", NULL}, {NULL} }; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 0e22ccd05a7..03b0d637de1 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -323,6 +323,8 @@ void wm_event_do_notifiers(bContext *C) scene_update_tagged(bmain, win->screen->scene); ED_render_engine_update_tagged(C, bmain); + + scene_clear_tagged(bmain, win->screen->scene); } } From b07d92408b3ca76e00ea0e69203418fee49b5e19 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Nov 2011 21:35:00 +0000 Subject: [PATCH 046/147] cmake could ignore defines for python lib/include passed from the command line if both weren't defined. --- .../cmake/Modules/FindPythonLibsUnix.cmake | 60 +++++++++++++------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/build_files/cmake/Modules/FindPythonLibsUnix.cmake b/build_files/cmake/Modules/FindPythonLibsUnix.cmake index fd5d20920da..8c3ff64d3f3 100644 --- a/build_files/cmake/Modules/FindPythonLibsUnix.cmake +++ b/build_files/cmake/Modules/FindPythonLibsUnix.cmake @@ -44,8 +44,19 @@ SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for p MARK_AS_ADVANCED(PYTHON_LINKFLAGS) +# if the user passes these defines as args, we dont want to overwrite +SET(_IS_INC_DEF OFF) +SET(_IS_LIB_DEF OFF) +IF(DEFINED PYTHON_INCLUDE_DIR) + SET(_IS_INC_DEF ON) +ENDIF() +IF(DEFINED PYTHON_LIBRARY) + SET(_IS_LIB_DEF ON) +ENDIF() + + # only search for the dirs if we havn't already -IF((NOT DEFINED PYTHON_INCLUDE_DIR) OR (NOT DEFINED PYTHON_LIBRARY)) +IF((NOT _IS_INC_DEF) OR (NOT _IS_LIB_DEF)) SET(_python_ABI_FLAGS "m;mu;u; " # release @@ -66,30 +77,38 @@ IF((NOT DEFINED PYTHON_INCLUDE_DIR) OR (NOT DEFINED PYTHON_LIBRARY)) #ENDIF() STRING(REPLACE " " "" _CURRENT_ABI_FLAGS ${_CURRENT_ABI_FLAGS}) - FIND_PATH(PYTHON_INCLUDE_DIR - NAMES - Python.h - HINTS - ${_python_SEARCH_DIRS} - PATH_SUFFIXES - include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS} - ) + IF(NOT DEFINED PYTHON_INCLUDE_DIR) + FIND_PATH(PYTHON_INCLUDE_DIR + NAMES + Python.h + HINTS + ${_python_SEARCH_DIRS} + PATH_SUFFIXES + include/python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS} + ) + ENDIF() - FIND_LIBRARY(PYTHON_LIBRARY - NAMES - "python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}" - HINTS - ${_python_SEARCH_DIRS} - PATH_SUFFIXES - lib64 lib - ) + IF(NOT DEFINED PYTHON_LIBRARY) + FIND_LIBRARY(PYTHON_LIBRARY + NAMES + "python${PYTHON_VERSION}${_CURRENT_ABI_FLAGS}" + HINTS + ${_python_SEARCH_DIRS} + PATH_SUFFIXES + lib64 lib + ) + ENDIF() IF(PYTHON_LIBRARY AND PYTHON_INCLUDE_DIR) break() ELSE() # ensure we dont find values from 2 different ABI versions - UNSET(PYTHON_INCLUDE_DIR CACHE) - UNSET(PYTHON_LIBRARY CACHE) + IF(NOT _IS_INC_DEF) + UNSET(PYTHON_INCLUDE_DIR CACHE) + ENDIF() + IF(NOT _IS_LIB_DEF) + UNSET(PYTHON_LIBRARY CACHE) + ENDIF() ENDIF() ENDFOREACH() @@ -100,6 +119,9 @@ IF((NOT DEFINED PYTHON_INCLUDE_DIR) OR (NOT DEFINED PYTHON_LIBRARY)) UNSET(_python_SEARCH_DIRS) ENDIF() +UNSET(_IS_INC_DEF) +UNSET(_IS_LIB_DEF) + # handle the QUIETLY and REQUIRED arguments and SET PYTHONLIBSUNIX_FOUND to TRUE IF # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) From 4293f4738ce0ea1bb81260b12a6b64f98b6a3468 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 2 Nov 2011 22:00:22 +0000 Subject: [PATCH 047/147] patch [#28947] Patches for #28943 (Support for XDG Base Directory Specification) from Cosme --- CMakeLists.txt | 2 + intern/ghost/CMakeLists.txt | 4 ++ intern/ghost/intern/GHOST_SystemPathsX11.cpp | 25 ++++++++ source/blender/blenlib/CMakeLists.txt | 4 ++ source/blender/blenlib/intern/path_util.c | 61 +++++++++++--------- 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f421c2c9395..0e06f39e718 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -157,6 +157,8 @@ endif() if(UNIX AND NOT APPLE) option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON) option(WITH_BUILTIN_GLEW "Use GLEW OpenGL wrapper library bundled with blender" ON) + option(WITH_XDG_USER_DIRS "Build with XDG Base Directory Specification (only config and documents for now)" OFF) + mark_as_advanced(WITH_XDG_USER_DIRS) else() # not an option for other OS's set(WITH_BUILTIN_GLEW ON) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 4446426098a..a84ff5825a9 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -108,6 +108,10 @@ if(WITH_INPUT_NDOF) ) endif() +if(WITH_XDG_USER_DIRS) + add_definitions(-DWITH_XDG_USER_DIRS) +endif() + if(WITH_HEADLESS OR WITH_GHOST_SDL) if(WITH_HEADLESS) list(APPEND SRC diff --git a/intern/ghost/intern/GHOST_SystemPathsX11.cpp b/intern/ghost/intern/GHOST_SystemPathsX11.cpp index 1456bdef543..726149138ed 100644 --- a/intern/ghost/intern/GHOST_SystemPathsX11.cpp +++ b/intern/ghost/intern/GHOST_SystemPathsX11.cpp @@ -41,6 +41,11 @@ #include // for fprintf only #include // for exit +#ifdef WITH_XDG_USER_DIRS +# include // for get home without use getenv() +# include // for PATH_MAX +#endif + #ifdef PREFIX static const char *static_path= PREFIX "/share" ; #else @@ -63,7 +68,27 @@ const GHOST_TUns8* GHOST_SystemPathsX11::getSystemDir() const const GHOST_TUns8* GHOST_SystemPathsX11::getUserDir() const { +#ifndef WITH_XDG_USER_DIRS return (const GHOST_TUns8 *)getenv("HOME"); +#else /* WITH_XDG_USER_DIRS */ + const char *home= getenv("XDG_CONFIG_HOME"); + + if (home) { + return (const GHOST_TUns8 *)home; + } + else { + static char user_path[PATH_MAX]; + + home= getenv("HOME"); + + if (home == NULL) { + home= getpwuid(getuid())->pw_dir; + } + + snprintf(user_path, sizeof(user_path), "%s/.config", home); + return (const GHOST_TUns8 *)user_path; + } +#endif /* WITH_XDG_USER_DIRS */ } const GHOST_TUns8* GHOST_SystemPathsX11::getBinaryDir() const diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 4711acbb600..5d54ffbeb36 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -148,4 +148,8 @@ if(WITH_OPENMP) add_definitions(-DPARALLEL=1) endif() +if(WITH_XDG_USER_DIRS) + add_definitions(-DWITH_XDG_USER_DIRS) +endif() + blender_add_lib(bf_blenlib "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index bbb62db58f2..7aa84523e9d 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -52,7 +52,7 @@ #include "GHOST_Path-api.h" #if defined WIN32 && !defined _LIBC -# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ +# include "BLI_fnmatch.h" /* use fnmatch included in blenlib */ #else # ifndef _GNU_SOURCE # define _GNU_SOURCE @@ -61,35 +61,34 @@ #endif #ifdef WIN32 -#include - -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 -#include -#include - -#include "BLI_winstuff.h" - +# include +# ifdef _WIN32_IE +# undef _WIN32_IE +# endif +# define _WIN32_IE 0x0501 +# include +# include +# include "BLI_winstuff.h" #else /* non windows */ - -#ifdef WITH_BINRELOC -#include "binreloc.h" -#endif - +# ifdef WITH_BINRELOC +# include "binreloc.h" +# endif #endif /* WIN32 */ /* standard paths */ #ifdef WIN32 -#define BLENDER_USER_FORMAT "%s\\Blender Foundation\\Blender\\%s" -#define BLENDER_SYSTEM_FORMAT "%s\\Blender Foundation\\Blender\\%s" +# define BLENDER_USER_FORMAT "%s\\Blender Foundation\\Blender\\%s" +# define BLENDER_SYSTEM_FORMAT "%s\\Blender Foundation\\Blender\\%s" #elif defined(__APPLE__) -#define BLENDER_USER_FORMAT "%s/Blender/%s" -#define BLENDER_SYSTEM_FORMAT "%s/Blender/%s" -#else -#define BLENDER_USER_FORMAT "%s/.blender/%s" -#define BLENDER_SYSTEM_FORMAT "%s/blender/%s" +# define BLENDER_USER_FORMAT "%s/Blender/%s" +# define BLENDER_SYSTEM_FORMAT "%s/Blender/%s" +#else /* UNIX */ +# ifndef WITH_XDG_USER_DIRS /* oldschool unix ~/.blender/ */ +# define BLENDER_USER_FORMAT "%s/.blender/%s" +# else /* new XDG ~/blender/.config/ */ +# define BLENDER_USER_FORMAT "%s/blender/%s" +# endif // WITH_XDG_USER_DIRS +# define BLENDER_SYSTEM_FORMAT "%s/blender/%s" #endif /* local */ @@ -797,10 +796,18 @@ void BLI_getlastdir(const char* dir, char *last, const size_t maxlen) as default location to save documents */ const char *BLI_getDefaultDocumentFolder(void) { - #if !defined(WIN32) +#ifndef WIN32 + +#ifdef WITH_XDG_USER_DIRS + const char *xdg_documents_dir= getenv("XDG_DOCUMENTS_DIR"); + if (xdg_documents_dir) { + return xdg_documents_dir; + } +#endif + return getenv("HOME"); - #else /* Windows */ +#else /* Windows */ const char * ret; static char documentfolder[MAXPATHLEN]; HRESULT hResult; @@ -825,7 +832,7 @@ const char *BLI_getDefaultDocumentFolder(void) } return NULL; - #endif +#endif /* WIN32 */ } /* NEW stuff, to be cleaned up when fully migrated */ From 1f291a69c1ba961bf96b6767fc7ce801c4ab5856 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 03:00:45 +0000 Subject: [PATCH 048/147] correct spelling mistakes --- source/blender/blenkernel/BKE_global.h | 2 +- source/blender/blenkernel/intern/node.c | 2 +- source/blender/editors/include/ED_render.h | 2 +- source/blender/editors/space_outliner/outliner_tree.c | 6 +++--- source/blender/render/intern/source/initrender.c | 2 +- source/blender/render/intern/source/shadbuf.c | 8 ++++---- source/blender/windowmanager/intern/wm_files.c | 8 ++++---- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index bc9134b40b8..5ccdd7c04af 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -58,7 +58,7 @@ typedef struct Global { /* flag: if != 0 G.main->name contains valid relative base path */ int relbase_valid; - /* strings of recent opend files */ + /* strings of recent opened files */ struct ListBase recent_files; short afbreek, moving, file_loaded; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index f35f034387b..8f609291351 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1321,7 +1321,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) node->flag |= NODE_ACTIVE_ID; } -/* use flags are not persistant yet, groups might need different tagging, so we do it each time +/* use flags are not persistent yet, groups might need different tagging, so we do it each time when we need to get this info */ void ntreeSocketUseFlags(bNodeTree *ntree) { diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index 8c0fa3a89a3..7461f5e9e9f 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -56,7 +56,7 @@ typedef struct RenderInfo { short curtile, tottile, status; rcti disprect; /* storage for view3d preview rect */ unsigned int* rect; - struct Render *re; /* persistant render */ + struct Render *re; /* persistent render */ } RenderInfo; /* ri->status */ diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 925c4571a66..794f898a1fc 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -109,7 +109,7 @@ #define TS_CHUNK 128 /* ********************************************************* */ -/* Persistant Data */ +/* Persistent Data */ static void outliner_storage_cleanup(SpaceOops *soops) { @@ -156,7 +156,7 @@ static void outliner_storage_cleanup(SpaceOops *soops) } } -static void check_persistant(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) +static void check_persistent(SpaceOops *soops, TreeElement *te, ID *id, short type, short nr) { TreeStore *ts; TreeStoreElem *tselem; @@ -818,7 +818,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i /* add to the visual tree */ BLI_addtail(lb, te); /* add to the storage */ - check_persistant(soops, te, id, type, index); + check_persistent(soops, te, id, type, index); tselem= TREESTORE(te); /* if we are searching for something expand to see child elements */ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index da935d0415d..091a64e418e 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -451,7 +451,7 @@ struct Object *RE_GetCamera(Render *re) } /* call this after InitState() */ -/* per render, there's one persistant viewplane. Parts will set their own viewplanes */ +/* per render, there's one persistent viewplane. Parts will set their own viewplanes */ void RE_SetCamera(Render *re, Object *camera) { object_camera_mode(&re->r, camera); diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index a4bf6c6b5e1..274fa4469e0 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -2156,7 +2156,7 @@ static int isb_add_samples(RenderPart *pa, ISBBranch *root, MemArena *memarena, int xi, yi, *xcos, *ycos; int sample, bsp_err= 0; - /* bsp split doesn't like to handle regular sequenes */ + /* bsp split doesn't like to handle regular sequences */ xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos"); ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos"); for(xi=0; xirectx; xi++) @@ -2301,7 +2301,7 @@ static void isb_make_buffer(RenderPart *pa, LampRen *lar) isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */ - /* copy shadow samples to persistant buffer, reduce memory overhead */ + /* copy shadow samples to persistent buffer, reduce memory overhead */ if(R.osa) { ISBShadfacA **isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); @@ -2360,7 +2360,7 @@ static int isb_add_samples_transp(RenderPart *pa, ISBBranch *root, MemArena *mem int xi, yi, *xcos, *ycos; int sample, bsp_err= 0; - /* bsp split doesn't like to handle regular sequenes */ + /* bsp split doesn't like to handle regular sequences */ xcos= MEM_mallocN( pa->rectx*sizeof(int), "xcos"); ycos= MEM_mallocN( pa->recty*sizeof(int), "ycos"); for(xi=0; xirectx; xi++) @@ -2505,7 +2505,7 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la /* go over all faces and fill in shadow values */ isb_bsp_fillfaces(&R, lar, &root); /* shb->persmat should have been calculated */ - /* copy shadow samples to persistant buffer, reduce memory overhead */ + /* copy shadow samples to persistent buffer, reduce memory overhead */ isbsa= isbdata->shadfaca= MEM_callocN(pa->rectx*pa->recty*sizeof(void *), "isb shadfacs"); isbdata->memarena = BLI_memarena_new(0x8000 * sizeof(ISBSampleA), "isb arena"); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 2bd3ed34b69..c292e9e2825 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -359,7 +359,7 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) BLI_exec_cb(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); /* first try to append data from exotic file formats... */ - /* it throws error box when file doesnt exist and returns -1 */ + /* it throws error box when file doesn't exist and returns -1 */ /* note; it should set some error message somewhere... (ton) */ retval= wm_read_exotic(CTX_data_scene(C), filepath); @@ -368,7 +368,7 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) int G_f= G.f; ListBase wmbase; - /* put aside screens to match with persistant windows later */ + /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); @@ -480,7 +480,7 @@ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory /* prevent loading no UI */ G.fileflags &= ~G_FILE_NO_UI; - /* put aside screens to match with persistant windows later */ + /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory && BLI_exists(tstr)) { @@ -576,7 +576,7 @@ void WM_read_history(void) G.recent_files.first = G.recent_files.last = NULL; - /* read list of recent opend files from recent-files.txt to memory */ + /* read list of recent opened files from recent-files.txt to memory */ for (l= lines, num= 0; l && (numnext) { line = l->link; if (line[0] && BLI_exists(line)) { From 887e1fed9951db8a9592199268139c7886dbf38b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 03:51:48 +0000 Subject: [PATCH 049/147] fix regression [#29076] 16bit Tiff save broken in Blender 2.60 --- source/blender/editors/space_image/image_ops.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index c83baf24c1c..7121e4872eb 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1009,11 +1009,17 @@ static int save_image_options_init(SaveImageOptions *simopts, SpaceImage *sima, return (ibuf != NULL); } -static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op) +static void save_image_options_from_op(SaveImageOptions *simopts, wmOperator *op, Scene *evil_scene) { if (RNA_property_is_set(op->ptr, "color_mode")) simopts->planes= RNA_enum_get(op->ptr, "color_mode"); if (RNA_property_is_set(op->ptr, "file_format")) simopts->imtype= RNA_enum_get(op->ptr, "file_format"); - // if (RNA_property_is_set(op->ptr, "subimtype")) simopts->subimtype= RNA_enum_get(op->ptr, "subimtype"); // XXX + +#if 0 + if (RNA_property_is_set(op->ptr, "subimtype")) simopts->subimtype= RNA_enum_get(op->ptr, "subimtype"); // XXX +#else + simopts->subimtype= evil_scene->r.subimtype; +#endif + if (RNA_property_is_set(op->ptr, "file_quality")) simopts->quality= RNA_int_get(op->ptr, "file_quality"); if (RNA_property_is_set(op->ptr, "filepath")) { @@ -1141,7 +1147,7 @@ static int image_save_as_exec(bContext *C, wmOperator *op) /* just incase to initialize values, * these should be set on invoke or by the caller. */ save_image_options_defaults(&simopts); - save_image_options_from_op(&simopts, op); + save_image_options_from_op(&simopts, op, CTX_data_scene(C)); save_image_doit(C, sima, op, &simopts, TRUE); @@ -1225,7 +1231,7 @@ static int image_save_exec(bContext *C, wmOperator *op) if (save_image_options_init(&simopts, sima, scene, FALSE) == 0) return OPERATOR_CANCELLED; - save_image_options_from_op(&simopts, op); + save_image_options_from_op(&simopts, op, scene); if (BLI_exists(simopts.filepath) && BLI_file_is_writable(simopts.filepath)) { save_image_doit(C, sima, op, &simopts, FALSE); From 7d7977658ad12a940597da5b78ce70e4e5081f4b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 04:58:11 +0000 Subject: [PATCH 050/147] fix for warning on osx --- source/blender/quicktime/apple/qtkit_import.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m index 979dd1e3c60..279192e9692 100644 --- a/source/blender/quicktime/apple/qtkit_import.m +++ b/source/blender/quicktime/apple/qtkit_import.m @@ -31,7 +31,9 @@ #include "IMB_anim.h" #include "BLO_sys_types.h" #include "BKE_global.h" + #include "BLI_dynstr.h" +#include "BLI_path_util.h" #import #import From e2393d11090765caf987e5ef8e2e688d80c0e64d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 06:53:52 +0000 Subject: [PATCH 051/147] ability to have permanent callbacks that stay active when new blend files are loaded. this works by tagging functions, eg: def my_func(scene): pass bpy.app.handlers.permanent_tag(my_func, True) # <-- important bit bpy.app.handlers.frame_change_pre.append(my_func) --- source/blender/python/BPY_extern.h | 2 +- .../blender/python/intern/bpy_app_handlers.c | 113 +++++++++++++++++- .../render/intern/source/convertblender.c | 2 +- .../blender/windowmanager/intern/wm_files.c | 4 +- .../windowmanager/intern/wm_init_exit.c | 7 +- source/creator/creator.c | 2 +- 6 files changed, 119 insertions(+), 11 deletions(-) diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index d8ddcd593a8..29e0185c2f2 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -71,7 +71,7 @@ void BPY_text_free_code(struct Text *text); void BPY_modules_update(struct bContext *C); // XXX - annoying, need this for pointers that get out of date void BPY_modules_load_user(struct bContext *C); -void BPY_app_handlers_reset(void); +void BPY_app_handlers_reset(const short do_all); void BPY_driver_reset(void); float BPY_driver_exec(struct ChannelDriver *driver); diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index e7f74569f1a..9ca0e71e71d 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -49,6 +49,11 @@ static PyStructSequence_Field app_cb_info_fields[]= { {(char *)"save_post", NULL}, {(char *)"scene_update_pre", NULL}, {(char *)"scene_update_post", NULL}, + + /* sets the permanent tag */ +# define APP_CB_OTHER_FIELDS 1 + {(char *)"permanent_tag", NULL}, + {NULL} }; @@ -65,6 +70,71 @@ static PyStructSequence_Desc app_cb_info_desc= { #endif */ +/* --------------------------------------------------------------------------*/ +/* permanent tagging code */ +#define PERMINENT_CB_ID "_bpy_permanent_tag" + +PyDoc_STRVAR(bpy_app_handlers_permanent_tag_doc, +".. function:: permanent_tag(func, state=True)\n" +"\n" +" Set the function as being permanent so its not cleared when new blend files are loaded.\n" +"\n" +" :arg func: The function to set as permanent.\n" +" :type func: function\n" +" :arg state: Set the permanent state to True or False.\n" +" :type state: bool\n" +" :return: the function argument\n" +" :rtype: function\n" +); + +static PyObject *bpy_app_handlers_permanent_tag(PyObject *UNUSED(self), PyObject *args) +{ + PyObject *value; + int state= 1; + + if(!PyArg_ParseTuple(args, "O|i:permanent_tag", &value, &state)) + return NULL; + + if (PyFunction_Check(value)) { + PyObject **dict_ptr= _PyObject_GetDictPtr(value); + if (dict_ptr == NULL) { + PyErr_SetString(PyExc_ValueError, + "bpy.app.handlers.permanent_tag wasn't able to " + "get the dictionary from the function passed"); + return NULL; + } + else { + if (state) { + /* set id */ + if (*dict_ptr == NULL) { + *dict_ptr= PyDict_New(); + } + + PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); + } + else { + /* clear id */ + if (*dict_ptr) { + PyDict_DelItemString(*dict_ptr, PERMINENT_CB_ID); + } + } + } + + Py_INCREF(value); + return value; + } + else { + PyErr_SetString(PyExc_ValueError, + "bpy.app.handlers.permanent_tag expected a function"); + return NULL; + } +} + +static PyMethodDef meth_bpy_app_handlers_permanent_tag= {"permanent_tag", (PyCFunction)bpy_app_handlers_permanent_tag, METH_VARARGS, bpy_app_handlers_permanent_tag_doc}; + + + + static PyObject *py_cb_array[BLI_CB_EVT_TOT]= {NULL}; static PyObject *make_app_cb_info(void) @@ -83,10 +153,13 @@ static PyObject *make_app_cb_info(void) } PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos]= PyList_New(0))); } - if (app_cb_info_fields[pos].name != NULL) { + if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) { Py_FatalError("invalid callback slots 2"); } + /* custom function */ + PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)PyCFunction_New(&meth_bpy_app_handlers_permanent_tag, NULL)); + return app_cb_info; } @@ -120,12 +193,46 @@ PyObject *BPY_app_handlers_struct(void) return ret; } -void BPY_app_handlers_reset(void) +void BPY_app_handlers_reset(const short do_all) { int pos= 0; + if (do_all) { for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { - PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL); + /* clear list */ + PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL); + } + } + else { + /* save string conversion thrashing */ + PyObject *perm_id_str= PyUnicode_FromString(PERMINENT_CB_ID); + + for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) { + /* clear only items without PERMINENT_CB_ID */ + PyObject *ls= py_cb_array[pos]; + Py_ssize_t i; + + PyObject *item; + PyObject **dict_ptr; + + for(i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) { + + if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) && + (dict_ptr= _PyObject_GetDictPtr(item)) && + (*dict_ptr) && + (PyDict_GetItem(*dict_ptr, perm_id_str) != NULL)) + { + /* keep */ + } + else { + /* remove */ + /* PySequence_DelItem(ls, i); */ /* more obvious buw slower */ + PyList_SetSlice(ls, i, i + 1, NULL); + } + } + } + + Py_DECREF(perm_id_str); } } diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 5968a6e64f8..7ef726a5330 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2391,7 +2391,7 @@ static void do_displacement(Render *re, ObjectRen *obr, float mat[][4], float im /* Object Size with parenting */ obt=obr->ob; while(obt){ - add_v3_v3v3(temp, obt->size, obt->dsize); + mul_v3_v3v3(temp, obt->size, obt->dsize); scale[0]*=temp[0]; scale[1]*=temp[1]; scale[2]*=temp[2]; obt=obt->parent; } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index c292e9e2825..83e4681251f 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -408,7 +408,7 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports) #ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ BPY_driver_reset(); - BPY_app_handlers_reset(); + BPY_app_handlers_reset(FALSE); BPY_modules_load_user(C); #endif @@ -538,7 +538,7 @@ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory BPY_string_exec(C, "__import__('addon_utils').reset_all()"); BPY_driver_reset(); - BPY_app_handlers_reset(); + BPY_app_handlers_reset(FALSE); BPY_modules_load_user(C); } #endif diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index b0be4bb9720..f32e2afa3e0 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -61,8 +61,9 @@ #include "BKE_sequencer.h" /* free seq clipboard */ #include "BKE_material.h" /* clear_matcopybuf */ -#include "BLI_blenlib.h" -#include "BLI_winstuff.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" #include "RE_engine.h" #include "RE_pipeline.h" /* RE_ free stuff */ @@ -158,7 +159,7 @@ void WM_init(bContext *C, int argc, const char **argv) BPY_python_start(argc, argv); BPY_driver_reset(); - BPY_app_handlers_reset(); /* causes addon callbacks to be freed [#28068], + BPY_app_handlers_reset(FALSE); /* causes addon callbacks to be freed [#28068], * but this is actually what we want. */ BPY_modules_load_user(C); #else diff --git a/source/creator/creator.c b/source/creator/creator.c index 1d083af7d07..2204ab85a2e 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -971,7 +971,7 @@ static int load_file(int UNUSED(argc), const char **argv, void *data) #ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ BPY_driver_reset(); - BPY_app_handlers_reset(); + BPY_app_handlers_reset(FALSE); BPY_modules_load_user(C); #endif From 5eef9374362eb1089f08d4ab5f397843d2301d7a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 09:13:47 +0000 Subject: [PATCH 052/147] modify previous api feature to tag functions as permanent, use nicer decorator style, eg: # -------- import bpy from bpy.app.handlers import persistent @persistent def my_func(scene): pass bpy.app.handlers.frame_change_pre.append(my_func) --- release/scripts/modules/bpy/__init__.py | 2 + .../blender/python/intern/bpy_app_handlers.c | 98 ++++++++++++------- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/release/scripts/modules/bpy/__init__.py b/release/scripts/modules/bpy/__init__.py index 5fe5cfd7cf4..75572a6294e 100644 --- a/release/scripts/modules/bpy/__init__.py +++ b/release/scripts/modules/bpy/__init__.py @@ -54,6 +54,8 @@ def main(): # fake module to allow: # from bpy.types import Panel + sys.modules["bpy.app"] = app + sys.modules["bpy.app.handlers"] = app.handlers sys.modules["bpy.types"] = types #~ if "-d" in sys.argv: # Enable this to measure start up speed diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 9ca0e71e71d..cf90443e212 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -52,7 +52,7 @@ static PyStructSequence_Field app_cb_info_fields[]= { /* sets the permanent tag */ # define APP_CB_OTHER_FIELDS 1 - {(char *)"permanent_tag", NULL}, + {(char *)"persistent", NULL}, {NULL} }; @@ -72,52 +72,30 @@ static PyStructSequence_Desc app_cb_info_desc= { /* --------------------------------------------------------------------------*/ /* permanent tagging code */ -#define PERMINENT_CB_ID "_bpy_permanent_tag" +#define PERMINENT_CB_ID "_bpy_persistent" -PyDoc_STRVAR(bpy_app_handlers_permanent_tag_doc, -".. function:: permanent_tag(func, state=True)\n" -"\n" -" Set the function as being permanent so its not cleared when new blend files are loaded.\n" -"\n" -" :arg func: The function to set as permanent.\n" -" :type func: function\n" -" :arg state: Set the permanent state to True or False.\n" -" :type state: bool\n" -" :return: the function argument\n" -" :rtype: function\n" -); - -static PyObject *bpy_app_handlers_permanent_tag(PyObject *UNUSED(self), PyObject *args) +static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *UNUSED(kwds)) { PyObject *value; - int state= 1; - if(!PyArg_ParseTuple(args, "O|i:permanent_tag", &value, &state)) + if(!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value)) return NULL; if (PyFunction_Check(value)) { PyObject **dict_ptr= _PyObject_GetDictPtr(value); if (dict_ptr == NULL) { PyErr_SetString(PyExc_ValueError, - "bpy.app.handlers.permanent_tag wasn't able to " + "bpy.app.handlers.persistent wasn't able to " "get the dictionary from the function passed"); return NULL; } else { - if (state) { - /* set id */ - if (*dict_ptr == NULL) { - *dict_ptr= PyDict_New(); - } + /* set id */ + if (*dict_ptr == NULL) { + *dict_ptr= PyDict_New(); + } - PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); - } - else { - /* clear id */ - if (*dict_ptr) { - PyDict_DelItemString(*dict_ptr, PERMINENT_CB_ID); - } - } + PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None); } Py_INCREF(value); @@ -125,15 +103,55 @@ static PyObject *bpy_app_handlers_permanent_tag(PyObject *UNUSED(self), PyObject } else { PyErr_SetString(PyExc_ValueError, - "bpy.app.handlers.permanent_tag expected a function"); + "bpy.app.handlers.persistent expected a function"); return NULL; } } -static PyMethodDef meth_bpy_app_handlers_permanent_tag= {"permanent_tag", (PyCFunction)bpy_app_handlers_permanent_tag, METH_VARARGS, bpy_app_handlers_permanent_tag_doc}; - - - +/* dummy type because decorators can't be PyCFunctions */ +static PyTypeObject BPyPersistent_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "persistent", /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + bpy_app_handlers_persistent_new, /* tp_new */ + 0, /* tp_free */ +}; static PyObject *py_cb_array[BLI_CB_EVT_TOT]= {NULL}; @@ -158,7 +176,7 @@ static PyObject *make_app_cb_info(void) } /* custom function */ - PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)PyCFunction_New(&meth_bpy_app_handlers_permanent_tag, NULL)); + PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type); return app_cb_info; } @@ -167,6 +185,10 @@ PyObject *BPY_app_handlers_struct(void) { PyObject *ret; + if (PyType_Ready(&BPyPersistent_Type) < 0) { + BLI_assert(!"error initializing 'bpy.app.handlers.persistent'"); + } + PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc); ret= make_app_cb_info(); From f69818e7f6dca2014b2904dcb1eea8477bd5f994 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 09:20:54 +0000 Subject: [PATCH 053/147] correct error in stub --- source/blenderplayer/bad_level_call_stubs/stubs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 306a24f9adf..812844398b8 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -389,7 +389,7 @@ void RE_engines_exit() {} void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) {} ListBase R_engines = {NULL, NULL}; void RE_engine_free(struct RenderEngine *engine) {} -struct RenderEngineType *RE_engines_find(const char *idname) {} +struct RenderEngineType *RE_engines_find(const char *idname) { return NULL; } /* python */ struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;} From fa8fffac1c498dc37a372e63324da48ca15c0907 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 3 Nov 2011 10:03:08 +0000 Subject: [PATCH 054/147] Depsgraph/Python: ensure datablocks with animation data get tagged as being updated on frame change. --- source/blender/blenkernel/intern/anim_sys.c | 12 +++++++++++- source/blender/blenkernel/intern/scene.c | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 981c20d6165..6d94b42a7ac 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -51,6 +51,7 @@ #include "BKE_animsys.h" #include "BKE_action.h" +#include "BKE_depsgraph.h" #include "BKE_fcurve.h" #include "BKE_nla.h" #include "BKE_global.h" @@ -1181,6 +1182,15 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i RNA_property_update_cache_add(&new_ptr, prop); } #endif + + /* as long as we don't do property update, we still tag datablock + as having been updated. this flag does not cause any updates to + be run, it's for e.g. render engines to synchronize data */ + if(new_ptr.id.data) { + ID *id= new_ptr.id.data; + id->flag |= LIB_ID_RECALC; + DAG_id_type_tag(G.main, GS(id->name)); + } } /* successful */ @@ -2322,7 +2332,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime) /* particles */ EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM); - /* lamps */ + /* speakers */ EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM); /* objects */ diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b25120c0fff..7ba0a642cdd 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1067,6 +1067,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) /* keep this last */ BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_POST); BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_POST); + + DAG_ids_clear_recalc(bmain); } /* return default layer, also used to patch old files */ From 9e8a7c7e3156ac886ab4d018586fac951043876e Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Thu, 3 Nov 2011 11:20:22 +0000 Subject: [PATCH 055/147] Bugfix [#29113] "Follow path" constraint subframes calculated incorrectly "Follow Path" constraint was applying subframe offsets to the curve- path evaltime value for non-fixed case. However, it turns out that when doing old-style mblur, this results in the offset getting applied twice, resulting in incorrect values (i.e. by the time the constraint gets ctime, this already has had subframe offset applied, and so too has curve evaltime). --- source/blender/blenkernel/intern/constraint.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index aebf3198cf4..d6d4e8304ba 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1256,10 +1256,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr float quat[4]; if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ - if (cob->scene) - curvetime= bsystem_time(cob->scene, ct->tar, cu->ctime, 0.0) - data->offset; - else - curvetime= cu->ctime - data->offset; + curvetime= cu->ctime - data->offset; /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, * but this will only work if it actually is animated... From dff93ddeccadf4e4ccc78bacf8073de1f8e64434 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 12:01:18 +0000 Subject: [PATCH 056/147] hopefully fix msvc build error --- source/blender/python/intern/bpy_app_handlers.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index cf90443e212..5b8c20bb12d 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -110,7 +110,13 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyO /* dummy type because decorators can't be PyCFunctions */ static PyTypeObject BPyPersistent_Type = { + +#if defined(_MSC_VER) || defined(FREE_WINDOWS) + PyVarObject_HEAD_INIT(NULL, 0) +#else PyVarObject_HEAD_INIT(&PyType_Type, 0) +#endif + "persistent", /* tp_name */ 0, /* tp_basicsize */ 0, /* tp_itemsize */ @@ -185,6 +191,10 @@ PyObject *BPY_app_handlers_struct(void) { PyObject *ret; +#if defined(_MSC_VER) || defined(FREE_WINDOWS) + BPyPersistent_Type.ob_base.ob_base.ob_type= &PyType_Type; +#endif + if (PyType_Ready(&BPyPersistent_Type) < 0) { BLI_assert(!"error initializing 'bpy.app.handlers.persistent'"); } From 6ea6e992ba427215bdd975effd3cb184866def0b Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 3 Nov 2011 12:24:29 +0000 Subject: [PATCH 057/147] Scons: * Minor cleanup --- build_files/scons/tools/btools.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index a678bc68f54..b457a05319d 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -116,7 +116,9 @@ def validate_arguments(args, bc): 'WITH_BF_INTERNATIONAL', 'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'WITH_BF_GETTEXT_STATIC', 'BF_GETTEXT_LIB_STATIC', 'BF_GETTEXT_LIBPATH', 'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH', - 'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'WITH_BF_ELTOPO', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', + 'WITH_BF_GAMEENGINE', + 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB', + 'WITH_BF_ELTOPO', 'BF_WINTAB', 'BF_WINTAB_INC', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC', 'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH', @@ -133,12 +135,10 @@ def validate_arguments(args, bc): 'WITHOUT_BF_INSTALL', 'WITHOUT_BF_PYTHON_INSTALL', 'WITHOUT_BF_OVERWRITE_INSTALL', - 'WITH_BF_OPENMP', - 'BF_OPENMP', - 'BF_OPENMP_INC', - 'BF_OPENMP_LIBPATH', + 'WITH_BF_OPENMP', 'BF_OPENMP', 'BF_OPENMP_LIBPATH', 'WITH_GHOST_COCOA', 'WITH_GHOST_SDL', + 'BF_GHOST_DEBUG', 'USE_QTKIT', 'BF_FANCY', 'BF_QUIET', 'BF_LINE_OVERWRITE', 'BF_X264_CONFIG', @@ -147,7 +147,6 @@ def validate_arguments(args, bc): 'BF_NUMJOBS', 'BF_MSVS', 'BF_VERSION', - 'BF_GHOST_DEBUG', 'WITH_BF_RAYOPTIMIZATION', 'BF_RAYOPTIMIZATION_SSE_FLAGS', 'WITH_BF_FLUID', @@ -155,7 +154,8 @@ def validate_arguments(args, bc): 'WITH_BF_BOOLEAN', 'WITH_BF_CXX_GUARDEDALLOC', 'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC', - 'BUILDBOT_BRANCH', 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC' + 'BUILDBOT_BRANCH', + 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC' ] # Have options here that scons expects to be lists @@ -239,9 +239,9 @@ def read_opts(env, cfg, args): ('LCGDIR', 'location of cvs lib dir'), (BoolVariable('WITH_BF_PYTHON', 'Compile with python', True)), (BoolVariable('WITH_BF_PYTHON_SAFETY', 'Internal API error checking to track invalid data to prevent crash on access (at the expense of some effeciency)', False)), - ('BF_PYTHON', 'base path for python', ''), + ('BF_PYTHON', 'Base path for python', ''), ('BF_PYTHON_VERSION', 'Python version to use', ''), - ('BF_PYTHON_INC', 'include path for Python headers', ''), + ('BF_PYTHON_INC', 'Include path for Python headers', ''), ('BF_PYTHON_BINARY', 'Path to the Python interpreter', ''), ('BF_PYTHON_LIB', 'Python library', ''), ('BF_PYTHON_DLL', 'Python dll - used on Windows only', ''), @@ -257,8 +257,8 @@ def read_opts(env, cfg, args): (BoolVariable('WITH_BF_BOOLEAN', 'Build with boolean modifier', True)), ('BF_PROFILE_FLAGS', 'Profiling compiler flags', ''), (BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)), - ('BF_OPENAL', 'base path for OpenAL', ''), - ('BF_OPENAL_INC', 'include path for python headers', ''), + ('BF_OPENAL', 'Base path for OpenAL', ''), + ('BF_OPENAL_INC', 'Include path for python headers', ''), ('BF_OPENAL_LIB', 'Path to OpenAL library', ''), ('BF_OPENAL_LIB_STATIC', 'Path to OpenAL static library', ''), ('BF_OPENAL_LIBPATH', 'Path to OpenAL library', ''), From 17f90f8fe492622b7e66f09d5774fbf1fc7b6e85 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 3 Nov 2011 12:28:32 +0000 Subject: [PATCH 058/147] Fix #29122: Curve Radius keyable from Outliner Datablock view but not Transform Radius field in 3D Viewport If there's only one control point selected, show radius property for this point, not for medium value. --- .../editors/space_view3d/view3d_buttons.c | 22 +++++++++++++++---- source/blender/makesrna/RNA_access.h | 1 + 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 63b0f68f158..70cf113384b 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -139,6 +139,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float float median[7], ve_median[7]; int tot, totw, totweight, totedge, totradius; char defstr[320]; + PointerRNA radius_ptr; median[0]= median[1]= median[2]= median[3]= median[4]= median[5]= median[6]= 0.0; tot= totw= totweight= totedge= totradius= 0; @@ -210,6 +211,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BezTriple *bezt; int a; ListBase *nurbs= curve_editnurbs(cu); + StructRNA *seltype= NULL; + void *selp= NULL; nu= nurbs->first; while(nu) { @@ -224,6 +227,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float totweight++; median[5]+= bezt->radius; totradius++; + selp= bezt; + seltype= &RNA_BezierSplinePoint; } else { if(bezt->f1 & SELECT) { @@ -251,12 +256,17 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float totweight++; median[5]+= bp->radius; totradius++; + selp= bp; + seltype= &RNA_SplinePoint; } bp++; } } nu= nu->next; } + + if(totradius==1) + RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr); } else if(ob->type==OB_LATTICE) { Lattice *lt= ob->data; @@ -319,9 +329,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiBlockEndAlign(block); if(totweight) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 20, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, ""); - if(totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); + if(totradius) { + if(totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 20, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL); + else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 20, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, "Radius of curve CPs"); } + } else { uiBlockBeginAlign(block); uiDefButBitS(block, TOG, V3D_GLOBAL_STATS, B_REDR, "Global", 0, 65, 100, 20, &v3d->flag, 0, 0, 0, 0, "Displays global values"); @@ -329,8 +341,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float uiBlockEndAlign(block); if(totweight) uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Weight:", 0, 40, 200, 20, &(tfp->ve_median[4]), 0.0, 1.0, 10, 3, ""); - if(totradius) - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 40, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); + if(totradius) { + if(totradius==1) uiDefButR(block, NUM, 0, "Radius", 0, 40, 200, 20, &radius_ptr, "radius", 0, 0.0, 100.0, 10, 3, NULL); + else uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Radius:", 0, 40, 200, 20, &(tfp->ve_median[5]), 0.0, 100.0, 10, 3, "Radius of curve CPs"); + } } } else { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index cf593555bc7..204f7b0b0ec 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -70,6 +70,7 @@ extern StructRNA RNA_ArmatureSensor; extern StructRNA RNA_ArrayModifier; extern StructRNA RNA_BackgroundImage; extern StructRNA RNA_BevelModifier; +extern StructRNA RNA_SplinePoint; extern StructRNA RNA_BezierSplinePoint; extern StructRNA RNA_BlendData; extern StructRNA RNA_BlendTexture; From 563becafb9439fd8ae5e642c25acd3c46fc56941 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 3 Nov 2011 12:40:15 +0000 Subject: [PATCH 059/147] Scons: * Basic support for OpenImageIO and Boost libraries * Path to libraries added for win32/64-vc-config.py, still commented out. --- build_files/scons/config/win32-vc-config.py | 14 ++++++++++++++ build_files/scons/config/win64-vc-config.py | 14 ++++++++++++++ build_files/scons/tools/Blender.py | 10 ++++++++++ build_files/scons/tools/btools.py | 14 +++++++++++++- 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py index ec37b3046c8..1e4821180d6 100644 --- a/build_files/scons/config/win32-vc-config.py +++ b/build_files/scons/config/win32-vc-config.py @@ -149,6 +149,20 @@ WITH_BF_3DMOUSE = True WITH_BF_OPENMP = True +''' +WITH_BF_OIIO = True +BF_OIIO = LIBDIR + '/openimageio' +BF_OIIO_INC = '${BF_OIIO}/include' +BF_OIIO_LIB = 'OpenImageIO' +BF_OIIO_LIBPATH = '${BF_OIIO}/lib' + +WITH_BF_BOOST = True +BF_BOOST = LIBDIR + '/boost' +BF_BOOST_INC = '${BF_BOOST}/include' +BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_46_1 libboost_filesystem-vc90-mt-s-1_46_1 libboost_regex-vc90-mt-s-1_46_1 libboost_system-vc90-mt-s-1_46_1 libboost_thread-vc90-mt-s-1_46_1' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' +''' + #Ray trace optimization WITH_BF_RAYOPTIMIZATION = True BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE'] diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py index afa64e03e80..0920d9375ae 100644 --- a/build_files/scons/config/win64-vc-config.py +++ b/build_files/scons/config/win64-vc-config.py @@ -153,6 +153,20 @@ WITH_BF_3DMOUSE = True WITH_BF_OPENMP = True +''' +WITH_BF_OIIO = True +BF_OIIO = LIBDIR + '/openimageio' +BF_OIIO_INC = '${BF_OIIO}/include' +BF_OIIO_LIB = 'OpenImageIO' +BF_OIIO_LIBPATH = '${BF_OIIO}/lib' + +WITH_BF_BOOST = True +BF_BOOST = LIBDIR + '/boost' +BF_BOOST_INC = '${BF_BOOST}/include' +BF_BOOST_LIB = 'libboost_date_time-vc90-mt-s-1_45 libboost_filesystem-vc90-mt-s-1_45 libboost_regex-vc90-mt-s-1_45 libboost_system-vc90-mt-s-1_45 libboost_thread-vc90-mt-s-1_45' +BF_BOOST_LIBPATH = '${BF_BOOST}/lib' +''' + #Ray trace optimization WITH_BF_RAYOPTIMIZATION = True BF_RAYOPTIMIZATION_SSE_FLAGS = ['/arch:SSE','/arch:SSE2'] diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index 875d8f7388b..44f9a4c8062 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -192,6 +192,11 @@ def setup_staticlibs(lenv): if lenv['WITH_BF_OPENMP']: if lenv['OURPLATFORM'] == 'linuxcross': libincs += Split(lenv['BF_OPENMP_LIBPATH']) + + if lenv['WITH_BF_OIIO']: + libincs += Split(lenv['BF_OIIO_LIBPATH']) + if lenv['WITH_BF_BOOST']: + libincs += Split(lenv['BF_BOOST_LIBPATH']) # setting this last so any overriding of manually libs could be handled if lenv['OURPLATFORM'] not in ('win32-vc', 'win32-mingw', 'win64-vc', 'linuxcross'): @@ -275,6 +280,11 @@ def setup_syslibs(lenv): if not lenv['WITH_BF_STATIC3DMOUSE']: syslibs += Split(lenv['BF_3DMOUSE_LIB']) + if lenv['WITH_BF_OIIO']: + syslibs += Split(lenv['BF_OIIO_LIB']) + if lenv['WITH_BF_BOOST']: + syslibs += Split(lenv['BF_BOOST_LIB']) + syslibs += lenv['LLIBS'] return syslibs diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index b457a05319d..68054fe485e 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -155,7 +155,9 @@ def validate_arguments(args, bc): 'WITH_BF_CXX_GUARDEDALLOC', 'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC', 'BUILDBOT_BRANCH', - 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC' + 'WITH_BF_3DMOUSE', 'WITH_BF_STATIC3DMOUSE', 'BF_3DMOUSE', 'BF_3DMOUSE_INC', 'BF_3DMOUSE_LIB', 'BF_3DMOUSE_LIBPATH', 'BF_3DMOUSE_LIB_STATIC', + 'WITH_BF_OIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIBPATH', + 'WITH_BF_BOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIBPATH' ] # Have options here that scons expects to be lists @@ -532,6 +534,16 @@ def read_opts(env, cfg, args): (BoolVariable('WITH_BF_CXX_GUARDEDALLOC', 'Enable GuardedAlloc for C++ memory allocation tracking.', False)), ('BUILDBOT_BRANCH', 'Buildbot branch name', ''), + + (BoolVariable('WITH_BF_OIIO', 'Build with OpenImageIO', False)), + ('BF_OIIO_INC', 'OIIO include path', ''), + ('BF_OIIO_LIB', 'OIIO library', ''), + ('BF_OIIO_LIBPATH', 'OIIO library path', ''), + + (BoolVariable('WITH_BF_BOOST', 'Build with Boost', False)), + ('BF_BOOST_INC', 'Boost include path', ''), + ('BF_BOOST_LIB', 'Boost library', ''), + ('BF_BOOST_LIBPATH', 'Boost library path', '') ) # end of opts.AddOptions() return localopts From aefa2cda10d5d3ad22a1ecb07c843602a4c589bb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 3 Nov 2011 12:43:45 +0000 Subject: [PATCH 060/147] Fix #28935: Material display error VBO + Texture Solid + Modifier --- source/blender/blenkernel/intern/subsurf_ccg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 115b26452e1..986e0e2b552 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1598,6 +1598,9 @@ static void ccgDM_drawFacesTex_common(DerivedMesh *dm, if(!mcol) mcol = dm->getFaceDataArray(dm, CD_MCOL); + if(!mcol) + mcol = dm->getFaceDataArray(dm, CD_TEXTURE_MCOL); + totface = ccgSubSurf_getNumFaces(ss); for(i = 0; i < totface; i++) { CCGFace *f = ccgdm->faceMap[i].face; From 0e51c9014c6a1cbdfe916edf79d1ca05d796e1fd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 12:47:39 +0000 Subject: [PATCH 061/147] patch [#27917] MARKER MENUS: Unification and adding "Duplicate Marker to Scene..." from Troy Sobotka (sobotka), with edits - remove Markers from Ctrl+L menu (was out of place here and was broken from recent changes to marker operators) - further de-duplicte scripts by having all menus call the same function: marker_menu_generic(). this fixes bug [#29083] too. --- .../scripts/startup/bl_ui/space_dopesheet.py | 14 ++---- release/scripts/startup/bl_ui/space_graph.py | 12 +---- release/scripts/startup/bl_ui/space_nla.py | 12 +---- .../scripts/startup/bl_ui/space_sequencer.py | 14 +----- release/scripts/startup/bl_ui/space_time.py | 44 ++++++++++++++----- release/scripts/startup/bl_ui/space_view3d.py | 2 - 6 files changed, 42 insertions(+), 56 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 90dcc99e6d7..106bbd85717 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -213,19 +213,11 @@ class DOPESHEET_MT_marker(Menu): def draw(self, context): layout = self.layout + from .space_time import marker_menu_generic + marker_menu_generic(layout) + st = context.space_data - #layout.operator_context = 'EXEC_REGION_WIN' - - layout.operator("marker.add", "Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") - if st.mode in {'ACTION', 'SHAPEKEY'} and st.action: layout.separator() layout.prop(st, "show_pose_markers") diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index d4b8c415a7f..b57d421dfaf 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -144,16 +144,8 @@ class GRAPH_MT_marker(Menu): def draw(self, context): layout = self.layout - #layout.operator_context = 'EXEC_REGION_WIN' - - layout.operator("marker.add", "Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") + from .space_time import marker_menu_generic + marker_menu_generic(layout) # TODO: pose markers for action edit mode only? diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index ffead81c507..c878c20c8a7 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -104,16 +104,8 @@ class NLA_MT_marker(Menu): def draw(self, context): layout = self.layout - #layout.operator_context = 'EXEC_REGION_WIN' - - layout.operator("marker.add", "Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") + from .space_time import marker_menu_generic + marker_menu_generic(layout) class NLA_MT_edit(Menu): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 2e957effccd..a4dcf64b679 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -158,18 +158,8 @@ class SEQUENCER_MT_marker(Menu): def draw(self, context): layout = self.layout - #layout.operator_context = 'EXEC_REGION_WIN' - - layout.operator("marker.add", "Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") - - #layout.operator("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS) + from .space_time import marker_menu_generic + marker_menu_generic(layout) class SEQUENCER_MT_change(Menu): diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index db009fe43c2..6f8e6a574ec 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -36,6 +36,7 @@ class TIME_HT_header(Header): if context.area.show_menus: row.menu("TIME_MT_view") + row.menu("TIME_MT_marker") row.menu("TIME_MT_frame") row.menu("TIME_MT_playback") @@ -91,6 +92,15 @@ class TIME_HT_header(Header): row.operator("anim.keyframe_delete", text="", icon='KEY_DEHLT') +class TIME_MT_marker(bpy.types.Menu): + bl_label = "Marker" + + def draw(self, context): + layout = self.layout + + marker_menu_generic(layout) + + class TIME_MT_view(Menu): bl_label = "View" @@ -142,17 +152,6 @@ class TIME_MT_frame(Menu): def draw(self, context): layout = self.layout - layout.operator("marker.add", text="Add Marker") - layout.operator("marker.duplicate", text="Duplicate Marker") - layout.operator("marker.delete", text="Delete Marker") - - layout.separator() - - layout.operator("marker.rename", text="Rename Marker") - layout.operator("marker.move", text="Grab/Move Marker") - - layout.separator() - layout.operator("time.start_frame_set") layout.operator("time.end_frame_set") @@ -197,5 +196,28 @@ class TIME_MT_autokey(Menu): layout.prop_enum(tools, "auto_keying_mode", 'ADD_REPLACE_KEYS') layout.prop_enum(tools, "auto_keying_mode", 'REPLACE_KEYS') + +def marker_menu_generic(layout): + + #layout.operator_context = 'EXEC_REGION_WIN' + + layout.column() + layout.operator("marker.add", "Add Marker") + layout.operator("marker.duplicate", text="Duplicate Marker") + + if(len(bpy.data.scenes) > 10): + layout.operator_context = 'INVOKE_DEFAULT' + layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY') + else: + layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene...") + + layout.operator("marker.delete", text="Delete Marker") + + layout.separator() + + layout.operator("marker.rename", text="Rename Marker") + layout.operator("marker.move", text="Grab/Move Marker") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 07c860fca31..3f5b7b86e89 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -976,10 +976,8 @@ class VIEW3D_MT_make_links(Menu): if(len(bpy.data.scenes) > 10): layout.operator_context = 'INVOKE_DEFAULT' layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY') - layout.operator("object.make_links_scene", text="Markers to Scene...", icon='OUTLINER_OB_EMPTY') else: layout.operator_menu_enum("object.make_links_scene", "scene", text="Objects to Scene...") - layout.operator_menu_enum("marker.make_links_scene", "scene", text="Markers to Scene...") layout.operator_enum("object.make_links_data", "type") # inline From d210703bcaf89014495f761797ae50f362394697 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 13:10:37 +0000 Subject: [PATCH 062/147] use Py_TYPE macro (no functional changes) --- intern/audaspace/Python/AUD_PyAPI.cpp | 32 +++++++++---------- source/gameengine/Ketsji/KX_PythonSeq.h | 4 +-- source/gameengine/VideoTexture/BlendType.h | 6 ++-- source/gameengine/VideoTexture/FilterBase.cpp | 2 +- source/gameengine/VideoTexture/ImageBase.cpp | 4 +-- source/gameengine/VideoTexture/Texture.cpp | 4 +-- .../gameengine/VideoTexture/blendVideoTex.cpp | 2 +- 7 files changed, 27 insertions(+), 27 deletions(-) diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp index 0dfa39de66c..bbc7a0ca52e 100644 --- a/intern/audaspace/Python/AUD_PyAPI.cpp +++ b/intern/audaspace/Python/AUD_PyAPI.cpp @@ -226,7 +226,7 @@ Factory_lowpass(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -267,7 +267,7 @@ Factory_delay(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "f:delay", &delay)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -303,7 +303,7 @@ PyDoc_STRVAR(M_aud_Factory_join_doc, static PyObject * Factory_join(Factory* self, PyObject* object) { - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); if(!PyObject_TypeCheck(object, type)) { @@ -354,7 +354,7 @@ Factory_highpass(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -395,7 +395,7 @@ Factory_limit(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "ff:limit", &start, &end)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -439,7 +439,7 @@ Factory_pitch(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "f:pitch", &factor)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -481,7 +481,7 @@ Factory_volume(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "f:volume", &volume)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -524,7 +524,7 @@ Factory_fadein(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -568,7 +568,7 @@ Factory_fadeout(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -610,7 +610,7 @@ Factory_loop(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "i:loop", &loop)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -646,7 +646,7 @@ PyDoc_STRVAR(M_aud_Factory_mix_doc, static PyObject * Factory_mix(Factory* self, PyObject* object) { - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); if(!PyObject_TypeCheck(object, type)) { @@ -686,7 +686,7 @@ PyDoc_STRVAR(M_aud_Factory_pingpong_doc, static PyObject * Factory_pingpong(Factory* self) { - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -725,7 +725,7 @@ PyDoc_STRVAR(M_aud_Factory_reverse_doc, static PyObject * Factory_reverse(Factory* self) { - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -763,7 +763,7 @@ PyDoc_STRVAR(M_aud_Factory_buffer_doc, static PyObject * Factory_buffer(Factory* self) { - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -802,7 +802,7 @@ Factory_square(Factory* self, PyObject* args) if(!PyArg_ParseTuple(args, "|f:square", &threshold)) return NULL; - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) @@ -905,7 +905,7 @@ Factory_filter(Factory* self, PyObject* args) else a.push_back(1); - PyTypeObject* type = ((PyObject*)self)->ob_type; + PyTypeObject* type = Py_TYPE(self); Factory *parent = (Factory*)type->tp_alloc(type, 0); if(parent != NULL) diff --git a/source/gameengine/Ketsji/KX_PythonSeq.h b/source/gameengine/Ketsji/KX_PythonSeq.h index 6e9cf9a36aa..1c2d2869be0 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.h +++ b/source/gameengine/Ketsji/KX_PythonSeq.h @@ -51,8 +51,8 @@ enum KX_PYGENSEQ_TYPE { /* The Main PyType Object defined in Main.c */ extern PyTypeObject KX_PythonSeq_Type; -#define BPy_KX_PythonSeq_Check(v) \ - ((v)->ob_type == &KX_PythonSeq_Type) +#define BPy_KX_PythonSeq_Check(obj) \ + (Py_TYPE(obj) == &KX_PythonSeq_Type) typedef struct { PyObject_VAR_HEAD diff --git a/source/gameengine/VideoTexture/BlendType.h b/source/gameengine/VideoTexture/BlendType.h index 4d63031a363..fad23af922e 100644 --- a/source/gameengine/VideoTexture/BlendType.h +++ b/source/gameengine/VideoTexture/BlendType.h @@ -43,15 +43,15 @@ public: if (m_objType == NULL) { // compare names of type - if (strcmp(obj->ob_type->tp_name, m_name) == 0) + if (strcmp(Py_TYPE(obj)->tp_name, m_name) == 0) // if name of type match, save pointer to type - m_objType = obj->ob_type; + m_objType = Py_TYPE(obj); else // if names of type don't match, return NULL return NULL; } // if pointer to type is set and don't match to type of provided object, return NULL - else if (obj->ob_type != m_objType) + else if (Py_TYPE(obj) != m_objType) return NULL; // return pointer to object, this class can only be used for KX object => // the Py object is actually a proxy diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp index 28e36cf80e0..6fa249ff00a 100644 --- a/source/gameengine/VideoTexture/FilterBase.cpp +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -141,7 +141,7 @@ int Filter_setPrevious (PyFilter * self, PyObject * value, void * closure) if (self->m_filter != NULL) { // check new value - if (value == NULL || !pyFilterTypes.in(value->ob_type)) + if (value == NULL || !pyFilterTypes.in(Py_TYPE(value))) { // report value error PyErr_SetString(PyExc_TypeError, "Invalid type of value"); diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index 0fe71dd8024..b1d77d8807f 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -567,7 +567,7 @@ PyObject * Image_setSource (PyImage * self, PyObject * args) if (self->m_image != NULL) { // check type of object - if (pyImageTypes.in(obj->ob_type)) + if (pyImageTypes.in(Py_TYPE(obj))) { // convert to image struct PyImage * img = reinterpret_cast(obj); @@ -619,7 +619,7 @@ int Image_setFilter (PyImage * self, PyObject * value, void * closure) if (self->m_image != NULL) { // check new value - if (value == NULL || !pyFilterTypes.in(value->ob_type)) + if (value == NULL || !pyFilterTypes.in(Py_TYPE(value))) { // report value error PyErr_SetString(PyExc_TypeError, "Invalid type of value"); diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index ba9922d455f..e1ddd7fce1e 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -171,7 +171,7 @@ void Texture_dealloc (Texture * self) // release scaled image buffer delete [] self->m_scaledImg; // release object - ((PyObject *)self)->ob_type->tp_free((PyObject*)self); + Py_TYPE((PyObject *)self)->tp_free((PyObject*)self); } @@ -410,7 +410,7 @@ PyObject * Texture_getSource (Texture * self, PyObject * value, void * closure) int Texture_setSource (Texture * self, PyObject * value, void * closure) { // check new value - if (value == NULL || !pyImageTypes.in(value->ob_type)) + if (value == NULL || !pyImageTypes.in(Py_TYPE(value))) { // report value error PyErr_SetString(PyExc_TypeError, "Invalid type of value"); diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index c93fadada77..abfd0ed49b7 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -91,7 +91,7 @@ static PyObject * imageToArray (PyObject * self, PyObject *args) // parameter is Image object PyObject * pyImg; char *mode = NULL; - if (!PyArg_ParseTuple(args, "O|s:imageToArray", &pyImg, &mode) || !pyImageTypes.in(pyImg->ob_type)) + if (!PyArg_ParseTuple(args, "O|s:imageToArray", &pyImg, &mode) || !pyImageTypes.in(Py_TYPE(pyImg))) { // if object is incorect, report error PyErr_SetString(PyExc_TypeError, "VideoTexture.imageToArray(image): The value must be a image source object"); From 665f602f152984f5a6f4ea05a2a90382acbf700a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 14:09:18 +0000 Subject: [PATCH 063/147] python string conversion - use _PyUnicode_AsStringAndSize where possible - use %R for PyErr_Format(...) rather then running repr on the object explicitly - use const char --- source/blender/imbuf/intern/moviecache.c | 2 +- source/blender/python/generic/IDProp.c | 39 ++++++++++++------- source/blender/python/generic/IDProp.h | 2 +- source/blender/python/generic/py_capi_utils.c | 2 +- source/blender/python/intern/bpy_operator.c | 4 +- source/blender/python/intern/bpy_props.c | 2 +- .../Converter/BL_ActionActuator.cpp | 5 ++- source/gameengine/Expressions/ListValue.cpp | 7 ++-- .../gameengine/Expressions/PyObjectPlus.cpp | 10 ++--- source/gameengine/Expressions/StringValue.h | 5 +-- .../GameLogic/SCA_PythonController.cpp | 13 +++---- source/gameengine/Ketsji/KX_Camera.cpp | 4 +- source/gameengine/Ketsji/KX_PythonInit.cpp | 2 +- source/gameengine/Ketsji/KX_PythonSeq.cpp | 4 +- 14 files changed, 55 insertions(+), 46 deletions(-) diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 7492b6aec44..1d752fe9c6d 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -230,7 +230,7 @@ void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf) key= BLI_mempool_alloc(cache->keys_pool); key->cache_owner= cache; - key->userkey= BLI_mempool_alloc(cache->userkeys_pool);; + key->userkey= BLI_mempool_alloc(cache->userkeys_pool); memcpy(key->userkey, userkey, cache->keysize); item= BLI_mempool_alloc(cache->items_pool); diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c index 076b4811d07..6d869a7eb1f 100644 --- a/source/blender/python/generic/IDProp.c +++ b/source/blender/python/generic/IDProp.c @@ -195,19 +195,22 @@ static PyObject *BPy_IDGroup_GetName(BPy_IDProperty *self, void *UNUSED(closure) static int BPy_IDGroup_SetName(BPy_IDProperty *self, PyObject *value, void *UNUSED(closure)) { - char *st; + const char *name; + Py_ssize_t name_size; + if (!PyUnicode_Check(value)) { PyErr_SetString(PyExc_TypeError, "expected a string!"); return -1; } - st = _PyUnicode_AsString(value); - if (BLI_strnlen(st, MAX_IDPROP_NAME) == MAX_IDPROP_NAME) { + name = _PyUnicode_AsStringAndSize(value, &name_size); + + if (name_size > MAX_IDPROP_NAME) { PyErr_SetString(PyExc_TypeError, "string length cannot exceed 31 characters!"); return -1; } - BLI_strncpy(self->prop->name, st, sizeof(self->prop->name)); + memcpy(self->prop->name, name, name_size); return 0; } @@ -236,7 +239,7 @@ static Py_ssize_t BPy_IDGroup_Map_Len(BPy_IDProperty *self) static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) { IDProperty *idprop; - char *name; + const char *name; if (self->prop->type != IDP_GROUP) { PyErr_SetString(PyExc_TypeError, "unsubscriptable object"); @@ -301,14 +304,22 @@ static int idp_sequence_type(PyObject *seq) return type; } -/* note: group can be a pointer array or a group */ -const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *group, PyObject *ob) +/* note: group can be a pointer array or a group. + * assume we already checked key is a string. */ +const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty *group, PyObject *ob) { IDProperty *prop = NULL; IDPropertyTemplate val = {0}; - if (strlen(name) >= sizeof(group->name)) - return "the length of IDProperty names is limited to 31 characters"; + const char *name= ""; + + if (name_obj) { + Py_ssize_t name_size; + name = _PyUnicode_AsStringAndSize(name_obj, &name_size); + if (name_size > MAX_IDPROP_NAME) { + return "the length of IDProperty names is limited to 31 characters"; + } + } if (PyFloat_Check(ob)) { val.d = PyFloat_AsDouble(ob); @@ -364,7 +375,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(const char *name, IDProperty *g for (i=0; im_size); ptr[attrdef->m_size-1] = 0; } @@ -1030,7 +1030,7 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt if (PyUnicode_Check(value)) { Py_ssize_t val_len; - char *val = _PyUnicode_AsStringAndSize(value, &val_len); + const char *val = _PyUnicode_AsStringAndSize(value, &val_len); /* XXX, should be 'const' but we do a silly trick to have a shorter string */ if (attrdef->m_clamp) { if (val_len < attrdef->m_imin) @@ -1042,10 +1042,8 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt else if (val_len > attrdef->m_imax) { // trim the string - char c = val[attrdef->m_imax]; - val[attrdef->m_imax] = 0; *var = val; - val[attrdef->m_imax] = c; + var->SetLength(attrdef->m_imax); break; } } else if (val_len < attrdef->m_imin || val_len > attrdef->m_imax) diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h index d0f74a6eed8..e5a892ff82d 100644 --- a/source/gameengine/Expressions/StringValue.h +++ b/source/gameengine/Expressions/StringValue.h @@ -31,8 +31,7 @@ public: CStringValue(); CStringValue (const char *txt, const char *name , AllocationTYPE alloctype = CValue::HEAPVALUE); - virtual ~CStringValue() { - }; + virtual ~CStringValue() {} /// CValue implementation virtual bool IsEqual(const STR_String & other); virtual const STR_String & GetText(); @@ -40,7 +39,7 @@ public: virtual CValue* Calc(VALUE_OPERATOR op, CValue *val); virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val); - virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); }; + virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); } virtual CValue* GetReplica(); #ifdef WITH_PYTHON virtual PyObject* ConvertValueToPython() { diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index 303b3e9529e..d69358928e6 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -199,7 +199,7 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) if (PyUnicode_Check(value)) { /* get the actuator from the name */ - char *name= _PyUnicode_AsString(value); + const char *name= _PyUnicode_AsString(value); for(it = lacts.begin(); it!= lacts.end(); ++it) { if( name == (*it)->GetName() ) { return *it; @@ -214,12 +214,11 @@ SCA_IActuator* SCA_PythonController::LinkedActuatorFromPy(PyObject *value) } } } - + /* set the exception */ - PyObject *value_str = PyObject_Repr(value); /* new ref */ - PyErr_Format(PyExc_ValueError, "'%s' not in this python controllers actuator list", _PyUnicode_AsString(value_str)); - Py_DECREF(value_str); - + PyErr_Format(PyExc_ValueError, + "%R not in this python controllers actuator list", value); + return NULL; } @@ -500,7 +499,7 @@ int SCA_PythonController::pyattr_set_script(void *self_v, const KX_PYATTRIBUTE_D { SCA_PythonController* self= static_cast(self_v); - char *scriptArg = _PyUnicode_AsString(value); + const char *scriptArg = _PyUnicode_AsString(value); if (scriptArg==NULL) { PyErr_SetString(PyExc_TypeError, "controller.script = string: Python Controller, expected a string script text"); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 3b777031831..77438b8f48a 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -883,7 +883,9 @@ bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok if (*object) { return true; } else { - PyErr_Format(PyExc_ValueError, "%s, requested name \"%s\" did not match any KX_Camera in this scene", error_prefix, _PyUnicode_AsString(value)); + PyErr_Format(PyExc_ValueError, + "%s, requested name \"%s\" did not match any KX_Camera in this scene", + error_prefix, _PyUnicode_AsString(value)); return false; } } diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 25145e87b78..c3a141e7405 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -705,7 +705,7 @@ static PyObject *gLibNew(PyObject*, PyObject* args) KX_Scene *kx_scene= gp_KetsjiScene; char *path; char *group; - char *name; + const char *name; PyObject *names; int idcode; diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 7d7dc39ba32..430dcdbd153 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -189,7 +189,7 @@ static PyObject *KX_PythonSeq_getIndex(PyObject* self, int index) return NULL; } -static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, char *key) +static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, const char *key) { PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); @@ -277,7 +277,7 @@ static PyObject * KX_PythonSeq_subscript(PyObject * self, PyObject *key) return KX_PythonSeq_getIndex(self, PyLong_AsSsize_t( key )); } else if ( PyUnicode_Check(key) ) { - char *name = _PyUnicode_AsString(key); + const char *name = _PyUnicode_AsString(key); PyObjectPlus *ret = KX_PythonSeq_subscript__internal(self, name); if(ret) { From b99f6e3d082b1b47591cdae1d2f3b78a75dd719b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 3 Nov 2011 16:16:19 +0000 Subject: [PATCH 064/147] Fix #29005: Bezier/Surface Datablock switching bug? This commit updates curve datablock to respect curve dimension flag when setting datablock for curve. Not ideal but this makes behavior quite expected, avoids big changes in curves core stuff which depends on object type and prevents restrictions on changing data datablock which works in general cases. --- source/blender/blenkernel/BKE_curve.h | 1 + source/blender/blenkernel/intern/curve.c | 29 ++++++++++++++++++++-- source/blender/makesrna/intern/rna_curve.c | 19 +++----------- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 9282f0ef29a..f0704741ebb 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -65,6 +65,7 @@ void make_local_curve( struct Curve *cu); struct ListBase *curve_editnurbs(struct Curve *cu); short curve_type( struct Curve *cu); void test_curve_type( struct Object *ob); +void update_curve_dimension( struct Curve *cu ); void tex_space_curve( struct Curve *cu); int count_curveverts( struct ListBase *nurb); int count_curveverts_without_handles( struct ListBase *nurb); diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 5d2180fe702..adc08f5cd9f 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -315,9 +315,34 @@ short curve_type(Curve *cu) return OB_CURVE; } +void update_curve_dimension(Curve *cu) +{ + ListBase *nurbs= BKE_curve_nurbs(cu); + Nurb *nu= nurbs->first; + + if(cu->flag&CU_3D) { + for( ; nu; nu= nu->next) { + nu->flag &= ~CU_2D; + } + } + else { + for( ; nu; nu= nu->next) { + nu->flag |= CU_2D; + test2DNurb(nu); + + /* since the handles are moved they need to be auto-located again */ + if(nu->type == CU_BEZIER) + calchandlesNurb(nu); + } + } +} + void test_curve_type(Object *ob) -{ - ob->type = curve_type(ob->data); +{ + ob->type= curve_type(ob->data); + + if(ob->type==OB_CURVE) + update_curve_dimension((Curve *)ob->data); } void tex_space_curve(Curve *cu) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index cbac594a80f..1f52b0ac149 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -271,23 +271,10 @@ static void rna_Curve_dimension_set(PointerRNA *ptr, int value) ListBase *nurbs= BKE_curve_nurbs(cu); Nurb *nu= nurbs->first; - if(value==CU_3D) { - cu->flag |= CU_3D; - for( ; nu; nu= nu->next) { - nu->flag &= ~CU_2D; - } - } - else { - cu->flag &= ~CU_3D; - for( ; nu; nu= nu->next) { - nu->flag |= CU_2D; - test2DNurb(nu); + if(value==CU_3D) cu->flag |= CU_3D; + else cu->flag &= ~CU_3D; - /* since the handles are moved they need to be auto-located again */ - if(nu->type == CU_BEZIER) - calchandlesNurb(nu); - } - } + update_curve_dimension(cu); } static EnumPropertyItem *rna_Curve_fill_mode_itemf(bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *UNUSED(free)) From d53989bda6e5b30f41846554c3a68ee695b031f2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 3 Nov 2011 16:41:48 +0000 Subject: [PATCH 065/147] Depsgraph: more tweaking for update acces from python API * Move scene_update_pre callback before depsgraph flusing so it works better when you do modifications on objects then. * Fix missing update after making modifications in frame_change_pre, recalc flags were not being flushed. --- source/blender/blenkernel/intern/scene.c | 31 +++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 7ba0a642cdd..a9de75dc7d0 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -990,18 +990,22 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen /* this is called in main loop, doing tagged updates before redraw */ void scene_update_tagged(Main *bmain, Scene *scene) { - DAG_ids_flush_tagged(bmain); - + /* keep this first */ BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE); + /* flush recalc flags to dependencies */ + DAG_ids_flush_tagged(bmain); + scene->physics_settings.quick_cache_step= 0; /* update all objects: drivers, matrices, displists, etc. flags set - by depgraph or manual, no layer check here, gets correct flushed */ + by depgraph or manual, no layer check here, gets correct flushed + in the future this should handle updates for all datablocks, not + only objects and scenes. - brecht */ scene_update_tagged_recursive(bmain, scene, scene); - /* recalc scene animation data here (for sequencer) */ + /* extra call here to recalc scene animation (for sequencer) */ { AnimData *adt= BKE_animdata_from_id(&scene->id); float ctime = BKE_curframe(scene); @@ -1010,15 +1014,15 @@ void scene_update_tagged(Main *bmain, Scene *scene) BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0); } + /* quick point cache updates */ if (scene->physics_settings.quick_cache_step) BKE_ptcache_quick_cache_all(bmain, scene); + /* notify editors about recalc */ DAG_ids_check_recalc(bmain); + /* keep this last */ BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST); - - /* in the future this should handle updates for all datablocks, not - only objects and scenes. - brecht */ } void scene_clear_tagged(Main *bmain, Scene *UNUSED(scene)) @@ -1033,7 +1037,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) Scene *sce_iter; /* keep this first */ - BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_PRE); + BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE); + BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE); sound_set_cfra(sce->r.cfra); @@ -1045,13 +1050,15 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) DAG_scene_sort(bmain, sce_iter); } + /* flush recalc flags to dependencies, if we were only changing a frame + this would not be necessary, but if a user or a script has modified + some datablock before scene_update_tagged was called, we need the flush */ + DAG_ids_flush_tagged(bmain); /* Following 2 functions are recursive * so dont call within 'scene_update_tagged_recursive' */ DAG_scene_update_flags(bmain, sce, lay, TRUE); // only stuff that moves or needs display still - BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_PRE); - /* All 'standard' (i.e. without any dependencies) animation is handled here, * with an 'local' to 'macro' order of evaluation. This should ensure that * settings stored nestled within a hierarchy (i.e. settings in a Texture block @@ -1065,8 +1072,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay) scene_update_tagged_recursive(bmain, sce, sce); /* keep this last */ - BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_SCENE_UPDATE_POST); - BLI_exec_cb(bmain, (ID *)sce, BLI_CB_EVT_FRAME_CHANGE_POST); + BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST); + BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST); DAG_ids_clear_recalc(bmain); } From 224c26f891cb2495a0d94a092e46f13784af6e6b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 3 Nov 2011 17:06:12 +0000 Subject: [PATCH 066/147] Fix #28998: sequence rendering with wrong progress bar Show overall progress when doing sequence rendering. Nice for cases when you're using sequencer to combine video strips only, without rendering scenes and so. If scene strips are used in sequencer, per-frame rendering would be used (because of scene rendering sets per-frame progress). --- source/blender/editors/render/render_internal.c | 6 +++++- source/blender/render/extern/include/RE_pipeline.h | 2 ++ source/blender/render/intern/source/pipeline.c | 14 ++++++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 9c38b1ce98f..cc1c8843015 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -503,6 +503,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) const short is_animation= RNA_boolean_get(op->ptr, "animation"); const short is_write_still= RNA_boolean_get(op->ptr, "write_still"); struct Object *camera_override= v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; + const char *name; /* only one render job at a time */ if(WM_jobs_test(CTX_wm_manager(C), scene)) @@ -577,7 +578,10 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->reports= op->reports; /* setup job */ - steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", jobflag); + if(RE_seq_render_active(scene, &scene->r)) name= "Sequence Render"; + else name= "Render"; + + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag); WM_jobs_customdata(steve, rj, render_freejob); WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0); WM_jobs_callbacks(steve, render_startjob, NULL, NULL, render_endjob); diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index cbb2f17043c..fac3329bae0 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -249,6 +249,8 @@ float RE_filter_value(int type, float x); /* vector blur zbuffer method */ void RE_zbuf_accumulate_vecblur(struct NodeBlurData *nbd, int xsize, int ysize, float *newrect, float *imgrect, float *vecbufrect, float *zbufrect); +int RE_seq_render_active(struct Scene *scene, struct RenderData *rd); + /* shaded view or baking options */ #define RE_BAKE_LIGHT 0 /* not listed in rna_scene.c -> can't be enabled! */ #define RE_BAKE_ALL 1 diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 8d72be1684c..de5d037675e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2517,14 +2517,14 @@ static void renderresult_stampinfo(Render *re) RE_ReleaseResultImage(re); } -static int seq_render_active(Render *re) +int RE_seq_render_active(Scene *scene, RenderData *rd) { Editing *ed; Sequence *seq; - ed = re->scene->ed; + ed = scene->ed; - if (!(re->r.scemode & R_DOSEQ) || !ed || !ed->seqbase.first) + if (!(rd->scemode & R_DOSEQ) || !ed || !ed->seqbase.first) return 0; for (seq= ed->seqbase.first; seq; seq= seq->next) { @@ -2632,6 +2632,12 @@ static void do_render_seq(Render * re) /* just in case this flag went missing at some point */ re->r.scemode |= R_DOSEQ; + + /* set overall progress of sequence rendering */ + if(re->r.efra!=re->r.sfra) + re->progress(re->prh, (float)(cfra-re->r.sfra) / (re->r.efra-re->r.sfra)); + else + re->progress(re->prh, 1.0f); } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -2649,7 +2655,7 @@ static void do_render_all_options(Render *re) if(RE_engine_render(re, 1)) { /* in this case external render overrides all */ } - else if(seq_render_active(re)) { + else if(RE_seq_render_active(re->scene, &re->r)) { /* note: do_render_seq() frees rect32 when sequencer returns float images */ if(!re->test_break(re->tbh)) do_render_seq(re); From 29575c9ac8c08ae264f06b6ce34fa606bb09bdab Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 3 Nov 2011 23:20:54 +0000 Subject: [PATCH 067/147] compile without python works again --- source/blender/editors/interface/interface.c | 2 ++ source/blender/editors/interface/interface_ops.c | 5 +++++ source/blender/makesrna/intern/rna_curve.c | 3 --- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index a6316dc0e9e..eff4d1f6397 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2569,10 +2569,12 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, if(block->curlayout) ui_layout_add_but(block->curlayout, but); +#ifdef WITH_PYTHON /* if the 'UI_OT_editsource' is running, extract the source info from the button */ if (UI_editsource_enable_check()) { UI_editsource_active_but_test(but); } +#endif return but; } diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 27f94ae8e49..d420b5c24c3 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -476,6 +476,7 @@ static void UI_OT_reports_to_textblock(wmOperatorType *ot) ot->exec= reports_to_text_exec; } +#ifdef WITH_PYTHON /* ------------------------------------------------------------------------- */ /* EditSource Utility funcs and operator, @@ -711,6 +712,7 @@ static void UI_OT_editsource(wmOperatorType *ot) ot->exec= editsource_exec; } +#endif /* WITH_PYTHON */ /* ********************************************************* */ /* Registration */ @@ -723,6 +725,9 @@ void UI_buttons_operatortypes(void) WM_operatortype_append(UI_OT_reset_default_button); WM_operatortype_append(UI_OT_copy_to_selected_button); WM_operatortype_append(UI_OT_reports_to_textblock); // XXX: temp? + +#ifdef WITH_PYTHON WM_operatortype_append(UI_OT_editsource); +#endif } diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 1f52b0ac149..93fdc2b2136 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -268,9 +268,6 @@ static void rna_Curve_active_textbox_index_range(PointerRNA *ptr, int *min, int static void rna_Curve_dimension_set(PointerRNA *ptr, int value) { Curve *cu= (Curve*)ptr->id.data; - ListBase *nurbs= BKE_curve_nurbs(cu); - Nurb *nu= nurbs->first; - if(value==CU_3D) cu->flag |= CU_3D; else cu->flag &= ~CU_3D; From 2d787e6e015e54e760086266415d66cad5d1edec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Nov 2011 01:15:04 +0000 Subject: [PATCH 068/147] utility function to find the biggest area: BKE_screen_find_big_area(...), was being done with static functions that were copied about. --- source/blender/blenkernel/BKE_screen.h | 22 ++++++++++-------- source/blender/blenkernel/intern/screen.c | 23 +++++++++++++++++++ .../blender/editors/interface/interface_ops.c | 21 ++--------------- source/blender/editors/object/object_bake.c | 21 ++--------------- source/blender/editors/render/render_view.c | 19 ++------------- .../windowmanager/intern/wm_init_exit.c | 20 +--------------- 6 files changed, 42 insertions(+), 84 deletions(-) diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 5b6d7e3cd96..77a351d534e 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -34,22 +34,23 @@ */ struct ARegion; +struct Header; +struct ListBase; +struct Menu; +struct Panel; +struct Scene; +struct ScrArea; +struct SpaceType; +struct View3D; struct bContext; struct bContextDataResult; struct bScreen; -struct ListBase; -struct Panel; -struct Header; -struct Menu; -struct ScrArea; -struct SpaceType; -struct Scene; +struct uiLayout; +struct uiMenuItem; +struct wmKeyConfig; struct wmNotifier; struct wmWindow; struct wmWindowManager; -struct wmKeyConfig; -struct uiLayout; -struct uiMenuItem; #include "RNA_types.h" @@ -239,6 +240,7 @@ void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar); void BKE_screen_area_free(struct ScrArea *sa); struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type); +struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min); void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene); void BKE_screen_view3d_scene_sync(struct bScreen *sc); diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 02e6fe945f3..b7f49bbab47 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -351,6 +351,29 @@ ARegion *BKE_area_find_region_type(ScrArea *sa, int type) return NULL; } +/* note, using this function is generally a last resort, you really want to be + * using the context when you can - campbell + * -1 for any type */ +struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min) +{ + ScrArea *sa, *big= NULL; + int size, maxsize= 0; + + for(sa= sc->areabase.first; sa; sa= sa->next) { + if ((spacetype == -1) || sa->spacetype == spacetype) { + if (min >= sa->winx && min >= sa->winy) { + size= sa->winx*sa->winy; + if (size > maxsize) { + maxsize= size; + big= sa; + } + } + } + } + + return big; +} + void BKE_screen_view3d_sync(struct View3D *v3d, struct Scene *scene) { int bit; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index d420b5c24c3..5803054caa7 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -43,6 +43,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_screen.h" #include "BKE_global.h" #include "BKE_text.h" /* for UI_OT_reports_to_text */ #include "BKE_report.h" @@ -577,24 +578,6 @@ void UI_editsource_active_but_test(uiBut *but) /* editsource operator component */ -static ScrArea *biggest_text_view(bContext *C) -{ - bScreen *sc= CTX_wm_screen(C); - ScrArea *sa, *big= NULL; - int size, maxsize= 0; - - for(sa= sc->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_TEXT) { - size= sa->winx * sa->winy; - if(size > maxsize) { - maxsize= size; - big= sa; - } - } - } - return big; -} - static int editsource_text_edit(bContext *C, wmOperator *op, char filepath[240], int line) { @@ -619,7 +602,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, else { /* naughty!, find text area to set, not good behavior * but since this is a dev tool lets allow it - campbell */ - ScrArea *sa= biggest_text_view(C); + ScrArea *sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_TEXT, 0); if(sa) { SpaceText *st= sa->spacedata.first; st->text= text; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index e29dfaa0a23..5487cbdadb2 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -54,6 +54,7 @@ #include "BLI_math_geom.h" #include "BKE_blender.h" +#include "BKE_screen.h" #include "BKE_context.h" #include "BKE_global.h" #include "BKE_image.h" @@ -1202,24 +1203,6 @@ static int thread_break(void *UNUSED(arg)) return G.afbreek; } -static ScrArea *biggest_image_area(bScreen *screen) -{ - ScrArea *sa, *big= NULL; - int size, maxsize= 0; - - for(sa= screen->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_IMAGE) { - size= sa->winx*sa->winy; - if(sa->winx > 10 && sa->winy > 10 && size > maxsize) { - maxsize= size; - big= sa; - } - } - } - return big; -} - - typedef struct BakeRender { Render *re; Main *main; @@ -1270,7 +1253,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) /* get editmode results */ ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */ - bkr->sa= biggest_image_area(CTX_wm_screen(C)); /* can be NULL */ + bkr->sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_IMAGE, 10); /* can be NULL */ bkr->main= CTX_data_main(C); bkr->scene= scene; bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 47957c0bb5a..d8719c7d7cd 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -58,6 +58,7 @@ /* returns biggest area that is not uv/image editor. Note that it uses buttons */ /* window as the last possible alternative. */ +/* would use BKE_screen_find_big_area(...) but this is too specific */ static ScrArea *biggest_non_image_area(bContext *C) { bScreen *sc= CTX_wm_screen(C); @@ -85,22 +86,6 @@ static ScrArea *biggest_non_image_area(bContext *C) return big; } -static ScrArea *biggest_area(bContext *C) -{ - bScreen *sc= CTX_wm_screen(C); - ScrArea *sa, *big= NULL; - int size, maxsize= 0; - - for(sa= sc->areabase.first; sa; sa= sa->next) { - size= sa->winx*sa->winy; - if(size > maxsize) { - maxsize= size; - big= sa; - } - } - return big; -} - static ScrArea *find_area_showing_r_result(bContext *C, wmWindow **win) { wmWindowManager *wm= CTX_wm_manager(C); @@ -206,7 +191,7 @@ void render_view_open(bContext *C, int mx, int my) } else { /* use any area of decent size */ - sa= biggest_area(C); + sa= BKE_screen_find_big_area(CTX_wm_screen(C), -1, 0); if(sa->spacetype!=SPACE_IMAGE) { // XXX newspace(sa, SPACE_IMAGE); sima= sa->spacedata.first; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index f32e2afa3e0..0795bc8deee 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -212,24 +212,6 @@ void WM_init_splash(bContext *C) } } -static ScrArea *biggest_view3d(bContext *C) -{ - bScreen *sc= CTX_wm_screen(C); - ScrArea *sa, *big= NULL; - int size, maxsize= 0; - - for(sa= sc->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_VIEW3D) { - size= sa->winx * sa->winy; - if(size > maxsize) { - maxsize= size; - big= sa; - } - } - } - return big; -} - int WM_init_game(bContext *C) { wmWindowManager *wm= CTX_wm_manager(C); @@ -252,7 +234,7 @@ int WM_init_game(bContext *C) if(win) CTX_wm_window_set(C, win); - sa = biggest_view3d(C); + sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0); ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); // if we have a valid 3D view From 7e9bc22925f3669248bf211f4f3049471cf23b2b Mon Sep 17 00:00:00 2001 From: Matt Ebb Date: Fri, 4 Nov 2011 02:31:00 +0000 Subject: [PATCH 069/147] Enabled ndof devices for controlling colour wheel and cube UI controls (eg. colour pickers). Tilting the ndof device up and down and rolling it left and right will move the 'colour cursor' in screen x and y, and twisting the ndof device will rotate the cursor around the colour wheel (hue). Now you can turn off the lights and pretend you have a fancy DI deck! --- .../editors/interface/interface_handlers.c | 130 +++++++++++++++++- 1 file changed, 129 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index e49cb4898d9..0f230df049e 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3216,6 +3216,63 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, return changed; } +static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift) +{ + float *hsv= ui_block_hsv_get(but->block); + float rgb[3]; + float sensitivity = (shift?0.15:0.3) * ndof->dt; + + int color_profile = but->block->color_profile; + + if (but->rnaprop) { + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) + color_profile = BLI_PR_NONE; + } + + ui_get_but_vectorf(but, rgb); + rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + + switch((int)but->a1) { + case UI_GRAD_SV: + hsv[2] += ndof->ry * sensitivity; + hsv[1] += ndof->rx * sensitivity; + break; + case UI_GRAD_HV: + hsv[0] += ndof->ry * sensitivity; + hsv[2] += ndof->rx * sensitivity; + break; + case UI_GRAD_HS: + hsv[0] += ndof->ry * sensitivity; + hsv[1] += ndof->rx * sensitivity; + break; + case UI_GRAD_H: + hsv[0] += ndof->ry * sensitivity; + break; + case UI_GRAD_S: + hsv[1] += ndof->ry * sensitivity; + break; + case UI_GRAD_V: + hsv[2] += ndof->ry * sensitivity; + break; + case UI_GRAD_V_ALT: + /* vertical 'value' strip */ + + /* exception only for value strip - use the range set in but->min/max */ + hsv[2] += ndof->rx * sensitivity; + + if (color_profile) + hsv[2] = srgb_to_linearrgb(hsv[2]); + + CLAMP(hsv[2], but->softmin, but->softmax); + default: + assert(!"invalid hsv type"); + } + + hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2); + copy_v3_v3(data->vec, rgb); + ui_set_but_vectorf(but, data->vec); +} + static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { int mx, my; @@ -3238,6 +3295,16 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_BREAK; } + else if (event->type == NDOF_MOTION) { + wmNDOFMotionData *ndof = (wmNDOFMotionData*) event->customdata; + + ui_ndofedit_but_HSVCUBE(but, data, ndof, event->shift); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + + return WM_UI_HANDLER_BREAK; + } /* XXX hardcoded keymap check.... */ else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { if (but->a1==UI_GRAD_V_ALT){ @@ -3337,11 +3404,62 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx return changed; } +static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmNDOFMotionData *ndof, int shift) +{ + float *hsv= ui_block_hsv_get(but->block); + float rgb[3]; + float phi, r, sqr, v[2]; + float sensitivity = (shift?0.15:0.3) * ndof->dt; + + ui_get_but_vectorf(but, rgb); + rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); + + /* Convert current colour on hue/sat disc to circular coordinates phi, r */ + phi = fmodf(hsv[0]+0.25, 1.0f) * -2.0f*M_PI; + r = hsv[1]; + sqr = r>0.f?sqrtf(r):1; + + /* Convert to 2d vectors */ + v[0] = r * cos(phi); + v[1] = r * sin(phi); + + /* Use ndof device y and x rotation to move the vector in 2d space */ + v[0] += ndof->ry * sensitivity; + v[1] += ndof->rx * sensitivity; + + /* convert back to polar coords on circle */ + phi = atan2(v[0], v[1])/(2.0f*(float)M_PI) + 0.5f; + + /* use ndof z rotation to additionally rotate hue */ + phi -= ndof->rz * sensitivity * 0.5; + + r = len_v2(v); + CLAMP(r, 0.0f, 1.0f); + + /* convert back to hsv values, in range [0,1] */ + hsv[0] = fmodf(phi, 1.0); + hsv[1] = r; + + /* exception, when using color wheel in 'locked' value state: + * allow choosing a hue for black values, by giving a tiny increment */ + if (but->flag & UI_BUT_COLOR_LOCK) { // lock + if (hsv[2] == 0.f) hsv[2] = 0.0001f; + } + + hsv_to_rgb(hsv[0], hsv[1], hsv[2], data->vec, data->vec+1, data->vec+2); + + if((but->flag & UI_BUT_VEC_SIZE_LOCK) && (data->vec[0] || data->vec[1] || data->vec[2])) { + normalize_v3(data->vec); + mul_v3_fl(data->vec, but->a2); + } + + ui_set_but_vectorf(but, data->vec); +} + static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) { int mx, my; - mx= event->x; my= event->y; ui_window_to_block(data->region, block, &mx, &my); @@ -3360,6 +3478,16 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_BREAK; } + else if (event->type == NDOF_MOTION) { + wmNDOFMotionData *ndof = (wmNDOFMotionData*) event->customdata; + + ui_ndofedit_but_HSVCIRCLE(but, data, ndof, event->shift); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + + return WM_UI_HANDLER_BREAK; + } /* XXX hardcoded keymap check.... */ else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { int len; From 87cd81b162912e16297eab39d58341aa99125c52 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Nov 2011 04:27:46 +0000 Subject: [PATCH 070/147] - added docs and examples for bpy.app.handlers - correct error in own last commit for BKE_screen_find_big_area() --- doc/python_api/examples/bpy.app.handlers.1.py | 20 +++ doc/python_api/examples/bpy.app.handlers.py | 12 ++ doc/python_api/sphinx_doc_gen.py | 146 +++++++++++++----- source/blender/blenkernel/intern/screen.c | 2 +- .../blender/python/intern/bpy_app_handlers.c | 24 +-- source/gameengine/Ketsji/KX_PythonInit.cpp | 2 +- 6 files changed, 153 insertions(+), 53 deletions(-) create mode 100644 doc/python_api/examples/bpy.app.handlers.1.py create mode 100644 doc/python_api/examples/bpy.app.handlers.py diff --git a/doc/python_api/examples/bpy.app.handlers.1.py b/doc/python_api/examples/bpy.app.handlers.1.py new file mode 100644 index 00000000000..a6591f6b83f --- /dev/null +++ b/doc/python_api/examples/bpy.app.handlers.1.py @@ -0,0 +1,20 @@ +""" +Persistent Handler Example +++++++++++++++++++++++++++ + +By default handlers are freed when loading new files, in some cases you may +wan't the handler stay running across multiple files (when the handler is +part of an addon for example). + +For this the :data:`bpy.app.handlers.persistent` decorator needs to be used. +""" + +import bpy +from bpy.app.handlers import persistent + + +@persistent +def load_handler(dummy): + print("Load Handler:", bpy.data.filepath) + +bpy.app.handlers.load_post.append(load_handler) diff --git a/doc/python_api/examples/bpy.app.handlers.py b/doc/python_api/examples/bpy.app.handlers.py new file mode 100644 index 00000000000..7c176063b7c --- /dev/null +++ b/doc/python_api/examples/bpy.app.handlers.py @@ -0,0 +1,12 @@ +""" +Basic Handler Example ++++++++++++++++++++++ +This script shows the most simple example of adding a handler. +""" + +import bpy + +def my_handler(scene): + print("Frame Change", scene.frame_current) + +bpy.app.handlers.frame_change_pre.append(my_handler) \ No newline at end of file diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 5843e5ddb6c..b0127c50b29 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -50,7 +50,7 @@ For PDF generation # Check we're running in blender if __import__("sys").modules.get("bpy") is None: - print("\nError, this script must run from inside blender2.5") + print("\nError, this script must run from inside blender") print(script_help_msg) import sys @@ -70,13 +70,14 @@ else: # for testing so doc-builds dont take so long. EXCLUDE_MODULES = ( "bpy.context", - "bpy.app", + #"bpy.app", + #"bpy.app.handlers", "bpy.path", "bpy.data", "bpy.props", "bpy.utils", "bpy.context", - # "bpy.types", # supports filtering + "bpy.types", # supports filtering "bpy.ops", # supports filtering "bpy_extras", "bge", @@ -109,6 +110,18 @@ INFO_DOCS = ( ("info_gotcha.rst", "Gotcha's: some of the problems you may come up against when writing scripts"), ) + +# ----------------------------------------------------------------------------- +# configure compile time options + +try: + __import__("aud") +except ImportError: + print("Warning: Built without 'aud' module, docs incomplete...") + EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", ) + + + # import rpdb2; rpdb2.start_embedded_debugger('test') import os @@ -120,6 +133,7 @@ import rna_info ClassMethodDescriptorType = type(dict.__dict__['fromkeys']) MethodDescriptorType = type(dict.get) GetSetDescriptorType = type(int.real) +from types import MemberDescriptorType EXAMPLE_SET = set() EXAMPLE_SET_USED = set() @@ -134,6 +148,14 @@ else: _BPY_PROP_COLLECTION_ID = "collection" +def is_struct_seq(value): + return isinstance(value, tuple) and type(tuple) != tuple and hasattr(value, "n_fields") + + +def module_id_as_ref(name): + return "mod_" + name.replace(".", "__") + + def undocumented_message(module_name, type_name, identifier): if str(type_name).startswith('").split(" ", 1)[-1][1:-1] # "" --> bpy.app.handlers + if type(descr) == types.GetSetDescriptorType: + py_descr2sphinx("", fw, descr, module_name, type_name, key) attribute_set.add(key) + descr_sorted = [] for key, descr in sorted(type(module).__dict__.items()): if key.startswith("__"): continue - if type(descr) == types.MemberDescriptorType: + if type(descr) == MemberDescriptorType: if descr.__doc__: - fw(".. data:: %s\n\n" % key) - write_indented_lines(" ", fw, descr.__doc__, False) - fw("\n") - attribute_set.add(key) + value = getattr(module, key, None) + value_type = type(value) + descr_sorted.append((key, descr, value, type(value))) + # sort by the valye type + descr_sorted.sort(key=lambda descr_data: str(descr_data[3])) + for key, descr, value, value_type in descr_sorted: + type_name = value_type.__name__ + py_descr2sphinx("", fw, descr, module_name, type_name, key) - del key, descr + if is_struct_seq(value): + # ack, cant use typical reference because we double up once here + # and one fort he module! + full_name = "%s.%s" % (module_name, type_name) + fw(" :ref:`%s submodule details <%s>`\n\n\n" % (full_name, module_id_as_ref(full_name))) # % (module_name, type_name) + del full_name + + attribute_set.add(key) + + del key, descr, descr_sorted classes = [] submodules = [] + # use this list so we can sort by type + module_dir_value_type = [] + for attribute in module_dir: - if not attribute.startswith("_"): - if attribute in attribute_set: - continue + if attribute.startswith("_"): + continue - if attribute.startswith("n_"): # annoying exception, needed for bpy.app - continue + if attribute in attribute_set: + continue - value = getattr(module, attribute) + if attribute.startswith("n_"): # annoying exception, needed for bpy.app + continue - value_type = type(value) + # workaround for bpy.app documenting .index() and .count() + if isinstance(module, tuple) and hasattr(tuple, attribute): + continue - if value_type == types.FunctionType: - pyfunc2sphinx("", fw, attribute, value, is_class=False) - elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof - # note: can't get args from these, so dump the string as is - # this means any module used like this must have fully formatted docstrings. - py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False) - elif value_type == type: - classes.append((attribute, value)) - elif issubclass(value_type, types.ModuleType): - submodules.append((attribute, value)) - elif value_type in (bool, int, float, str, tuple): - # constant, not much fun we can do here except to list it. - # TODO, figure out some way to document these! - fw(".. data:: %s\n\n" % attribute) - write_indented_lines(" ", fw, "constant value %s" % repr(value), False) - fw("\n") - else: - print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__)) - continue + value = getattr(module, attribute) - attribute_set.add(attribute) - # TODO, more types... + module_dir_value_type.append((attribute, value, type(value))) + + # sort by str of each type + # this way lists, functions etc are grouped. + module_dir_value_type.sort(key=lambda triple: str(triple[2])) + + for attribute, value, value_type in module_dir_value_type: + if value_type == types.FunctionType: + pyfunc2sphinx("", fw, attribute, value, is_class=False) + elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof + # note: can't get args from these, so dump the string as is + # this means any module used like this must have fully formatted docstrings. + py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False) + elif value_type == type: + classes.append((attribute, value)) + elif issubclass(value_type, types.ModuleType): + submodules.append((attribute, value)) + elif value_type in (bool, int, float, str, tuple): + # constant, not much fun we can do here except to list it. + # TODO, figure out some way to document these! + #fw(".. data:: %s\n\n" % attribute) + write_indented_lines(" ", fw, "constant value %s" % repr(value), False) + fw("\n") + else: + print("\tnot documenting %s.%s of %r type" % (module_name, attribute, value_type.__name__)) + continue + + attribute_set.add(attribute) + # TODO, more types... + del module_dir_value_type # TODO, bpy_extras does this already, mathutils not. """ @@ -1103,6 +1165,8 @@ def rna2sphinx(BASEPATH): fw(" bpy.path.rst\n\n") if "bpy.app" not in EXCLUDE_MODULES: fw(" bpy.app.rst\n\n") + if "bpy.app.handlers" not in EXCLUDE_MODULES: + fw(" bpy.app.handlers.rst\n\n") # C modules if "bpy.props" not in EXCLUDE_MODULES: @@ -1242,6 +1306,10 @@ def rna2sphinx(BASEPATH): from bpy import app as module pymodule2sphinx(BASEPATH, "bpy.app", module, "Application Data") + if "bpy.app.handlers" not in EXCLUDE_MODULES: + from bpy.app import handlers as module + pymodule2sphinx(BASEPATH, "bpy.app.handlers", module, "Application Handlers") + if "bpy.props" not in EXCLUDE_MODULES: from bpy import props as module pymodule2sphinx(BASEPATH, "bpy.props", module, "Property Definitions") diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index b7f49bbab47..3d28e45f6b7 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -361,7 +361,7 @@ struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype for(sa= sc->areabase.first; sa; sa= sa->next) { if ((spacetype == -1) || sa->spacetype == spacetype) { - if (min >= sa->winx && min >= sa->winy) { + if (min <= sa->winx && min <= sa->winy) { size= sa->winx*sa->winy; if (size > maxsize) { maxsize= size; diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 5b8c20bb12d..f130a4bcc5c 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -38,21 +38,21 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg); static PyTypeObject BlenderAppCbType; static PyStructSequence_Field app_cb_info_fields[]= { - {(char *)"frame_change_pre", NULL}, - {(char *)"frame_change_post", NULL}, - {(char *)"render_pre", NULL}, - {(char *)"render_post", NULL}, - {(char *)"render_stats", NULL}, - {(char *)"load_pre", NULL}, - {(char *)"load_post", NULL}, - {(char *)"save_pre", NULL}, - {(char *)"save_post", NULL}, - {(char *)"scene_update_pre", NULL}, - {(char *)"scene_update_post", NULL}, + {(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"}, + {(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"}, + {(char *)"render_pre", (char *)"Callback list - on render (before)"}, + {(char *)"render_post", (char *)"Callback list - on render (after)"}, + {(char *)"render_stats", (char *)"Callback list - on printing render statistics"}, + {(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"}, + {(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"}, + {(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"}, + {(char *)"save_post", (char *)"Callback list - on saving a blend file (after)"}, + {(char *)"scene_update_pre", (char *)"Callback list - on updating the scenes data (before)"}, + {(char *)"scene_update_post", (char *)"Callback list - on updating the scenes data (after)"}, /* sets the permanent tag */ # define APP_CB_OTHER_FIELDS 1 - {(char *)"persistent", NULL}, + {(char *)"persistent", (char *)"Function decorator for callback functions not to be removed when loading new files"}, {NULL} }; diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index c3a141e7405..02e6ebea71b 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -815,7 +815,7 @@ static struct PyMethodDef game_methods[] = { {"getAverageFrameRate", (PyCFunction) gPyGetAverageFrameRate, METH_NOARGS, (const char *)"Gets the estimated average frame rate"}, {"getBlendFileList", (PyCFunction)gPyGetBlendFileList, METH_VARARGS, (const char *)"Gets a list of blend files in the same directory as the current blend file"}, {"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"}, - {"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine stastics"}, + {"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine statistics"}, /* library functions */ {"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""}, From dbc5941caedf4b400b6a65a69e9f4aee1713fe16 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Nov 2011 08:06:46 +0000 Subject: [PATCH 071/147] Bugfix [#28515] Dupliframes start/end animation broken since 2.56A Due to changes with the way that dupliframes were being evaluated (one of those being that the animation for the object being animated would get reevaluated for every frame sample for dupliframes) to get them working properly again sometime during the 2.5 series, the dupliframe- sampling loop would be prematurely terminated on the first frame in this example. That is because after the first step of the loop, the ob->dupend property would have changed its value as it was being animated, leading to the loop terminating, and only the a single dupli getting added. --- source/blender/blenkernel/intern/anim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 2ef13318af4..f939c168f51 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -753,6 +753,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, extern int enable_cu_speed; /* object.c */ Object copyob = {{NULL}}; int cfrao = scene->r.cfra; + int dupend = ob->dupend; /* simple prevention of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; @@ -773,7 +774,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, /* duplicate over the required range */ if (ob->transflag & OB_DUPLINOSPEED) enable_cu_speed= 0; - for (scene->r.cfra= ob->dupsta; scene->r.cfra<=ob->dupend; scene->r.cfra++) { + for (scene->r.cfra= ob->dupsta; scene->r.cfra<=dupend; scene->r.cfra++) { short ok= 1; /* - dupoff = how often a frames within the range shouldn't be made into duplis From 371705951122f16a3d551e35d092d06b126fac4c Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Fri, 4 Nov 2011 08:08:47 +0000 Subject: [PATCH 072/147] Comments and other text editing: * Renamed one of the two "File is Saved" entries, as having two entries with the same name in the Datablocks viewer was confusing * Edited the tooltip text for "speed" option for dupliframes to clarify what it does (or what it's supposed to do) --- source/blender/blenkernel/intern/constraint.c | 3 ++- source/blender/makesrna/intern/rna_main.c | 2 +- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/nodes/composite/nodes/node_composite_rotate.c | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index d6d4e8304ba..8b5cf3bd196 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -447,7 +447,8 @@ static void contarget_get_mesh_mat (Object *ob, const char *substring, float mat } else { /* when not in EditMode, use the 'final' derived mesh, depsgraph - * ensures we build with CD_MDEFORMVERT layer */ + * ensures we build with CD_MDEFORMVERT layer + */ dm = (DerivedMesh *)ob->derivedFinal; } diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 92c84da165b..076bdfe1964 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -324,7 +324,7 @@ void RNA_def_main(BlenderRNA *brna) prop= RNA_def_property(srna, "is_dirty", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Main_is_dirty_get", NULL); - RNA_def_property_ui_text(prop, "File is Saved", "Have recent edits been saved to disk"); + RNA_def_property_ui_text(prop, "File Has Unsaved Changes", "Have recent edits been saved to disk"); prop= RNA_def_property(srna, "is_saved", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 0fa63671951..bc050f3a902 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2226,7 +2226,7 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "use_dupli_frames_speed", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "transflag", OB_DUPLINOSPEED); - RNA_def_property_ui_text(prop, "Dupli Frames Speed", "Set dupliframes to use the frame"); // TODO, better descriptio! + RNA_def_property_ui_text(prop, "Dupli Frames Speed", "Set dupliframes to use the current frame instead of parent curve's evaluation time"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_internal_update"); prop= RNA_def_property(srna, "use_dupli_vertices_rotation", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c index 74ab33eb093..58e17cab3a8 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rotate.c +++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c @@ -60,6 +60,7 @@ static void node_composit_exec_rotate(void *UNUSED(data), bNode *node, bNodeStac rad= (M_PI*in[1]->vec[0])/180.0f; + s= sin(rad); c= cos(rad); centx= cbuf->x/2; From 2d09bf85aff5783bc6284bc58f40acd64362f81e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Nov 2011 09:14:49 +0000 Subject: [PATCH 073/147] cleanup some BLF macros and dont over-alloc BGE's PyObjectPlus when setting strings (better change then the one I made recently). --- source/blender/blenfont/intern/blf_font.c | 35 ++++++++++--------- .../gameengine/Expressions/PyObjectPlus.cpp | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index bebc87cc5d4..7ec7e2357dd 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -122,36 +122,37 @@ static void blf_font_ensure_ascii_table(FontBLF *font) /* Note, * blf_font_ensure_ascii_table(font); must be called before this macro */ -#define BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table) \ - if(((c)= (str)[i]) < 0x80) { \ - g= (glyph_ascii_table)[c]; \ - i++; \ +#define BLF_UTF8_NEXT_FAST(_font, _g, _str, _i, _c, _glyph_ascii_table) \ + if(((_c)= (_str)[_i]) < 0x80) { \ + _g= (_glyph_ascii_table)[_c]; \ + _i++; \ } \ - else if ((c= BLI_str_utf8_as_unicode_step((str), &(i))) != BLI_UTF8_ERR) { \ - if ((g= blf_glyph_search((font)->glyph_cache, c)) == NULL) { \ - g= blf_glyph_add(font, FT_Get_Char_Index((font)->face, c), c); \ + else if ((_c= BLI_str_utf8_as_unicode_step(_str, &(_i)))!=BLI_UTF8_ERR) { \ + if ((_g= blf_glyph_search((_font)->glyph_cache, _c)) == NULL) { \ + _g= blf_glyph_add(_font, \ + FT_Get_Char_Index((_font)->face, _c), _c); \ } \ } \ #define BLF_KERNING_VARS(_font, _has_kerning, _kern_mode) \ - const short has_kerning= FT_HAS_KERNING((_font)->face); \ - const FT_UInt kern_mode= (has_kerning == 0) ? 0 : \ + const short _has_kerning= FT_HAS_KERNING((_font)->face); \ + const FT_UInt _kern_mode= (_has_kerning == 0) ? 0 : \ (((_font)->flags & BLF_KERNING_DEFAULT) ? \ ft_kerning_default : FT_KERNING_UNFITTED) \ -#define BLF_KERNING_STEP(_font, kern_mode, g_prev, g, delta, pen_x) \ +#define BLF_KERNING_STEP(_font, _kern_mode, _g_prev, _g, _delta, _pen_x) \ { \ - if (g_prev) { \ - delta.x= delta.y= 0; \ + if (_g_prev) { \ + _delta.x= _delta.y= 0; \ if (FT_Get_Kerning((_font)->face, \ - (g_prev)->idx, \ - (g)->idx, \ - kern_mode, \ - &(delta)) == 0) \ + (_g_prev)->idx, \ + (_g)->idx, \ + _kern_mode, \ + &(_delta)) == 0) \ { \ - pen_x += delta.x >> 6; \ + _pen_x += delta.x >> 6; \ } \ } \ } \ diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index b05b7be0877..87f776a726e 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -1042,8 +1042,8 @@ int PyObjectPlus::py_set_attrdef(PyObject *self_py, PyObject *value, const PyAtt else if (val_len > attrdef->m_imax) { // trim the string - *var = val; var->SetLength(attrdef->m_imax); + memcpy(var->Ptr(), val, attrdef->m_imax - 1); break; } } else if (val_len < attrdef->m_imin || val_len > attrdef->m_imax) From 936178d10ff37e3dc1e0ff0ee260be8647e2970a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 09:29:58 +0000 Subject: [PATCH 074/147] Do not run versioning code for new files. All stuff from current verisoning block was written before 2.60 release, so it should be safe to move it into if'ed block checking version number. This patch should also fix bug #29147 which was caused by old->new particle rotation mode switch. --- source/blender/blenloader/intern/readfile.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 15f5b49dd24..8427f7c326a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12121,8 +12121,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } - /* put compatibility code here until next subversion bump */ - { + if (main->versionfile < 260){ { /* set default alpha value of Image outputs in image and render layer nodes to 0 */ Scene *sce; @@ -12157,6 +12156,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* put compatibility code here until next subversion bump */ + { + + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ From 298790850c44ba4381191bce208650c0522efbfb Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 11:37:13 +0000 Subject: [PATCH 075/147] Fix #29051: Set Origin - Center: Bounds does not work Operator sued to check incorrect property to check initialization. Patch by Kalle-Samuli Riihikoski, thanks! --- source/blender/editors/object/object_transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 1efe79fff9e..a82ed95079f 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -645,7 +645,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* get the view settings if 'around' isnt set and the view is available */ View3D *v3d= CTX_wm_view3d(C); copy_v3_v3(cursor, give_cursor(scene, v3d)); - if(v3d && !RNA_property_is_set(op->ptr, "around")) + if(v3d && !RNA_property_is_set(op->ptr, "center")) around= v3d->around; } From 2e1b935e2bccb432142022eff76a3c2bf7a2bd10 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 12:50:29 +0000 Subject: [PATCH 076/147] Changes to node sockets default values to deal better with artists workflow (in most cases it needed to do extra tweaks to values which was annoying). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Sebastian König. --- .../nodes/composite/nodes/node_composite_alphaOver.c | 4 ++-- .../nodes/composite/nodes/node_composite_bilateralblur.c | 4 ++-- .../blender/nodes/composite/nodes/node_composite_blur.c | 2 +- .../nodes/composite/nodes/node_composite_brightness.c | 2 +- .../nodes/composite/nodes/node_composite_channelMatte.c | 2 +- .../nodes/composite/nodes/node_composite_chromaMatte.c | 4 ++-- .../nodes/composite/nodes/node_composite_colorMatte.c | 4 ++-- .../nodes/composite/nodes/node_composite_colorSpill.c | 2 +- .../nodes/composite/nodes/node_composite_colorbalance.c | 2 +- .../blender/nodes/composite/nodes/node_composite_crop.c | 2 +- .../blender/nodes/composite/nodes/node_composite_curves.c | 2 +- .../nodes/composite/nodes/node_composite_defocus.c | 4 ++-- .../nodes/composite/nodes/node_composite_diffMatte.c | 4 ++-- .../composite/nodes/node_composite_directionalblur.c | 2 +- .../nodes/composite/nodes/node_composite_displace.c | 2 +- .../nodes/composite/nodes/node_composite_distanceMatte.c | 4 ++-- .../blender/nodes/composite/nodes/node_composite_filter.c | 4 ++-- .../blender/nodes/composite/nodes/node_composite_flip.c | 2 +- .../blender/nodes/composite/nodes/node_composite_gamma.c | 2 +- .../blender/nodes/composite/nodes/node_composite_glare.c | 2 +- .../nodes/composite/nodes/node_composite_hueSatVal.c | 2 +- .../nodes/composite/nodes/node_composite_huecorrect.c | 2 +- .../blender/nodes/composite/nodes/node_composite_idMask.c | 2 +- .../blender/nodes/composite/nodes/node_composite_invert.c | 2 +- .../nodes/composite/nodes/node_composite_lensdist.c | 2 +- .../nodes/composite/nodes/node_composite_lummaMatte.c | 2 +- .../blender/nodes/composite/nodes/node_composite_mapUV.c | 2 +- .../nodes/composite/nodes/node_composite_mapValue.c | 2 +- .../nodes/composite/nodes/node_composite_normalize.c | 2 +- .../nodes/composite/nodes/node_composite_premulkey.c | 2 +- source/blender/nodes/composite/nodes/node_composite_rgb.c | 2 +- .../blender/nodes/composite/nodes/node_composite_rotate.c | 2 +- .../blender/nodes/composite/nodes/node_composite_scale.c | 2 +- .../nodes/composite/nodes/node_composite_sepcombHSVA.c | 2 +- .../nodes/composite/nodes/node_composite_sepcombRGBA.c | 2 +- .../nodes/composite/nodes/node_composite_sepcombYCCA.c | 2 +- .../nodes/composite/nodes/node_composite_sepcombYUVA.c | 2 +- .../nodes/composite/nodes/node_composite_tonemap.c | 2 +- .../nodes/composite/nodes/node_composite_translate.c | 2 +- .../nodes/composite/nodes/node_composite_vecBlur.c | 2 +- .../nodes/composite/nodes/node_composite_zcombine.c | 8 ++++---- 41 files changed, 52 insertions(+), 52 deletions(-) diff --git a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c index d9774453d3e..b542954948a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c +++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c @@ -35,8 +35,8 @@ /* **************** ALPHAOVER ******************** */ static bNodeSocketTemplate cmp_node_alphaover_in[]= { { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_alphaover_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c index fe04e69993f..166eae9d1bc 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c @@ -33,8 +33,8 @@ /* **************** BILATERALBLUR ******************** */ static bNodeSocketTemplate cmp_node_bilateralblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, - { SOCK_RGBA, 1, "Determinator", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_RGBA, 1, "Determinator", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c index 2db80385951..188ac653506 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -35,7 +35,7 @@ /* **************** BLUR ******************** */ static bNodeSocketTemplate cmp_node_blur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Size", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_brightness.c b/source/blender/nodes/composite/nodes/node_composite_brightness.c index 95099e7adfb..9153e3899fc 100644 --- a/source/blender/nodes/composite/nodes/node_composite_brightness.c +++ b/source/blender/nodes/composite/nodes/node_composite_brightness.c @@ -37,7 +37,7 @@ /* **************** Brigh and contrsast ******************** */ static bNodeSocketTemplate cmp_node_brightcontrast_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Bright", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, { SOCK_FLOAT, 1, "Contrast", 0.0f, 0.0f, 0.0f, 0.0f, -100.0f, 100.0f, PROP_NONE}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_channelMatte.c b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c index dbdfc6712dc..10f0afb6cf6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_channelMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_channelMatte.c @@ -35,7 +35,7 @@ /* ******************* Channel Matte Node ********************************* */ static bNodeSocketTemplate cmp_node_channel_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c index 71bb7c35d01..25891aeaa68 100644 --- a/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_chromaMatte.c @@ -34,8 +34,8 @@ /* ******************* Chroma Key ********************************************************** */ static bNodeSocketTemplate cmp_node_chroma_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c index a82d8cf1f41..3dfc3a193a8 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c @@ -34,8 +34,8 @@ /* ******************* Color Key ********************************************************** */ static bNodeSocketTemplate cmp_node_color_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c index 6b833d44f72..c85a81b9bdb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c @@ -37,7 +37,7 @@ /* ******************* Color Spill Supression ********************************* */ static bNodeSocketTemplate cmp_node_color_spill_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, {SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c index e9176db4c0d..eb75802c0a6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorbalance.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorbalance.c @@ -37,7 +37,7 @@ /* ******************* Color Balance ********************************* */ static bNodeSocketTemplate cmp_node_colorbalance_in[]={ {SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_crop.c b/source/blender/nodes/composite/nodes/node_composite_crop.c index c20593726cc..7847726c68e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_crop.c +++ b/source/blender/nodes/composite/nodes/node_composite_crop.c @@ -35,7 +35,7 @@ /* **************** Crop ******************** */ static bNodeSocketTemplate cmp_node_crop_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_crop_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_curves.c b/source/blender/nodes/composite/nodes/node_composite_curves.c index c796a01f5a8..675710942fb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_curves.c +++ b/source/blender/nodes/composite/nodes/node_composite_curves.c @@ -121,7 +121,7 @@ void register_node_type_cmp_curve_vec(ListBase *lb) /* **************** CURVE RGB ******************** */ static bNodeSocketTemplate cmp_node_curve_rgb_in[]= { { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_RGBA, 1, "Black Level", 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_RGBA, 1, "White Level", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index 72a9897188c..2232c4a489e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -34,8 +34,8 @@ /* ************ qdn: Defocus node ****************** */ static bNodeSocketTemplate cmp_node_defocus_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, - { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_defocus_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c index 8b1647414da..c621d524044 100644 --- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c @@ -34,8 +34,8 @@ /* ******************* channel Difference Matte ********************************* */ static bNodeSocketTemplate cmp_node_diff_matte_in[]={ - {SOCK_RGBA,1,"Image 1", 0.8f, 0.8f, 0.8f, 1.0f}, - {SOCK_RGBA,1,"Image 2", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image 1", 1.0f, 1.0f, 1.0f, 1.0f}, + {SOCK_RGBA,1,"Image 2", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c index c77dc16bbf3..591870d0911 100644 --- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c @@ -33,7 +33,7 @@ #include "node_composite_util.h" static bNodeSocketTemplate cmp_node_dblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_displace.c b/source/blender/nodes/composite/nodes/node_composite_displace.c index 8242acb6d49..02a1d203bef 100644 --- a/source/blender/nodes/composite/nodes/node_composite_displace.c +++ b/source/blender/nodes/composite/nodes/node_composite_displace.c @@ -36,7 +36,7 @@ /* **************** Displace ******************** */ static bNodeSocketTemplate cmp_node_displace_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_VECTOR, 1, "Vector", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_TRANSLATION}, { SOCK_FLOAT, 1, "X Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, "Y Scale", 0.0f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f, PROP_FACTOR}, diff --git a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c index c4c6abbd718..401b143aac3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c @@ -34,8 +34,8 @@ /* ******************* channel Distance Matte ********************************* */ static bNodeSocketTemplate cmp_node_distance_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, - {SOCK_RGBA,1,"Key Color", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, + {SOCK_RGBA,1,"Key Color", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.c b/source/blender/nodes/composite/nodes/node_composite_filter.c index 717942a0ec9..071ee84377c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_filter.c +++ b/source/blender/nodes/composite/nodes/node_composite_filter.c @@ -34,8 +34,8 @@ /* **************** FILTER ******************** */ static bNodeSocketTemplate cmp_node_filter_in[]= { - { SOCK_FLOAT, 1, "Fac", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_FLOAT, 1, "Fac", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_filter_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_flip.c b/source/blender/nodes/composite/nodes/node_composite_flip.c index ba1b72a1fb4..01f58182227 100644 --- a/source/blender/nodes/composite/nodes/node_composite_flip.c +++ b/source/blender/nodes/composite/nodes/node_composite_flip.c @@ -34,7 +34,7 @@ /* **************** Flip ******************** */ static bNodeSocketTemplate cmp_node_flip_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_gamma.c b/source/blender/nodes/composite/nodes/node_composite_gamma.c index 1f8f934b1ba..2bb600db99d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_gamma.c +++ b/source/blender/nodes/composite/nodes/node_composite_gamma.c @@ -36,7 +36,7 @@ /* **************** Gamma Tools ******************** */ static bNodeSocketTemplate cmp_node_gamma_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Gamma", 1.0f, 0.0f, 0.0f, 0.0f, 0.001f, 10.0f, PROP_UNSIGNED}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.c b/source/blender/nodes/composite/nodes/node_composite_glare.c index 8660a4d612f..f4391a1af77 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.c +++ b/source/blender/nodes/composite/nodes/node_composite_glare.c @@ -33,7 +33,7 @@ #include "node_composite_util.h" static bNodeSocketTemplate cmp_node_glare_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_glare_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c index a1c17abfdf6..c2304b37c0d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c +++ b/source/blender/nodes/composite/nodes/node_composite_hueSatVal.c @@ -36,7 +36,7 @@ /* **************** Hue Saturation ******************** */ static bNodeSocketTemplate cmp_node_hue_sat_in[]= { { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_hue_sat_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c index 6b9196d58dc..f18eca3dfcc 100644 --- a/source/blender/nodes/composite/nodes/node_composite_huecorrect.c +++ b/source/blender/nodes/composite/nodes/node_composite_huecorrect.c @@ -34,7 +34,7 @@ static bNodeSocketTemplate cmp_node_huecorrect_in[]= { { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Image", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_idMask.c b/source/blender/nodes/composite/nodes/node_composite_idMask.c index cf21efb000e..914483bc52f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_idMask.c +++ b/source/blender/nodes/composite/nodes/node_composite_idMask.c @@ -36,7 +36,7 @@ /* **************** ID Mask ******************** */ static bNodeSocketTemplate cmp_node_idmask_in[]= { - { SOCK_FLOAT, 1, "ID value", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "ID value", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_idmask_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_invert.c b/source/blender/nodes/composite/nodes/node_composite_invert.c index 25ac24cf185..c428e37bd35 100644 --- a/source/blender/nodes/composite/nodes/node_composite_invert.c +++ b/source/blender/nodes/composite/nodes/node_composite_invert.c @@ -34,7 +34,7 @@ /* **************** INVERT ******************** */ static bNodeSocketTemplate cmp_node_invert_in[]= { { SOCK_FLOAT, 1, "Fac", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, - { SOCK_RGBA, 1, "Color", 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_RGBA, 1, "Color", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.c b/source/blender/nodes/composite/nodes/node_composite_lensdist.c index 4d2794d844d..e57f405ed68 100644 --- a/source/blender/nodes/composite/nodes/node_composite_lensdist.c +++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.c @@ -33,7 +33,7 @@ #include "node_composite_util.h" static bNodeSocketTemplate cmp_node_lensdist_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Distort", 0.f, 0.f, 0.f, 0.f, -0.999f, 1.f, PROP_NONE}, { SOCK_FLOAT, 1, "Dispersion", 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, PROP_NONE}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c index 8c37b3dd90f..8573849b069 100644 --- a/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_lummaMatte.c @@ -35,7 +35,7 @@ /* ******************* Luma Matte Node ********************************* */ static bNodeSocketTemplate cmp_node_luma_matte_in[]={ - {SOCK_RGBA,1,"Image", 0.8f, 0.8f, 0.8f, 1.0f}, + {SOCK_RGBA,1,"Image", 1.0f, 1.0f, 1.0f, 1.0f}, {-1,0,""} }; diff --git a/source/blender/nodes/composite/nodes/node_composite_mapUV.c b/source/blender/nodes/composite/nodes/node_composite_mapUV.c index f4daf49f55d..5dc6d1c3aaa 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mapUV.c +++ b/source/blender/nodes/composite/nodes/node_composite_mapUV.c @@ -35,7 +35,7 @@ /* **************** Map UV ******************** */ static bNodeSocketTemplate cmp_node_mapuv_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_VECTOR, 1, "UV", 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c index 30eb0b8640b..81e963d4790 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mapValue.c +++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c @@ -34,7 +34,7 @@ /* **************** MAP VALUE ******************** */ static bNodeSocketTemplate cmp_node_map_value_in[]= { - { SOCK_FLOAT, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Value", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_map_value_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c index a119a0b7de3..36206d82d0b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normalize.c +++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c @@ -35,7 +35,7 @@ /* **************** NORMALIZE single channel, useful for Z buffer ******************** */ static bNodeSocketTemplate cmp_node_normalize_in[]= { - { SOCK_FLOAT, 1, "Value", 1.0f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f, PROP_NONE}, + { SOCK_FLOAT, 1, "Value", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, PROP_NONE}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_normalize_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_premulkey.c b/source/blender/nodes/composite/nodes/node_composite_premulkey.c index 7ce2f80e580..b188b0dd323 100644 --- a/source/blender/nodes/composite/nodes/node_composite_premulkey.c +++ b/source/blender/nodes/composite/nodes/node_composite_premulkey.c @@ -36,7 +36,7 @@ /* **************** Premul and Key Alpha Convert ******************** */ static bNodeSocketTemplate cmp_node_premulkey_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_premulkey_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_rgb.c b/source/blender/nodes/composite/nodes/node_composite_rgb.c index e86de3c7839..a7c820ddce6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_rgb.c @@ -35,7 +35,7 @@ /* **************** RGB ******************** */ static bNodeSocketTemplate cmp_node_rgb_out[]= { - { SOCK_RGBA, 0, "RGBA", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 0, "RGBA", 0.5f, 0.5f, 0.5f, 1.0f}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_rotate.c b/source/blender/nodes/composite/nodes/node_composite_rotate.c index 58e17cab3a8..96712baf8b0 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rotate.c +++ b/source/blender/nodes/composite/nodes/node_composite_rotate.c @@ -35,7 +35,7 @@ /* **************** Rotate ******************** */ static bNodeSocketTemplate cmp_node_rotate_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Degr", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_ANGLE}, { -1, 0, "" } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 48631a18dcb..5eb789ae0c9 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -37,7 +37,7 @@ #define CMP_SCALE_MAX 12000 static bNodeSocketTemplate cmp_node_scale_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, { SOCK_FLOAT, 1, "Y", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c index 4a5036a6a7f..bf58d443aec 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombHSVA.c @@ -35,7 +35,7 @@ /* **************** SEPARATE HSVA ******************** */ static bNodeSocketTemplate cmp_node_sephsva_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_sephsva_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c index 143c67d099a..ade2b22bf35 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombRGBA.c @@ -34,7 +34,7 @@ /* **************** SEPARATE RGBA ******************** */ static bNodeSocketTemplate cmp_node_seprgba_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_seprgba_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c index 502d1999101..3b3d57bf442 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYCCA.c @@ -35,7 +35,7 @@ /* **************** SEPARATE YCCA ******************** */ static bNodeSocketTemplate cmp_node_sepycca_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_sepycca_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c index 5a766df29ed..aedb5652e61 100644 --- a/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c +++ b/source/blender/nodes/composite/nodes/node_composite_sepcombYUVA.c @@ -35,7 +35,7 @@ /* **************** SEPARATE YUVA ******************** */ static bNodeSocketTemplate cmp_node_sepyuva_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_sepyuva_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.c b/source/blender/nodes/composite/nodes/node_composite_tonemap.c index c243c104774..36e583a77ff 100644 --- a/source/blender/nodes/composite/nodes/node_composite_tonemap.c +++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.c @@ -33,7 +33,7 @@ #include "node_composite_util.h" static bNodeSocketTemplate cmp_node_tonemap_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_tonemap_out[]= { diff --git a/source/blender/nodes/composite/nodes/node_composite_translate.c b/source/blender/nodes/composite/nodes/node_composite_translate.c index 1865d6fc3d4..2b25ef92a1e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_translate.c +++ b/source/blender/nodes/composite/nodes/node_composite_translate.c @@ -36,7 +36,7 @@ /* **************** Translate ******************** */ static bNodeSocketTemplate cmp_node_translate_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_NONE}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c index cdf56c230d8..a0fbcec198a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_vecBlur.c +++ b/source/blender/nodes/composite/nodes/node_composite_vecBlur.c @@ -35,7 +35,7 @@ /* **************** VECTOR BLUR ******************** */ static bNodeSocketTemplate cmp_node_vecblur_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "Z", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, { SOCK_VECTOR, 1, "Speed", 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_VELOCITY}, { -1, 0, "" } diff --git a/source/blender/nodes/composite/nodes/node_composite_zcombine.c b/source/blender/nodes/composite/nodes/node_composite_zcombine.c index 46a66957eac..7aac3539960 100644 --- a/source/blender/nodes/composite/nodes/node_composite_zcombine.c +++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.c @@ -36,10 +36,10 @@ /* **************** Z COMBINE ******************** */ /* lazy coder note: node->custom2 is abused to send signal */ static bNodeSocketTemplate cmp_node_zcombine_in[]= { - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, - { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, - { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f}, - { SOCK_FLOAT, 1, "Z", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, + { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, + { SOCK_FLOAT, 1, "Z", 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 10000.0f, PROP_NONE}, { -1, 0, "" } }; static bNodeSocketTemplate cmp_node_zcombine_out[]= { From 90acd1d0fc7716d6b8db1ae58304b930a84a701f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Nov 2011 12:53:46 +0000 Subject: [PATCH 077/147] Fix #29146: object used for particle instancing did not update when affected by an object on a hidden layer. Dependency was set in the wrong direction. --- source/blender/blenkernel/intern/depsgraph.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 9d51571346f..286854f345c 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -591,9 +591,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if(part->ren_as == PART_DRAW_OB && part->dup_ob) { node2 = dag_get_node(dag, part->dup_ob); - dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualisation"); + dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Object Visualisation"); if(part->dup_ob->type == OB_MBALL) - dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualisation"); + dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Object Visualisation"); } if(part->ren_as == PART_DRAW_GR && part->dup_group) { From 21d188a70f48ef156f8543b5d9191196a95d7966 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Nov 2011 13:17:35 +0000 Subject: [PATCH 078/147] Depsgraph: add "Dependency Relations" operator to print the dependency graph to the console, useful for debugging and understanding the relations. --- source/blender/blenkernel/BKE_depsgraph.h | 3 +++ source/blender/blenkernel/intern/depsgraph.c | 25 +++++++++++++++++-- .../windowmanager/intern/wm_operators.c | 23 +++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 0b0637fb42a..e0b8e40d731 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -133,6 +133,9 @@ void DAG_pose_sort(struct Object *ob); /* callback for editors module to do updates */ void DAG_editors_update_cb(void (*func)(struct Main *bmain, struct ID *id)); + /* debugging */ +void DAG_print_dependencies(struct Main *bmain, struct Scene *scene, struct Object *ob); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 286854f345c..51edee9ea71 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -799,6 +799,7 @@ DagNode * dag_find_node (DagForest *forest,void * fob) } static int ugly_hack_sorry= 1; // prevent type check +static int dag_print_dependencies= 0; // debugging /* no checking of existence, use dag_find_node first or dag_get_node */ DagNode * dag_add_node (DagForest *forest, void * fob) @@ -926,7 +927,6 @@ static const char *dag_node_name(DagNode *node) return ((bPoseChannel*)(node->ob))->name; } -#if 0 static void dag_node_print_dependencies(DagNode *node) { DagAdjList *itA; @@ -937,7 +937,6 @@ static void dag_node_print_dependencies(DagNode *node) printf(" %s through %s\n", dag_node_name(itA->node), itA->name); printf("\n"); } -#endif static int dag_node_print_dependency_recurs(DagNode *node, DagNode *endnode) { @@ -998,6 +997,11 @@ static void dag_check_cycle(DagForest *dag) DagNode *node; DagAdjList *itA; + /* debugging print */ + if(dag_print_dependencies) + for(node = dag->DagNode.first; node; node= node->next) + dag_node_print_dependencies(node); + /* tag nodes unchecked */ for(node = dag->DagNode.first; node; node= node->next) node->color= DAG_WHITE; @@ -2834,5 +2838,22 @@ void DAG_pose_sort(Object *ob) ugly_hack_sorry= 1; } +/* ************************ DAG DEBUGGING ********************* */ +void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob) +{ + /* utility for debugging dependencies */ + dag_print_dependencies= 1; + + if(ob && (ob->mode & OB_MODE_POSE)) { + printf("\nDEPENDENCY RELATIONS for %s\n\n", ob->id.name+2); + DAG_pose_sort(ob); + } + else { + printf("\nDEPENDENCY RELATIONS for %s\n\n", scene->id.name+2); + DAG_scene_sort(bmain, scene); + } + + dag_print_dependencies= 0; +} diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index acd5df79982..933066513e2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3450,6 +3450,28 @@ static void WM_OT_memory_statistics(wmOperatorType *ot) ot->exec= memory_statistics_exec; } +/* ************************** memory statistics for testing ***************** */ + +static int dependency_relations_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Object *ob= CTX_data_active_object(C); + + DAG_print_dependencies(bmain, scene, ob); + + return OPERATOR_FINISHED; +} + +static void WM_OT_dependency_relations(wmOperatorType *ot) +{ + ot->name= "Dependency Relations"; + ot->idname= "WM_OT_dependency_relations"; + ot->description= "Print dependency graph relations to the console"; + + ot->exec= dependency_relations_exec; +} + /* ******************************************************* */ static int wm_ndof_sensitivity_exec(bContext *UNUSED(C), wmOperator *op) @@ -3532,6 +3554,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_save_mainfile); WM_operatortype_append(WM_OT_redraw_timer); WM_operatortype_append(WM_OT_memory_statistics); + WM_operatortype_append(WM_OT_dependency_relations); WM_operatortype_append(WM_OT_debug_menu); WM_operatortype_append(WM_OT_splash); WM_operatortype_append(WM_OT_search_menu); From 82dc05391cdda573f1523325bfd4c6a2a5233323 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 13:31:15 +0000 Subject: [PATCH 079/147] Fix #29139: Comp Group nodes don't retain name Added tree node id browser to Active Node panel so name of nodetree editing in group node can be easily changed now. --- source/blender/editors/space_node/drawnode.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 7a9cf644b55..db8d9b1ddf1 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -842,6 +842,11 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN } } +void node_uifunc_group(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateIDBrowse(layout, C, ptr, "node_tree", NULL, NULL, NULL); +} + static void node_common_buts_whileloop(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { uiItemR(layout, ptr, "max_iterations", 0, NULL, 0); @@ -867,7 +872,7 @@ static void node_common_set_butfunc(bNodeType *ntype) { switch(ntype->type) { case NODE_GROUP: -// ntype->uifunc= node_common_buts_group; + ntype->uifunc= node_uifunc_group; ntype->drawfunc= node_draw_group; ntype->drawupdatefunc= node_update_group; break; From 4ea816837de646af124ffc82758cae37950a0a51 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 14:36:06 +0000 Subject: [PATCH 080/147] Configurable sensor size: - Added support of variable size sensor width and height. - Added presets for most common cameras, also new presets can be defined by user. - Added option to control which dimension (vertical or horizontal) of sensor size defines FOV. Old behavior of automatic FOV calculation is also kept. - Renderer, viewport, game engine and collada importer/exporter should deal fine with this changes. Other exporters would be updated soon. --- release/scripts/presets/camera/APS-C_DSLR.py | 4 + release/scripts/presets/camera/Blender.py | 4 + release/scripts/presets/camera/Canon_1100D.py | 4 + release/scripts/presets/camera/Canon_1D.py | 4 + release/scripts/presets/camera/Canon_1DS.py | 4 + release/scripts/presets/camera/Canon_500D.py | 4 + release/scripts/presets/camera/Canon_550D.py | 4 + release/scripts/presets/camera/Canon_5D.py | 4 + release/scripts/presets/camera/Canon_600D.py | 4 + release/scripts/presets/camera/Canon_60D.py | 4 + release/scripts/presets/camera/Canon_7D.py | 4 + release/scripts/presets/camera/Nikon_D300S.py | 4 + release/scripts/presets/camera/Nikon_D3100.py | 4 + release/scripts/presets/camera/Nikon_D35.py | 4 + release/scripts/presets/camera/Nikon_D5000.py | 4 + release/scripts/presets/camera/Nikon_D5100.py | 4 + release/scripts/presets/camera/Nikon_D7000.py | 4 + release/scripts/presets/camera/Nikon_D90.py | 4 + release/scripts/presets/camera/Red_Epic.py | 4 + release/scripts/presets/camera/Red_One_2K.py | 4 + release/scripts/presets/camera/Red_One_3K.py | 4 + release/scripts/presets/camera/Red_One_4K.py | 4 + .../presets/camera/full_frame_35mm_film.py | 4 + .../presets/camera/micro_four_thirds.py | 4 + .../scripts/presets/camera/super_16_film.py | 4 + .../scripts/presets/camera/super_35_film.py | 4 + .../scripts/startup/bl_operators/presets.py | 19 +++ .../startup/bl_ui/properties_data_camera.py | 71 +++++++--- source/blender/blenkernel/BKE_object.h | 5 +- source/blender/blenkernel/intern/object.c | 104 +++++++++++---- source/blender/blenlib/BLI_math_rotation.h | 4 +- source/blender/blenlib/intern/math_rotation.c | 8 +- source/blender/blenlib/intern/uvproject.c | 2 +- source/blender/blenloader/intern/readfile.c | 12 +- source/blender/collada/CameraExporter.cpp | 2 +- source/blender/collada/DocumentImporter.cpp | 6 +- .../editors/sculpt_paint/paint_image.c | 6 +- .../editors/space_view3d/view3d_draw.c | 63 +++++++-- .../editors/space_view3d/view3d_edit.c | 9 +- .../editors/space_view3d/view3d_intern.h | 2 +- .../editors/space_view3d/view3d_view.c | 65 ++++++++-- source/blender/makesdna/DNA_camera_types.h | 12 ++ source/blender/makesrna/intern/rna_camera.c | 122 +++++++++++++++--- .../blender/modifiers/intern/MOD_uvproject.c | 21 ++- .../render/intern/include/render_types.h | 2 + source/blender/render/intern/source/envmap.c | 1 + .../blender/render/intern/source/initrender.c | 2 +- .../Converter/BL_BlenderDataConversion.cpp | 2 +- source/gameengine/Ketsji/KX_Camera.cpp | 19 +++ source/gameengine/Ketsji/KX_Camera.h | 6 + source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 4 + source/gameengine/Rasterizer/RAS_CameraData.h | 9 +- .../Rasterizer/RAS_FramingManager.cpp | 59 ++++++--- .../Rasterizer/RAS_FramingManager.h | 13 ++ .../gameengine/VideoTexture/ImageRender.cpp | 6 + 55 files changed, 634 insertions(+), 126 deletions(-) create mode 100644 release/scripts/presets/camera/APS-C_DSLR.py create mode 100644 release/scripts/presets/camera/Blender.py create mode 100644 release/scripts/presets/camera/Canon_1100D.py create mode 100644 release/scripts/presets/camera/Canon_1D.py create mode 100644 release/scripts/presets/camera/Canon_1DS.py create mode 100644 release/scripts/presets/camera/Canon_500D.py create mode 100644 release/scripts/presets/camera/Canon_550D.py create mode 100644 release/scripts/presets/camera/Canon_5D.py create mode 100644 release/scripts/presets/camera/Canon_600D.py create mode 100644 release/scripts/presets/camera/Canon_60D.py create mode 100644 release/scripts/presets/camera/Canon_7D.py create mode 100644 release/scripts/presets/camera/Nikon_D300S.py create mode 100644 release/scripts/presets/camera/Nikon_D3100.py create mode 100644 release/scripts/presets/camera/Nikon_D35.py create mode 100644 release/scripts/presets/camera/Nikon_D5000.py create mode 100644 release/scripts/presets/camera/Nikon_D5100.py create mode 100644 release/scripts/presets/camera/Nikon_D7000.py create mode 100644 release/scripts/presets/camera/Nikon_D90.py create mode 100644 release/scripts/presets/camera/Red_Epic.py create mode 100644 release/scripts/presets/camera/Red_One_2K.py create mode 100644 release/scripts/presets/camera/Red_One_3K.py create mode 100644 release/scripts/presets/camera/Red_One_4K.py create mode 100644 release/scripts/presets/camera/full_frame_35mm_film.py create mode 100644 release/scripts/presets/camera/micro_four_thirds.py create mode 100644 release/scripts/presets/camera/super_16_film.py create mode 100644 release/scripts/presets/camera/super_35_film.py diff --git a/release/scripts/presets/camera/APS-C_DSLR.py b/release/scripts/presets/camera/APS-C_DSLR.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/APS-C_DSLR.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Blender.py b/release/scripts/presets/camera/Blender.py new file mode 100644 index 00000000000..9fa4ab752e3 --- /dev/null +++ b/release/scripts/presets/camera/Blender.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 32 +bpy.context.object.data.sensor_height = 18 +bpy.context.object.data.sensor_fit = 'AUTO' diff --git a/release/scripts/presets/camera/Canon_1100D.py b/release/scripts/presets/camera/Canon_1100D.py new file mode 100644 index 00000000000..54f2cf75b54 --- /dev/null +++ b/release/scripts/presets/camera/Canon_1100D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.2 +bpy.context.object.data.sensor_height = 14.7 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_1D.py b/release/scripts/presets/camera/Canon_1D.py new file mode 100644 index 00000000000..0bb0e910377 --- /dev/null +++ b/release/scripts/presets/camera/Canon_1D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 27.9 +bpy.context.object.data.sensor_height = 18.6 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_1DS.py b/release/scripts/presets/camera/Canon_1DS.py new file mode 100644 index 00000000000..158a6235f32 --- /dev/null +++ b/release/scripts/presets/camera/Canon_1DS.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 36.0 +bpy.context.object.data.sensor_height = 24.0 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_500D.py b/release/scripts/presets/camera/Canon_500D.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/Canon_500D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_550D.py b/release/scripts/presets/camera/Canon_550D.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/Canon_550D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_5D.py b/release/scripts/presets/camera/Canon_5D.py new file mode 100644 index 00000000000..158a6235f32 --- /dev/null +++ b/release/scripts/presets/camera/Canon_5D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 36.0 +bpy.context.object.data.sensor_height = 24.0 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_600D.py b/release/scripts/presets/camera/Canon_600D.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/Canon_600D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_60D.py b/release/scripts/presets/camera/Canon_60D.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/Canon_60D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Canon_7D.py b/release/scripts/presets/camera/Canon_7D.py new file mode 100644 index 00000000000..829e03cc5cf --- /dev/null +++ b/release/scripts/presets/camera/Canon_7D.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.3 +bpy.context.object.data.sensor_height = 14.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D300S.py b/release/scripts/presets/camera/Nikon_D300S.py new file mode 100644 index 00000000000..a0505bf9b9c --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D300S.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.6 +bpy.context.object.data.sensor_height = 15.8 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D3100.py b/release/scripts/presets/camera/Nikon_D3100.py new file mode 100644 index 00000000000..238d9c22d12 --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D3100.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.1 +bpy.context.object.data.sensor_height = 15.4 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D35.py b/release/scripts/presets/camera/Nikon_D35.py new file mode 100644 index 00000000000..e6dc62dc100 --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D35.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 36.0 +bpy.context.object.data.sensor_height = 23.9 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D5000.py b/release/scripts/presets/camera/Nikon_D5000.py new file mode 100644 index 00000000000..a0505bf9b9c --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D5000.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.6 +bpy.context.object.data.sensor_height = 15.8 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D5100.py b/release/scripts/presets/camera/Nikon_D5100.py new file mode 100644 index 00000000000..1d819cce65b --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D5100.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.6 +bpy.context.object.data.sensor_height = 15.6 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D7000.py b/release/scripts/presets/camera/Nikon_D7000.py new file mode 100644 index 00000000000..1d819cce65b --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D7000.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.6 +bpy.context.object.data.sensor_height = 15.6 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Nikon_D90.py b/release/scripts/presets/camera/Nikon_D90.py new file mode 100644 index 00000000000..a0505bf9b9c --- /dev/null +++ b/release/scripts/presets/camera/Nikon_D90.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 23.6 +bpy.context.object.data.sensor_height = 15.8 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Red_Epic.py b/release/scripts/presets/camera/Red_Epic.py new file mode 100644 index 00000000000..14f4abaee90 --- /dev/null +++ b/release/scripts/presets/camera/Red_Epic.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 30.0 +bpy.context.object.data.sensor_height = 15.0 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Red_One_2K.py b/release/scripts/presets/camera/Red_One_2K.py new file mode 100644 index 00000000000..ef2708f75b2 --- /dev/null +++ b/release/scripts/presets/camera/Red_One_2K.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 11.1 +bpy.context.object.data.sensor_height = 6.24 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Red_One_3K.py b/release/scripts/presets/camera/Red_One_3K.py new file mode 100644 index 00000000000..5ddff2746eb --- /dev/null +++ b/release/scripts/presets/camera/Red_One_3K.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 16.65 +bpy.context.object.data.sensor_height = 9.36 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/Red_One_4K.py b/release/scripts/presets/camera/Red_One_4K.py new file mode 100644 index 00000000000..8ab9b38cbd5 --- /dev/null +++ b/release/scripts/presets/camera/Red_One_4K.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 22.2 +bpy.context.object.data.sensor_height = 12.6 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/full_frame_35mm_film.py b/release/scripts/presets/camera/full_frame_35mm_film.py new file mode 100644 index 00000000000..d3e141ba4d9 --- /dev/null +++ b/release/scripts/presets/camera/full_frame_35mm_film.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 36 +bpy.context.object.data.sensor_height = 24 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/micro_four_thirds.py b/release/scripts/presets/camera/micro_four_thirds.py new file mode 100644 index 00000000000..36fb0aac391 --- /dev/null +++ b/release/scripts/presets/camera/micro_four_thirds.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 17.3 +bpy.context.object.data.sensor_height = 13.0 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/super_16_film.py b/release/scripts/presets/camera/super_16_film.py new file mode 100644 index 00000000000..1e42953bf05 --- /dev/null +++ b/release/scripts/presets/camera/super_16_film.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 12.52 +bpy.context.object.data.sensor_height = 7.41 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/presets/camera/super_35_film.py b/release/scripts/presets/camera/super_35_film.py new file mode 100644 index 00000000000..65ccb0f216c --- /dev/null +++ b/release/scripts/presets/camera/super_35_film.py @@ -0,0 +1,4 @@ +import bpy +bpy.context.object.data.sensor_width = 24.89 +bpy.context.object.data.sensor_height = 18.66 +bpy.context.object.data.sensor_fit = 'HORIZONTAL' diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 2e42105fbf0..21ac128f177 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -195,6 +195,25 @@ class AddPresetRender(AddPresetBase, Operator): preset_subdir = "render" +class AddPresetCamera(AddPresetBase, Operator): + '''Add a Camera Preset''' + bl_idname = "camera.preset_add" + bl_label = "Add Camera Preset" + preset_menu = "CAMERA_MT_presets" + + preset_defines = [ + "cam = bpy.context.object.data" + ] + + preset_values = [ + "cam.sensor_width", + "cam.sensor_height", + "cam.sensor_fit" + ] + + preset_subdir = "camera" + + class AddPresetSSS(AddPresetBase, Operator): '''Add a Subsurface Scattering Preset''' bl_idname = "material.sss_preset_add" diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 5255af40951..4adaad75e42 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -33,6 +33,14 @@ class CameraButtonsPanel(): return context.camera and (engine in cls.COMPAT_ENGINES) +class CAMERA_MT_presets(bpy.types.Menu): + bl_label = "Camera Presets" + preset_subdir = "camera" + preset_operator = "script.execute_preset" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + draw = bpy.types.Menu.draw_preset + + class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} @@ -54,7 +62,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): split.separator() -class DATA_PT_camera(CameraButtonsPanel, Panel): +class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @@ -69,12 +77,12 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): col = split.column() if cam.type == 'PERSP': + row = col.row() if cam.lens_unit == 'MILLIMETERS': - col.prop(cam, "lens") + row.prop(cam, "lens") elif cam.lens_unit == 'DEGREES': - col.prop(cam, "angle") - col = split.column() - col.prop(cam, "lens_unit", text="") + row.prop(cam, "angle") + row.prop(cam, "lens_unit", text="") elif cam.type == 'ORTHO': col.prop(cam, "ortho_scale") @@ -90,26 +98,55 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): split = layout.split() + col = split.column() + col.label(text="Depth of Field:") + + col.prop(cam, "dof_object", text="") + + col = col.column() + if cam.dof_object is not None: + col.enabled = False + col.prop(cam, "dof_distance", text="Distance") + col = split.column(align=True) col.label(text="Shift:") col.prop(cam, "shift_x", text="X") col.prop(cam, "shift_y", text="Y") - col = split.column(align=True) - col.label(text="Clipping:") - col.prop(cam, "clip_start", text="Start") - col.prop(cam, "clip_end", text="End") - layout.label(text="Depth of Field:") +class DATA_PT_camera(CameraButtonsPanel, Panel): + bl_label = "Camera" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + + def draw(self, context): + layout = self.layout + + cam = context.camera + + row = layout.row(align=True) + + row.menu("CAMERA_MT_presets", text=bpy.types.CAMERA_MT_presets.bl_label) + row.operator("camera.preset_add", text="", icon="ZOOMIN") + row.operator("camera.preset_add", text="", icon="ZOOMOUT").remove_active = True + + layout.label(text="Sensor:") split = layout.split() - split.prop(cam, "dof_object", text="") - col = split.column() + col = split.column(align=True) + if cam.sensor_fit == 'AUTO': + col.prop(cam, "sensor_width", text="Size") + else: + col.prop(cam, "sensor_width", text="Width") + col.prop(cam, "sensor_height", text="Height") - if cam.dof_object is not None: - col.enabled = False - col.prop(cam, "dof_distance", text="Distance") + col = split.column(align=True) + col.prop(cam, "sensor_fit", text="") + + layout.label(text="Clipping:") + row = layout.row(align=True) + row.prop(cam, "clip_start", text="Start") + row.prop(cam, "clip_end", text="End") class DATA_PT_camera_display(CameraButtonsPanel, Panel): @@ -127,10 +164,12 @@ class DATA_PT_camera_display(CameraButtonsPanel, Panel): col.prop(cam, "show_limits", text="Limits") col.prop(cam, "show_mist", text="Mist") col.prop(cam, "show_title_safe", text="Title Safe") + col.prop(cam, "show_sensor", text="Sensor") col.prop(cam, "show_name", text="Name") - col.prop_menu_enum(cam, "show_guide") col = split.column() + col.prop_menu_enum(cam, "show_guide") + col.separator() col.prop(cam, "draw_size", text="Size") col.separator() col.prop(cam, "show_passepartout", text="Passepartout") diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 393568c6b60..c5a24c1e5e9 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -139,9 +139,12 @@ struct KeyBlock *object_insert_shape_key(struct Scene *scene, struct Object *ob, int object_is_modified(struct Scene *scene, struct Object *ob); void object_camera_mode(struct RenderData *rd, struct Object *camera); +void object_camera_intrinsics(struct Object *camera, struct Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, + float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit); void object_camera_matrix( struct RenderData *rd, struct Object *camera, int winx, int winy, short field_second, - float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, float *ycor, + float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, + float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, float *viewdx, float *viewdy); void camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float drawsize, const short do_clip, const float scale[3], diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a5edd569bc2..cec2f0f6895 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -724,6 +724,7 @@ void *add_camera(const char *name) cam= alloc_libblock(&G.main->camera, ID_CA, name); cam->lens= 35.0f; + cam->sensor_x = 32.f; cam->clipsta= 0.1f; cam->clipend= 100.0f; cam->drawsize= 0.5f; @@ -2954,27 +2955,23 @@ void object_camera_mode(RenderData *rd, Object *camera) } } -/* 'lens' may be set for envmap only */ -void object_camera_matrix( - RenderData *rd, Object *camera, int winx, int winy, short field_second, - float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, float *ycor, - float *viewdx, float *viewdy -) { - Camera *cam=NULL; - float pixsize; - float shiftx=0.0, shifty=0.0, winside, viewfac; - short is_ortho= FALSE; +void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, + float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit) +{ + Camera *cam= NULL; - /* question mark */ - (*ycor)= rd->yasp / rd->xasp; - if(rd->mode & R_FIELDS) - (*ycor) *= 2.0f; + (*shiftx)= 0.0f; + (*shifty)= 0.0f; + + (*sensor_x)= DEFAULT_SENSOR_WIDTH; + (*sensor_y)= DEFAULT_SENSOR_HEIGHT; + (*sensor_fit)= CAMERA_SENSOR_FIT_AUTO; if(camera->type==OB_CAMERA) { cam= camera->data; if(cam->type == CAM_ORTHO) { - is_ortho= TRUE; + *is_ortho= TRUE; } /* solve this too... all time depending stuff is in convertblender.c? @@ -2987,11 +2984,14 @@ void object_camera_matrix( execute_ipo(&cam->id, cam->ipo); } #endif // XXX old animation system - shiftx=cam->shiftx; - shifty=cam->shifty; + (*shiftx)=cam->shiftx; + (*shifty)=cam->shifty; (*lens)= cam->lens; + (*sensor_x)= cam->sensor_x; + (*sensor_y)= cam->sensor_y; (*clipsta)= cam->clipsta; (*clipend)= cam->clipend; + (*sensor_fit)= cam->sensor_fit; } else if(camera->type==OB_LAMP) { Lamp *la= camera->data; @@ -3005,7 +3005,7 @@ void object_camera_matrix( (*clipend)= la->clipend; } else { /* envmap exception... */; - if((*lens)==0.0f) + if((*lens)==0.0f) /* is this needed anymore? */ (*lens)= 16.0f; if((*clipsta)==0.0f || (*clipend)==0.0f) { @@ -3014,25 +3014,69 @@ void object_camera_matrix( } } + (*cam_r)= cam; +} + +/* 'lens' may be set for envmap only */ +void object_camera_matrix( + RenderData *rd, Object *camera, int winx, int winy, short field_second, + float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, + float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, + float *viewdx, float *viewdy) +{ + Camera *cam=NULL; + float pixsize; + float shiftx=0.0, shifty=0.0, winside, viewfac; + short is_ortho= FALSE; + + /* question mark */ + (*ycor)= rd->yasp / rd->xasp; + if(rd->mode & R_FIELDS) + (*ycor) *= 2.0f; + + object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, sensor_fit); + /* ortho only with camera available */ if(cam && is_ortho) { - if(rd->xasp*winx >= rd->yasp*winy) { + if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { + if(rd->xasp*winx >= rd->yasp*winy) viewfac= winx; + else viewfac= (*ycor) * winy; + } + else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { viewfac= winx; } else { viewfac= (*ycor) * winy; } + /* ortho_scale == 1.0 means exact 1 to 1 mapping */ pixsize= cam->ortho_scale/viewfac; } else { - if(rd->xasp*winx >= rd->yasp*winy) viewfac= ((*lens) * winx)/32.0f; - else viewfac= (*ycor) * ((*lens) * winy)/32.0f; + if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { + if(rd->xasp*winx >= rd->yasp*winy) viewfac= ((*lens) * winx) / (*sensor_x); + else viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x); + } + else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { + viewfac= ((*lens) * winx) / (*sensor_x); + } + else if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { + viewfac= ((*lens) * winy) / (*sensor_y); + } + pixsize= (*clipsta) / viewfac; } /* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */ winside= MAX2(winx, winy); + + if(cam) { + if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) + winside= winx; + else if(cam->sensor_fit==CAMERA_SENSOR_FIT_VERT) + winside= winy; + } + viewplane->xmin= -0.5f*(float)winx + shiftx*winside; viewplane->ymin= -0.5f*(*ycor)*(float)winy + shifty*winside; viewplane->xmax= 0.5f*(float)winx + shiftx*winside; @@ -3076,7 +3120,17 @@ void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const sh float aspx= (float) scene->r.xsch*scene->r.xasp; float aspy= (float) scene->r.ysch*scene->r.yasp; - if(aspx < aspy) { + if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + if(aspx < aspy) { + r_asp[0]= aspx / aspy; + r_asp[1]= 1.0; + } + else { + r_asp[0]= 1.0; + r_asp[1]= aspy / aspx; + } + } + else if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { r_asp[0]= aspx / aspy; r_asp[1]= 1.0; } @@ -3102,16 +3156,18 @@ void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const sh else { /* that way it's always visible - clipsta+0.1 */ float fac; + float half_sensor= 0.5f*((camera->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x)); + *r_drawsize= drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); if(do_clip) { /* fixed depth, variable size (avoids exceeding clipping range) */ depth = -(camera->clipsta + 0.1f); - fac = depth / (camera->lens/-16.0f * scale[2]); + fac = depth / (camera->lens/(-half_sensor) * scale[2]); } else { /* fixed size, variable depth (stays a reasonable size in the 3D view) */ - depth= *r_drawsize * camera->lens/-16.0f * scale[2]; + depth= *r_drawsize * camera->lens/(-half_sensor) * scale[2]; fac= *r_drawsize; } diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h index aef1c4bb46c..fca7c3469a1 100644 --- a/source/blender/blenlib/BLI_math_rotation.h +++ b/source/blender/blenlib/BLI_math_rotation.h @@ -179,8 +179,8 @@ void dquat_to_mat4(float R[4][4], DualQuat *dq); void quat_apply_track(float quat[4], short axis, short upflag); void vec_apply_track(float vec[3], short axis); -float lens_to_angle(float lens); -float angle_to_lens(float angle); +float focallength_to_fov(float focal_length, float sensor); +float fov_to_focallength(float fov, float sensor); float angle_wrap_rad(float angle); float angle_wrap_deg(float angle); diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 0ca8b72c1e3..7fecbae8229 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1688,14 +1688,14 @@ void vec_apply_track(float vec[3], short axis) } /* lens/angle conversion (radians) */ -float lens_to_angle(float lens) +float focallength_to_fov(float focal_length, float sensor) { - return 2.0f * atanf(16.0f/lens); + return 2.0f * atanf((sensor/2.0f) / focal_length); } -float angle_to_lens(float angle) +float fov_to_focallength(float hfov, float sensor) { - return 16.0f / tanf(angle * 0.5f); + return (sensor/2.0f) / tanf(hfov * 0.5f); } /* 'mod_inline(-3,4)= 1', 'fmod(-3,4)= -3' */ diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c index 30625e7b34e..8b00d8e48a6 100644 --- a/source/blender/blenlib/intern/uvproject.c +++ b/source/blender/blenlib/intern/uvproject.c @@ -141,7 +141,7 @@ UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, fl uci.do_pano = (camera->flag & CAM_PANORAMA); uci.do_persp = (camera->type==CAM_PERSP); - uci.camangle= lens_to_angle(camera->lens) / 2.0f; + uci.camangle= focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f; uci.camsize= uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale; /* account for scaled cameras */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8427f7c326a..ea8e8f30d76 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12154,11 +12154,21 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } + } /* put compatibility code here until next subversion bump */ { - + { + Camera *cam; + for(cam= main->camera.first; cam; cam= cam->id.next) { + if (cam->sensor_x < 0.01) + cam->sensor_x = DEFAULT_SENSOR_WIDTH; + + if (cam->sensor_y < 0.01) + cam->sensor_y = DEFAULT_SENSOR_HEIGHT; + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp index 6fa2c8763e0..fcb98cc7c32 100644 --- a/source/blender/collada/CameraExporter.cpp +++ b/source/blender/collada/CameraExporter.cpp @@ -71,7 +71,7 @@ void CamerasExporter::operator()(Object *ob, Scene *sce) if (cam->type == CAM_PERSP) { COLLADASW::PerspectiveOptic persp(mSW); - persp.setXFov(RAD2DEGF(lens_to_angle(cam->lens)), "xfov"); + persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov"); persp.setAspectRatio((float)(sce->r.xsch)/(float)(sce->r.ysch),false,"aspect_ratio"); persp.setZFar(cam->clipend, false , "zfar"); persp.setZNear(cam->clipsta,false , "znear"); diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 8d133979fa4..8cdb1065699 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -814,7 +814,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) double aspect = camera->getAspectRatio().getValue(); double xfov = aspect*yfov; // xfov is in degrees, cam->lens is in millimiters - cam->lens = angle_to_lens(DEG2RADF(xfov)); + cam->lens = fov_to_focallength(DEG2RADF(xfov), cam->sensor_x); } break; } @@ -835,7 +835,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) { double x = camera->getXFov().getValue(); // x is in degrees, cam->lens is in millimiters - cam->lens = angle_to_lens(DEG2RADF(x)); + cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); } break; } @@ -852,7 +852,7 @@ bool DocumentImporter::writeCamera( const COLLADAFW::Camera* camera ) { double yfov = camera->getYFov().getValue(); // yfov is in degrees, cam->lens is in millimiters - cam->lens = angle_to_lens(DEG2RADF(yfov)); + cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); } break; } diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index d49ce0cf49a..92544b2309c 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -57,6 +57,7 @@ #include "IMB_imbuf_types.h" #include "DNA_brush_types.h" +#include "DNA_camera_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_node_types.h" @@ -3000,7 +3001,8 @@ static void project_paint_begin(ProjPaintState *ps) Object *camera= ps->scene->camera; /* dont actually use these */ - float _viewdx, _viewdy, _ycor, _lens=0.0f; + float _viewdx, _viewdy, _ycor, _lens=0.0f, _sensor_x=DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT; + short _sensor_fit= CAMERA_SENSOR_FIT_AUTO; rctf _viewplane; /* viewmat & viewinv */ @@ -3012,7 +3014,7 @@ static void project_paint_begin(ProjPaintState *ps) object_camera_mode(&ps->scene->r, camera); object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0, winmat, &_viewplane, &ps->clipsta, &ps->clipend, - &_lens, &_ycor, &_viewdx, &_viewdy); + &_lens, &_sensor_x, &_sensor_x, &_sensor_fit, &_ycor, &_viewdx, &_viewdy); ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 96031a7b3d3..a764ae77c9d 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -921,17 +921,34 @@ static void draw_selected_name(Scene *scene, Object *ob) BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)-1); } -void view3d_viewborder_size_get(Scene *scene, ARegion *ar, float size_r[2]) +void view3d_viewborder_size_get(Scene *scene, Object *camob, ARegion *ar, float size_r[2]) { - float winmax= MAX2(ar->winx, ar->winy); float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); - - if(aspect > 1.0f) { - size_r[0]= winmax; - size_r[1]= winmax/aspect; - } else { - size_r[0]= winmax*aspect; - size_r[1]= winmax; + short sensor_fit= CAMERA_SENSOR_FIT_AUTO; + + if(camob && camob->type==OB_CAMERA) { + Camera *cam= (Camera *)camob->data; + sensor_fit= cam->sensor_fit; + } + + if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + float winmax= MAX2(ar->winx, ar->winy); + + if(aspect > 1.0f) { + size_r[0]= winmax; + size_r[1]= winmax/aspect; + } else { + size_r[0]= winmax*aspect; + size_r[1]= winmax; + } + } + else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) { + size_r[0]= ar->winx; + size_r[1]= ar->winx/aspect; + } + else { + size_r[0]= ar->winy*aspect; + size_r[1]= ar->winy; } } @@ -941,7 +958,7 @@ void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, Region float size[2]; float dx= 0.0f, dy= 0.0f; - view3d_viewborder_size_get(scene, ar, size); + view3d_viewborder_size_get(scene, v3d->camera, ar, size); size[0]= size[0]*zoomfac; size[1]= size[1]*zoomfac; @@ -1208,6 +1225,21 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); } + if (ca && (ca->flag & CAM_SHOWSENSOR)) { + /* assume fixed sensor width for now */ + + float sensor_aspect = ca->sensor_x / ca->sensor_y; + float sensor_scale = (x2i-x1i) / ca->sensor_x; + float sensor_height = sensor_scale * ca->sensor_y; + + float ymid = y1i + (y2i-y1i)/2.f; + float sy1= ymid - sensor_height/2.f; + float sy2= ymid + sensor_height/2.f; + + UI_ThemeColorShade(TH_WIRE, 100); + + uiDrawBox(GL_LINE_LOOP, x1i, sy1, x2i, sy2, 2.0); + } } setlinestyle(0); @@ -2396,10 +2428,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in /* render 3d view */ if(rv3d->persp==RV3D_CAMOB && v3d->camera) { float winmat[4][4]; - float _clipsta, _clipend, _lens, _yco, _dx, _dy; + float _clipsta, _clipend, _lens, _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT; + short _sensor_fit= CAMERA_SENSOR_FIT_AUTO; rctf _viewplane; - object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens, &_yco, &_dx, &_dy); + object_camera_matrix(&scene->r, v3d->camera, sizex, sizey, 0, winmat, &_viewplane, &_clipsta, &_clipend, &_lens, + &_sensor_x, &_sensor_y, &_sensor_fit, &_yco, &_dx, &_dy); ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat); } @@ -2454,9 +2488,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w invert_m4_m4(rv3d.viewmat, rv3d.viewinv); { - float _yco, _dx, _dy; + float _yco, _dx, _dy, _sensor_x= DEFAULT_SENSOR_WIDTH, _sensor_y= DEFAULT_SENSOR_HEIGHT; + short _sensor_fit= CAMERA_SENSOR_FIT_AUTO; rctf _viewplane; - object_camera_matrix(&scene->r, v3d.camera, width, height, 0, rv3d.winmat, &_viewplane, &v3d.near, &v3d.far, &v3d.lens, &_yco, &_dx, &_dy); + object_camera_matrix(&scene->r, v3d.camera, width, height, 0, rv3d.winmat, &_viewplane, &v3d.near, &v3d.far, &v3d.lens, &_sensor_x, &_sensor_y, &_sensor_fit, &_yco, &_dx, &_dy); } mul_m4_m4m4(rv3d.persmat, rv3d.viewmat, rv3d.winmat); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index ea8db17daf0..e7fbdaf1deb 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2255,13 +2255,14 @@ static int view3d_center_camera_exec(bContext *C, wmOperator *UNUSED(op)) /* was { ARegion *ar= CTX_wm_region(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); + View3D *v3d= CTX_wm_view3d(C); Scene *scene= CTX_data_scene(C); float xfac, yfac; float size[2]; rv3d->camdx= rv3d->camdy= 0.0f; - view3d_viewborder_size_get(scene, ar, size); + view3d_viewborder_size_get(scene, v3d->camera, ar, size); /* 4px is just a little room from the edge of the area */ xfac= (float)ar->winx / (float)(size[0] + 4); @@ -2523,13 +2524,13 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot) } /* sets the view to 1:1 camera/render-pixel */ -static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar) +static void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar, View3D *v3d) { RegionView3D *rv3d= ar->regiondata; float size[2]; int im_width= (scene->r.size*scene->r.xsch)/100; - view3d_viewborder_size_get(scene, ar, size); + view3d_viewborder_size_get(scene, v3d->camera, ar, size); rv3d->camzoom= BKE_screen_view3d_zoom_from_fac((float)im_width/size[0]); CLAMP(rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); @@ -2540,7 +2541,7 @@ static int view3d_zoom_1_to_1_camera_exec(bContext *C, wmOperator *UNUSED(op)) Scene *scene= CTX_data_scene(C); ARegion *ar= CTX_wm_region(C); - view3d_set_1_to_1_viewborder(scene, ar); + view3d_set_1_to_1_viewborder(scene, ar, CTX_wm_view3d(C)); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C)); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index b087c7ac873..b07d2d1ca73 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -135,7 +135,7 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d); void view3d_clr_clipping(void); void view3d_set_clipping(RegionView3D *rv3d); void add_view3d_after(ListBase *lb, Base *base, int flag); -void view3d_viewborder_size_get(struct Scene *scene, struct ARegion *ar, float size_r[2]); +void view3d_viewborder_size_get(struct Scene *scene, struct Object *camob, struct ARegion *ar, float size_r[2]); void circf(float x, float y, float rad); void circ(float x, float y, float rad); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 93c577619de..7de1f2a85bb 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -966,10 +966,14 @@ int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, fl int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winyi, rctf *viewplane, float *clipsta, float *clipend, float *pixsize) { Camera *cam=NULL; - float lens, fac, x1, y1, x2, y2; + float lens, sensor_x =DEFAULT_SENSOR_WIDTH, sensor_y= DEFAULT_SENSOR_HEIGHT, fac, x1, y1, x2, y2; float winx= (float)winxi, winy= (float)winyi; int orth= 0; - + short sensor_fit= CAMERA_SENSOR_FIT_AUTO; + + /* currnetly using sensor size (depends on fov calculating method) */ + float sensor= DEFAULT_SENSOR_WIDTH; + lens= v3d->lens; *clipsta= v3d->near; @@ -992,8 +996,13 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy else if(v3d->camera->type==OB_CAMERA) { cam= v3d->camera->data; lens= cam->lens; + sensor_x= cam->sensor_x; + sensor_y= cam->sensor_y; *clipsta= cam->clipsta; *clipend= cam->clipend; + sensor_fit= cam->sensor_fit; + + sensor= (cam->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (cam->sensor_y) : (cam->sensor_x); } } } @@ -1024,21 +1033,44 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy if(cam && cam->type==CAM_ORTHO) { /* ortho_scale == 1 means exact 1 to 1 mapping */ float dfac= 2.0f*cam->ortho_scale/fac; - - if(winx>winy) x1= -dfac; - else x1= -winx*dfac/winy; + + if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + if(winx>winy) { + x1= -dfac; + y1= -winy*dfac/winx; + } + else { + x1= -winx*dfac/winy; + y1= -dfac; + } + } + else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) { + x1= -dfac; + y1= -winy*dfac/winx; + } + else { + x1= -winx*dfac/winy; + y1= -dfac; + } + x2= -x1; - - if(winx>winy) y1= -winy*dfac/winx; - else y1= -dfac; y2= -y1; + orth= 1; } else { float dfac; - if(winx>winy) dfac= 64.0f/(fac*winx*lens); - else dfac= 64.0f/(fac*winy*lens); + if(sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + if(winx>winy) dfac= (sensor_x * 2.0) / (fac*winx*lens); + else dfac= (sensor_x * 2.0) / (fac*winy*lens); + } + else if(sensor_fit==CAMERA_SENSOR_FIT_HOR) { + dfac= (sensor_x * 2.0) / (fac*winx*lens); + } + else { + dfac= (sensor_y * 2.0) / (fac*winy*lens); + } x1= - *clipsta * winx*dfac; x2= -x1; @@ -1057,8 +1089,8 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy dy += cam->shifty * cam->ortho_scale; } else { - dx += cam->shiftx * (cam->clipsta / cam->lens) * 32.0f; - dy += cam->shifty * (cam->clipsta / cam->lens) * 32.0f; + dx += cam->shiftx * (cam->clipsta / cam->lens) * sensor; + dy += cam->shifty * (cam->clipsta / cam->lens) * sensor; } x1+= dx; @@ -1076,7 +1108,14 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winxi, int winy *pixsize= 1.0f/viewfac; } else { - viewfac= (((winx >= winy)? winx: winy)*lens)/32.0f; + float size= ((winx >= winy)? winx: winy); + + if(sensor_fit==CAMERA_SENSOR_FIT_HOR) + size= winx; + else if(sensor_fit==CAMERA_SENSOR_FIT_VERT) + size= winy; + + viewfac= (size*lens)/sensor; *pixsize= *clipsta/viewfac; } } diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h index 8ad6821702a..292f920da66 100644 --- a/source/blender/makesdna/DNA_camera_types.h +++ b/source/blender/makesdna/DNA_camera_types.h @@ -51,6 +51,7 @@ typedef struct Camera { float passepartalpha; float clipsta, clipend; float lens, ortho_scale, drawsize; + float sensor_x, sensor_y; float shiftx, shifty; /* yafray: dof params */ @@ -61,6 +62,9 @@ typedef struct Camera { struct Ipo *ipo; // XXX depreceated... old animation system struct Object *dof_ob; + + char sensor_fit; + char pad[7]; } Camera; /* **************** CAMERA ********************* */ @@ -88,10 +92,18 @@ typedef struct Camera { #define CAM_ANGLETOGGLE 32 #define CAM_DS_EXPAND 64 #define CAM_PANORAMA 128 +#define CAM_SHOWSENSOR 256 /* yafray: dof sampling switch */ /* #define CAM_YF_NO_QMC 512 */ /* depreceated */ +/* Sensor fit */ +#define CAMERA_SENSOR_FIT_AUTO 0 +#define CAMERA_SENSOR_FIT_HOR 1 +#define CAMERA_SENSOR_FIT_VERT 2 + +#define DEFAULT_SENSOR_WIDTH 32.0f +#define DEFAULT_SENSOR_HEIGHT 18.0f #ifdef __cplusplus } diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 9e89c4aaab0..1e7a969caaa 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -40,19 +40,65 @@ #ifdef RNA_RUNTIME #include "BKE_object.h" +#include "BKE_depsgraph.h" /* only for rad/deg conversion! can remove later */ +static float get_camera_sensor(Camera *cam) +{ + if(cam->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + return cam->sensor_x; + } + else if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) { + return cam->sensor_x; + } + else { + return cam->sensor_y; + } +} + static float rna_Camera_angle_get(PointerRNA *ptr) { Camera *cam= ptr->id.data; - - return lens_to_angle(cam->lens); + float sensor= get_camera_sensor(cam); + return focallength_to_fov(cam->lens, sensor); } static void rna_Camera_angle_set(PointerRNA *ptr, float value) { Camera *cam= ptr->id.data; - cam->lens= angle_to_lens(value); + float sensor= get_camera_sensor(cam); + cam->lens= fov_to_focallength(value, sensor); +} + +static float rna_Camera_angle_x_get(PointerRNA *ptr) +{ + Camera *cam= ptr->id.data; + return focallength_to_fov(cam->lens, cam->sensor_x); +} + +static void rna_Camera_angle_x_set(PointerRNA *ptr, float value) +{ + Camera *cam= ptr->id.data; + cam->lens= fov_to_focallength(value, cam->sensor_x); +} + +static float rna_Camera_angle_y_get(PointerRNA *ptr) +{ + Camera *cam= ptr->id.data; + return focallength_to_fov(cam->lens, cam->sensor_y); +} + +static void rna_Camera_angle_y_set(PointerRNA *ptr, float value) +{ + Camera *cam= ptr->id.data; + cam->lens= fov_to_focallength(value, cam->sensor_y); +} + +static void rna_Camera_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Camera *camera= (Camera*)ptr->id.data; + + DAG_id_tag_update(&camera->id, 0); } #else @@ -79,6 +125,11 @@ void RNA_def_camera(BlenderRNA *brna) {0, "MILLIMETERS", 0, "Millimeters", ""}, {CAM_ANGLETOGGLE, "DEGREES", 0, "Degrees", ""}, {0, NULL, 0, NULL, NULL}}; + static EnumPropertyItem sensor_fit_items[] = { + {CAMERA_SENSOR_FIT_AUTO, "AUTO", 0, "Auto", "Calculate field of view using sensor size, with direction depending on image resolution"}, + {CAMERA_SENSOR_FIT_HOR, "HORIZONTAL", 0, "Horizontal", "Calculate field of view using sensor width"}, + {CAMERA_SENSOR_FIT_VERT, "VERTICAL", 0, "Vertical", "Calculate field of view using sensor height"}, + {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Camera", "ID"); RNA_def_struct_ui_text(srna, "Camera", "Camera datablock for storing camera settings"); @@ -88,7 +139,7 @@ void RNA_def_camera(BlenderRNA *brna) prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "Type", "Camera types"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); prop= RNA_def_property(srna, "show_guide", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dtx"); @@ -96,7 +147,13 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_ENUM_FLAG); RNA_def_property_ui_text(prop, "Composition Guides", "Draw overlay"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); - + + prop= RNA_def_property(srna, "sensor_fit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "sensor_fit"); + RNA_def_property_enum_items(prop, sensor_fit_items); + RNA_def_property_ui_text(prop, "Sensor Fit", "Mode of calculating field of view from sensor dimensions and focal length"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + /* Number values */ prop= RNA_def_property(srna, "passepartout_alpha", PROP_FLOAT, PROP_FACTOR); @@ -104,6 +161,27 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Passepartout Alpha", "Opacity (alpha) of the darkened overlay in Camera view"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + prop= RNA_def_property(srna, "angle_x", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0)); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Horizontal FOV", "Camera lens horizontal field of view in degrees"); + RNA_def_property_float_funcs(prop, "rna_Camera_angle_x_get", "rna_Camera_angle_x_set", NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + + prop= RNA_def_property(srna, "angle_y", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0)); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Vertical FOV", "Camera lens vertical field of view in degrees"); + RNA_def_property_float_funcs(prop, "rna_Camera_angle_y_get", "rna_Camera_angle_y_set", NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + + prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0)); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Field of View", "Camera lens field of view in degrees"); + RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + prop= RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "clipsta"); RNA_def_property_range(prop, 0.001f, FLT_MAX); @@ -120,20 +198,27 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "lens"); RNA_def_property_range(prop, 1.0f, 5000.0f); RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); - - prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_range(prop, M_PI * (0.367/180.0), M_PI * (172.847/180.0)); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Angle", "Perspective Camera lens field of view in degrees"); - RNA_def_property_float_funcs(prop, "rna_Camera_angle_get", "rna_Camera_angle_set", NULL); /* only for deg/rad conversion */ - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + + prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "sensor_x"); + RNA_def_property_range(prop, 1.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2); + RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); + + prop= RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "sensor_y"); + RNA_def_property_range(prop, 1.0f, FLT_MAX); + RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2); + RNA_def_property_ui_text(prop, "Sensor Height", "Vertical size of the image sensor area in millimeters"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); prop= RNA_def_property(srna, "ortho_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ortho_scale"); RNA_def_property_range(prop, 0.01f, 4000.0f); RNA_def_property_ui_text(prop, "Orthographic Scale", "Orthographic Camera scale (similar to zoom)"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); prop= RNA_def_property(srna, "draw_size", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "drawsize"); @@ -147,14 +232,14 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_range(prop, -10.0f, 10.0f); RNA_def_property_ui_range(prop, -2.0, 2.0, 1, 3); RNA_def_property_ui_text(prop, "Shift X", "Perspective Camera horizontal shift"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); prop= RNA_def_property(srna, "shift_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "shifty"); RNA_def_property_range(prop, -10.0f, 10.0f); RNA_def_property_ui_range(prop, -2.0, 2.0, 1, 3); RNA_def_property_ui_text(prop, "Shift Y", "Perspective Camera vertical shift"); - RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Camera_update"); prop= RNA_def_property(srna, "dof_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "YF_dofdist"); @@ -188,6 +273,11 @@ void RNA_def_camera(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Show Name", "Show the active Camera's name in Camera view"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + prop= RNA_def_property(srna, "show_sensor", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CAM_SHOWSENSOR); + RNA_def_property_ui_text(prop, "Show Sensor Size", "Show sensor size (film gate) in Camera view"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); + prop= RNA_def_property(srna, "lens_unit", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, prop_lens_unit_items); diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 36d773ad605..d5dd0078a80 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -38,6 +38,7 @@ #include "DNA_meshdata_types.h" #include "DNA_camera_types.h" #include "DNA_object_types.h" +#include "DNA_scene_types.h" #include "BLI_math.h" #include "BLI_string.h" @@ -159,7 +160,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, float scax= umd->scalex ? umd->scalex : 1.0f; float scay= umd->scaley ? umd->scaley : 1.0f; int free_uci= 0; - + aspect = aspx / aspy; for(i = 0; i < umd->num_projectors; ++i) @@ -194,16 +195,28 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, free_uci= 1; } else { - float scale= (cam->type == CAM_PERSP) ? cam->clipsta * 32.0f / cam->lens : cam->ortho_scale; + float sensor= (cam->sensor_fit == CAMERA_SENSOR_FIT_VERT) ? (cam->sensor_y) : cam->sensor_x; + float scale= (cam->type == CAM_PERSP) ? cam->clipsta * sensor / cam->lens : cam->ortho_scale; float xmax, xmin, ymax, ymin; - if(aspect > 1.0f) { + if(cam->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + if(aspect > 1.0f) { + xmax = 0.5f * scale; + ymax = xmax / aspect; + } else { + ymax = 0.5f * scale; + xmax = ymax * aspect; + } + } + else if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) { xmax = 0.5f * scale; ymax = xmax / aspect; - } else { + } + else { ymax = 0.5f * scale; xmax = ymax * aspect; } + xmin = -xmax; ymin = -ymax; diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index ae4e55b9b88..7cad8c36df4 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -153,7 +153,9 @@ struct Render /* values for viewing */ float lens; + float sensor_x, sensor_y; /* image sensor size, same variable in camera */ float ycor; /* (scene->xasp / scene->yasp), multiplied with 'winy' */ + short sensor_fit; float panophi, panosi, panoco, panodxp, panodxv; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index e285b9b1ed9..2f20c328405 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -157,6 +157,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) /* view stuff in env render */ envre->lens= 16.0f; + envre->sensor_x= 32.0f; if(env->type==ENV_PLANE) envre->lens*= env->viewscale; envre->ycor= 1.0f; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 091a64e418e..f8e4ee8f6a7 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -458,7 +458,7 @@ void RE_SetCamera(Render *re, Object *camera) object_camera_matrix(&re->r, camera, re->winx, re->winy, re->flag & R_SEC_FIELD, re->winmat, &re->viewplane, &re->clipsta, &re->clipend, - &re->lens, &re->ycor, &re->viewdx, &re->viewdy); + &re->lens, &re->sensor_x, &re->sensor_y, &re->sensor_fit, &re->ycor, &re->viewdx, &re->viewdy); } void RE_SetPixelSize(Render *re, float pixsize) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 77bd6e0f374..ca37b06d12e 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1724,7 +1724,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) { Camera* ca = static_cast(ob->data); - RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); + RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->sensor_x, ca->sensor_y, ca->sensor_fit, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, ca->YF_dofdist); KX_Camera *gamecamera; gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata); diff --git a/source/gameengine/Ketsji/KX_Camera.cpp b/source/gameengine/Ketsji/KX_Camera.cpp index 77438b8f48a..14a307794db 100644 --- a/source/gameengine/Ketsji/KX_Camera.cpp +++ b/source/gameengine/Ketsji/KX_Camera.cpp @@ -200,7 +200,26 @@ float KX_Camera::GetScale() const return m_camdata.m_scale; } +/* +* Gets the horizontal size of the sensor - for camera matching. +*/ +float KX_Camera::GetSensorWidth() const +{ + return m_camdata.m_sensor_x; +} +/* +* Gets the vertical size of the sensor - for camera matching. +*/ +float KX_Camera::GetSensorHeight() const +{ + return m_camdata.m_sensor_y; +} +/** Gets the mode FOV is calculating from sensor dimensions */ +short KX_Camera::GetSensorFit() const +{ + return m_camdata.m_sensor_fit; +} float KX_Camera::GetCameraNear() const { diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 4c8cf21a7bf..236e914b9e5 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -199,6 +199,12 @@ public: float GetLens() const; /** Gets the ortho scale. */ float GetScale() const; + /** Gets the horizontal size of the sensor - for camera matching */ + float GetSensorWidth() const; + /** Gets the vertical size of the sensor - for camera matching */ + float GetSensorHeight() const; + /** Gets the mode FOV is calculating from sensor dimensions */ + short GetSensorFit() const; /** Gets the near clip distance. */ float GetCameraNear() const; /** Gets the far clip distance. */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index 5de6adc5af4..a9be588e6b2 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -1251,6 +1251,7 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) cam->GetScale(), nearfrust, farfrust, + cam->GetSensorFit(), frustum ); if (!cam->GetViewport()) { @@ -1268,6 +1269,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) area, viewport, cam->GetLens(), + cam->GetSensorWidth(), + cam->GetSensorHeight(), + cam->GetSensorFit(), nearfrust, farfrust, frustum diff --git a/source/gameengine/Rasterizer/RAS_CameraData.h b/source/gameengine/Rasterizer/RAS_CameraData.h index 2056068a2ad..2120a18f139 100644 --- a/source/gameengine/Rasterizer/RAS_CameraData.h +++ b/source/gameengine/Rasterizer/RAS_CameraData.h @@ -36,6 +36,9 @@ struct RAS_CameraData { float m_lens; float m_scale; + float m_sensor_x; + float m_sensor_y; + short m_sensor_fit; float m_clipstart; float m_clipend; bool m_perspective; @@ -46,11 +49,15 @@ struct RAS_CameraData int m_viewporttop; float m_focallength; - RAS_CameraData(float lens = 35.0, float scale = 6.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, + RAS_CameraData(float lens = 35.0, float scale = 6.0, float sensor_x = 32.0, float sensor_y = 18.0, short sensor_fit = 0, + float clipstart = 0.1, float clipend = 5000.0, bool perspective = true, float focallength = 3.0, bool viewport = false, int viewportleft = 0, int viewportbottom = 0, int viewportright = 0, int viewporttop = 0) : m_lens(lens), m_scale(scale), + m_sensor_x(sensor_x), + m_sensor_y(sensor_y), + m_sensor_fit(sensor_fit), m_clipstart(clipstart), m_clipend(clipend), m_perspective(perspective), diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.cpp b/source/gameengine/Rasterizer/RAS_FramingManager.cpp index da6c230ffc1..8a5c10b3a3b 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.cpp +++ b/source/gameengine/Rasterizer/RAS_FramingManager.cpp @@ -39,25 +39,35 @@ ComputeDefaultFrustum( const float camnear, const float camfar, const float lens, + const float sensor_x, const float sensor_y, + const short sensor_fit, const float design_aspect_ratio, RAS_FrameFrustum & frustum -){ - - /* - * Magic Blender calculation. - * Blender does not give a Field of View as lens but a size - * at 16 units away from the lens. - */ - float halfSize = 16.f * camnear / lens; +){ + float halfSize; float sizeX; float sizeY; - if (design_aspect_ratio > 1.f) { - // halfsize defines the width + if(sensor_fit==RAS_SENSORFIT_AUTO) { + halfSize = (sensor_x / 2.f) * camnear / lens; + + if (design_aspect_ratio > 1.f) { + // halfsize defines the width + sizeX = halfSize; + sizeY = halfSize/design_aspect_ratio; + } else { + // halfsize defines the height + sizeX = halfSize * design_aspect_ratio; + sizeY = halfSize; + } + } + else if(sensor_fit==RAS_SENSORFIT_HOR) { + halfSize = (sensor_x / 2.f) * camnear / lens; sizeX = halfSize; sizeY = halfSize/design_aspect_ratio; - } else { - // halfsize defines the height + } + else { + halfSize = (sensor_y / 2.f) * camnear / lens; sizeX = halfSize * design_aspect_ratio; sizeY = halfSize; } @@ -77,6 +87,7 @@ ComputeDefaultOrtho( const float camfar, const float scale, const float design_aspect_ratio, + const short sensor_fit, RAS_FrameFrustum & frustum ) { @@ -84,12 +95,22 @@ ComputeDefaultOrtho( float sizeX; float sizeY; - if (design_aspect_ratio > 1.f) { - // halfsize defines the width + if(sensor_fit==RAS_SENSORFIT_AUTO) { + if (design_aspect_ratio > 1.f) { + // halfsize defines the width + sizeX = halfSize; + sizeY = halfSize/design_aspect_ratio; + } else { + // halfsize defines the height + sizeX = halfSize * design_aspect_ratio; + sizeY = halfSize; + } + } + else if(sensor_fit==RAS_SENSORFIT_HOR) { sizeX = halfSize; sizeY = halfSize/design_aspect_ratio; - } else { - // halfsize defines the height + } + else { sizeX = halfSize * design_aspect_ratio; sizeY = halfSize; } @@ -199,6 +220,7 @@ ComputeFrustum( const RAS_Rect &availableViewport, const RAS_Rect &viewport, const float lens, + const float sensor_x, const float sensor_y, const short sensor_fit, const float camnear, const float camfar, RAS_FrameFrustum &frustum @@ -224,6 +246,9 @@ ComputeFrustum( camnear, camfar, lens, + sensor_x, + sensor_y, + sensor_fit, design_aspect_ratio, frustum ); @@ -269,6 +294,7 @@ RAS_FramingManager:: const float scale, const float camnear, const float camfar, + const short sensor_fit, RAS_FrameFrustum &frustum ) { @@ -293,6 +319,7 @@ RAS_FramingManager:: camfar, scale, design_aspect_ratio, + sensor_fit, frustum ); diff --git a/source/gameengine/Rasterizer/RAS_FramingManager.h b/source/gameengine/Rasterizer/RAS_FramingManager.h index 38ea8f4e07a..612142234e3 100644 --- a/source/gameengine/Rasterizer/RAS_FramingManager.h +++ b/source/gameengine/Rasterizer/RAS_FramingManager.h @@ -184,6 +184,14 @@ enum RAS_CullingMode RAS_CULLING_NONE }; +/* Should match CAMERA_SENSOR_FIT... from DNA_camera_types.h */ +enum RAS_SensorFit +{ + RAS_SENSORFIT_AUTO = 0, + RAS_SENSORFIT_HOR, + RAS_SENSORFIT_VERT +}; + /** * @section RAS_FramingManager * This class helps to compute a view frustum @@ -229,6 +237,7 @@ public : const float scale, const float camnear, const float camfar, + const short sensor_fit, RAS_FrameFrustum &frustum ); @@ -239,6 +248,7 @@ public : const RAS_Rect &availableViewport, const RAS_Rect &viewport, const float lens, + const float sensor_x, const float sensor_y, const short sensor_fit, const float camnear, const float camfar, RAS_FrameFrustum &frustum @@ -250,6 +260,8 @@ public : const float camnear, const float camfar, const float lens, + const float sensor_x, const float sensor_y, + const short sensor_fit, const float design_aspect_ratio, RAS_FrameFrustum & frustum ); @@ -261,6 +273,7 @@ public : const float camfar, const float scale, const float design_aspect_ratio, + const short sensor_fit, RAS_FrameFrustum & frustum ); diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 912d5864560..a349b45e403 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -214,6 +214,8 @@ void ImageRender::Render() } else { float lens = m_camera->GetLens(); + float sensor_x = m_camera->GetSensorWidth(); + float sensor_y = m_camera->GetSensorHeight(); bool orthographic = !m_camera->GetCameraData()->m_perspective; float nearfrust = m_camera->GetCameraNear(); float farfrust = m_camera->GetCameraFar(); @@ -233,6 +235,7 @@ void ImageRender::Render() farfrust, m_camera->GetScale(), aspect_ratio, + m_camera->GetSensorFit(), frustrum ); @@ -244,6 +247,9 @@ void ImageRender::Render() nearfrust, farfrust, lens, + sensor_x, + sensor_y, + RAS_SENSORFIT_AUTO, aspect_ratio, frustrum); From 209ceb6969cf2398aa38a7a292e64ef130d5e8db Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 4 Nov 2011 15:21:34 +0000 Subject: [PATCH 081/147] correct some warnings, also sensor_x was being paassed to object_camera_matrix(...) for x and y args, looks like an accident --- build_files/cmake/project_info.py | 1 - doc/python_api/sphinx_doc_gen.py | 10 ++++------ .../startup/bl_ui/properties_data_camera.py | 2 +- .../startup/bl_ui/space_view3d_toolbar.py | 6 +++--- source/blender/blenkernel/intern/object.c | 4 ++-- .../editors/interface/interface_handlers.c | 18 +++++++++--------- .../blender/editors/sculpt_paint/paint_image.c | 2 +- .../blender/editors/space_view3d/view3d_draw.c | 4 ++-- 8 files changed, 22 insertions(+), 25 deletions(-) diff --git a/build_files/cmake/project_info.py b/build_files/cmake/project_info.py index da1f2087f4f..eed002ce7ba 100755 --- a/build_files/cmake/project_info.py +++ b/build_files/cmake/project_info.py @@ -234,4 +234,3 @@ def project_name_get(path, fallback="Blender", prefix="Blender_"): if "/branches/" in l: return prefix + l.rsplit("/branches/", 1)[-1].split("/", 1)[0] return fallback - diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index b0127c50b29..3c43b5bc4da 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -121,9 +121,7 @@ except ImportError: EXCLUDE_MODULES = EXCLUDE_MODULES + ("aud", ) - # import rpdb2; rpdb2.start_embedded_debugger('test') - import os import inspect import bpy @@ -327,7 +325,7 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier): fw(ident + ".. attribute:: %s\n\n" % identifier) write_indented_lines(ident + " ", fw, doc, False) fw("\n") - elif type(descr) == MemberDescriptorType: # same as above but use 'data' + elif type(descr) == MemberDescriptorType: # same as above but use 'data' fw(ident + ".. data:: %s\n\n" % identifier) write_indented_lines(ident + " ", fw, doc, False) fw("\n") @@ -443,7 +441,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title): # naughty, we also add getset's into PyStructs, this is not typical py but also not incorrect. # type_name is only used for examples and messages - type_name = str(type(module)).strip("<>").split(" ", 1)[-1][1:-1] # "" --> bpy.app.handlers + type_name = str(type(module)).strip("<>").split(" ", 1)[-1][1:-1] # "" --> bpy.app.handlers if type(descr) == types.GetSetDescriptorType: py_descr2sphinx("", fw, descr, module_name, type_name, key) attribute_set.add(key) @@ -467,7 +465,7 @@ def pymodule2sphinx(BASEPATH, module_name, module, title): # ack, cant use typical reference because we double up once here # and one fort he module! full_name = "%s.%s" % (module_name, type_name) - fw(" :ref:`%s submodule details <%s>`\n\n\n" % (full_name, module_id_as_ref(full_name))) # % (module_name, type_name) + fw(" :ref:`%s submodule details <%s>`\n\n\n" % (full_name, module_id_as_ref(full_name))) del full_name attribute_set.add(key) @@ -1306,7 +1304,7 @@ def rna2sphinx(BASEPATH): from bpy import app as module pymodule2sphinx(BASEPATH, "bpy.app", module, "Application Data") - if "bpy.app.handlers" not in EXCLUDE_MODULES: + if "bpy.app.handlers" not in EXCLUDE_MODULES: from bpy.app import handlers as module pymodule2sphinx(BASEPATH, "bpy.app.handlers", module, "Application Handlers") diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 4adaad75e42..4061a331261 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -142,7 +142,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): col = split.column(align=True) col.prop(cam, "sensor_fit", text="") - + layout.label(text="Clipping:") row = layout.row(align=True) row.prop(cam, "clip_start", text="Start") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 591191321ee..96201a4b960 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1133,7 +1133,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): sub.prop(ipaint, "normal_angle", text="") split = layout.split() - + split.active = (use_projection) split.prop(ipaint, "use_stencil_layer", text="Stencil") @@ -1148,10 +1148,10 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): row.menu("VIEW3D_MT_tools_projectpaint_clone", text=mesh.uv_texture_clone.name) layout.prop(ipaint, "seam_bleed") - + col = layout.column() col.label(text="External Editing:") - + row = col.split(align=True, percentage=0.55) row.operator("image.project_edit", text="Quick Edit") row.operator("image.project_apply", text="Apply") diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index cec2f0f6895..9a0dbd2a2eb 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3045,7 +3045,7 @@ void object_camera_matrix( else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { viewfac= winx; } - else { + else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ viewfac= (*ycor) * winy; } @@ -3060,7 +3060,7 @@ void object_camera_matrix( else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { viewfac= ((*lens) * winx) / (*sensor_x); } - else if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { + else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ viewfac= ((*lens) * winy) / (*sensor_y); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 0f230df049e..b77f3977355 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3408,20 +3408,20 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmND { float *hsv= ui_block_hsv_get(but->block); float rgb[3]; - float phi, r, sqr, v[2]; - float sensitivity = (shift?0.15:0.3) * ndof->dt; + float phi, r /*, sqr */ /* UNUSED */, v[2]; + float sensitivity = (shift ? 0.15f : 0.3f) * ndof->dt; ui_get_but_vectorf(but, rgb); rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); /* Convert current colour on hue/sat disc to circular coordinates phi, r */ - phi = fmodf(hsv[0]+0.25, 1.0f) * -2.0f*M_PI; + phi = fmodf(hsv[0]+0.25f, 1.0f) * -2.0f*M_PI; r = hsv[1]; - sqr = r>0.f?sqrtf(r):1; + /* sqr= r>0.f?sqrtf(r):1; */ /* UNUSED */ /* Convert to 2d vectors */ - v[0] = r * cos(phi); - v[1] = r * sin(phi); + v[0] = r * cosf(phi); + v[1] = r * sinf(phi); /* Use ndof device y and x rotation to move the vector in 2d space */ v[0] += ndof->ry * sensitivity; @@ -3431,19 +3431,19 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, wmND phi = atan2(v[0], v[1])/(2.0f*(float)M_PI) + 0.5f; /* use ndof z rotation to additionally rotate hue */ - phi -= ndof->rz * sensitivity * 0.5; + phi -= ndof->rz * sensitivity * 0.5f; r = len_v2(v); CLAMP(r, 0.0f, 1.0f); /* convert back to hsv values, in range [0,1] */ - hsv[0] = fmodf(phi, 1.0); + hsv[0] = fmodf(phi, 1.0f); hsv[1] = r; /* exception, when using color wheel in 'locked' value state: * allow choosing a hue for black values, by giving a tiny increment */ if (but->flag & UI_BUT_COLOR_LOCK) { // lock - if (hsv[2] == 0.f) hsv[2] = 0.0001f; + if (hsv[2] == 0.0f) hsv[2] = 0.0001f; } hsv_to_rgb(hsv[0], hsv[1], hsv[2], data->vec, data->vec+1, data->vec+2); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 92544b2309c..6b6003fb098 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -3014,7 +3014,7 @@ static void project_paint_begin(ProjPaintState *ps) object_camera_mode(&ps->scene->r, camera); object_camera_matrix(&ps->scene->r, camera, ps->winx, ps->winy, 0, winmat, &_viewplane, &ps->clipsta, &ps->clipend, - &_lens, &_sensor_x, &_sensor_x, &_sensor_fit, &_ycor, &_viewdx, &_viewdy); + &_lens, &_sensor_x, &_sensor_y, &_sensor_fit, &_ycor, &_viewdx, &_viewdy); ps->is_ortho= (ps->scene->r.mode & R_ORTHO) ? 1 : 0; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index a764ae77c9d..aa69e7121e0 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1228,7 +1228,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (ca && (ca->flag & CAM_SHOWSENSOR)) { /* assume fixed sensor width for now */ - float sensor_aspect = ca->sensor_x / ca->sensor_y; + /* float sensor_aspect = ca->sensor_x / ca->sensor_y; */ /* UNUSED */ float sensor_scale = (x2i-x1i) / ca->sensor_x; float sensor_height = sensor_scale * ca->sensor_y; @@ -1238,7 +1238,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) UI_ThemeColorShade(TH_WIRE, 100); - uiDrawBox(GL_LINE_LOOP, x1i, sy1, x2i, sy2, 2.0); + uiDrawBox(GL_LINE_LOOP, x1i, sy1, x2i, sy2, 2.0f); } } From 65f5408d75e46b31f6c0e01857f4c49949cd84b8 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 15:53:12 +0000 Subject: [PATCH 082/147] Fix #29155: Inconsistency with 0 and Del hotkeys Use del key to reset values in widgets like color selection and histogram. --- source/blender/editors/interface/interface_handlers.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b77f3977355..0ba141163b3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3306,7 +3306,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_BREAK; } /* XXX hardcoded keymap check.... */ - else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { + else if (event->type == DELKEY && event->val == KM_PRESS) { if (but->a1==UI_GRAD_V_ALT){ int len; @@ -3489,7 +3489,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_BREAK; } /* XXX hardcoded keymap check.... */ - else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { + else if (event->type == DELKEY && event->val == KM_PRESS) { int len; /* reset only saturation */ @@ -3938,7 +3938,7 @@ static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_BREAK; } /* XXX hardcoded keymap check.... */ - else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { + else if (event->type == DELKEY && event->val == KM_PRESS) { Histogram *hist = (Histogram *)but->poin; hist->ymax = 1.f; @@ -4021,7 +4021,7 @@ static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleB return WM_UI_HANDLER_BREAK; } /* XXX hardcoded keymap check.... */ - else if (ELEM(event->type, ZEROKEY, PAD0) && event->val == KM_PRESS) { + else if (event->type == DELKEY && event->val == KM_PRESS) { Scopes *scopes = (Scopes *)but->poin; scopes->wavefrm_yfac = 1.f; From ac47da5d6b42ba605a652d681c36c50e40c81646 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 15:53:20 +0000 Subject: [PATCH 083/147] Fix #29024: Logic Bricks allow same name for multiple bricks Check for unique name when setting name for logic bricks. --- source/blender/makesrna/intern/rna_actuator.c | 13 +++++++++++++ source/blender/makesrna/intern/rna_controller.c | 13 +++++++++++++ source/blender/makesrna/intern/rna_sensor.c | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c index 596e1a7f357..db71dee26ce 100644 --- a/source/blender/makesrna/intern/rna_actuator.c +++ b/source/blender/makesrna/intern/rna_actuator.c @@ -109,6 +109,18 @@ static StructRNA* rna_Actuator_refine(struct PointerRNA *ptr) } } +void rna_Actuator_name_set(PointerRNA *ptr, const char *value) +{ + bActuator *act= (bActuator *)ptr->data; + + BLI_strncpy_utf8(act->name, value, sizeof(act->name)); + + if (ptr->id.data) { + Object *ob= (Object *)ptr->id.data; + BLI_uniquename(&ob->actuators, act, "Actuator", '.', offsetof(bActuator, name), sizeof(act->name)); + } +} + static void rna_Actuator_type_set(struct PointerRNA *ptr, int value) { bActuator *act= (bActuator *)ptr->data; @@ -525,6 +537,7 @@ void rna_def_actuator(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Actuator_name_set"); RNA_def_struct_name_property(srna, prop); prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c index fe899f99ed2..89239c10ffd 100644 --- a/source/blender/makesrna/intern/rna_controller.c +++ b/source/blender/makesrna/intern/rna_controller.c @@ -75,6 +75,18 @@ static struct StructRNA* rna_Controller_refine(struct PointerRNA *ptr) } } +void rna_Constroller_name_set(PointerRNA *ptr, const char *value) +{ + bController *cont= (bController *)ptr->data; + + BLI_strncpy_utf8(cont->name, value, sizeof(cont->name)); + + if (ptr->id.data) { + Object *ob= (Object *)ptr->id.data; + BLI_uniquename(&ob->controllers, cont, "Controller", '.', offsetof(bController, name), sizeof(cont->name)); + } +} + static void rna_Controller_type_set(struct PointerRNA *ptr, int value) { bController *cont= (bController *)ptr->data; @@ -177,6 +189,7 @@ void RNA_def_controller(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Constroller_name_set"); RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_LOGIC, NULL); diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c index 217b50b38e5..ba58a66a2d6 100644 --- a/source/blender/makesrna/intern/rna_sensor.c +++ b/source/blender/makesrna/intern/rna_sensor.c @@ -102,6 +102,18 @@ static StructRNA* rna_Sensor_refine(struct PointerRNA *ptr) } } +void rna_Sensor_name_set(PointerRNA *ptr, const char *value) +{ + bSensor *sens= (bSensor *)ptr->data; + + BLI_strncpy_utf8(sens->name, value, sizeof(sens->name)); + + if (ptr->id.data) { + Object *ob= (Object *)ptr->id.data; + BLI_uniquename(&ob->sensors, sens, "Sensor", '.', offsetof(bSensor, name), sizeof(sens->name)); + } +} + static void rna_Sensor_type_set(struct PointerRNA *ptr, int value) { bSensor *sens= (bSensor *)ptr->data; @@ -260,6 +272,7 @@ static void rna_def_sensor(BlenderRNA *brna) prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Name", "Sensor name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Sensor_name_set"); RNA_def_struct_name_property(srna, prop); RNA_def_property_update(prop, NC_LOGIC, NULL); From 77934cfaed55b559637e37ce9c158cd703cec360 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 15:53:34 +0000 Subject: [PATCH 084/147] Fix #28865: Draw_bounds_type does not display Polyhedron or Capsule types Separate DNA properties for bounding box used for bounding box display in 3d viewport and bounding box used for collision detection in game engine. Bumped subversion for proper updating old files to new system, but it need more complex testing. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenloader/intern/readfile.c | 14 ++++++++-- .../blender/editors/space_view3d/drawobject.c | 27 ++++++++++++------- source/blender/makesdna/DNA_object_types.h | 4 ++- source/blender/makesrna/intern/rna_object.c | 7 +++-- .../Converter/BL_BlenderDataConversion.cpp | 2 +- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 71771b6077d..9b28f083a24 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 260 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ea8e8f30d76..678d0e1406f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -12157,8 +12157,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } - /* put compatibility code here until next subversion bump */ - { + if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)){ + Object *ob; + + for (ob= main->object.first; ob; ob= ob->id.next) { + ob->collision_boundtype= ob->boundtype; + } + { Camera *cam; for(cam= main->camera.first; cam; cam= cam->id.next) { @@ -12171,6 +12176,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + /* put compatibility code here until next subversion bump */ + { + + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 593537f82d0..6a8e850a4ea 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -107,7 +107,7 @@ ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX)) -static void draw_bounding_volume(Scene *scene, Object *ob); +static void draw_bounding_volume(Scene *scene, Object *ob, short type); static void drawcube_size(float size); static void drawcircle_size(float size); @@ -2703,7 +2703,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D if(dt==OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0) - draw_bounding_volume(scene, ob); + draw_bounding_volume(scene, ob, ob->boundtype); } else if(hasHaloMat || (totface==0 && totedge==0)) { glPointSize(1.5); @@ -5508,7 +5508,7 @@ static void draw_bb_quadric(BoundBox *bb, short type) gluDeleteQuadric(qobj); } -static void draw_bounding_volume(Scene *scene, Object *ob) +static void draw_bounding_volume(Scene *scene, Object *ob, short type) { BoundBox *bb= NULL; @@ -5534,8 +5534,8 @@ static void draw_bounding_volume(Scene *scene, Object *ob) if(bb==NULL) return; - if(ob->boundtype==OB_BOUND_BOX) draw_box(bb->vec); - else draw_bb_quadric(bb, ob->boundtype); + if(type==OB_BOUND_BOX) draw_box(bb->vec); + else draw_bb_quadric(bb, type); } @@ -6101,7 +6101,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } else if(dt==OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0) - draw_bounding_volume(scene, ob); + draw_bounding_volume(scene, ob, ob->boundtype); } else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) empty_object= drawDispList(scene, v3d, rv3d, base, dt); @@ -6117,7 +6117,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } else if(dt==OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0) - draw_bounding_volume(scene, ob); + draw_bounding_volume(scene, ob, ob->boundtype); } else if(ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) { empty_object= drawDispList(scene, v3d, rv3d, base, dt); @@ -6134,7 +6134,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) drawmball(scene, v3d, rv3d, base, dt); else if(dt==OB_BOUNDBOX) { if((v3d->flag2 & V3D_RENDER_OVERRIDE && v3d->drawtype >= OB_WIRE)==0) - draw_bounding_volume(scene, ob); + draw_bounding_volume(scene, ob, ob->boundtype); } else empty_object= drawmball(scene, v3d, rv3d, base, dt); @@ -6376,6 +6376,14 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) } } + if(ob->gameflag & OB_BOUNDS) { + if(ob->boundtype!=ob->collision_boundtype || (dtx & OB_BOUNDBOX)==0) { + setlinestyle(2); + draw_bounding_volume(scene, ob, ob->collision_boundtype); + setlinestyle(0); + } + } + /* draw extra: after normal draw because of makeDispList */ if(dtx && (G.f & G_RENDER_OGL)==0) { @@ -6383,8 +6391,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) drawaxes(1.0f, OB_ARROWS); } if(dtx & OB_BOUNDBOX) { - if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) - draw_bounding_volume(scene, ob); + draw_bounding_volume(scene, ob, ob->boundtype); } if(dtx & OB_TEXSPACE) drawtexspace(ob); if(dtx & OB_DRAWNAME) { diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3e17d7f4942..d158f227df5 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -265,7 +265,9 @@ typedef struct Object { ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */ float ima_ofs[2]; /* offset for image empties */ - char pad3[8]; + + short collision_boundtype; /* bounding box type used for collision */ + char pad3[6]; } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index bc050f3a902..7e2700629ad 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -948,10 +948,10 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) if (ob->type == OB_MESH) { /* this is needed to refresh the derived meshes draw func */ DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); - WM_main_add_notifier(NC_OBJECT|ND_DRAW, ptr->id.data); } } + WM_main_add_notifier(NC_OBJECT|ND_DRAW, ptr->id.data); } static PointerRNA rna_Object_active_particle_system_get(PointerRNA *ptr) @@ -1532,9 +1532,10 @@ static void rna_def_object_game_settings(BlenderRNA *brna) prop= RNA_def_property(srna, "use_collision_bounds", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gameflag", OB_BOUNDS); RNA_def_property_ui_text(prop, "Use Collision Bounds", "Specify a collision bounds type other than the default"); + RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, NULL); prop= RNA_def_property(srna, "collision_bounds_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "boundtype"); + RNA_def_property_enum_sdna(prop, NULL, "collision_boundtype"); RNA_def_property_enum_items(prop, collision_bounds_items); RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_Object_collision_bounds_itemf"); RNA_def_property_ui_text(prop, "Collision Bounds", "Select the collision type"); @@ -1803,8 +1804,6 @@ static void rna_def_object(BlenderRNA *brna) {OB_BOUND_SPHERE, "SPHERE", 0, "Sphere", "Draw bounds as sphere"}, {OB_BOUND_CYLINDER, "CYLINDER", 0, "Cylinder", "Draw bounds as cylinder"}, {OB_BOUND_CONE, "CONE", 0, "Cone", "Draw bounds as cone"}, - {OB_BOUND_TRIANGLE_MESH, "POLYHEDRON", 0, "Polyhedron", "Draw bounds as polyhedron"}, - {OB_BOUND_CAPSULE, "CAPSULE", 0, "Capsule", "Draw bounds as capsule"}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem dupli_items[] = { diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index ca37b06d12e..779d794cc10 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1579,7 +1579,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, my_get_local_bounds(blenderobject,dm,objprop.m_boundobject.box.m_center,bb.m_extends); if (blenderobject->gameflag & OB_BOUNDS) { - switch (blenderobject->boundtype) + switch (blenderobject->collision_boundtype) { case OB_BOUND_BOX: objprop.m_boundclass = KX_BOUNDBOX; From 7b47a4125fa4219a0f6c1a3e8c78047211caaa53 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Nov 2011 18:10:50 +0000 Subject: [PATCH 085/147] Camera UI: tweaking panels, move clipping back because it's not part of the preset, and move depth of field settings to a separate panel. --- .../startup/bl_ui/properties_data_camera.py | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 4061a331261..0abbf281754 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -98,21 +98,15 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): split = layout.split() - col = split.column() - col.label(text="Depth of Field:") - - col.prop(cam, "dof_object", text="") - - col = col.column() - if cam.dof_object is not None: - col.enabled = False - col.prop(cam, "dof_distance", text="Distance") - col = split.column(align=True) col.label(text="Shift:") col.prop(cam, "shift_x", text="X") col.prop(cam, "shift_y", text="Y") + col = split.column(align=True) + col.label(text="Clipping:") + col.prop(cam, "clip_start", text="Start") + col.prop(cam, "clip_end", text="End") class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" @@ -143,11 +137,24 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): col = split.column(align=True) col.prop(cam, "sensor_fit", text="") - layout.label(text="Clipping:") - row = layout.row(align=True) - row.prop(cam, "clip_start", text="Start") - row.prop(cam, "clip_end", text="End") +class DATA_PT_camera_dof(CameraButtonsPanel, Panel): + bl_label = "Depth of Field" + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} + def draw(self, context): + layout = self.layout + + cam = context.camera + + layout.label(text="Focus:") + + split = layout.split() + split.prop(cam, "dof_object", text="") + + col = split.column() + + col.active = cam.dof_object is None + col.prop(cam, "dof_distance", text="Distance") class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Display" From c13bf35c22c20ffebb39202540ef7929e3a90341 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 4 Nov 2011 21:29:28 +0000 Subject: [PATCH 086/147] UI: fix region embossing being drawn 1 pixel misaligned, due to wrong opengl state. --- source/blender/editors/screen/area.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 7e79849ba40..9d6d663df5c 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -84,19 +84,19 @@ static void region_draw_emboss(ARegion *ar, rcti *scirct) glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); /* right */ - glColor4ub(0,0,0, 50); + glColor4ub(0,0,0, 30); sdrawline(rect.xmax, rect.ymin, rect.xmax, rect.ymax); /* bottom */ - glColor4ub(0,0,0, 80); + glColor4ub(0,0,0, 30); sdrawline(rect.xmin, rect.ymin, rect.xmax, rect.ymin); /* top */ - glColor4ub(255,255,255, 60); + glColor4ub(255,255,255, 30); sdrawline(rect.xmin, rect.ymax, rect.xmax, rect.ymax); /* left */ - glColor4ub(255,255,255, 50); + glColor4ub(255,255,255, 30); sdrawline(rect.xmin, rect.ymin, rect.xmin, rect.ymax); glDisable( GL_BLEND ); @@ -414,6 +414,9 @@ void ED_region_do_draw(bContext *C, ARegion *ar) /* note; this sets state, so we can use wmOrtho and friends */ wmSubWindowScissorSet(win, ar->swinid, &ar->drawrct); + + ar->do_draw= 0; + memset(&ar->drawrct, 0, sizeof(ar->drawrct)); UI_SetTheme(sa?sa->spacetype:0, ar->type?ar->type->regionid:0); @@ -429,18 +432,15 @@ void ED_region_do_draw(bContext *C, ARegion *ar) at->draw(C, ar); } + /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ + ED_region_pixelspace(ar); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_PIXEL); uiFreeInactiveBlocks(C, &ar->uiblocks); - + if(sa) region_draw_emboss(ar, &winrct); - - /* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */ - ED_region_pixelspace(ar); - - ar->do_draw= 0; - memset(&ar->drawrct, 0, sizeof(ar->drawrct)); } /* ********************************** From 2cc8d75bd8e7698bbefd7efb1d0949c857c137c6 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 4 Nov 2011 22:13:30 +0000 Subject: [PATCH 087/147] Forgot to initialize sensor height when creating new camera. --- source/blender/blenkernel/intern/object.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 9a0dbd2a2eb..a7acf096448 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -724,7 +724,8 @@ void *add_camera(const char *name) cam= alloc_libblock(&G.main->camera, ID_CA, name); cam->lens= 35.0f; - cam->sensor_x = 32.f; + cam->sensor_x= 32.0f; + cam->sensor_y= 18.0f; cam->clipsta= 0.1f; cam->clipend= 100.0f; cam->drawsize= 0.5f; From 1ba044b18d669dc63fb9ac1b987fc75f6f07ed10 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 5 Nov 2011 00:52:01 +0000 Subject: [PATCH 088/147] Fix #29141: fill / beautify fill produced incorrect results in edge selection mode. --- source/blender/editors/mesh/editmesh_tools.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 54b46cc14a6..99af17c161e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -6970,12 +6970,12 @@ static void beautify_fill(EditMesh *em) w= EM_face_from_faces(em, efaa[0], efaa[1], vindex[0], vindex[1], 4+vindex[2], -1); - w->f |= SELECT; + EM_select_face(w, 1); w= EM_face_from_faces(em, efaa[0], efaa[1], vindex[0], 4+vindex[2], 4+vindex[3], -1); - w->f |= SELECT; + EM_select_face(w, 1); onedone= 1; } @@ -6991,12 +6991,11 @@ static void beautify_fill(EditMesh *em) w= EM_face_from_faces(em, efaa[0], efaa[1], vindex[1], 4+vindex[2], 4+vindex[3], -1); - w->f |= SELECT; - + EM_select_face(w, 1); w= EM_face_from_faces(em, efaa[0], efaa[1], vindex[0], 4+vindex[1], 4+vindex[3], -1); - w->f |= SELECT; + EM_select_face(w, 1); onedone= 1; } From 6483069a84fc335283ffe400f5a85c9be46a0a80 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 5 Nov 2011 00:59:50 +0000 Subject: [PATCH 089/147] Fix #29138: changing game engine physics type from soft body to occluder, navmesh or no collision did not clear flag properly, causing soft body to still be partially applied. --- source/blender/makesrna/intern/rna_object.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 7e2700629ad..be2375f5716 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -901,11 +901,11 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) break; case OB_BODY_TYPE_OCCLUDER: ob->gameflag |= OB_OCCLUDER; - ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC|OB_NAVMESH); + ob->gameflag &= ~(OB_SENSOR|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION|OB_DYNAMIC|OB_NAVMESH); break; case OB_BODY_TYPE_NAVMESH: ob->gameflag |= OB_NAVMESH; - ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_DYNAMIC|OB_OCCLUDER); + ob->gameflag &= ~(OB_SENSOR|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION|OB_DYNAMIC|OB_OCCLUDER); if (ob->type == OB_MESH) { /* could be moved into mesh UI but for now ensure mesh data layer */ @@ -914,7 +914,7 @@ static void rna_GameObjectSettings_physics_type_set(PointerRNA *ptr, int value) break; case OB_BODY_TYPE_NO_COLLISION: - ob->gameflag &= ~(OB_SENSOR|OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC|OB_NAVMESH); + ob->gameflag &= ~(OB_SENSOR|OB_RIGID_BODY|OB_SOFT_BODY|OB_COLLISION|OB_OCCLUDER|OB_DYNAMIC|OB_NAVMESH); break; case OB_BODY_TYPE_STATIC: ob->gameflag |= OB_COLLISION; From 057bf2a02bd453ac8dd5048baa298de39f213560 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 01:48:10 +0000 Subject: [PATCH 090/147] misc doc edits - remove recently added sphinx reference workaround. - tested doxygen, correct some warnings, set tab width and added pymathutils group. - added convenience target 'make doc_doxy' --- GNUmakefile | 7 ++++++- doc/doxygen/Doxyfile | 2 +- doc/doxygen/doxygen.source | 4 ++++ doc/python_api/sphinx_doc_gen.py | 21 ++++++------------- intern/audaspace/intern/AUD_C-API.h | 2 +- intern/ghost/intern/GHOST_Buttons.h | 6 +++--- intern/ghost/intern/GHOST_DisplayManager.h | 2 +- intern/ghost/intern/GHOST_EventWheel.h | 2 +- source/blender/editors/curve/editcurve.c | 7 +------ source/blender/editors/include/ED_view3d.h | 4 ++-- source/blender/imbuf/intern/moviecache.c | 2 +- source/blender/python/mathutils/mathutils.c | 4 ++-- source/blender/python/mathutils/mathutils.h | 4 ++-- .../python/mathutils/mathutils_Color.c | 4 ++-- .../python/mathutils/mathutils_Color.h | 4 ++-- .../python/mathutils/mathutils_Euler.c | 4 ++-- .../python/mathutils/mathutils_Euler.h | 4 ++-- .../python/mathutils/mathutils_Matrix.c | 4 ++-- .../python/mathutils/mathutils_Matrix.h | 4 ++-- .../python/mathutils/mathutils_Quaternion.c | 4 ++-- .../python/mathutils/mathutils_Quaternion.h | 4 ++-- .../python/mathutils/mathutils_Vector.c | 4 ++-- .../python/mathutils/mathutils_Vector.h | 4 ++-- .../python/mathutils/mathutils_geometry.c | 4 ++-- .../python/mathutils/mathutils_geometry.h | 4 ++-- .../render/intern/source/external_engine.c | 2 +- source/gameengine/Ketsji/KX_KetsjiEngine.h | 3 +-- 27 files changed, 57 insertions(+), 63 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index b06344ca238..f6a6ee91f31 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -151,6 +151,7 @@ help: @echo "" @echo "Documentation Targets (not assosiated with building blender)" @echo " * doc_py - generate sphinx python api docs" + @echo " * doc_doxy - generate doxygen C/C++ docs" @echo " * doc_dna - generate blender file format reference" @echo " * doc_man - generate manpage" @echo "" @@ -238,9 +239,13 @@ check_sparse: # Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation. doc_py: $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python doc/python_api/sphinx_doc_gen.py - cd doc/python_api ; sphinx-build -n -b html sphinx-in sphinx-out + cd doc/python_api ; sphinx-build -b html sphinx-in sphinx-out @echo "docs written into: '$(BLENDER_DIR)/doc/python_api/sphinx-out/contents.html'" +doc_doxy: + cd doc/doxygen; doxygen + @echo "docs written into: '$(BLENDER_DIR)/doc/doxygen/html/index.html'" + doc_dna: $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python doc/blender_file_format/BlendFileDnaExporter_25.py @echo "docs written into: '$(BLENDER_DIR)/doc/blender_file_format/dna.html'" diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index b4d3b14b9dd..dd112ed6a48 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -193,7 +193,7 @@ SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 8 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". diff --git a/doc/doxygen/doxygen.source b/doc/doxygen/doxygen.source index 375234d26a3..cc3a2b14a92 100644 --- a/doc/doxygen/doxygen.source +++ b/doc/doxygen/doxygen.source @@ -22,6 +22,10 @@ * \ingroup python */ +/** \defgroup pymathutils Python Mathutils + * \ingroup python + */ + /** \defgroup pythonintern Python RNA and Operators * \ingroup python */ diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 3c43b5bc4da..36e092f85b7 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -150,10 +150,6 @@ def is_struct_seq(value): return isinstance(value, tuple) and type(tuple) != tuple and hasattr(value, "n_fields") -def module_id_as_ref(name): - return "mod_" + name.replace(".", "__") - - def undocumented_message(module_name, type_name, identifier): if str(type_name).startswith('`\n\n\n" % (full_name, module_id_as_ref(full_name))) - del full_name - attribute_set.add(key) del key, descr, descr_sorted diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index c7b8cb77771..2b7c94bcc5b 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -454,7 +454,7 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high, /** * Pauses a playing sound after a specific amount of time. * \param handle The handle to the sound. - * \param time The time in seconds. + * \param seconds The time in seconds. * \return The silence handle. */ extern AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds); diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h index 7a3d8b6ae71..0209dc304e4 100644 --- a/intern/ghost/intern/GHOST_Buttons.h +++ b/intern/ghost/intern/GHOST_Buttons.h @@ -52,15 +52,15 @@ struct GHOST_Buttons { /** * Returns the state of a single button. - * @param mask. Key button to return. + * @param mask Key button to return. * @return The state of the button (pressed == true). */ virtual bool get(GHOST_TButtonMask mask) const; /** * Updates the state of a single button. - * @param mask. Button state to update. - * @param down. The new state of the button. + * @param mask Button state to update. + * @param down The new state of the button. */ virtual void set(GHOST_TButtonMask mask, bool down); diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h index 8329d7be94e..d7a9b151d14 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.h +++ b/intern/ghost/intern/GHOST_DisplayManager.h @@ -72,7 +72,7 @@ public: /** * Returns the number of display settings for this display device. * @param display The index of the display to query with 0 <= display < getNumDisplays(). - * @param setting The number of settings of the display device with this index. + * @param numSettings The number of settings of the display device with this index. * @return Indication of success. */ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const; diff --git a/intern/ghost/intern/GHOST_EventWheel.h b/intern/ghost/intern/GHOST_EventWheel.h index 0036fa60275..2a82ab8a630 100644 --- a/intern/ghost/intern/GHOST_EventWheel.h +++ b/intern/ghost/intern/GHOST_EventWheel.h @@ -26,7 +26,7 @@ */ /** \file ghost/intern/GHOST_EventWheel.h - * \ingroup GHOSTeel.h + * \ingroup GHOST * Declaration of GHOST_EventWheel class. */ diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4087002598e..4a12206d404 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -2812,12 +2812,7 @@ void CURVE_OT_select_inverse(wmOperatorType *ot) /** Divide the line segments associated with the currently selected * curve nodes (Bezier or NURB). If there are no valid segment * selections within the current selection, nothing happens. - * - * @deffunc subdividenurb subdivideNurb(void) - * @return Nothing - * @param None -*/ - + */ static void subdividenurb(Object *obedit, int number_cuts) { Curve *cu= obedit->data; diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f69abb0996a..e43ad964c9c 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -130,7 +130,6 @@ void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const * In orthographic view the resulting ray_normal will match the view vector. * @param ar The region (used for the window width and height). * @param v3d The 3d viewport (used for near clipping value). - * @param out The resulting normalized world-space direction vector. * @param mval The area relative 2d location (such as event->mval, converted into float[2]). * @param ray_start The world-space starting point of the segment. * @param ray_normal The normalized world-space direction of towards mval. @@ -140,7 +139,7 @@ void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mv /** * Calculate a normalized 3d direction vector from the viewpoint towards a global location. * In orthographic view the resulting vector will match the view vector. - * @param ar The region (used for the window width and height). + * @param rv3d The region (used for the window width and height). * @param coord The world-space location. * @param vec The resulting normalized vector. */ @@ -171,6 +170,7 @@ void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist) * @param ofs The view offset to be set, normally from RegionView3D.ofs. * @param quat The view rotation to be set, quaternion normally from RegionView3D.viewquat. * @param dist The view distance from ofs to be set, normally from RegionView3D.dist. + * @param lens The view lens angle set for cameras and lamps, normally from View3D.lens. */ void ED_view3d_from_object(struct Object *ob, float ofs[3], float quat[4], float *dist, float *lens); diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c index 1d752fe9c6d..41169a1c211 100644 --- a/source/blender/imbuf/intern/moviecache.c +++ b/source/blender/imbuf/intern/moviecache.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/blenkernel/intern/moviecache.c +/** \file blender/imbuf/intern/moviecache.c * \ingroup bke */ diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c index 770a743b733..41c1568dbde 100644 --- a/source/blender/python/mathutils/mathutils.c +++ b/source/blender/python/mathutils/mathutils.c @@ -25,8 +25,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils.c + * \ingroup pymathutils */ #include diff --git a/source/blender/python/mathutils/mathutils.h b/source/blender/python/mathutils/mathutils.h index bcea62c8f1c..70b0ef93ebd 100644 --- a/source/blender/python/mathutils/mathutils.h +++ b/source/blender/python/mathutils/mathutils.h @@ -26,8 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils.h + * \ingroup pymathutils */ //Include this file for access to vector, quat, matrix, euler, etc... diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index a0035e5f34d..c374d0eb73d 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -21,8 +21,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_Color.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Color.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index 231fab511c8..6c84b5f596d 100644 --- a/source/blender/python/mathutils/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -27,8 +27,8 @@ * */ -/** \file blender/python/generic/mathutils_Color.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Color.h + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c index 4d44ec8b1e9..ce9ac5fbbb5 100644 --- a/source/blender/python/mathutils/mathutils_Euler.c +++ b/source/blender/python/mathutils/mathutils_Euler.c @@ -25,8 +25,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_Euler.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Euler.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Euler.h b/source/blender/python/mathutils/mathutils_Euler.h index 0c51a2a1dd8..46f5910f31f 100644 --- a/source/blender/python/mathutils/mathutils_Euler.h +++ b/source/blender/python/mathutils/mathutils_Euler.h @@ -27,8 +27,8 @@ * */ -/** \file blender/python/generic/mathutils_Euler.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Euler.h + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 2a5d45bdff0..980dbd17a96 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -24,8 +24,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_Matrix.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Matrix.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Matrix.h b/source/blender/python/mathutils/mathutils_Matrix.h index 01fae91b1a4..275f4270787 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.h +++ b/source/blender/python/mathutils/mathutils_Matrix.h @@ -26,8 +26,8 @@ * */ -/** \file blender/python/generic/mathutils_Matrix.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Matrix.h + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c index f892c25f67e..3f0a5d55ec2 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.c +++ b/source/blender/python/mathutils/mathutils_Quaternion.c @@ -24,8 +24,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_Quaternion.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Quaternion.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Quaternion.h b/source/blender/python/mathutils/mathutils_Quaternion.h index c8029d61679..13060ed9ff9 100644 --- a/source/blender/python/mathutils/mathutils_Quaternion.h +++ b/source/blender/python/mathutils/mathutils_Quaternion.h @@ -27,8 +27,8 @@ * */ -/** \file blender/python/generic/mathutils_Quaternion.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Quaternion.h + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index a932d8d6b01..ba7cf604c42 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -24,8 +24,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_Vector.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Vector.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_Vector.h b/source/blender/python/mathutils/mathutils_Vector.h index bd4cd5f5be7..610805fcee0 100644 --- a/source/blender/python/mathutils/mathutils_Vector.h +++ b/source/blender/python/mathutils/mathutils_Vector.h @@ -27,8 +27,8 @@ * */ -/** \file blender/python/generic/mathutils_Vector.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_Vector.h + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index 6e8624721b7..e8721a3a91d 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -26,8 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_geometry.c - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_geometry.c + * \ingroup pymathutils */ diff --git a/source/blender/python/mathutils/mathutils_geometry.h b/source/blender/python/mathutils/mathutils_geometry.h index 58a2bf9142f..1b339bdaf00 100644 --- a/source/blender/python/mathutils/mathutils_geometry.h +++ b/source/blender/python/mathutils/mathutils_geometry.h @@ -26,8 +26,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/generic/mathutils_geometry.h - * \ingroup pygen +/** \file blender/python/mathutils/mathutils_geometry.h + * \ingroup pymathutils */ /*Include this file for access to vector, quat, matrix, euler, etc...*/ diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index b37da67f743..b7f89e260a8 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -26,7 +26,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/render/intern/pipeline/engine.c +/** \file blender/render/intern/source/external_engine.c * \ingroup render */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 40f157ef0a4..5a02da07e43 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -387,8 +387,7 @@ public: void SetUseOverrideFrameColor(bool overrideFrameColor); /** - * Enables/disables the use of the framing bar color of the Blender file's scenes. - * @param useSceneFrameColor The new setting. + * Check if the frame color is being overridden. */ bool GetUseOverrideFrameColor(void) const; From b0adf37ef90c5c42ff48da9938fe1a041d52ae46 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 02:30:25 +0000 Subject: [PATCH 091/147] - view bounds (now split from collision bounds) was still being used for bge physics in one place, comparison was incorrectly treating it as a flag too. - cleanup Object struct - remove pad and unused flags, convert some shot's to char's, saving 24 bytes. --- source/blender/blenkernel/intern/object.c | 1 - source/blender/blenloader/intern/readfile.c | 5 +-- source/blender/editors/object/object_edit.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 6 ++-- source/blender/makesdna/DNA_object_types.h | 36 +++++++++---------- .../Converter/BL_BlenderDataConversion.cpp | 2 +- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a7acf096448..1e0ece1c5e6 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1107,7 +1107,6 @@ Object *add_only_object(int type, const char *name) ob->obstacleRad = 1.; /* NT fluid sim defaults */ - ob->fluidsimFlag = 0; ob->fluidsimSettings = NULL; ob->pc_ids.first = ob->pc_ids.last = NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 678d0e1406f..fc0f3028a0e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -8245,7 +8245,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(main->versionfile <= 233) { bScreen *sc; Material *ma= main->mat.first; - Object *ob= main->object.first; + /* Object *ob= main->object.first; */ while(ma) { if(ma->rampfac_col==0.0f) ma->rampfac_col= 1.0; @@ -8255,11 +8255,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } /* this should have been done loooong before! */ +#if 0 /* deprecated in 2.5+ */ while(ob) { if(ob->ipowin==0) ob->ipowin= ID_OB; ob= ob->id.next; } - +#endif for (sc= main->screen.first; sc; sc= sc->id.next) { ScrArea *sa; for (sa= sc->areabase.first; sa; sa= sa->next) { diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index d3473225095..f2997dc743d 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1182,7 +1182,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->min_vel= ob->min_vel; base->object->max_vel= ob->max_vel; if (ob->gameflag & OB_BOUNDS) { - base->object->boundtype = ob->boundtype; + base->object->collision_boundtype = ob->collision_boundtype; } base->object->margin= ob->margin; base->object->bsoft= copy_bulletsoftbody(ob->bsoft); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6a8e850a4ea..cb3bc2954e1 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -107,7 +107,7 @@ ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX)) -static void draw_bounding_volume(Scene *scene, Object *ob, short type); +static void draw_bounding_volume(Scene *scene, Object *ob, char type); static void drawcube_size(float size); static void drawcircle_size(float size); @@ -5469,7 +5469,7 @@ static void get_local_bounds(Object *ob, float center[3], float size[3]) } #endif -static void draw_bb_quadric(BoundBox *bb, short type) +static void draw_bb_quadric(BoundBox *bb, char type) { float size[3], cent[3]; GLUquadricObj *qobj = gluNewQuadric(); @@ -5508,7 +5508,7 @@ static void draw_bb_quadric(BoundBox *bb, short type) gluDeleteQuadric(qobj); } -static void draw_bounding_volume(Scene *scene, Object *ob, short type) +static void draw_bounding_volume(Scene *scene, Object *ob, char type) { BoundBox *bb= NULL; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index d158f227df5..c5fd17e1bdb 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -164,9 +164,10 @@ typedef struct Object { short transflag, protectflag; /* transformation settings and transform locks */ short trackflag, upflag; short nlaflag, ipoflag; // xxx depreceated... old animation system - short ipowin, scaflag; /* ipowin: blocktype last ipowindow */ - short scavisflag, boundtype; - + short scaflag; /* ipowin: blocktype last ipowindow */ + char scavisflag; + char pad5; + int dupon, dupoff, dupsta, dupend; float sf, ctime; /* sf is time-offset, ctime is the objects current time (XXX timing needs to be revised) */ @@ -193,12 +194,16 @@ typedef struct Object { float min_vel; /* clamp the maximum velocity 0.0 is disabled */ float m_contactProcessingThreshold; float obstacleRad; - char pad0[4]; - + short rotmode; /* rotation mode - uses defines set out in DNA_action_types.h for PoseChannel rotations... */ - + + char boundtype; /* bounding box use for drawing */ + char collision_boundtype; /* bounding box type used for collision */ + + char restrictflag; /* for restricting view, select, render etc. accessible in outliner */ + char dt, dtx; - char empty_drawtype, pad1[3]; + char empty_drawtype; float empty_drawsize; float dupfacesca; /* dupliface scale */ @@ -206,7 +211,7 @@ typedef struct Object { ListBase sensors; ListBase controllers; ListBase actuators; - + float bbsize[3]; short index; /* custom index, for renderpasses */ unsigned short actdef; /* current deformation group, note: index starts at 1 */ @@ -242,16 +247,12 @@ typedef struct Object { struct PartDeflect *pd; /* particle deflector/attractor/collision data */ struct SoftBody *soft; /* if exists, saved in file */ struct Group *dup_group; /* object duplicator for group */ - - short fluidsimFlag; /* NT toggle fluidsim participation on/off */ - - short restrictflag; /* for restricting view, select, render etc. accessible in outliner */ - short shapenr, shapeflag; /* current shape key for menu or pinned, flag for pinning */ + char body_type; /* for now used to temporarily holds the type of collision object */ + char shapeflag; /* flag for pinning */ + short shapenr; /* current shape key for menu or pinned */ float smoothresh; /* smoothresh is phong interpolation ray_shadow correction in render */ - short recalco; /* recalco for temp storage of ob->recalc, bad design warning */ - short body_type; /* for now used to temporarily holds the type of collision object */ - + struct FluidsimSettings *fluidsimSettings; /* if fluidsim enabled, store additional settings */ struct DerivedMesh *derivedDeform, *derivedFinal; @@ -265,9 +266,6 @@ typedef struct Object { ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */ float ima_ofs[2]; /* offset for image empties */ - - short collision_boundtype; /* bounding box type used for collision */ - char pad3[6]; } Object; /* Warning, this is not used anymore because hooks are now modifiers */ diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 779d794cc10..57611d65e14 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1648,7 +1648,7 @@ void BL_CreatePhysicsObjectNew(KX_GameObject* gameobj, } - objprop.m_concave = (blenderobject->boundtype & 4) != 0; + objprop.m_concave = (blenderobject->collision_boundtype == OB_BOUND_TRIANGLE_MESH); switch (physics_engine) { From cc7e79f37272c9e9565d6eb456138a6f07fea9fc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 03:02:55 +0000 Subject: [PATCH 092/147] more DNA object edits - remove 'path' pointer, wasnt used anywhere. - remove comments about what each game flag 'bit' does, these are defines now. - reduce the size of DupliObject 8 bytes. also commented some of the struct members. --- source/blender/blenkernel/intern/object.c | 3 -- source/blender/blenloader/intern/readfile.c | 4 +- source/blender/makesdna/DNA_object_types.h | 58 +++++++++------------ 3 files changed, 27 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1e0ece1c5e6..b09d1ea98aa 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -303,8 +303,6 @@ void free_object(Object *ob) ob->matbits= NULL; if(ob->bb) MEM_freeN(ob->bb); ob->bb= NULL; - if(ob->path) free_path(ob->path); - ob->path= NULL; if(ob->adt) BKE_free_animdata((ID *)ob); if(ob->poselib) ob->poselib->id.us--; if(ob->gpd) ((ID *)ob->gpd)->us--; @@ -1376,7 +1374,6 @@ Object *copy_object(Object *ob) } if(ob->bb) obn->bb= MEM_dupallocN(ob->bb); - obn->path= NULL; obn->flag &= ~OB_FROMGROUP; obn->modifiers.first = obn->modifiers.last= NULL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fc0f3028a0e..13c21840459 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7429,9 +7429,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if(main->versionfile <= 200) { Object *ob= main->object.first; while(ob) { - ob->scaflag = ob->gameflag & (64+128+256+512+1024+2048); + ob->scaflag = ob->gameflag & (OB_DO_FH|OB_ROT_FH|OB_ANISOTROPIC_FRICTION|OB_GHOST|OB_RIGID_BODY|OB_BOUNDS); /* 64 is do_fh */ - ob->gameflag &= ~(128+256+512+1024+2048); + ob->gameflag &= ~(OB_ROT_FH|OB_ANISOTROPIC_FRICTION|OB_GHOST|OB_RIGID_BODY|OB_BOUNDS); ob = ob->id.next; } } diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index c5fd17e1bdb..3306b9e97bc 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -111,12 +111,12 @@ typedef struct Object { /* proxy_from is set in target back to the proxy. */ struct Object *proxy, *proxy_group, *proxy_from; struct Ipo *ipo; // XXX depreceated... old animation system - struct Path *path; + /* struct Path *path; */ struct BoundBox *bb; struct bAction *action; // XXX depreceated... old animation system struct bAction *poselib; - struct bPose *pose; - void *data; + struct bPose *pose; /* pose data, armature objects only */ + void *data; /* pointer to objects data - an 'ID' or NULL */ struct bGPdata *gpd; /* Grease Pencil data */ @@ -124,9 +124,9 @@ typedef struct Object { bMotionPath *mpath; /* motion path cache for this object */ ListBase constraintChannels; // XXX depreceated... old animation system - ListBase effect; - ListBase disp; - ListBase defbase; + ListBase effect; // XXX depreceated... keep for readfile + ListBase disp; /* list of DispList, used by lattice, metaballs curve & surfaces */ + ListBase defbase; /* list of bDeformGroup (vertex groups) names and flag only */ ListBase modifiers; /* list of ModifierData structures */ int mode; /* Local object mode */ @@ -156,7 +156,7 @@ typedef struct Object { */ float imat_ren[4][4]; - unsigned int lay; /* copy of Base */ + unsigned int lay; /* copy of Base's layer in the scene */ short flag; /* copy of Base */ short colbits; /* deprecated */ @@ -164,8 +164,8 @@ typedef struct Object { short transflag, protectflag; /* transformation settings and transform locks */ short trackflag, upflag; short nlaflag, ipoflag; // xxx depreceated... old animation system - short scaflag; /* ipowin: blocktype last ipowindow */ - char scavisflag; + short scaflag; /* ui state for game logic */ + char scavisflag; /* more display settings for game logic */ char pad5; int dupon, dupoff, dupsta, dupend; @@ -200,39 +200,27 @@ typedef struct Object { char boundtype; /* bounding box use for drawing */ char collision_boundtype; /* bounding box type used for collision */ - char restrictflag; /* for restricting view, select, render etc. accessible in outliner */ + char restrictflag; /* for restricting view, select, render etc. accessible in outliner */ - char dt, dtx; + char dt; /* viewport draw type */ + char dtx; /* viewport draw extra settings */ char empty_drawtype; float empty_drawsize; float dupfacesca; /* dupliface scale */ - ListBase prop; - ListBase sensors; - ListBase controllers; - ListBase actuators; + ListBase prop; /* game logic property list (not to be confused with IDProperties) */ + ListBase sensors; /* game logic sensors */ + ListBase controllers; /* game logic controllers */ + ListBase actuators; /* game logic actuators */ float bbsize[3]; short index; /* custom index, for renderpasses */ unsigned short actdef; /* current deformation group, note: index starts at 1 */ float col[4]; /* object color */ - /** - * Settings for game objects - * bit 0: Object has dynamic behaviour - * bit 2: Object is evaluated by the gameengine - * bit 6: Use Fh settings in Materials - * bit 7: Use face normal to rotate Object - * bit 8: Friction is anisotropic - * bit 9: Object is a ghost - * bit 10: Do rigid body dynamics. - * bit 11: Use bounding object for physics - */ + int gameflag; - /** - * More settings - * bit 15: Always ignore activity culling - */ int gameflag2; + struct BulletSoftBody *bsoft; /* settings for game engine bullet soft body */ short softflag; /* softbody settings */ @@ -241,7 +229,7 @@ typedef struct Object { ListBase constraints; /* object constraints */ ListBase nlastrips; // XXX depreceated... old animation system - ListBase hooks; + ListBase hooks; // XXX depreceated... old animation system ListBase particlesystem; /* particle systems */ struct PartDeflect *pd; /* particle deflector/attractor/collision data */ @@ -261,7 +249,7 @@ typedef struct Object { unsigned int state; /* bit masks of game controllers that are active */ unsigned int init_state; /* bit masks of initial state as recorded by the users */ - ListBase gpulamp; /* runtime, for lamps only */ + ListBase gpulamp; /* runtime, for glsl lamp display only */ ListBase pc_ids; ListBase *duplilist; /* for temporary dupli list storage, only for use by RNA API */ @@ -286,13 +274,17 @@ typedef struct ObHook { float force; } ObHook; +/* runtime only, but include here for rna access */ typedef struct DupliObject { struct DupliObject *next, *prev; struct Object *ob; unsigned int origlay; - int index, no_draw, type, animated; + int index; float mat[4][4], omat[4][4]; float orco[3], uv[2]; + + short type; /* from Object.transflag */ + char no_draw, animated; } DupliObject; /* **************** OBJECT ********************* */ From a71e2c498cbb3c1ec077e38e0fcb8ee1581e4d6b Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 5 Nov 2011 03:29:37 +0000 Subject: [PATCH 093/147] GPU Buffers Small type cleanup, use `GPU_Buffers *' rather than `void *'. Should be no functional changes. --- source/blender/blenlib/intern/pbvh.c | 2 +- source/blender/gpu/GPU_buffers.h | 13 +++++++------ source/blender/gpu/intern/gpu_buffers.c | 16 ++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c index 9471f096682..5a8e378e8c4 100644 --- a/source/blender/blenlib/intern/pbvh.c +++ b/source/blender/blenlib/intern/pbvh.c @@ -80,7 +80,7 @@ typedef struct { struct PBVHNode { /* Opaque handle for drawing code */ - void *draw_buffers; + GPU_Buffers *draw_buffers; /* Voxel bounds */ BB vb; diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h index 7dabb9898cc..5e0eff69047 100644 --- a/source/blender/gpu/GPU_buffers.h +++ b/source/blender/gpu/GPU_buffers.h @@ -161,17 +161,18 @@ void GPU_buffer_unbind(void); int GPU_buffer_legacy( struct DerivedMesh *dm ); /* Buffers for non-DerivedMesh drawing */ -void *GPU_build_mesh_buffers(struct GHash *map, struct MVert *mvert, +typedef struct GPU_Buffers GPU_Buffers; +GPU_Buffers *GPU_build_mesh_buffers(struct GHash *map, struct MVert *mvert, struct MFace *mface, int *face_indices, int totface, int *vert_indices, int uniq_verts, int totvert); -void GPU_update_mesh_buffers(void *buffers, struct MVert *mvert, +void GPU_update_mesh_buffers(GPU_Buffers *buffers, struct MVert *mvert, int *vert_indices, int totvert); -void *GPU_build_grid_buffers(struct DMGridData **grids, +GPU_Buffers *GPU_build_grid_buffers(struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize); -void GPU_update_grid_buffers(void *buffers_v, struct DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers_v, struct DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth); -void GPU_draw_buffers(void *buffers); -void GPU_free_buffers(void *buffers); +void GPU_draw_buffers(GPU_Buffers *buffers); +void GPU_free_buffers(GPU_Buffers *buffers); #endif diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index d833fb5eb04..22cae058b2a 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1279,7 +1279,7 @@ typedef struct { short no[3]; } VertexBufferFormat; -typedef struct { +struct GPU_Buffers { /* opengl buffer handles */ GLuint vert_buf, index_buf; GLenum index_type; @@ -1297,9 +1297,9 @@ typedef struct { int gridsize; unsigned int tot_tri, tot_quad; -} GPU_Buffers; +}; -void GPU_update_mesh_buffers(void *buffers_v, MVert *mvert, +void GPU_update_mesh_buffers(GPU_Buffers *buffers_v, MVert *mvert, int *vert_indices, int totvert) { GPU_Buffers *buffers = buffers_v; @@ -1336,7 +1336,7 @@ void GPU_update_mesh_buffers(void *buffers_v, MVert *mvert, buffers->mvert = mvert; } -void *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface, +GPU_Buffers *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface, int *face_indices, int totface, int *vert_indices, int tot_uniq_verts, int totvert) @@ -1416,7 +1416,7 @@ void *GPU_build_mesh_buffers(GHash *map, MVert *mvert, MFace *mface, return buffers; } -void GPU_update_grid_buffers(void *buffers_v, DMGridData **grids, +void GPU_update_grid_buffers(GPU_Buffers *buffers_v, DMGridData **grids, int *grid_indices, int totgrid, int gridsize, int smooth) { GPU_Buffers *buffers = buffers_v; @@ -1471,7 +1471,7 @@ void GPU_update_grid_buffers(void *buffers_v, DMGridData **grids, //printf("node updated %p\n", buffers_v); } -void *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indices), +GPU_Buffers *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indices), int totgrid, int gridsize) { GPU_Buffers *buffers; @@ -1561,7 +1561,7 @@ void *GPU_build_grid_buffers(DMGridData **UNUSED(grids), int *UNUSED(grid_indice return buffers; } -void GPU_draw_buffers(void *buffers_v) +void GPU_draw_buffers(GPU_Buffers *buffers_v) { GPU_Buffers *buffers = buffers_v; @@ -1635,7 +1635,7 @@ void GPU_draw_buffers(void *buffers_v) } } -void GPU_free_buffers(void *buffers_v) +void GPU_free_buffers(GPU_Buffers *buffers_v) { if(buffers_v) { GPU_Buffers *buffers = buffers_v; From 62f22185546e80b661424b45c88006f8b592d8b1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 05:44:52 +0000 Subject: [PATCH 094/147] macro formatting & remve some unused code. --- source/blender/blenkernel/BKE_context.h | 18 ++-- source/blender/blenkernel/BKE_sequencer.h | 22 ++--- .../blender/editors/space_graph/graph_draw.c | 10 +- .../blender/editors/space_view3d/drawobject.c | 4 +- .../editors/space_view3d/view3d_header.c | 3 - source/blender/makesdna/DNA_userdef_types.h | 8 +- source/blender/makesrna/RNA_access.h | 54 ++++++----- source/blender/makesrna/intern/makesrna.c | 41 +++++---- source/blender/makesrna/intern/rna_access.c | 40 ++++---- source/blender/makesrna/intern/rna_color.c | 25 ++--- .../nodes/composite/node_composite_util.c | 36 ++++---- .../nodes/node_composite_bilateralblur.c | 56 +++++------ source/blender/python/generic/bgl.c | 47 ++++++---- source/blender/python/generic/bgl.h | 15 +-- .../python/generic/bpy_internal_import.c | 80 +--------------- source/blender/python/intern/bpy_props.c | 92 ++++++++++--------- source/blender/python/intern/bpy_rna.c | 32 ++++--- .../blender/render/intern/include/texture.h | 33 ++++--- source/creator/creator.c | 37 ++++---- source/gameengine/Expressions/PyObjectPlus.h | 41 +++++---- 20 files changed, 331 insertions(+), 363 deletions(-) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 3f9edf41e3c..c065a210a98 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -203,17 +203,17 @@ int CTX_data_dir(const char *member); /*void CTX_data_pointer_set(bContextDataResult *result, void *data); void CTX_data_list_add(bContextDataResult *result, void *data);*/ -#define CTX_DATA_BEGIN(C, Type, instance, member) \ - { \ - ListBase ctx_data_list; \ - CollectionPointerLink *ctx_link; \ - CTX_data_##member(C, &ctx_data_list); \ - for(ctx_link=ctx_data_list.first; ctx_link; ctx_link=ctx_link->next) { \ +#define CTX_DATA_BEGIN(C, Type, instance, member) \ + { \ + ListBase ctx_data_list; \ + CollectionPointerLink *ctx_link; \ + CTX_data_##member(C, &ctx_data_list); \ + for(ctx_link=ctx_data_list.first; ctx_link; ctx_link=ctx_link->next) {\ Type instance= ctx_link->ptr.data; -#define CTX_DATA_END \ - } \ - BLI_freelistN(&ctx_data_list); \ +#define CTX_DATA_END \ + } \ + BLI_freelistN(&ctx_data_list); \ } int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase*)); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index e64de965db5..917b62c27cf 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -67,21 +67,21 @@ void seq_next(SeqIterator *iter); void seq_end(SeqIterator *iter); void seq_array(struct Editing *ed, struct Sequence ***seqarray, int *tot, int use_pointer); -#define SEQP_BEGIN(ed, _seq) \ -{ \ - SeqIterator iter;\ - for(seq_begin(ed, &iter, 1); iter.valid; seq_next(&iter)) { \ +#define SEQP_BEGIN(ed, _seq) \ +{ \ + SeqIterator iter; \ + for(seq_begin(ed, &iter, 1); iter.valid; seq_next(&iter)) { \ _seq= iter.seq; -#define SEQ_BEGIN(ed, _seq) \ - { \ - SeqIterator iter;\ - for(seq_begin(ed, &iter, 0); iter.valid; seq_next(&iter)) { \ +#define SEQ_BEGIN(ed, _seq) \ + { \ + SeqIterator iter; \ + for(seq_begin(ed, &iter, 0); iter.valid; seq_next(&iter)) { \ _seq= iter.seq; -#define SEQ_END \ - } \ - seq_end(&iter); \ +#define SEQ_END \ + } \ + seq_end(&iter); \ } typedef struct SeqRenderData { diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 37e6c0b73c9..7091fe094c6 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -78,11 +78,11 @@ * - intV: integer value containing color info packed into an int * - alpha: float value describing the */ -#define cpackA(intVC, alpha) \ - { \ - float _cpackCol[3]; \ - cpack_to_rgb(intVC, &_cpackCol[0], &_cpackCol[1], &_cpackCol[2]); \ - glColor4f(_cpackCol[0], _cpackCol[1], _cpackCol[2], alpha); \ +#define cpackA(intVC, alpha) \ + { \ + float _cpackCol[3]; \ + cpack_to_rgb(intVC, &_cpackCol[0], &_cpackCol[1], &_cpackCol[2]); \ + glColor4f(_cpackCol[0], _cpackCol[1], _cpackCol[2], alpha); \ } /* *************************** */ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index cb3bc2954e1..c455c107b48 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -103,8 +103,8 @@ /* this condition has been made more complex since editmode can draw textures */ -#define CHECK_OB_DRAWTEXTURE(vd, dt) \ - ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ +#define CHECK_OB_DRAWTEXTURE(vd, dt) \ + ((vd->drawtype==OB_TEXTURE && dt>OB_SOLID) || \ (vd->drawtype==OB_SOLID && vd->flag2 & V3D_SOLID_TEX)) static void draw_bounding_volume(Scene *scene, Object *ob, char type); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index fa6611b9925..73174dcace8 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -83,9 +83,6 @@ * This can be cleaned when I make some new 'mode' icons. */ -#define TEST_EDITMESH if(obedit==0) return; \ - if( (v3d->lay & obedit->lay)==0 ) return; - /* view3d handler codes */ #define VIEW3D_HANDLER_BACKGROUND 1 #define VIEW3D_HANDLER_PROPERTIES 2 diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 8dd00f4ac08..f54c83d6612 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -440,10 +440,10 @@ extern UserDef U; /* from blenkernel blender.c */ #define USER_TOOLTIPS_PYTHON (1 << 26) /* helper macro for checking frame clamping */ -#define FRAMENUMBER_MIN_CLAMP(cfra) \ - { \ - if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \ - cfra = 0; \ +#define FRAMENUMBER_MIN_CLAMP(cfra) \ + { \ + if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \ + cfra = 0; \ } /* viewzom */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 204f7b0b0ec..7adfc9a5c16 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -874,37 +874,49 @@ int RNA_collection_length(PointerRNA *ptr, const char *name); void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value); void RNA_collection_clear(PointerRNA *ptr, const char *name); -#define RNA_BEGIN(sptr, itemptr, propname) \ - { \ - CollectionPropertyIterator rna_macro_iter; \ - for(RNA_collection_begin(sptr, propname, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \ +#define RNA_BEGIN(sptr, itemptr, propname) \ + { \ + CollectionPropertyIterator rna_macro_iter; \ + for(RNA_collection_begin(sptr, propname, &rna_macro_iter); \ + rna_macro_iter.valid; \ + RNA_property_collection_next(&rna_macro_iter)) \ + { \ PointerRNA itemptr= rna_macro_iter.ptr; -#define RNA_END \ - } \ - RNA_property_collection_end(&rna_macro_iter); \ +#define RNA_END \ + } \ + RNA_property_collection_end(&rna_macro_iter); \ } -#define RNA_PROP_BEGIN(sptr, itemptr, prop) \ - { \ - CollectionPropertyIterator rna_macro_iter; \ - for(RNA_property_collection_begin(sptr, prop, &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \ +#define RNA_PROP_BEGIN(sptr, itemptr, prop) \ + { \ + CollectionPropertyIterator rna_macro_iter; \ + for(RNA_property_collection_begin(sptr, prop, &rna_macro_iter); \ + rna_macro_iter.valid; \ + RNA_property_collection_next(&rna_macro_iter)) \ + { \ PointerRNA itemptr= rna_macro_iter.ptr; -#define RNA_PROP_END \ - } \ - RNA_property_collection_end(&rna_macro_iter); \ +#define RNA_PROP_END \ + } \ + RNA_property_collection_end(&rna_macro_iter); \ } -#define RNA_STRUCT_BEGIN(sptr, prop) \ - { \ - CollectionPropertyIterator rna_macro_iter; \ - for(RNA_property_collection_begin(sptr, RNA_struct_iterator_property(sptr->type), &rna_macro_iter); rna_macro_iter.valid; RNA_property_collection_next(&rna_macro_iter)) { \ +#define RNA_STRUCT_BEGIN(sptr, prop) \ + { \ + CollectionPropertyIterator rna_macro_iter; \ + for(RNA_property_collection_begin( \ + sptr, \ + RNA_struct_iterator_property(sptr->type), \ + &rna_macro_iter); \ + rna_macro_iter.valid; \ + RNA_property_collection_next(&rna_macro_iter)) \ + { \ PropertyRNA *prop= rna_macro_iter.ptr.data; -#define RNA_STRUCT_END \ - } \ - RNA_property_collection_end(&rna_macro_iter); \ +#define RNA_STRUCT_END \ + } \ + RNA_property_collection_end(&rna_macro_iter); \ } /* check if the idproperty exists, for operators */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index adedcbb18b3..891b62f7c79 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -70,25 +70,28 @@ static int replace_if_different(char *tmpfile, const char *dep_files[]) { // return 0; // use for testing had edited rna -#define REN_IF_DIFF \ - { \ - FILE *file_test= fopen(orgfile, "rb"); \ - if(file_test) { \ - fclose(file_test); \ - if(fp_org) fclose(fp_org); \ - if(fp_new) fclose(fp_new); \ - if(remove(orgfile) != 0) { \ - fprintf(stderr, "%s:%d, Remove Error (%s): \"%s\"\n", __FILE__, __LINE__, strerror(errno), orgfile); \ - return -1; \ - } \ - } \ - } \ - if(rename(tmpfile, orgfile) != 0) { \ - fprintf(stderr, "%s:%d, Rename Error (%s): \"%s\" -> \"%s\"\n", __FILE__, __LINE__, strerror(errno), tmpfile, orgfile); \ - return -1; \ - } \ - remove(tmpfile); \ - return 1; \ +#define REN_IF_DIFF \ + { \ + FILE *file_test= fopen(orgfile, "rb"); \ + if(file_test) { \ + fclose(file_test); \ + if(fp_org) fclose(fp_org); \ + if(fp_new) fclose(fp_new); \ + if(remove(orgfile) != 0) { \ + fprintf(stderr, "%s:%d, Remove Error (%s): \"%s\"\n", \ + __FILE__, __LINE__, strerror(errno), orgfile); \ + return -1; \ + } \ + } \ + } \ + if(rename(tmpfile, orgfile) != 0) { \ + fprintf(stderr, "%s:%d, Rename Error (%s): \"%s\" -> \"%s\"\n", \ + __FILE__, __LINE__, strerror(errno), tmpfile, orgfile); \ + return -1; \ + } \ + remove(tmpfile); \ + return 1; \ + /* end REN_IF_DIFF */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index a33efda38d0..793d0112af7 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -2930,28 +2930,28 @@ int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, Proper return 1; } -#define RAW_GET(dtype, var, raw, a) \ -{ \ - switch(raw.type) { \ - case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \ - case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \ - case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \ - case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \ - case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \ - default: var = (dtype)0; \ - } \ +#define RAW_GET(dtype, var, raw, a) \ +{ \ + switch(raw.type) { \ + case PROP_RAW_CHAR: var = (dtype)((char*)raw.array)[a]; break; \ + case PROP_RAW_SHORT: var = (dtype)((short*)raw.array)[a]; break; \ + case PROP_RAW_INT: var = (dtype)((int*)raw.array)[a]; break; \ + case PROP_RAW_FLOAT: var = (dtype)((float*)raw.array)[a]; break; \ + case PROP_RAW_DOUBLE: var = (dtype)((double*)raw.array)[a]; break; \ + default: var = (dtype)0; \ + } \ } -#define RAW_SET(dtype, raw, a, var) \ -{ \ - switch(raw.type) { \ - case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \ - case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \ - case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \ - case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \ - case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \ - default: break; \ - } \ +#define RAW_SET(dtype, raw, a, var) \ +{ \ + switch(raw.type) { \ + case PROP_RAW_CHAR: ((char*)raw.array)[a] = (char)var; break; \ + case PROP_RAW_SHORT: ((short*)raw.array)[a] = (short)var; break; \ + case PROP_RAW_INT: ((int*)raw.array)[a] = (int)var; break; \ + case PROP_RAW_FLOAT: ((float*)raw.array)[a] = (float)var; break; \ + case PROP_RAW_DOUBLE: ((double*)raw.array)[a] = (double)var; break; \ + default: break; \ + } \ } int RNA_raw_type_sizeof(RawPropertyType type) diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 59d23b7a878..60144e0cf7f 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -167,19 +167,20 @@ static char *rna_ColorRampElement_path(PointerRNA *ptr) /* helper macro for use here to try and get the path * - this calls the standard code for getting a path to a texture... */ -#define COLRAMP_GETPATH \ -{ \ -prop= RNA_struct_find_property(&ramp_ptr, "elements"); \ -if (prop) { \ -index= RNA_property_collection_lookup_index(&ramp_ptr, prop, ptr); \ -if (index >= 0) { \ -char *texture_path= rna_ColorRamp_path(&ramp_ptr); \ -path= BLI_sprintfN("%s.elements[%d]", texture_path, index); \ -MEM_freeN(texture_path); \ -} \ -} \ + +#define COLRAMP_GETPATH \ +{ \ + prop= RNA_struct_find_property(&ramp_ptr, "elements"); \ + if (prop) { \ + index= RNA_property_collection_lookup_index(&ramp_ptr, prop, ptr); \ + if (index >= 0) { \ + char *texture_path= rna_ColorRamp_path(&ramp_ptr); \ + path= BLI_sprintfN("%s.elements[%d]", texture_path, index); \ + MEM_freeN(texture_path); \ + } \ + } \ } - + /* determine the path from the ID-block to the ramp */ // FIXME: this is a very slow way to do it, but it will have to suffice... if (ptr->id.data) { diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index b8282f2c452..929b87618d8 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -1358,24 +1358,24 @@ void IIR_gauss(CompBuf* src, float sigma, int chan, int xy) tsM[7] = sc*(cf[1]*cf[2] + cf[3]*cf[2]*cf[2] - cf[1]*cf[3]*cf[3] - cf[3]*cf[3]*cf[3] - cf[3]*cf[2] + cf[3]); tsM[8] = sc*(cf[3]*(cf[1] + cf[3]*cf[2])); -#define YVV(L)\ -{\ - W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0];\ - W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0];\ - W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0];\ - for (i=3; i=0; i--)\ - Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3];\ +#define YVV(L) \ +{ \ + W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0]; \ + W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0]; \ + W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0]; \ + for (i=3; i=0; i--) \ + Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3]; \ } // intermediate buffers diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c index 166eae9d1bc..17038fd6780 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c @@ -43,43 +43,47 @@ static bNodeSocketTemplate cmp_node_bilateralblur_out[]= { { -1, 0, "" } }; -#define INIT_C3\ - mean0 = 1; mean1[0] = src[0];mean1[1] = src[1];mean1[2] = src[2];mean1[3] = src[3]; +#define INIT_C3 \ + mean0 = 1; \ + mean1[0] = src[0]; \ + mean1[1] = src[1]; \ + mean1[2] = src[2]; \ + mean1[3] = src[3]; /* finds color distances */ -#define COLOR_DISTANCE_C3(c1, c2)\ - ((c1[0] - c2[0])*(c1[0] - c2[0]) + \ - (c1[1] - c2[1])*(c1[1] - c2[1]) + \ - (c1[2] - c2[2])*(c1[2] - c2[2]) + \ - (c1[3] - c2[3])*(c1[3] - c2[3])) +#define COLOR_DISTANCE_C3(c1, c2) \ + ((c1[0] - c2[0])*(c1[0] - c2[0]) + \ + (c1[1] - c2[1])*(c1[1] - c2[1]) + \ + (c1[2] - c2[2])*(c1[2] - c2[2]) + \ + (c1[3] - c2[3])*(c1[3] - c2[3])) /* this is the main kernel function for comparing color distances and adding them weighted to the final color */ -#define KERNEL_ELEMENT_C3(k)\ - temp_color = src + deltas[k];\ - ref_color = ref + deltas[k];\ - w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color;\ - w = 1./(w*w + 1); \ - mean0 += w;\ - mean1[0] += temp_color[0]*w; \ - mean1[1] += temp_color[1]*w; \ - mean1[2] += temp_color[2]*w; \ +#define KERNEL_ELEMENT_C3(k) \ + temp_color = src + deltas[k]; \ + ref_color = ref + deltas[k]; \ + w = weight_tab[k] + COLOR_DISTANCE_C3(ref, ref_color )*i2sigma_color; \ + w = 1.0/(w*w + 1); \ + mean0 += w; \ + mean1[0] += temp_color[0]*w; \ + mean1[1] += temp_color[1]*w; \ + mean1[2] += temp_color[2]*w; \ mean1[3] += temp_color[3]*w; /* write blurred values to image */ -#define UPDATE_OUTPUT_C3\ - mean0 = 1./mean0;\ - dest[x*pix + 0] = mean1[0]*mean0; \ - dest[x*pix + 1] = mean1[1]*mean0; \ - dest[x*pix + 2] = mean1[2]*mean0; \ +#define UPDATE_OUTPUT_C3 \ + mean0 = 1.0/mean0; \ + dest[x*pix + 0] = mean1[0]*mean0; \ + dest[x*pix + 1] = mean1[1]*mean0; \ + dest[x*pix + 2] = mean1[2]*mean0; \ dest[x*pix + 3] = mean1[3]*mean0; /* initializes deltas for fast access to neighbour pixels */ -#define INIT_3X3_DELTAS( deltas, step, nch ) \ - ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ - (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ - (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ - (deltas)[6] = (step), (deltas)[7] = (step) + (nch)); +#define INIT_3X3_DELTAS( deltas, step, nch ) \ + ((deltas)[0] = (nch), (deltas)[1] = -(step) + (nch), \ + (deltas)[2] = -(step), (deltas)[3] = -(step) - (nch), \ + (deltas)[4] = -(nch), (deltas)[5] = (step) - (nch), \ + (deltas)[6] = (step), (deltas)[7] = (step) + (nch)); /* code of this node was heavily inspired by the smooth function of opencv library. diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 24d963243f6..441c4b6438a 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -205,29 +205,36 @@ PyTypeObject BGL_bufferType = { NULL /*tp_del*/ }; - -/* #ifndef __APPLE__ */ - -#define BGL_Wrap(nargs, funcname, ret, arg_list) \ -static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) {\ - arg_def##nargs arg_list; \ - ret_def_##ret; \ - if (!PyArg_ParseTuple(args, arg_str##nargs arg_list, arg_ref##nargs arg_list)) return NULL;\ - ret_set_##ret gl##funcname (arg_var##nargs arg_list);\ - ret_ret_##ret; \ +#define BGL_Wrap(nargs, funcname, ret, arg_list) \ +static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) \ +{ \ + arg_def##nargs arg_list; \ + ret_def_##ret; \ + if (!PyArg_ParseTuple(args, \ + arg_str##nargs arg_list, \ + arg_ref##nargs arg_list)) \ + { \ + return NULL; \ + } \ + ret_set_##ret gl##funcname (arg_var##nargs arg_list); \ + ret_ret_##ret; \ } -#define BGLU_Wrap(nargs, funcname, ret, arg_list) \ -static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) {\ - arg_def##nargs arg_list; \ - ret_def_##ret; \ - if (!PyArg_ParseTuple(args, arg_str##nargs arg_list, arg_ref##nargs arg_list)) return NULL;\ - ret_set_##ret glu##funcname (arg_var##nargs arg_list);\ - ret_ret_##ret; \ +#define BGLU_Wrap(nargs, funcname, ret, arg_list) \ +static PyObject *Method_##funcname (PyObject *UNUSED(self), PyObject *args) \ +{ \ + arg_def##nargs arg_list; \ + ret_def_##ret; \ + if (!PyArg_ParseTuple(args, \ + arg_str##nargs arg_list, \ + arg_ref##nargs arg_list)) \ + { \ + return NULL; \ + } \ + ret_set_##ret glu##funcname (arg_var##nargs arg_list); \ + ret_ret_##ret; \ } -/* #endif */ - /********/ int BGL_typeSize(int type) { @@ -267,7 +274,7 @@ Buffer *BGL_MakeBuffer(int type, int ndimensions, int *dimensions, void *initbuf memcpy(buffer->dimensions, dimensions, ndimensions*sizeof(int)); buffer->type= type; buffer->buf.asvoid= buf; - + if (initbuffer) { memcpy(buffer->buf.asvoid, initbuffer, length*size); } diff --git a/source/blender/python/generic/bgl.h b/source/blender/python/generic/bgl.h index 5cf9eac8289..6df534a3940 100644 --- a/source/blender/python/generic/bgl.h +++ b/source/blender/python/generic/bgl.h @@ -331,12 +331,13 @@ extern PyTypeObject BGL_bufferType; #define ret_def_GLstring const unsigned char *ret_str; #define ret_set_GLstring ret_str= -#define ret_ret_GLstring \ - if (ret_str) {\ - return PyUnicode_FromString((const char *)ret_str);\ - } else {\ - PyErr_SetString(PyExc_AttributeError, "could not get opengl string");\ - return NULL;\ - } +#define ret_ret_GLstring \ + if (ret_str) { \ + return PyUnicode_FromString((const char *)ret_str); \ + } \ + else { \ + PyErr_SetString(PyExc_AttributeError, "could not get opengl string"); \ + return NULL; \ + } \ #endif /* BGL_H */ diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index 293ade35584..acfe6ee80bf 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -15,12 +15,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * * This is a new part of Blender. * - * Contributor(s): Willian P. Germano + * Contributor(s): Willian P. Germano, + * Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ @@ -308,77 +306,3 @@ static PyObject *blender_reload(PyObject *UNUSED(self), PyObject *module) PyMethodDef bpy_import_meth= {"bpy_import_meth", (PyCFunction)blender_import, METH_VARARGS | METH_KEYWORDS, "blenders import"}; PyMethodDef bpy_reload_meth= {"bpy_reload_meth", (PyCFunction)blender_reload, METH_O, "blenders reload"}; - - -/* Clear user modules. - * This is to clear any modules that could be defined from running scripts in blender. - * - * Its also needed for the BGE Python api so imported scripts are not used between levels - * - * This clears every modules that has a __file__ attribute (is not a builtin) - * - * Note that clearing external python modules is important for the BGE otherwise - * it wont reload scripts between loading different blend files or while making the game. - * - use 'clear_all' arg in this case. - * - * Since pythons built-ins include a full path even for win32. - * even if we remove a python module a re-import will bring it back again. - */ - -#if 0 // not used anymore but may still come in handy later - -#if defined(WIN32) || defined(WIN64) -#define SEPSTR "\\" -#else -#define SEPSTR "/" -#endif - - -void bpy_text_clear_modules(int clear_all) -{ - PyObject *modules= PyImport_GetModuleDict(); - - char *fname; - char *file_extension; - - /* looping over the dict */ - PyObject *key, *value; - Py_ssize_t pos= 0; - - /* new list */ - PyObject *list; - - if (modules==NULL) - return; /* should never happen but just incase */ - - list= PyList_New(0); - - /* go over sys.modules and remove anything with a - * sys.modukes[x].__file__ thats ends with a .py and has no path - */ - while (PyDict_Next(modules, &pos, &key, &value)) { - fname= PyModule_GetFilename(value); - if (fname) { - if (clear_all || ((strstr(fname, SEPSTR))==0)) { /* no path ? */ - file_extension= strstr(fname, ".py"); - if (file_extension && (*(file_extension + 3) == '\0' || *(file_extension + 4) == '\0')) { /* .py or pyc extension? */ - /* now we can be fairly sure its a python import from the blendfile */ - PyList_Append(list, key); /* free'd with the list */ - } - } - } - else { - PyErr_Clear(); - } - } - - /* remove all our modules */ - for (pos=0; pos < PyList_GET_SIZE(list); pos++) { - /* PyObject_Print(key, stderr, 0); */ - key= PyList_GET_ITEM(list, pos); - PyDict_DelItem(modules, key); - } - - Py_DECREF(list); /* removes all references from append */ -} -#endif diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index b10223207bf..cfd2e5556a1 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -279,52 +279,60 @@ static int py_long_as_int(PyObject *py_long, int *r_int) /* this define runs at the start of each function and deals with * returning a deferred property (to be registered later) */ -#define BPY_PROPDEF_HEAD(_func) \ - if (PyTuple_GET_SIZE(args) == 1) { \ - PyObject *ret; \ - self= PyTuple_GET_ITEM(args, 0); \ - args= PyTuple_New(0); \ - ret= BPy_##_func(self, args, kw); \ - Py_DECREF(args); \ - return ret; \ - } \ - else if (PyTuple_GET_SIZE(args) > 1) { \ - PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ - return NULL; \ - } \ - srna= srna_from_self(self, #_func"(...):"); \ - if (srna==NULL) { \ - if (PyErr_Occurred()) \ - return NULL; \ - return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \ - } \ +#define BPY_PROPDEF_HEAD(_func) \ + if (PyTuple_GET_SIZE(args) == 1) { \ + PyObject *ret; \ + self= PyTuple_GET_ITEM(args, 0); \ + args= PyTuple_New(0); \ + ret= BPy_##_func(self, args, kw); \ + Py_DECREF(args); \ + return ret; \ + } \ + else if (PyTuple_GET_SIZE(args) > 1) { \ + PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \ + return NULL; \ + } \ + srna= srna_from_self(self, #_func"(...):"); \ + if (srna==NULL) { \ + if (PyErr_Occurred()) \ + return NULL; \ + return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \ + } \ /* terse macros for error checks shared between all funcs cant use function * calls because of static strins passed to pyrna_set_to_enum_bitfield */ -#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ - if (id_len >= MAX_IDPROP_NAME) { \ - PyErr_Format(PyExc_TypeError, \ - #_func"(): '%.200s' too long, max length is %d", \ - id, MAX_IDPROP_NAME-1); \ - return NULL; \ - } \ - if (RNA_def_property_free_identifier(srna, id) == -1) { \ - PyErr_Format(PyExc_TypeError, \ - #_func"(): '%s' is defined as a non-dynamic type", \ - id); \ - return NULL; \ - } \ - if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \ - return NULL; \ +#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \ + if (id_len >= MAX_IDPROP_NAME) { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(): '%.200s' too long, max length is %d", \ + id, MAX_IDPROP_NAME-1); \ + return NULL; \ + } \ + if (RNA_def_property_free_identifier(srna, id) == -1) { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(): '%s' is defined as a non-dynamic type", \ + id); \ + return NULL; \ + } \ + if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \ + pyopts, \ + &opts, \ + #_func"(options={...}):")) \ + { \ + return NULL; \ + } \ -#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ - BPY_PROPDEF_CHECK(_func, _property_flag_items) \ - if (pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \ - PyErr_Format(PyExc_TypeError, \ - #_func"(subtype='%s'): invalid subtype", \ - pysubtype); \ - return NULL; \ - } \ +#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \ + BPY_PROPDEF_CHECK(_func, _property_flag_items) \ + if (pysubtype && RNA_enum_value_from_id(_subtype, \ + pysubtype, \ + &subtype)==0) \ + { \ + PyErr_Format(PyExc_TypeError, \ + #_func"(subtype='%s'): invalid subtype", \ + pysubtype); \ + return NULL; \ + } \ #define BPY_PROPDEF_NAME_DOC \ diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 1ecbeb4d16a..3411bceda69 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -82,10 +82,10 @@ static PyObject* pyrna_struct_Subtype(PointerRNA *ptr); static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self); -#define BPY_DOC_ID_PROP_TYPE_NOTE \ -" .. note::\n" \ -"\n" \ -" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \ +#define BPY_DOC_ID_PROP_TYPE_NOTE \ +" .. note::\n" \ +"\n" \ +" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \ " :class:`bpy.types.PoseBone` classes support custom properties.\n" @@ -6404,17 +6404,19 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun if (item==NULL) { /* Sneaky workaround to use the class name as the bl_idname */ -#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \ - if (strcmp(identifier, rna_attr) == 0) { \ - item= PyObject_GetAttrString(py_class, py_attr); \ - if (item && item != Py_None) { \ - if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { \ - Py_DECREF(item); \ - return -1; \ - } \ - } \ - Py_XDECREF(item); \ - } \ +#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \ + if (strcmp(identifier, rna_attr) == 0) { \ + item= PyObject_GetAttrString(py_class, py_attr); \ + if (item && item != Py_None) { \ + if (pyrna_py_to_prop(dummyptr, prop, NULL, \ + item, "validating class:") != 0) \ + { \ + Py_DECREF(item); \ + return -1; \ + } \ + } \ + Py_XDECREF(item); \ + } \ BPY_REPLACEMENT_STRING("bl_idname", "__name__"); diff --git a/source/blender/render/intern/include/texture.h b/source/blender/render/intern/include/texture.h index 736f9e380aa..a702e890c3b 100644 --- a/source/blender/render/intern/include/texture.h +++ b/source/blender/render/intern/include/texture.h @@ -36,21 +36,26 @@ #ifndef TEXTURE_EXT_H #define TEXTURE_EXT_H -#define BRICONT texres->tin= (texres->tin-0.5f)*tex->contrast+tex->bright-0.5f; \ -if(texres->tin<0.0f) texres->tin= 0.0f; else if(texres->tin>1.0f) texres->tin= 1.0f; +#define BRICONT \ + texres->tin= (texres->tin-0.5f) * tex->contrast+tex->bright-0.5f; \ + if(texres->tin < 0.0f) texres->tin= 0.0f; \ + else if(texres->tin > 1.0f) texres->tin= 1.0f; \ -#define BRICONTRGB texres->tr= tex->rfac*((texres->tr-0.5f)*tex->contrast+tex->bright-0.5f); \ -if(texres->tr<0.0f) texres->tr= 0.0f; \ -texres->tg= tex->gfac*((texres->tg-0.5f)*tex->contrast+tex->bright-0.5f); \ -if(texres->tg<0.0f) texres->tg= 0.0f; \ -texres->tb= tex->bfac*((texres->tb-0.5f)*tex->contrast+tex->bright-0.5f); \ -if(texres->tb<0.0f) texres->tb= 0.0f; \ -if(tex->saturation != 1.0f) { \ - float _hsv[3]; \ - rgb_to_hsv(texres->tr, texres->tg, texres->tb, _hsv, _hsv+1, _hsv+2); \ - _hsv[1] *= tex->saturation; \ - hsv_to_rgb(_hsv[0], _hsv[1], _hsv[2], &texres->tr, &texres->tg, &texres->tb); \ -} \ +#define BRICONTRGB \ + texres->tr= tex->rfac*((texres->tr-0.5f)*tex->contrast+tex->bright-0.5f); \ + if(texres->tr<0.0f) texres->tr= 0.0f; \ + texres->tg= tex->gfac*((texres->tg-0.5f)*tex->contrast+tex->bright-0.5f); \ + if(texres->tg<0.0f) texres->tg= 0.0f; \ + texres->tb= tex->bfac*((texres->tb-0.5f)*tex->contrast+tex->bright-0.5f); \ + if(texres->tb<0.0f) texres->tb= 0.0f; \ + if(tex->saturation != 1.0f) { \ + float _hsv[3]; \ + rgb_to_hsv(texres->tr, texres->tg, texres->tb, \ + _hsv, _hsv+1, _hsv+2); \ + _hsv[1] *= tex->saturation; \ + hsv_to_rgb(_hsv[0], _hsv[1], _hsv[2], \ + &texres->tr, &texres->tg, &texres->tb); \ + } \ #define RGBTOBW(r,g,b) ( r*0.35f + g*0.45f + b*0.2f ) /* keep this in sync with gpu_shader_material.glsl:rgbtobw */ diff --git a/source/creator/creator.c b/source/creator/creator.c index 2204ab85a2e..39ea82f141f 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -141,7 +141,9 @@ static int print_version(int argc, const char **argv, void *data); extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */ -#define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION +#define BLEND_VERSION_STRING_FMT \ + "Blender %d.%02d (sub %d)\n", \ + BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION \ /* Initialize callbacks for the modules that need them */ static void setCallbacks(void); @@ -850,22 +852,23 @@ static int set_skip_frame(int argc, const char **argv, void *data) /* macro for ugly context setup/reset */ #ifdef WITH_PYTHON -#define BPY_CTX_SETUP(_cmd) \ -{ \ - wmWindowManager *wm= CTX_wm_manager(C); \ - wmWindow *prevwin= CTX_wm_window(C); \ - Scene *prevscene= CTX_data_scene(C); \ - if(wm->windows.first) { \ - CTX_wm_window_set(C, wm->windows.first); \ - _cmd; \ - CTX_wm_window_set(C, prevwin); \ - } \ - else { \ - fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \ - _cmd; \ - } \ - CTX_data_scene_set(C, prevscene); \ -} \ +#define BPY_CTX_SETUP(_cmd) \ +{ \ + wmWindowManager *wm= CTX_wm_manager(C); \ + wmWindow *prevwin= CTX_wm_window(C); \ + Scene *prevscene= CTX_data_scene(C); \ + if(wm->windows.first) { \ + CTX_wm_window_set(C, wm->windows.first); \ + _cmd; \ + CTX_wm_window_set(C, prevwin); \ + } \ + else { \ + fprintf(stderr, "Python script \"%s\" " \ + "running with missing context data.\n", argv[1]); \ + _cmd; \ + } \ + CTX_data_scene_set(C, prevscene); \ +} \ #endif /* WITH_PYTHON */ diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index 7ee4760c48d..f7bd1b91466 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -69,26 +69,27 @@ typedef struct { void *link; } WarnLink; -#define ShowDeprecationWarning(old_way, new_way) \ -{ \ - static WarnLink wlink = {false, NULL}; \ - if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \ - { \ - ShowDeprecationWarning_func(old_way, new_way); \ - \ - WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \ - wlink.warn_done = true; \ - wlink.link = NULL; \ - \ - if(wlink_last) { \ - wlink_last->link= (void *)&(wlink); \ - SetDeprecationWarningLinkLast(&(wlink)); \ - } else { \ - SetDeprecationWarningFirst(&(wlink)); \ - SetDeprecationWarningLinkLast(&(wlink)); \ - } \ - } \ -} \ +#define ShowDeprecationWarning(old_way, new_way) \ +{ \ + static WarnLink wlink = {false, NULL}; \ + if ((m_ignore_deprecation_warnings || wlink.warn_done)==0) \ + { \ + ShowDeprecationWarning_func(old_way, new_way); \ + \ + WarnLink *wlink_last= GetDeprecationWarningLinkLast(); \ + wlink.warn_done = true; \ + wlink.link = NULL; \ + \ + if(wlink_last) { \ + wlink_last->link= (void *)&(wlink); \ + SetDeprecationWarningLinkLast(&(wlink)); \ + } \ + else { \ + SetDeprecationWarningFirst(&(wlink)); \ + SetDeprecationWarningLinkLast(&(wlink)); \ + } \ + } \ +} \ From 2b939904ab4b6af614879ada711ac47be01cbf83 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 08:21:12 +0000 Subject: [PATCH 095/147] documentation - brief descriptions for bpy api files. --- source/blender/python/intern/bpy.c | 8 ++++---- source/blender/python/intern/bpy_app.c | 4 ++++ source/blender/python/intern/bpy_app_handlers.c | 4 ++++ source/blender/python/intern/bpy_driver.c | 4 ++++ source/blender/python/intern/bpy_interface.c | 4 ++++ source/blender/python/intern/bpy_interface_atexit.c | 4 ++++ source/blender/python/intern/bpy_intern_string.c | 4 ++++ source/blender/python/intern/bpy_library.c | 6 ++++++ source/blender/python/intern/bpy_operator.c | 9 +++++++-- source/blender/python/intern/bpy_operator_wrap.c | 5 +++++ source/blender/python/intern/bpy_props.c | 6 +++++- source/blender/python/intern/bpy_rna.c | 11 +++++++++-- source/blender/python/intern/bpy_rna_anim.c | 2 ++ source/blender/python/intern/bpy_rna_array.c | 4 +++- source/blender/python/intern/bpy_rna_callback.c | 3 +++ source/blender/python/intern/bpy_traceback.c | 3 +++ source/blender/python/intern/bpy_util.c | 3 +++ source/blender/python/intern/gpu.c | 3 +++ 18 files changed, 77 insertions(+), 10 deletions(-) diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index dfb7a1e8f75..2df907f3a12 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -22,11 +22,11 @@ /** \file blender/python/intern/bpy.c * \ingroup pythonintern + * + * This file defines the '_bpy' module which is used by python's 'bpy' package + * to access C defined builtin functions. + * A script writer should never directly access this module. */ - - -/* This file defines the '_bpy' module which is used by python's 'bpy' package. - * a script writer should never directly access this module */ #define WITH_PYTHON /* for AUD_PyInit.h, possibly others */ diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index cc3b88722b6..b5ae225fda7 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_app.c * \ingroup pythonintern + * + * This file defines a 'PyStructSequence' accessed via 'bpy.app', mostly + * exposing static applications variables such as version and buildinfo + * however some writable variables have been added such as 'debug' and 'tempdir' */ diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index f130a4bcc5c..edab92b295b 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_app_handlers.c * \ingroup pythonintern + * + * This file defines a 'PyStructSequence' accessed via 'bpy.app.handlers', + * which exposes various lists that the script author can add callback + * functions into (called via blenders generic BLI_cb api) */ #include diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 0fe1d2d26ba..98b4786607f 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_driver.c * \ingroup pythonintern + * + * This file defines the 'BPY_driver_exec' to execute python drivers, + * called by the animation system, there are also some utility functions + * to deal with the namespace used for driver execution. */ /* ****************************************** */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index ea2266c99b4..ffa9e5cc27c 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -23,6 +23,10 @@ /** \file blender/python/intern/bpy_interface.c * \ingroup pythonintern + * + * This file deals with embedding the python interpreter within blender, + * starting and stopping python and exposing blender/python modules so they can + * be accesses from scripts. */ diff --git a/source/blender/python/intern/bpy_interface_atexit.c b/source/blender/python/intern/bpy_interface_atexit.c index aa5b934891c..a0cf3c38503 100644 --- a/source/blender/python/intern/bpy_interface_atexit.c +++ b/source/blender/python/intern/bpy_interface_atexit.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_interface_atexit.c * \ingroup pythonintern + * + * This file inserts an exit callback into pythons 'atexit' module. + * Without this sys.exit() can crash because blender is not properly closing + * resources. */ diff --git a/source/blender/python/intern/bpy_intern_string.c b/source/blender/python/intern/bpy_intern_string.c index 32d329e11b3..4f206c4c365 100644 --- a/source/blender/python/intern/bpy_intern_string.c +++ b/source/blender/python/intern/bpy_intern_string.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_intern_string.c * \ingroup pythonintern + * + * Store python versions of strings frequently used for python lookups + * to avoid converting, creating the hash and freeing every time as + * PyDict_GetItemString and PyObject_GetAttrString do. */ #include diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 382a513f40a..54398f75a1d 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -22,6 +22,12 @@ /** \file blender/python/intern/bpy_library.c * \ingroup pythonintern + * + * This file exposed blend file library appending/linking to python, typically + * this would be done via RNA api but in this case a hand written python api + * allows us to use pythons context manager (__enter__ and __exit__). + * + * Everything here is exposed via bpy.data.libraries.load(...) context manager. */ /* nifty feature. swap out strings for RNA data */ diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 70a5d79e9ac..3fd4e8a128b 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -1,6 +1,4 @@ - /* - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -24,6 +22,13 @@ /** \file blender/python/intern/bpy_operator.c * \ingroup pythonintern + * + * This file defines '_bpy.ops', an internal python module which gives python + * the ability to inspect and call both C and Python defined operators. + * + * \note + * This module is exposed to the user via 'release/scripts/modules/bpy/ops.py' + * which fakes exposing operators as modules/functions using its own classes. */ diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c index cb460f2fa08..aa458925202 100644 --- a/source/blender/python/intern/bpy_operator_wrap.c +++ b/source/blender/python/intern/bpy_operator_wrap.c @@ -22,6 +22,11 @@ /** \file blender/python/intern/bpy_operator_wrap.c * \ingroup pythonintern + * + * This file is so python can define operators that C can call into. + * The generic callback functions for python operators are defines in + * 'rna_wm.c', some calling into functions here to do python specific + * functionality. */ diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index cfd2e5556a1..4dbaf5db4a4 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -22,6 +22,10 @@ /** \file blender/python/intern/bpy_props.c * \ingroup pythonintern + * + * This file defines 'bpy.props' module used so scripts can define their own + * rna properties for use with python operators or adding new properties to + * existing blender types. */ @@ -254,7 +258,7 @@ static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_c { /* assume this is already checked for type and arg length */ if (update_cb) { - PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, "bpy_prop_callback_assign"); + PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__); RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb); py_data[BPY_DATA_CB_SLOT_UPDATE]= update_cb; RNA_def_py_data(prop, py_data); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 3411bceda69..44e26a56db6 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -22,9 +22,14 @@ /** \file blender/python/intern/bpy_rna.c * \ingroup pythonintern + * + * This file is the main interface between python and blenders data api (RNA), + * exposing RNA to python so blender data can be accessed in a python like way. + * + * The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base + * classes for most of the data python accesses in blender. */ - #include #include @@ -6470,7 +6475,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param const int is_operator= RNA_struct_is_a(ptr->type, &RNA_Operator); const char *func_id= RNA_function_identifier(func); /* testing, for correctness, not operator and not draw function */ - const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !is_operator; + const short is_readonly= ((strncmp("draw", func_id, 4) ==0) || /* draw or draw_header */ + /*strstr("render", func_id) ||*/ + !is_operator); #endif py_class= RNA_struct_py_type_get(ptr->type); diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index 4ebb407f4d6..edc6e672238 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -22,6 +22,8 @@ /** \file blender/python/intern/bpy_rna_anim.c * \ingroup pythonintern + * + * This file defines the animation related methods used in bpy_rna.c */ #include diff --git a/source/blender/python/intern/bpy_rna_array.c b/source/blender/python/intern/bpy_rna_array.c index eda2511a187..73e9e0a44d9 100644 --- a/source/blender/python/intern/bpy_rna_array.c +++ b/source/blender/python/intern/bpy_rna_array.c @@ -15,13 +15,15 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor(s): Arystanbek Dyussenov + * Contributor(s): Arystanbek Dyussenov, Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/python/intern/bpy_rna_array.c * \ingroup pythonintern + * + * This file deals with array access for 'BPy_PropertyArrayRNA' from bpy_rna.c */ #include diff --git a/source/blender/python/intern/bpy_rna_callback.c b/source/blender/python/intern/bpy_rna_callback.c index af6fc88097b..85f950947a7 100644 --- a/source/blender/python/intern/bpy_rna_callback.c +++ b/source/blender/python/intern/bpy_rna_callback.c @@ -22,6 +22,9 @@ /** \file blender/python/intern/bpy_rna_callback.c * \ingroup pythonintern + * + * This file currently exposes callbacks for interface regions but may be + * extended later. */ diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c index aa21627a279..5045f6708b5 100644 --- a/source/blender/python/intern/bpy_traceback.c +++ b/source/blender/python/intern/bpy_traceback.c @@ -20,6 +20,9 @@ /** \file blender/python/intern/bpy_traceback.c * \ingroup pythonintern + * + * This file contains utility functions for getting data from a python stack + * trace. */ diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index bec3a07d32a..43ca4da7ae2 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -22,6 +22,9 @@ /** \file blender/python/intern/bpy_util.c * \ingroup pythonintern + * + * This file contains blender/python utility functions for the api's internal + * use (unrelated to 'bpy.utils') */ diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index 1162491ee26..57ce7b59067 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -27,6 +27,9 @@ /** \file blender/python/intern/gpu.c * \ingroup pythonintern + * + * This file defines the 'gpu' module, used to get GLSL shader code and data + * from blender materials. */ /* python redefines */ From e5647ea196c360905d8f0e1c1b2fad1745cb5cf5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 08:40:07 +0000 Subject: [PATCH 096/147] py operators - don't use the screen as an operators ID anymore, screen's don't store operator instances and operator functions have access to the context if they need the current screen. also add some more py api file descriptions. --- source/blender/editors/interface/interface.c | 8 ++++---- source/blender/makesrna/intern/rna_wm.c | 12 ++++++------ source/blender/python/generic/bgl.c | 16 ++++++++-------- source/blender/python/generic/bgl.h | 3 +-- source/blender/python/generic/blf_py_api.c | 3 ++- .../blender/python/generic/bpy_internal_import.c | 9 +++++++-- source/blender/python/generic/noise_py_api.c | 9 ++++----- source/blender/python/generic/py_capi_utils.c | 7 +++++++ source/blender/python/intern/bpy_driver.c | 2 +- source/blender/python/intern/bpy_library.c | 11 ++++++----- source/blender/python/intern/bpy_util.c | 1 - 11 files changed, 46 insertions(+), 35 deletions(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index eff4d1f6397..dd75f506be8 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -766,7 +766,7 @@ static void ui_menu_block_set_keyaccels(uiBlock *block) { uiBut *but; - unsigned int meny_key_mask= 0; + unsigned int menu_key_mask= 0; unsigned char menu_key; const char *str_pt; int pass; @@ -788,8 +788,8 @@ static void ui_menu_block_set_keyaccels(uiBlock *block) if(but->str) { for(str_pt= but->str; *str_pt; ) { menu_key= tolower(*str_pt); - if((menu_key >= 'a' && menu_key <= 'z') && !(meny_key_mask & 1<<(menu_key-'a'))) { - meny_key_mask |= 1<<(menu_key-'a'); + if((menu_key >= 'a' && menu_key <= 'z') && !(menu_key_mask & 1<<(menu_key-'a'))) { + menu_key_mask |= 1<<(menu_key-'a'); break; } @@ -816,7 +816,7 @@ static void ui_menu_block_set_keyaccels(uiBlock *block) } /* if all keys have been used just exit, unlikely */ - if(meny_key_mask == (1<<26)-1) { + if(menu_key_mask == (1<<26)-1) { return; } } diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index c7f7fe5feea..dfbdafd7d18 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -821,7 +821,7 @@ static int operator_execute(bContext *C, wmOperator *op) void *ret; int result; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_execute_func; /* RNA_struct_find_function(&opr, "execute"); */ RNA_parameter_list_create(&list, &opr, func); @@ -847,7 +847,7 @@ static int operator_check(bContext *C, wmOperator *op) void *ret; int result; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_check_func; /* RNA_struct_find_function(&opr, "check"); */ RNA_parameter_list_create(&list, &opr, func); @@ -872,7 +872,7 @@ static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event) void *ret; int result; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_invoke_func; /* RNA_struct_find_function(&opr, "invoke"); */ RNA_parameter_list_create(&list, &opr, func); @@ -899,7 +899,7 @@ static int operator_modal(bContext *C, wmOperator *op, wmEvent *event) void *ret; int result; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_modal_func; /* RNA_struct_find_function(&opr, "modal"); */ RNA_parameter_list_create(&list, &opr, func); @@ -923,7 +923,7 @@ static void operator_draw(bContext *C, wmOperator *op) ParameterList list; FunctionRNA *func; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_draw_func; /* RNA_struct_find_function(&opr, "draw"); */ RNA_parameter_list_create(&list, &opr, func); @@ -944,7 +944,7 @@ static int operator_cancel(bContext *C, wmOperator *op) void *ret; int result; - RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr); + RNA_pointer_create(NULL, op->type->ext.srna, op, &opr); func= &rna_Operator_cancel_func; /* RNA_struct_find_function(&opr, "cancel"); */ RNA_parameter_list_create(&list, &opr, func); diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index 441c4b6438a..03d66e918d5 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -1,5 +1,4 @@ -/* - * +/* * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -21,20 +20,21 @@ * * This is a new part of Blender. * - * Contributor(s): Willian P. Germano + * Contributor(s): Willian P. Germano, Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/python/generic/bgl.c * \ingroup pygen + * + * This file is the 'bgl' module which wraps OpenGL functions and constants, + * allowing script writers to make OpenGL calls in their Python scripts. + * + * \note + * This module is very similar to 'PyOpenGL' which could replace 'bgl' one day. */ - -/* This file is the 'bgl' module. - * The BGL submodule "wraps" OpenGL functions and constants, - * allowing script writers to make OpenGL calls in their Python scripts. */ - #include #include "bgl.h" /*This must come first */ diff --git a/source/blender/python/generic/bgl.h b/source/blender/python/generic/bgl.h index 6df534a3940..2e02900d69f 100644 --- a/source/blender/python/generic/bgl.h +++ b/source/blender/python/generic/bgl.h @@ -1,5 +1,4 @@ -/* - * +/* * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index a9cd16c70f0..a4373e46e23 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -22,9 +22,10 @@ /** \file blender/python/generic/blf_py_api.c * \ingroup pygen + * + * This file defines the 'bgl' module, used for drawing text in OpenGL. */ - #include #include "blf_py_api.h" diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c index acfe6ee80bf..88e2da16eb5 100644 --- a/source/blender/python/generic/bpy_internal_import.c +++ b/source/blender/python/generic/bpy_internal_import.c @@ -17,14 +17,19 @@ * * This is a new part of Blender. * - * Contributor(s): Willian P. Germano, - * Campbell Barton + * Contributor(s): Willian P. Germano, Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/python/generic/bpy_internal_import.c * \ingroup pygen + * + * This file defines replacements for pythons '__import__' and 'imp.reload' + * functions which can import from blender textblocks. + * + * \note + * This should eventually be replaced by import hooks (pep 302). */ diff --git a/source/blender/python/generic/noise_py_api.c b/source/blender/python/generic/noise_py_api.c index 6afb1a00e2f..c12cc1ccdd2 100644 --- a/source/blender/python/generic/noise_py_api.c +++ b/source/blender/python/generic/noise_py_api.c @@ -1,8 +1,4 @@ /* - * - * Blender.Noise BPython module implementation. - * This submodule has functions to generate noise of various types. - * * ***** BEGIN GPL LICENSE BLOCK ***** * * This program is free software; you can redistribute it and/or @@ -24,13 +20,16 @@ * * This is a new part of Blender. * - * Contributor(s): eeshlo + * Contributor(s): eeshlo, Campbell Barton * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/python/generic/noise_py_api.c * \ingroup pygen + * + * This file defines the 'noise' module, a general purpose module to access + * blenders noise functions. */ diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index eb4ecf79941..7fbd8baa558 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -20,6 +20,13 @@ /** \file blender/python/generic/py_capi_utils.c * \ingroup pygen + * + * Extend upon CPython's API, filling in some gaps, these functions use PyC_ + * prefix to distinguish them apart from CPython. + * + * \note + * This module should only depend on CPython, however it currently uses + * BLI_string_utf8() for unicode conversion. */ diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index 98b4786607f..12fb5ed43b4 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -23,7 +23,7 @@ /** \file blender/python/intern/bpy_driver.c * \ingroup pythonintern * - * This file defines the 'BPY_driver_exec' to execute python drivers, + * This file defines the 'BPY_driver_exec' to execute python driver expressions, * called by the animation system, there are also some utility functions * to deal with the namespace used for driver execution. */ diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c index 54398f75a1d..b91948cc0b8 100644 --- a/source/blender/python/intern/bpy_library.c +++ b/source/blender/python/intern/bpy_library.c @@ -27,7 +27,8 @@ * this would be done via RNA api but in this case a hand written python api * allows us to use pythons context manager (__enter__ and __exit__). * - * Everything here is exposed via bpy.data.libraries.load(...) context manager. + * Everything here is exposed via bpy.data.libraries.load(...) which returns + * a context manager. */ /* nifty feature. swap out strings for RNA data */ @@ -77,8 +78,8 @@ static PyObject *bpy_lib_dir(BPy_Library *self); static PyMethodDef bpy_lib_methods[]= { {"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS}, - {"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS}, - {"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS}, + {"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS}, + {"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS}, {NULL} /* sentinel */ }; @@ -289,7 +290,7 @@ static void bpy_lib_exit_warn_idname(BPy_Library *self, const char *name_plural, PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); if (PyErr_WarnFormat(PyExc_UserWarning, 1, - "load: '%s' does not contain %s[\"%s\"]", + "load: '%s' does not contain %s[\"%s\"]", self->abspath, name_plural, idname)) { /* Spurious errors can appear at shutdown */ if (PyErr_ExceptionMatches(PyExc_Warning)) { @@ -304,7 +305,7 @@ static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item) PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); if (PyErr_WarnFormat(PyExc_UserWarning, 1, - "load: '%s' expected a string type, not a %.200s", + "load: '%s' expected a string type, not a %.200s", self->abspath, Py_TYPE(item)->tp_name)) { /* Spurious errors can appear at shutdown */ if (PyErr_ExceptionMatches(PyExc_Warning)) { diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 43ca4da7ae2..fb42f7d59e0 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -27,7 +27,6 @@ * use (unrelated to 'bpy.utils') */ - #include #include "bpy_util.h" From 133a7df75e2bdd7efe82c7d50389cf198433684d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sat, 5 Nov 2011 10:19:36 +0000 Subject: [PATCH 097/147] Disable x-mirror option when proportional edit is enabled. This option isn't supported because it behaves strangely in 50% of cases and hopefully disabled x-mirror will stop users be confused by this. --- .../startup/bl_ui/space_view3d_toolbar.py | 17 ++++++++++------- .../blender/editors/space_view3d/space_view3d.c | 1 + 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 96201a4b960..e6869a0d204 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -179,18 +179,21 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): ob = context.active_object if ob: + tool_settings = context.tool_settings mesh = ob.data + col = layout.column(align=True) + col.active = tool_settings.proportional_edit == 'DISABLED' col.prop(mesh, "use_mirror_x") - sub = col.column() - sub.active = ob.data.use_mirror_x - sub.prop(mesh, "use_mirror_topology") - ts = context.tool_settings + row = col.row() + row.active = ob.data.use_mirror_x + row.prop(mesh, "use_mirror_topology") - col.label("Edge Select Mode") - col.prop(ts, "edge_path_mode", text="") - col.prop(context.tool_settings, "edge_path_live_unwrap") + col = layout.column(align=True) + col.label("Edge Select Mode:") + col.prop(tool_settings, "edge_path_mode", text="") + col.prop(tool_settings, "edge_path_live_unwrap") # ********** default tools for editmode_curve **************** diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index ef806cb8881..0c7b81beb1e 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -874,6 +874,7 @@ static void view3d_buttons_area_listener(ARegion *ar, wmNotifier *wmn) case ND_MODE: case ND_LAYER: case ND_LAYER_CONTENT: + case ND_TOOLSETTINGS: ED_region_tag_redraw(ar); break; } From 010cd66747b83cf34eeb87328fded1badc3e1a4a Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Sat, 5 Nov 2011 10:34:29 +0000 Subject: [PATCH 098/147] VIEW3D_PT_tools_meshedit_options panel: * Removed ob check and add a proper poll function. --- .../startup/bl_ui/space_view3d_toolbar.py | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index e6869a0d204..332577a7902 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -172,28 +172,31 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): bl_context = "mesh_edit" bl_label = "Mesh Options" + + @classmethod + def poll(cls, context): + return context.active_object def draw(self, context): layout = self.layout ob = context.active_object - if ob: - tool_settings = context.tool_settings - mesh = ob.data + tool_settings = context.tool_settings + mesh = ob.data - col = layout.column(align=True) - col.active = tool_settings.proportional_edit == 'DISABLED' - col.prop(mesh, "use_mirror_x") + col = layout.column(align=True) + col.active = tool_settings.proportional_edit == 'DISABLED' + col.prop(mesh, "use_mirror_x") - row = col.row() - row.active = ob.data.use_mirror_x - row.prop(mesh, "use_mirror_topology") + row = col.row() + row.active = ob.data.use_mirror_x + row.prop(mesh, "use_mirror_topology") - col = layout.column(align=True) - col.label("Edge Select Mode:") - col.prop(tool_settings, "edge_path_mode", text="") - col.prop(tool_settings, "edge_path_live_unwrap") + col = layout.column(align=True) + col.label("Edge Select Mode:") + col.prop(tool_settings, "edge_path_mode", text="") + col.prop(tool_settings, "edge_path_live_unwrap") # ********** default tools for editmode_curve **************** From 45b8a61bf39dade4efcad16c26324d1cb2e95d48 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 5 Nov 2011 10:48:43 +0000 Subject: [PATCH 099/147] Fix #29162: grease pencil did not decrement user count on adding new datablock to replace an existing one. --- source/blender/editors/gpencil/gpencil_edit.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index c915bc9ea37..d481be94bcc 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -183,7 +183,10 @@ static int gp_data_add_exec (bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - /* just add new datablock now */ + /* decrement user count and add new datablock */ + bGPdata *gpd= (*gpd_ptr); + + id_us_min(&gpd->id); *gpd_ptr= gpencil_data_addnew("GPencil"); } @@ -231,7 +234,7 @@ static int gp_data_unlink_exec (bContext *C, wmOperator *op) /* just unlink datablock now, decreasing its user count */ bGPdata *gpd= (*gpd_ptr); - gpd->id.us--; + id_us_min(&gpd->id); *gpd_ptr= NULL; } From 33accdb725bb7e5bb133b17faa2cc6191eca73ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 11:04:28 +0000 Subject: [PATCH 100/147] use (const char*) rather than (char*) where possible. also removed some unused function definitons. --- doc/doxygen/Doxyfile | 2 +- source/blender/blenkernel/BKE_animsys.h | 4 ++-- source/blender/blenkernel/BKE_blender.h | 2 +- .../blender/blenkernel/BKE_customdata_file.h | 10 +++++----- source/blender/blenkernel/BKE_lattice.h | 20 +++++++++---------- source/blender/blenkernel/BKE_pointcache.h | 2 +- source/blender/blenkernel/BKE_property.h | 7 +++---- source/blender/blenkernel/BKE_sequencer.h | 2 +- source/blender/blenkernel/BKE_text.h | 2 +- source/blender/blenkernel/BKE_unit.h | 4 ++-- source/blender/blenkernel/BKE_writeffmpeg.h | 2 +- source/blender/blenkernel/intern/anim_sys.c | 10 +++++----- source/blender/blenkernel/intern/blender.c | 2 +- .../blenkernel/intern/customdata_file.c | 10 +++++----- source/blender/blenkernel/intern/fcurve.c | 4 ++-- source/blender/blenkernel/intern/lattice.c | 6 ++++-- source/blender/blenkernel/intern/pointcache.c | 6 +++--- source/blender/blenkernel/intern/property.c | 6 +++--- source/blender/blenkernel/intern/sequencer.c | 6 +++--- source/blender/blenkernel/intern/text.c | 2 +- source/blender/blenkernel/intern/unit.c | 16 +++++++-------- .../blender/blenkernel/intern/writeffmpeg.c | 2 +- .../editors/armature/armature_intern.h | 6 +++--- .../blender/editors/armature/editarmature.c | 6 +++--- .../editors/armature/editarmature_sketch.c | 2 +- source/blender/editors/armature/poseUtils.c | 2 +- source/blender/editors/include/ED_armature.h | 4 ++-- source/blender/editors/include/ED_fluidsim.h | 5 ----- source/blender/editors/include/ED_logic.h | 3 --- source/blender/editors/include/ED_particle.h | 2 +- source/blender/editors/include/ED_transform.h | 4 +++- source/blender/editors/include/UI_interface.h | 2 -- .../blender/editors/physics/particle_edit.c | 2 +- source/blender/editors/space_file/filelist.c | 4 ++-- source/blender/editors/space_file/filelist.h | 2 +- .../blender/editors/space_image/image_draw.c | 2 +- .../editors/space_image/image_intern.h | 2 +- source/blender/editors/space_node/drawnode.c | 2 +- .../blender/editors/space_node/node_intern.h | 2 +- .../editors/space_view3d/view3d_header.c | 7 ++----- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/util/editmode_undo.c | 2 +- source/blender/editors/util/undo.c | 2 +- source/blender/editors/util/util_intern.h | 2 +- 44 files changed, 91 insertions(+), 103 deletions(-) diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index dd112ed6a48..e8fb065e7a4 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -44,7 +44,7 @@ PROJECT_BRIEF = # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = ../../release/freedesktop/icons/48x48/blender.png +PROJECT_LOGO = ../../release/freedesktop/icons/48x48/apps/blender.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index cba6b0ef257..8e5b313b919 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -105,10 +105,10 @@ void BKE_keyingsets_free(struct ListBase *list); /* Path Fixing API */ /* Fix all the paths for the given ID+AnimData */ -void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, const char *prefix, char *oldName, char *newName, int oldSubscript, int newSubscript, int verify_paths); +void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, int verify_paths); /* Fix all the paths for the entire database... */ -void BKE_all_animdata_fix_paths_rename(char *prefix, char *oldName, char *newName); +void BKE_all_animdata_fix_paths_rename(const char *prefix, const char *oldName, const char *newName); /* -------------------------------------- */ diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 9b28f083a24..7033a2e0cce 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -87,7 +87,7 @@ extern int BKE_undo_valid(const char *name); extern void BKE_reset_undo(void); extern char *BKE_undo_menu_string(void); extern void BKE_undo_number(struct bContext *C, int nr); -extern char *BKE_undo_get_name(int nr, int *active); +extern const char *BKE_undo_get_name(int nr, int *active); extern void BKE_undo_save_quit(void); extern struct Main *BKE_undo_get_main(struct Scene **scene); diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h index f32a4b1e6a8..be7aaa70188 100644 --- a/source/blender/blenkernel/BKE_customdata_file.h +++ b/source/blender/blenkernel/BKE_customdata_file.h @@ -40,22 +40,22 @@ void cdf_free(CDataFile *cdf); /* File read/write/remove */ -int cdf_read_open(CDataFile *cdf, char *filename); +int cdf_read_open(CDataFile *cdf, const char *filename); int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay); int cdf_read_data(CDataFile *cdf, unsigned int size, void *data); void cdf_read_close(CDataFile *cdf); -int cdf_write_open(CDataFile *cdf, char *filename); +int cdf_write_open(CDataFile *cdf, const char *filename); int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay); int cdf_write_data(CDataFile *cdf, unsigned int size, void *data); void cdf_write_close(CDataFile *cdf); -void cdf_remove(char *filename); +void cdf_remove(const char *filename); /* Layers */ -CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name); -CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize); +CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, const char *name); +CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, const char *name, size_t datasize); #endif /* BKE_CUSTOMDATA_FILE_H */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 57c05637d50..dcca857179c 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -55,19 +55,19 @@ void end_latt_deform(struct Object *); int object_deform_mball(struct Object *ob, struct ListBase *dispbase); void outside_lattice(struct Lattice *lt); -void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target, - struct DerivedMesh *dm, float (*vertexCos)[3], - int numVerts, char *vgroup, short defaxis); -void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, - float *orco, float *vec, float mat[][3], int no_rot_axis); +void curve_deform_verts(struct Scene *scene, struct Object *cuOb, struct Object *target, + struct DerivedMesh *dm, float (*vertexCos)[3], + int numVerts, const char *vgroup, short defaxis); +void curve_deform_vector(struct Scene *scene, struct Object *cuOb, struct Object *target, + float *orco, float *vec, float mat[][3], int no_rot_axis); void lattice_deform_verts(struct Object *laOb, struct Object *target, - struct DerivedMesh *dm, float (*vertexCos)[3], - int numVerts, char *vgroup); + struct DerivedMesh *dm, float (*vertexCos)[3], + int numVerts, const char *vgroup); void armature_deform_verts(struct Object *armOb, struct Object *target, - struct DerivedMesh *dm, float (*vertexCos)[3], - float (*defMats)[3][3], int numVerts, int deformflag, - float (*prevCos)[3], const char *defgrp_name); + struct DerivedMesh *dm, float (*vertexCos)[3], + float (*defMats)[3][3], int numVerts, int deformflag, + float (*prevCos)[3], const char *defgrp_name); float (*lattice_getVertexCos(struct Object *ob, int *numVerts_r))[3]; void lattice_applyVertexCos(struct Object *ob, float (*vertexCos)[3]); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 110e6e851c8..28ca1006a03 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -323,7 +323,7 @@ void BKE_ptcache_mem_to_disk(struct PTCacheID *pid); void BKE_ptcache_toggle_disk_cache(struct PTCacheID *pid); /* Rename all disk cache files with a new name. Doesn't touch the actual content of the files. */ -void BKE_ptcache_disk_cache_rename(struct PTCacheID *pid, char *from, char *to); +void BKE_ptcache_disk_cache_rename(struct PTCacheID *pid, const char *name_src, const char *name_dst); /* Loads simulation from external (disk) cache files. */ void BKE_ptcache_load_external(struct PTCacheID *pid); diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h index ce0ea3dcc9a..779c83acf21 100644 --- a/source/blender/blenkernel/BKE_property.h +++ b/source/blender/blenkernel/BKE_property.h @@ -44,11 +44,10 @@ struct bProperty *new_property(int type); void unique_property(struct bProperty *first, struct bProperty *prop, int force); struct bProperty *get_ob_property(struct Object *ob, const char *name); void set_ob_property(struct Object *ob, struct bProperty *propc); -int compare_property(struct bProperty *prop, char *str); -void set_property(struct bProperty *prop, char *str); -void add_property(struct bProperty *prop, char *str); +int compare_property(struct bProperty *prop, const char *str); +void set_property(struct bProperty *prop, const char *str); +void add_property(struct bProperty *prop, const char *str); void set_property_valstr(struct bProperty *prop, char *str); void cp_property(struct bProperty *prop1, struct bProperty *prop2); #endif - diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 917b62c27cf..a16e55ce8ff 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -274,7 +274,7 @@ struct Sequence *seq_metastrip( struct Sequence * meta /* = NULL */, struct Sequence *seq); void seq_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); -void seq_dupe_animdata(struct Scene *scene, char *name_from, char *name_to); +void seq_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst); int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test, struct Scene *evil_scene); int shuffle_seq_time(ListBase * seqbasep, struct Scene *evil_scene); int seqbase_isolated_sel_check(struct ListBase *seqbase); diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index 2a613522686..a951347d946 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -56,7 +56,7 @@ void write_text(struct Text *text, const char *str); char* txt_to_buf (struct Text *text); void txt_clean_text (struct Text *text); void txt_order_cursors (struct Text *text); -int txt_find_string (struct Text *text, char *findstr, int wrap, int match_case); +int txt_find_string (struct Text *text, const char *findstr, int wrap, int match_case); int txt_has_sel (struct Text *text); int txt_get_span (struct TextLine *from, struct TextLine *to); void txt_move_up (struct Text *text, short sel); diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h index 1f54e4eeef0..db586f6d262 100644 --- a/source/blender/blenkernel/BKE_unit.h +++ b/source/blender/blenkernel/BKE_unit.h @@ -37,10 +37,10 @@ extern "C" { void bUnit_AsString(char *str, int len_max, double value, int prec, int system, int type, int split, int pad); /* replace units with values, used before python button evaluation */ -int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pref, int system, int type); +int bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type); /* make string keyboard-friendly: 10µm --> 10um */ -void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int type); +void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type); /* the size of the unit used for this value (used for calculating the ckickstep) */ double bUnit_ClosestScalar(double value, int system, int type); diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 2b10f1b246c..3263a1659f3 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -74,7 +74,7 @@ void filepath_ffmpeg(char* string, struct RenderData* rd); extern void ffmpeg_set_preset(struct RenderData *rd, int preset); extern void ffmpeg_verify_image_type(struct RenderData *rd); -extern struct IDProperty *ffmpeg_property_add(struct RenderData *Rd, char *type, int opt_index, int parent_index); +extern struct IDProperty *ffmpeg_property_add(struct RenderData *Rd, const char *type, int opt_index, int parent_index); extern int ffmpeg_property_add_string(struct RenderData *rd, const char *type, const char *str); extern void ffmpeg_property_del(struct RenderData *rd, void *type, void *prop_); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 6d94b42a7ac..63ab74fc105 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -545,7 +545,7 @@ void BKE_animdata_separate_by_basepath (ID *srcID, ID *dstID, ListBase *basepath /* Path Validation -------------------------------------------- */ /* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */ -static short check_rna_path_is_valid (ID *owner_id, char *path) +static short check_rna_path_is_valid (ID *owner_id, const char *path) { PointerRNA id_ptr, ptr; PropertyRNA *prop=NULL; @@ -560,7 +560,7 @@ static short check_rna_path_is_valid (ID *owner_id, char *path) /* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate * NOTE: we assume that oldName and newName have [" "] padding around them */ -static char *rna_path_rename_fix (ID *owner_id, const char *prefix, char *oldName, char *newName, char *oldpath, int verify_paths) +static char *rna_path_rename_fix (ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, int verify_paths) { char *prefixPtr= strstr(oldpath, prefix); char *oldNamePtr= strstr(oldpath, oldName); @@ -631,7 +631,7 @@ static void fcurves_path_rename_fix (ID *owner_id, const char *prefix, char *old } /* Check RNA-Paths for a list of Drivers */ -static void drivers_path_rename_fix (ID *owner_id, const char *prefix, char *oldName, char *newName, char *oldKey, char *newKey, ListBase *curves, int verify_paths) +static void drivers_path_rename_fix (ID *owner_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *curves, int verify_paths) { FCurve *fcu; @@ -691,7 +691,7 @@ static void nlastrips_path_rename_fix (ID *owner_id, const char *prefix, char *o * NOTE: it is assumed that the structure we're replacing is <["><"]> * i.e. pose.bones["Bone"] */ -void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, const char *prefix, char *oldName, char *newName, int oldSubscript, int newSubscript, int verify_paths) +void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, int verify_paths) { NlaTrack *nlt; char *oldN, *newN; @@ -808,7 +808,7 @@ void BKE_animdata_main_cb (Main *mainptr, ID_AnimData_Edit_Callback func, void * * i.e. pose.bones["Bone"] */ /* TODO: use BKE_animdata_main_cb for looping over all data */ -void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newName) +void BKE_all_animdata_fix_paths_rename (const char *prefix, const char *oldName, const char *newName) { Main *mainptr= G.main; ID *id; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index d68b0b361d1..0e8d598da3d 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -663,7 +663,7 @@ int BKE_undo_valid(const char *name) /* get name of undo item, return null if no item with this index */ /* if active pointer, set it to 1 if true */ -char *BKE_undo_get_name(int nr, int *active) +const char *BKE_undo_get_name(int nr, int *active) { UndoElem *uel= BLI_findlink(&undobase, nr); diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c index d65f08ed7a3..75898018a2b 100644 --- a/source/blender/blenkernel/intern/customdata_file.c +++ b/source/blender/blenkernel/intern/customdata_file.c @@ -273,7 +273,7 @@ static int cdf_write_header(CDataFile *cdf) return 1; } -int cdf_read_open(CDataFile *cdf, char *filename) +int cdf_read_open(CDataFile *cdf, const char *filename) { FILE *f; @@ -341,7 +341,7 @@ void cdf_read_close(CDataFile *cdf) } } -int cdf_write_open(CDataFile *cdf, char *filename) +int cdf_write_open(CDataFile *cdf, const char *filename) { CDataFileHeader *header; CDataFileImageHeader *image; @@ -405,14 +405,14 @@ void cdf_write_close(CDataFile *cdf) } } -void cdf_remove(char *filename) +void cdf_remove(const char *filename) { BLI_delete(filename, 0, 0); } /********************************** Layers ***********************************/ -CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name) +CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, const char *name) { CDataFileLayer *layer; int a; @@ -427,7 +427,7 @@ CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name) return NULL; } -CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize) +CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, const char *name, size_t datasize) { CDataFileLayer *newlayer, *layer; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 474b3a5ce63..5ab997d2c54 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -184,7 +184,7 @@ FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *pro char *path; if(driven) - *driven = 0; + *driven = FALSE; /* only use the current action ??? */ if (ELEM(NULL, adt, adt->action)) @@ -205,7 +205,7 @@ FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *pro if ((fcu == NULL) && (adt->drivers.first)) { fcu= list_find_fcurve(&adt->drivers, path, index); if(fcu && driven) - *driven = 1; + *driven = TRUE; fcu = NULL; } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 47878242604..cef23ac3824 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -658,7 +658,9 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C return 0; } -void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, char *vgroup, short defaxis) +void curve_deform_verts(Scene *scene, Object *cuOb, Object *target, + DerivedMesh *dm, float (*vertexCos)[3], + int numVerts, const char *vgroup, short defaxis) { Curve *cu; int a, flag; @@ -817,7 +819,7 @@ void curve_deform_vector(Scene *scene, Object *cuOb, Object *target, float *orco } void lattice_deform_verts(Object *laOb, Object *target, DerivedMesh *dm, - float (*vertexCos)[3], int numVerts, char *vgroup) + float (*vertexCos)[3], int numVerts, const char *vgroup) { int a; int use_vgroups; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index fa9d94eb24d..ae12ad8e66f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2875,7 +2875,7 @@ void BKE_ptcache_toggle_disk_cache(PTCacheID *pid) BKE_ptcache_update_info(pid); } -void BKE_ptcache_disk_cache_rename(PTCacheID *pid, char *from, char *to) +void BKE_ptcache_disk_cache_rename(PTCacheID *pid, const char *name_src, const char *name_dst) { char old_name[80]; int len; /* store the length of the string */ @@ -2892,7 +2892,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, char *from, char *to) BLI_strncpy(old_name, pid->cache->name, sizeof(old_name)); /* get "from" filename */ - BLI_strncpy(pid->cache->name, from, sizeof(pid->cache->name)); + BLI_strncpy(pid->cache->name, name_src, sizeof(pid->cache->name)); len = ptcache_filename(pid, old_filename, 0, 0, 0); /* no path */ @@ -2906,7 +2906,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, char *from, char *to) BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index); /* put new name into cache */ - BLI_strncpy(pid->cache->name, to, sizeof(pid->cache->name)); + BLI_strncpy(pid->cache->name, name_dst, sizeof(pid->cache->name)); while ((de = readdir(dir)) != NULL) { if (strstr(de->d_name, ext)) { /* do we have the right extension?*/ diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c index f9d470e48d8..d6c4b5f3a2e 100644 --- a/source/blender/blenkernel/intern/property.c +++ b/source/blender/blenkernel/intern/property.c @@ -200,7 +200,7 @@ void set_ob_property(Object *ob, bProperty *propc) /* negative: prop is smaller * positive: prop is larger */ -int compare_property(bProperty *prop, char *str) +int compare_property(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ float fvalue, ftest; @@ -237,7 +237,7 @@ int compare_property(bProperty *prop, char *str) return 0; } -void set_property(bProperty *prop, char *str) +void set_property(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ @@ -261,7 +261,7 @@ void set_property(bProperty *prop, char *str) } -void add_property(bProperty *prop, char *str) +void add_property(bProperty *prop, const char *str) { // extern int Gdfra; /* sector.c */ diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 6b319e6b5e1..9bde9374ab7 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -3404,7 +3404,7 @@ void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs) } } -void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to) +void seq_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst) { char str_from[32]; FCurve *fcu; @@ -3415,7 +3415,7 @@ void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to) if(scene->adt==NULL || scene->adt->action==NULL) return; - sprintf(str_from, "[\"%s\"]", name_from); + sprintf(str_from, "[\"%s\"]", name_src); fcu_last= scene->adt->action->curves.last; @@ -3427,7 +3427,7 @@ void seq_dupe_animdata(Scene *scene, char *name_from, char *name_to) } /* notice validate is 0, keep this because the seq may not be added to the scene yet */ - BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_from, name_to, 0, 0, 0); + BKE_animdata_fix_paths_rename(&scene->id, scene->adt, "sequence_editor.sequences_all", name_src, name_dst, 0, 0, 0); /* add the original fcurves back */ BLI_movelisttolist(&scene->adt->action->curves, &lb); diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 69af2570d0c..955127a8000 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1234,7 +1234,7 @@ char *txt_to_buf (Text *text) return buf; } -int txt_find_string(Text *text, char *findstr, int wrap, int match_case) +int txt_find_string(Text *text, const char *findstr, int wrap, int match_case) { TextLine *tl, *startl; char *s= NULL; diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 01b090f2967..616c27f6b0b 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -426,9 +426,9 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system, } -static char *unit_find_str(char *str, const char *substr) +static const char *unit_find_str(const char *str, const char *substr) { - char *str_found; + const char *str_found; if(substr && substr[0] != '\0') { str_found= strstr(str, substr); @@ -485,7 +485,7 @@ static int unit_scale_str(char *str, int len_max, char *str_tmp, double scale_pr { char *str_found; - if((len_max>0) && (str_found= unit_find_str(str, replace_str))) { /* XXX - investigate, does not respect len_max properly */ + if((len_max>0) && (str_found= (char *)unit_find_str(str, replace_str))) { /* XXX - investigate, does not respect len_max properly */ int len, len_num, len_name, len_move, found_ofs; found_ofs = (int)(str_found-str); @@ -537,7 +537,7 @@ static int unit_replace(char *str, int len_max, char *str_tmp, double scale_pref return ofs; } -static int unit_find(char *str, bUnitDef *unit) +static int unit_find(const char *str, bUnitDef *unit) { if (unit_find_str(str, unit->name_short)) return 1; if (unit_find_str(str, unit->name_plural)) return 1; @@ -562,7 +562,7 @@ static int unit_find(char *str, bUnitDef *unit) * * return true of a change was made. */ -int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pref, int system, int type) +int bUnit_ReplaceString(char *str, int len_max, const char *str_prev, double scale_pref, int system, int type) { bUnitCollection *usys = unit_get_system(system, type); @@ -676,7 +676,7 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre } /* 45µm --> 45um */ -void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int type) +void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int system, int type) { bUnitCollection *usys = unit_get_system(system, type); @@ -687,9 +687,7 @@ void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int for(unit= usys->units; unit->name; unit++) { if(len_max > 0 && (unit->name_alt || unit == unit_def)) { - char *found= NULL; - - found= unit_find_str(orig_str, unit->name_short); + const char *found= unit_find_str(orig_str, unit->name_short); if(found) { int offset= (int)(found - orig_str); int len_name= 0; diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index da1412dac0d..2646f5164b2 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -1046,7 +1046,7 @@ void ffmpeg_property_del(RenderData *rd, void *type, void *prop_) } } -IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int parent_index) +IDProperty *ffmpeg_property_add(RenderData *rd, const char *type, int opt_index, int parent_index) { AVCodecContext c; const AVOption * o; diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 47123b7fb4d..87254c20c0f 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -173,7 +173,7 @@ void poseAnim_mapping_refresh(struct bContext *C, struct Scene *scene, struct Ob void poseAnim_mapping_reset(ListBase *pfLinks); void poseAnim_mapping_autoKeyframe(struct bContext *C, struct Scene *scene, struct Object *ob, ListBase *pfLinks, float cframe); -LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, char *path); +LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path); /* ******************************************************* */ /* PoseLib */ @@ -209,13 +209,13 @@ void BIF_sk_selectStroke(struct bContext *C, const int mval[2], short extend); /* duplicate method */ void preEditBoneDuplicate(struct ListBase *editbones); -struct EditBone *duplicateEditBone(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *ob); +struct EditBone *duplicateEditBone(struct EditBone *curBone, const char *name, struct ListBase *editbones, struct Object *ob); void updateDuplicateSubtarget(struct EditBone *dupBone, struct ListBase *editbones, struct Object *ob); /* duplicate method (cross objects */ /* editbones is the target list */ -struct EditBone *duplicateEditBoneObjects(struct EditBone *curBone, char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); +struct EditBone *duplicateEditBoneObjects(struct EditBone *curBone, const char *name, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); /* editbones is the source list */ void updateDuplicateSubtargetObjects(struct EditBone *dupBone, struct ListBase *editbones, struct Object *src_ob, struct Object *dst_ob); diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 15c8868f9b9..7376b2e804c 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -2523,7 +2523,7 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob } -EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) +EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) { EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone"); @@ -2567,7 +2567,7 @@ EditBone *duplicateEditBoneObjects(EditBone *curBone, char *name, ListBase *edit return eBone; } -EditBone *duplicateEditBone(EditBone *curBone, char *name, ListBase *editbones, Object *ob) +EditBone *duplicateEditBone(EditBone *curBone, const char *name, ListBase *editbones, Object *ob) { return duplicateEditBoneObjects(curBone, name, editbones, ob, ob); } @@ -5319,7 +5319,7 @@ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldnam /* called by UI for renaming a bone */ /* warning: make sure the original bone was not renamed yet! */ /* seems messy, but thats what you get with not using pointers but channel names :) */ -void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep) +void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *newnamep) { Object *ob; char newname[MAXBONENAME]; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 31be1efdc1f..d228d4d3772 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -187,7 +187,7 @@ void BIF_makeListTemplates(const bContext *C) } } -char *BIF_listTemplates(const bContext *UNUSED(C)) +const char *BIF_listTemplates(const bContext *UNUSED(C)) { GHashIterator ghi; char menu_header[] = "Template%t|None%x0|"; diff --git a/source/blender/editors/armature/poseUtils.c b/source/blender/editors/armature/poseUtils.c index 71cdda7fe15..1a9ff73e5dc 100644 --- a/source/blender/editors/armature/poseUtils.c +++ b/source/blender/editors/armature/poseUtils.c @@ -262,7 +262,7 @@ void poseAnim_mapping_autoKeyframe (bContext *C, Scene *scene, Object *ob, ListB /* find the next F-Curve for a PoseChannel with matching path... * - path is not just the pfl rna_path, since that path doesn't have property info yet */ -LinkData *poseAnim_mapping_getNextFCurve (ListBase *fcuLinks, LinkData *prev, char *path) +LinkData *poseAnim_mapping_getNextFCurve (ListBase *fcuLinks, LinkData *prev, const char *path) { LinkData *first= (prev)? prev->next : (fcuLinks)? fcuLinks->first : NULL; LinkData *ld; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 121c53f7c65..2e9186b6c2f 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -141,7 +141,7 @@ void create_vgroups_from_armature(struct ReportList *reports, struct Scene *scen void auto_align_armature(struct Scene *scene, struct View3D *v3d, short mode); void unique_editbone_name(struct ListBase *ebones, char *name, EditBone *bone); /* if bone is already in list, pass it as param to ignore it */ -void ED_armature_bone_rename(struct bArmature *arm, char *oldnamep, char *newnamep); +void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep); void undo_push_armature(struct bContext *C, const char *name); @@ -163,7 +163,7 @@ void BIF_deleteSketch(struct bContext *C); void BIF_selectAllSketch(struct bContext *C, int mode); /* -1: deselect, 0: select, 1: toggle */ void BIF_makeListTemplates(const struct bContext *C); -char *BIF_listTemplates(const struct bContext *C); +const char *BIF_listTemplates(const struct bContext *C); int BIF_currentTemplate(const struct bContext *C); void BIF_freeTemplates(struct bContext *C); void BIF_setTemplate(struct bContext *C, int index); diff --git a/source/blender/editors/include/ED_fluidsim.h b/source/blender/editors/include/ED_fluidsim.h index f48b5df56c0..d47ba2bfba9 100644 --- a/source/blender/editors/include/ED_fluidsim.h +++ b/source/blender/editors/include/ED_fluidsim.h @@ -48,9 +48,4 @@ void fluidsimSettingsFree(struct FluidsimSettings* sb); /* duplicate internal data */ struct FluidsimSettings* fluidsimSettingsCopy(struct FluidsimSettings* sb); -/* memory estimate */ -void fluidsimEstimateMemory(struct Object *ob, struct FluidsimSettings *fs, char *value); - #endif /* ED_FLUIDSIM_H */ - - diff --git a/source/blender/editors/include/ED_logic.h b/source/blender/editors/include/ED_logic.h index e6026eb5fee..ce1f2b8faac 100644 --- a/source/blender/editors/include/ED_logic.h +++ b/source/blender/editors/include/ED_logic.h @@ -34,6 +34,3 @@ void ED_operatortypes_logic(void); #endif /* ED_LOGIC_H */ - - - diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index 48232acf562..d1da9f308fb 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -72,7 +72,7 @@ void PE_undo(struct Scene *scene); void PE_redo(struct Scene *scene); int PE_undo_valid(struct Scene *scene); void PE_undo_number(struct Scene *scene, int nr); -char *PE_undo_get_name(struct Scene *scene, int nr, int *active); +const char *PE_undo_get_name(struct Scene *scene, int nr, int *active); #endif /* ED_PARTICLE_H */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index c644b1d27b4..3a6cbc556d1 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -107,10 +107,12 @@ struct Base; struct Scene; struct Object; +#if 0 /* UNUSED, deprecate? */ void BIF_setSingleAxisConstraint(float vec[3], char *text); void BIF_setDualAxisConstraint(float vec1[3], float vec2[3], char *text); void BIF_setLocalAxisConstraint(char axis, char *text); void BIF_setLocalLockConstraint(char axis, char *text); +#endif int BIF_snappingSupported(struct Object *obedit); @@ -132,7 +134,7 @@ struct EnumPropertyItem *BIF_enumTransformOrientation(struct bContext *C); const char * BIF_menustringTransformOrientation(const struct bContext *C, const char *title); /* the returned value was allocated and needs to be freed after use */ int BIF_countTransformOrientation(const struct bContext *C); -void BIF_TransformSetUndo(char *str); +void BIF_TransformSetUndo(const char *str); void BIF_selectOrientation(void); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cb18ea37ffc..7a556eddd2b 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -506,8 +506,6 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, const char *str, int x1, i uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, int x1, int y1, short x2, short y2, float a1, float a2, const char *tip); -void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval); - uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, const char *name, int icon, int x1, int y1, int x2, int y2); int uiDefAutoButsRNA(uiLayout *layout, struct PointerRNA *ptr, int (*check_prop)(struct PropertyRNA *), const char label_align); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 3694102fa5b..b0a17c6f9a9 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -4023,7 +4023,7 @@ void PE_undo_number(Scene *scene, int nr) /* get name of undo item, return null if no item with this index */ /* if active pointer, set it to 1 if true */ -char *PE_undo_get_name(Scene *scene, int nr, int *active) +const char *PE_undo_get_name(Scene *scene, int nr, int *active) { PTCacheEdit *edit= PE_get_current(scene, OBACT); PTCacheUndo *undo; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index e739c5fe22e..deed7ad2a3a 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -666,7 +666,7 @@ struct direntry * filelist_file(struct FileList* filelist, int index) return &filelist->filelist[fidx]; } -int filelist_find(struct FileList* filelist, char *file) +int filelist_find(struct FileList* filelist, const char *filename) { int index = -1; int i; @@ -677,7 +677,7 @@ int filelist_find(struct FileList* filelist, char *file) for (i = 0; i < filelist->numfiles; ++i) { - if ( strcmp(filelist->filelist[i].relname, file) == 0) { /* not dealing with user input so dont need BLI_path_cmp */ + if ( strcmp(filelist->filelist[i].relname, filename) == 0) { /* not dealing with user input so dont need BLI_path_cmp */ index = i; break; } diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index a7f2a0d1af9..cd4c22df418 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -66,7 +66,7 @@ typedef enum FileCheckType struct FileList * filelist_new(short type); void filelist_init_icons(void); void filelist_free_icons(void); -int filelist_find(struct FileList* filelist, char *file); +int filelist_find(struct FileList* filelist, const char *file); void filelist_free(struct FileList* filelist); void filelist_sort(struct FileList* filelist, short sort); int filelist_numfiles(struct FileList* filelist); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 505452f504c..77ac577792c 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -127,7 +127,7 @@ static void draw_render_info(Scene *scene, Image *ima, ARegion *ar) BKE_image_release_renderresult(scene, ima); } -void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf) +void draw_image_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf) { char str[256]; float dx= 6; diff --git a/source/blender/editors/space_image/image_intern.h b/source/blender/editors/space_image/image_intern.h index 4310b5dbae8..04156c80c0e 100644 --- a/source/blender/editors/space_image/image_intern.h +++ b/source/blender/editors/space_image/image_intern.h @@ -55,7 +55,7 @@ void IMAGE_OT_toolbox(struct wmOperatorType *ot); /* image_draw.c */ void draw_image_main(struct SpaceImage *sima, struct ARegion *ar, struct Scene *scene); -void draw_image_info(struct ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp, int *zp, float *zpf); +void draw_image_info(struct ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4], int *zp, float *zpf); void draw_image_grease_pencil(struct bContext *C, short onlyv2d); /* image_ops.c */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index db8d9b1ddf1..24ea51567ad 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2124,7 +2124,7 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage) } } -void draw_nodespace_color_info(ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp) +void draw_nodespace_color_info(ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4]) { char str[256]; float dx= 6; diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 655d54ac8a7..88b81d0855c 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -99,7 +99,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link, int t int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol); void node_draw_link_straight(View2D *v2d, SpaceNode *snode, bNodeLink *link, int th_col1, int do_shaded, int th_col2, int do_triple, int th_col3 ); void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage); -void draw_nodespace_color_info(struct ARegion *ar, int color_manage, int channels, int x, int y, char *cp, float *fp); +void draw_nodespace_color_info(struct ARegion *ar, int color_manage, int channels, int x, int y, const char cp[4], const float fp[4]); /* node_edit.c */ void node_tree_from_ID(ID *id, bNodeTree **ntree, bNodeTree **edittree, int *treetype); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 73174dcace8..6eafb10d74c 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -551,12 +551,9 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) if(obedit==NULL && v3d->localvd==NULL) { unsigned int ob_lay = ob ? ob->lay : 0; - + /* Layers */ - if (v3d->scenelock) - uiTemplateLayers(layout, &sceneptr, "layers", &v3dptr, "layers_used", ob_lay); - else - uiTemplateLayers(layout, &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); + uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); /* Scene lock */ uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 759fefba438..c3a77dc67a5 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -5861,7 +5861,7 @@ int TimeScale(TransInfo *t, const int UNUSED(mval[2])) /* ************************************ */ -void BIF_TransformSetUndo(char *UNUSED(str)) +void BIF_TransformSetUndo(const char *UNUSED(str)) { // TRANSFORM_FIX_ME //Trans.undostr= str; diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index a312b0abbb4..34dffc11d94 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -338,7 +338,7 @@ int undo_editmode_valid(const char *undoname) /* get name of undo item, return null if no item with this index */ /* if active pointer, set it to 1 if true */ -char *undo_editmode_get_name(bContext *C, int nr, int *active) +const char *undo_editmode_get_name(bContext *C, int nr, int *active) { UndoElem *uel; diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 6a1819736a2..527537b5efb 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -426,7 +426,7 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem) int active, i= 0; while(TRUE) { - char *name= NULL; + const char *name= NULL; if(undosys==UNDOSYSTEM_PARTICLE) { name= PE_undo_get_name(CTX_data_scene(C), i, &active); diff --git a/source/blender/editors/util/util_intern.h b/source/blender/editors/util/util_intern.h index 3e2833ec89a..c6e2d079c28 100644 --- a/source/blender/editors/util/util_intern.h +++ b/source/blender/editors/util/util_intern.h @@ -37,7 +37,7 @@ /* editmode_undo.c */ void undo_editmode_name (struct bContext *C, const char *undoname); int undo_editmode_valid (const char *undoname); -char *undo_editmode_get_name (struct bContext *C, int nr, int *active); +const char *undo_editmode_get_name (struct bContext *C, int nr, int *active); void *undo_editmode_get_prev (struct Object *ob); void undo_editmode_step (struct bContext *C, int step); void undo_editmode_number (struct bContext *C, int nr); From fd6138a26d1efdf46be3d8dff85d63eaad5f0d21 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 12:16:40 +0000 Subject: [PATCH 101/147] remove dirs to make them external's --- po/POTFILES.in | 201 ------------------------- po/README.txt | 81 ---------- po/check_po.py | 92 ------------ po/clean_po.py | 189 ----------------------- po/merge_po.py | 166 --------------------- po/update_mo.py | 67 --------- po/update_msg.py | 380 ----------------------------------------------- po/update_po.py | 66 -------- po/update_pot.py | 106 ------------- 9 files changed, 1348 deletions(-) delete mode 100644 po/POTFILES.in delete mode 100644 po/README.txt delete mode 100755 po/check_po.py delete mode 100755 po/clean_po.py delete mode 100755 po/merge_po.py delete mode 100755 po/update_mo.py delete mode 100644 po/update_msg.py delete mode 100755 po/update_po.py delete mode 100755 po/update_pot.py diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index 5a4ba6a9cb2..00000000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,201 +0,0 @@ -release/scripts/modules/rna_prop_ui.py - -release/scripts/startup/bl_operators/object.py -release/scripts/startup/bl_operators/object_align.py -release/scripts/startup/bl_operators/object_quick_effects.py -release/scripts/startup/bl_operators/object_randomize_transform.py -release/scripts/startup/bl_operators/presets.py -release/scripts/startup/bl_operators/screen_play_rendered_anim.py -release/scripts/startup/bl_operators/sequencer.py -release/scripts/startup/bl_operators/wm.py - -release/scripts/startup/bl_ui/properties_animviz.py -release/scripts/startup/bl_ui/properties_data_armature.py -release/scripts/startup/bl_ui/properties_data_bone.py -release/scripts/startup/bl_ui/properties_data_camera.py -release/scripts/startup/bl_ui/properties_data_curve.py -release/scripts/startup/bl_ui/properties_data_empty.py -release/scripts/startup/bl_ui/properties_data_lamp.py -release/scripts/startup/bl_ui/properties_data_lattice.py -release/scripts/startup/bl_ui/properties_data_mesh.py -release/scripts/startup/bl_ui/properties_data_metaball.py -release/scripts/startup/bl_ui/properties_data_modifier.py -release/scripts/startup/bl_ui/properties_game.py -release/scripts/startup/bl_ui/properties_material.py -release/scripts/startup/bl_ui/properties_object_constraint.py -release/scripts/startup/bl_ui/properties_object.py -release/scripts/startup/bl_ui/properties_particle.py -release/scripts/startup/bl_ui/properties_physics_cloth.py -release/scripts/startup/bl_ui/properties_physics_common.py -release/scripts/startup/bl_ui/properties_physics_field.py -release/scripts/startup/bl_ui/properties_physics_fluid.py -release/scripts/startup/bl_ui/properties_physics_smoke.py -release/scripts/startup/bl_ui/properties_physics_softbody.py -release/scripts/startup/bl_ui/properties_render.py -release/scripts/startup/bl_ui/properties_scene.py -release/scripts/startup/bl_ui/properties_texture.py -release/scripts/startup/bl_ui/properties_world.py - -release/scripts/startup/bl_ui/space_console.py -release/scripts/startup/bl_ui/space_dopesheet.py -release/scripts/startup/bl_ui/space_graph.py -release/scripts/startup/bl_ui/space_image.py -release/scripts/startup/bl_ui/space_info.py -release/scripts/startup/bl_ui/space_logic.py -release/scripts/startup/bl_ui/space_nla.py -release/scripts/startup/bl_ui/space_node.py -release/scripts/startup/bl_ui/space_outliner.py -release/scripts/startup/bl_ui/space_sequencer.py -release/scripts/startup/bl_ui/space_text.py -release/scripts/startup/bl_ui/space_time.py -release/scripts/startup/bl_ui/space_userpref.py -release/scripts/startup/bl_ui/space_userpref_keymap.py -release/scripts/startup/bl_ui/space_view3d.py -release/scripts/startup/bl_ui/space_view3d_toolbar.py - -source/blender/editors/animation/anim_channels_edit.c -source/blender/editors/animation/anim_markers.c -source/blender/editors/animation/anim_ops.c -source/blender/editors/animation/drivers.c -source/blender/editors/animation/keyframing.c -source/blender/editors/animation/keyingsets.c - -source/blender/editors/armature/armature_ops.c -source/blender/editors/armature/editarmature.c -source/blender/editors/armature/editarmature_sketch.c -source/blender/editors/armature/poselib.c -source/blender/editors/armature/poseobject.c -source/blender/editors/armature/poseSlide.c - -source/blender/editors/curve/editcurve.c -source/blender/editors/curve/editfont.c - -source/blender/editors/gpencil/gpencil_paint.c - -source/blender/editors/interface/interface_layout.c -source/blender/editors/interface/interface_ops.c -source/blender/editors/interface/interface_regions.c -source/blender/editors/interface/interface_templates.c -source/blender/editors/interface/interface_utils.c -source/blender/editors/interface/view2d_ops.c - -source/blender/editors/mesh/editmesh.c -source/blender/editors/mesh/editmesh_add.c -source/blender/editors/mesh/editmesh_loop.c -source/blender/editors/mesh/editmesh_mods.c -source/blender/editors/mesh/editmesh_tools.c -source/blender/editors/mesh/loopcut.c -source/blender/editors/mesh/mesh_data.c -source/blender/editors/mesh/mesh_ops.c - -source/blender/editors/metaball/mball_edit.c - -source/blender/editors/object/object_add.c -source/blender/editors/object/object_constraint.c -source/blender/editors/object/object_edit.c -source/blender/editors/object/object_group.c -source/blender/editors/object/object_lattice.c -source/blender/editors/object/object_modifier.c -source/blender/editors/object/object_ops.c -source/blender/editors/object/object_relations.c -source/blender/editors/object/object_select.c -source/blender/editors/object/object_shapekey.c -source/blender/editors/object/object_transform.c -source/blender/editors/object/object_vgroup.c - -source/blender/editors/physics/particle_edit.c -source/blender/editors/physics/particle_object.c -source/blender/editors/physics/physics_pointcache.c - -source/blender/editors/render/render_internal.c -source/blender/editors/render/render_opengl.c -source/blender/editors/render/render_shading.c -source/blender/editors/render/render_view.c - -source/blender/editors/screen/area.c -source/blender/editors/screen/screendump.c -source/blender/editors/screen/screen_ops.c - -source/blender/editors/sculpt_paint/paint_ops.c -source/blender/editors/sculpt_paint/paint_image.c -source/blender/editors/sculpt_paint/paint_utils.c -source/blender/editors/sculpt_paint/paint_vertex.c -source/blender/editors/sculpt_paint/sculpt.c - -source/blender/editors/sound/sound_ops.c - -source/blender/editors/space_action/action_edit.c -source/blender/editors/space_action/action_ops.c -source/blender/editors/space_action/action_select.c - -source/blender/editors/space_buttons/buttons_header.c -source/blender/editors/space_buttons/buttons_ops.c - -source/blender/editors/space_console/console_ops.c - -source/blender/editors/space_file/file_draw.c -source/blender/editors/space_file/file_ops.c -source/blender/editors/space_file/file_panels.c - -source/blender/editors/space_graph/graph_buttons.c -source/blender/editors/space_graph/graph_edit.c -source/blender/editors/space_graph/graph_ops.c -source/blender/editors/space_graph/graph_select.c - -source/blender/editors/space_image/image_buttons.c -source/blender/editors/space_image/image_ops.c - -source/blender/editors/space_info/info_ops.c -source/blender/editors/space_info/info_report.c -source/blender/editors/space_info/space_info.c - -source/blender/editors/space_logic/logic_buttons.c - -source/blender/editors/space_nla/nla_buttons.c -source/blender/editors/space_nla/nla_channels.c -source/blender/editors/space_nla/nla_edit.c -source/blender/editors/space_nla/nla_select.c - -source/blender/editors/space_node/node_buttons.c -source/blender/editors/space_node/node_edit.c -source/blender/editors/space_node/node_header.c -source/blender/editors/space_node/node_ops.c -source/blender/editors/space_node/node_select.c -source/blender/editors/space_node/node_state.c - -source/blender/editors/space_script/script_edit.c - -source/blender/editors/space_sequencer/sequencer_add.c -source/blender/editors/space_sequencer/sequencer_buttons.c -source/blender/editors/space_sequencer/sequencer_edit.c -source/blender/editors/space_sequencer/sequencer_select.c - -source/blender/editors/space_text/text_header.c -source/blender/editors/space_text/text_ops.c -source/blender/editors/space_time/time_ops.c - -source/blender/editors/space_view3d/view3d_buttons.c -source/blender/editors/space_view3d/view3d_draw.c -source/blender/editors/space_view3d/view3d_edit.c -source/blender/editors/space_view3d/view3d_fly.c -source/blender/editors/space_view3d/view3d_header.c -source/blender/editors/space_view3d/view3d_select.c -source/blender/editors/space_view3d/view3d_view.c -source/blender/editors/space_view3d/view3d_toolbar.c - -source/blender/editors/transform/transform.c -source/blender/editors/transform/transform_ops.c -source/blender/editors/transform/transform_orientations.c - -source/blender/editors/util/undo.c - -source/blender/editors/uvedit/uvedit_ops.c -source/blender/editors/uvedit/uvedit_unwrap_ops.c - -source/blender/makesrna/intern/rna_userdef.c - -source/blender/windowmanager/intern/wm_files.c -source/blender/windowmanager/intern/wm_operators.c -source/blender/windowmanager/intern/wm_window.c - - diff --git a/po/README.txt b/po/README.txt deleted file mode 100644 index 6e634ae5ee3..00000000000 --- a/po/README.txt +++ /dev/null @@ -1,81 +0,0 @@ -Blender translation HOWTO -========================= - -I'll try briefly explain how translation works and how to update translation files. - -1. How it works ---------------- - -This folder contains source files for translation system. These source files have -got .po extension and they've got pretty simple syntax: - -msgid "some message id" -msgstr "translation for this message" - -This means when string "some message id" is used as operator name, tooltip, menu -and so it'll be displayed on the screen as "translation for this message". -Pretty simple. - -This source files are pre-compiled into ../release/datafiles/locale//LC_MESSAGES/blender.mo, -so they aren't getting compiled every time Blender is compiling to save some time and prevent -failure on systems which don't have needed tools for compiling .po files. - -2. How to update translations ------------------------------ - -It's also pretty simple. If you can find string you want to translate in .po -file as msgid, just write correct msgstr string for it. If msgid is marked as fuzzy, -i.e. - -#, fuzzy -msgid "some message id" -msgstr "translation for this message" - -it means translation used to exist for this message, but message was changed, so translation -also have to be updated (it's easier to make new translation based on previous translation). -When translation was updated, remove line with '#, fuzzy' and it'll work. - -If there's no message in .po file you want to translate, probably .po file should be updated. -Use the following steps for this: -- With newly compiled blender run: - `blender --background --factory-startup --python update_msg.py` - to update messages.txt file (this file contains strings collected - automatically from RNA system and python UI scripts) -- Run update_pot.py script which will update blender.pot file. This file contains all - strings which should be transated. -- Run update_po.py script to merge all .po files with blender.pot (so all .po files - will contain all msgid-s declared in blender.pot) or update_po.py to - update only needed .po file(s) to save time when you're busy with translation. - But before commit all .po files better be updated. - -When you've finished with translation, you should re-compile .po file into .mo file. -It's also pretty simple: just run update_mo.py script to recompile all languages or -just update_mo.py to re-compile only needed language(s). - -NOTE: msgfmt, msgmerge and xgettext tools should be available in your PATH. - -These steps to update template, translation files and compile them can be made in "batch" mode -using GNUMakefile: - -make -f GNUMakefile translations - -NOTE: Blender has to be compiled using GNUMakefile first. - - -3. Note for Windows users -------------------------- -You can find compiled builds of gettext in the lib folder under "binaries\gettext\" for both windows and win64. -In order to run the scripts you will need to replace the location of the GETTEXT_..._EXECUTABLE. - -For example in update_pot.py: --GETTEXT_XGETTEXT_EXECUTABLE = "xgettext" -+GETTEXT_XGETTEXT_EXECUTABLE = "C:\\Blender\\lib\\\windows\\\binaries\\\gettext\\xgettext.exe" - -4. Other scripts ----------------- - -- check_po.py: this script checks if all messages declared in blender.pot exists in.po files - and that no extra messages are declared in .po files -- clean_po.py: this script removes all commented messages which aren't required by .pot file anymore. -- merge_po.py: this script accepts two files as arguments and copies translations from second file - into first file. diff --git a/po/check_po.py b/po/check_po.py deleted file mode 100755 index a2b19d57428..00000000000 --- a/po/check_po.py +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update the pot file according the POTFILES.in - -import os -import sys -from codecs import open - -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) - -FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot") - - -def read_messages(fname): - def stripeol(s): - return s.rstrip("\n\r") - - messages = {} - reading_message = False - message = "" - with open(fname, 'r', "utf-8") as handle: - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - if line.startswith("msgid"): - reading_message = True - message = line[7:-1] - elif line.startswith("msgstr"): - reading_message = False - messages[message] = True - elif reading_message: - message += line[1:-1] - return messages - - -def main(): - pot_messages = read_messages(FILE_NAME_POT) - - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - po_messages = read_messages(po) - for msgid in po_messages: - if not pot_messages.get(msgid): - print('Unneeded message id \'%s\'' % (msgid)) - - for msgid in pot_messages: - if not po_messages.get(msgid): - print('Missed message id \'%s\'' % (msgid)) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith('.po'): - print('Processing %s...' % (po)) - po_messages = read_messages(po) - for msgid in po_messages: - if not pot_messages.get(msgid): - print(' Unneeded message id \'%s\'' % (msgid)) - - for msgid in pot_messages: - if not po_messages.get(msgid): - print(' Missed message id \'%s\'' % (msgid)) - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/clean_po.py b/po/clean_po.py deleted file mode 100755 index 95bac39b42e..00000000000 --- a/po/clean_po.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update the pot file according the POTFILES.in - -import os -import sys -import collections - -from codecs import open - -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) - -FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot") - - -def read_messages(fname): - def stripeol(s): - return s.rstrip("\n\r") - - last_message = None - - if hasattr(collections, 'OrderedDict'): - messages = collections.OrderedDict() - commented_messages = collections.OrderedDict() - else: - messages = {} - commented_messages = {} - - reading_message = False - reading_translation = False - commented = False - message = "" - translation = "" - message_lines = [] - translation_lines = [] - comment_lines = [] - with open(fname, 'r', "utf-8") as handle: - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - if line.startswith("msgid") or line.startswith("#~ msgid"): - if reading_translation: - last_message['translation'] = translation - translation_lines = [] - - reading_message = True - reading_translation = False - - if line.startswith('#~'): - message = line[10:-1] - commented = True - else: - message = line[7:-1] - commented = False - - message_lines.append(message) - elif line.startswith("msgstr") or line.startswith("#~ msgstr"): - reading_message = False - reading_translation = True - last_message = {'comment_lines': comment_lines, - 'message_lines': message_lines, - 'translation_lines': translation_lines} - - if commented: - translation = line[11:-1] - commented_messages[message] = last_message - else: - translation = line[8:-1] - messages[message] = last_message - - message_lines = [] - comment_lines = [] - translation_lines.append(translation) - elif not line.startswith('"') and not line.startswith('#~ "'): - if reading_translation: - last_message['translation'] = translation - else: - comment_lines.append(line) - - reading_message = False - reading_translation = False - message_lines = [] - translation_lines = [] - elif reading_message: - if line.startswith('#~ "'): - m = line[4:-1] - else: - m = line[1:-1] - - message += m - message_lines.append(m) - elif reading_translation: - if line.startswith('#~ "'): - t = line[4:-1] - else: - t = line[1:-1] - - translation += t - translation_lines.append(t) - - return (messages, commented_messages) - - -def do_clean(po, pot_messages): - po_messages, commented_messages = read_messages(po) - - for msgid in commented_messages: - if pot_messages.get(msgid): - t = po_messages.get(msgid) - if not t: - print("Reusing full item from commented " - "lines for msgid '%s'" % msgid) - po_messages[msgid] = commented_messages[msgid] - elif not t['translation']: - print("Reusing translation from commented " - "lines for msgid '%s'" % msgid) - m = commented_messages[msgid] - t['translation'] = m['translation'] - t['translation_lines'] = m['translation_lines'] - - with open(po, 'w', 'utf-8') as handle: - for msgid in po_messages: - item = po_messages[msgid] - - for x in item['comment_lines']: - handle.write(x + "\n") - - first = True - for x in item['message_lines']: - if first: - handle.write("msgid \"%s\"\n" % x) - else: - handle.write("\"%s\"\n" % x) - first = False - - first = True - for x in item['translation_lines']: - if first: - handle.write("msgstr \"%s\"\n" % x) - else: - handle.write("\"%s\"\n" % x) - first = False - - handle.write("\n") - - -def main(): - pot_messages, commented_messages = read_messages(FILE_NAME_POT) - - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - do_clean(po, pot_messages) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith('.po'): - print('Processing %s...' % (po)) - do_clean(po, pot_messages) - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/merge_po.py b/po/merge_po.py deleted file mode 100755 index dcbe9fc9890..00000000000 --- a/po/merge_po.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update the pot file according the POTFILES.in - -import sys -import collections - -from codecs import open - - -def read_messages(fname): - def stripeol(s): - return s.rstrip("\n\r") - - last_message = None - - if hasattr(collections, 'OrderedDict'): - messages = collections.OrderedDict() - commented_messages = collections.OrderedDict() - else: - messages = {} - commented_messages = {} - - reading_message = False - reading_translation = False - commented = False - message = "" - translation = "" - message_lines = [] - translation_lines = [] - comment_lines = [] - with open(fname, 'r', "utf-8") as handle: - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - if line.startswith("msgid") or line.startswith("#~ msgid"): - if reading_translation: - last_message['translation'] = translation - translation_lines = [] - - reading_message = True - reading_translation = False - - if line.startswith('#~'): - message = line[10:-1] - commented = True - else: - message = line[7:-1] - commented = False - - message_lines.append(message) - elif line.startswith("msgstr") or line.startswith("#~ msgstr"): - reading_message = False - reading_translation = True - last_message = {'comment_lines': comment_lines, - 'message_lines': message_lines, - 'translation_lines': translation_lines} - - if commented: - translation = line[11:-1] - commented_messages[message] = last_message - else: - translation = line[8:-1] - messages[message] = last_message - - message_lines = [] - comment_lines = [] - translation_lines.append(translation) - elif not line.startswith('"') and not line.startswith('#~ "'): - if reading_translation: - last_message['translation'] = translation - else: - comment_lines.append(line) - - reading_message = False - reading_translation = False - message_lines = [] - translation_lines = [] - elif reading_message: - if line.startswith('#~ "'): - m = line[4:-1] - else: - m = line[1:-1] - - message += m - message_lines.append(m) - elif reading_translation: - if line.startswith('#~ "'): - t = line[4:-1] - else: - t = line[1:-1] - - translation += t - translation_lines.append(t) - - return (messages, commented_messages) - - -def main(): - if len(sys.argv) == 3: - dst_messages, tmp = read_messages(sys.argv[1]) - from_messages, tmp = read_messages(sys.argv[2]) - - for msgid in dst_messages: - msg = dst_messages.get(msgid) - from_msg = from_messages.get(msgid) - - if from_msg and from_msg['translation']: - msg['translation'] = from_msg['translation'] - msg['translation_lines'] = from_msg['translation_lines'] - - with open(sys.argv[1], 'w', 'utf-8') as handle: - for msgid in dst_messages: - item = dst_messages[msgid] - - for x in item['comment_lines']: - handle.write(x + "\n") - - first = True - for x in item['message_lines']: - if first: - handle.write("msgid \"%s\"\n" % x) - else: - handle.write("\"%s\"\n" % x) - first = False - - first = True - for x in item['translation_lines']: - if first: - handle.write("msgstr \"%s\"\n" % x) - else: - handle.write("\"%s\"\n" % x) - first = False - - handle.write("\n") - else: - print('Usage: %s ' % (sys.argv[0])) - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_mo.py b/po/update_mo.py deleted file mode 100755 index 50e99c7eeaa..00000000000 --- a/po/update_mo.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update all mo files in the LANGS - -import subprocess -import os -import sys - -GETTEXT_MSGFMT_EXECUTABLE = "msgfmt" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) -LOCALE_DIR = os.path.join(SOURCE_DIR, "release", "datafiles", "locale") - -DOMAIN = "blender" - - -def process_po(po): - lang = os.path.basename(po)[:-3] - - # show stats - cmd = (GETTEXT_MSGFMT_EXECUTABLE, - "--statistics", - os.path.join(CURRENT_DIR, "%s.po" % lang), - "-o", - os.path.join(LOCALE_DIR, lang, "LC_MESSAGES", "%s.mo" % DOMAIN), - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - -def main(): - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - process_po(po) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith(".po"): - process_po(po) - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_msg.py b/po/update_msg.py deleted file mode 100644 index 21d727922d4..00000000000 --- a/po/update_msg.py +++ /dev/null @@ -1,380 +0,0 @@ -# ***** 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 ***** - -# - -# Write out messages.txt from blender - -# Execite: -# blender --background --python po/update_msg.py - -import os - -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) - -FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt") -COMMENT_PREFIX = "#~ " - - -def dump_messages_rna(messages): - import bpy - - def classBlackList(): - blacklist_rna_class = [ - # core classes - "Context", "Event", "Function", "UILayout", - "BlendData", - # registerable classes - "Panel", "Menu", "Header", "RenderEngine", - "Operator", "OperatorMacro", "Macro", - "KeyingSetInfo", "UnknownType", - # window classes - "WindowManager", "Window" - ] - - # --------------------------------------------------------------------- - # Collect internal operators - - # extend with all internal operators - # note that this uses internal api introspection functions - # all possible operator names - op_names = list(sorted(set( - [cls.bl_rna.identifier for cls in - bpy.types.OperatorProperties.__subclasses__()] + - [cls.bl_rna.identifier for cls in - bpy.types.Operator.__subclasses__()] + - [cls.bl_rna.identifier for cls in - bpy.types.OperatorMacro.__subclasses__()] - ))) - - get_inatance = __import__("_bpy").ops.get_instance - path_resolve = type(bpy.context).__base__.path_resolve - for idname in op_names: - op = get_inatance(idname) - if 'INTERNAL' in path_resolve(op, "bl_options"): - blacklist_rna_class.append(idname) - - # --------------------------------------------------------------------- - # Collect builtin classes we dont need to doc - blacklist_rna_class.append("Property") - blacklist_rna_class.extend( - [cls.__name__ for cls in - bpy.types.Property.__subclasses__()]) - - # --------------------------------------------------------------------- - # Collect classes which are attached to collections, these are api - # access only. - collection_props = set() - for cls_id in dir(bpy.types): - cls = getattr(bpy.types, cls_id) - for prop in cls.bl_rna.properties: - if prop.type == 'COLLECTION': - prop_cls = prop.srna - if prop_cls is not None: - collection_props.add(prop_cls.identifier) - blacklist_rna_class.extend(sorted(collection_props)) - - return blacklist_rna_class - - blacklist_rna_class = classBlackList() - - def filterRNA(bl_rna): - id = bl_rna.identifier - if id in blacklist_rna_class: - print(" skipping", id) - return True - return False - - # ------------------------------------------------------------------------- - # Function definitions - - def walkProperties(bl_rna): - import bpy - - # get our parents properties not to export them multiple times - bl_rna_base = bl_rna.base - if bl_rna_base: - bl_rna_base_props = bl_rna_base.properties.values() - else: - bl_rna_base_props = () - - for prop in bl_rna.properties: - # only write this property is our parent hasn't got it. - if prop in bl_rna_base_props: - continue - if prop.identifier == "rna_type": - continue - - msgsrc = "bpy.types.%s.%s" % (bl_rna.identifier, prop.identifier) - if prop.name and prop.name != prop.identifier: - messages.setdefault(prop.name, []).append(msgsrc) - if prop.description: - messages.setdefault(prop.description, []).append(msgsrc) - - if isinstance(prop, bpy.types.EnumProperty): - for item in prop.enum_items: - msgsrc = "bpy.types.%s.%s, '%s'" % (bl_rna.identifier, - prop.identifier, - item.identifier, - ) - # Here identifier and name can be the same! - if item.name: # and item.name != item.identifier: - messages.setdefault(item.name, - []).append(msgsrc) - if item.description: - messages.setdefault(item.description, - []).append(msgsrc) - - def walkRNA(bl_rna): - - if filterRNA(bl_rna): - return - - msgsrc = "bpy.types.%s" % bl_rna.identifier - - if bl_rna.name and bl_rna.name != bl_rna.identifier: - messages.setdefault(bl_rna.name, []).append(msgsrc) - - if bl_rna.description: - messages.setdefault(bl_rna.description, []).append(msgsrc) - - if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label: - messages.setdefault(bl_rna.bl_label, []).append(msgsrc) - - walkProperties(bl_rna) - - def walkClass(cls): - walkRNA(cls.bl_rna) - - def walk_keymap_hierarchy(hier, msgsrc_prev): - for lvl in hier: - msgsrc = "%s.%s" % (msgsrc_prev, lvl[1]) - messages.setdefault(lvl[0], []).append(msgsrc) - - if lvl[3]: - walk_keymap_hierarchy(lvl[3], msgsrc) - - # ------------------------------------------------------------------------- - # Dump Messages - - def full_class_id(cls): - """ gives us 'ID.Lamp.AreaLamp' which is best for sorting. - """ - cls_id = "" - bl_rna = cls.bl_rna - while bl_rna: - cls_id = "%s.%s" % (bl_rna.identifier, cls_id) - bl_rna = bl_rna.base - return cls_id - - cls_list = type(bpy.context).__base__.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.Space.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.Operator.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.OperatorProperties.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - cls_list = bpy.types.Menu.__subclasses__() - cls_list.sort(key=full_class_id) - for cls in cls_list: - walkClass(cls) - - from bpy_extras.keyconfig_utils import KM_HIERARCHY - - walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY") - - -def dump_messages_pytext(messages): - """ dumps text inlined in the python user interface: eg. - - layout.prop("someprop", text="My Name") - """ - import ast - - # ------------------------------------------------------------------------- - # Gather function names - - import bpy - # key: func_id - # val: [(arg_kw, arg_pos), (arg_kw, arg_pos), ...] - func_translate_args = {} - - # so far only 'text' keywords, but we may want others translated later - translate_kw = ("text", ) - - for func_id, func in bpy.types.UILayout.bl_rna.functions.items(): - # check it has a 'text' argument - for (arg_pos, (arg_kw, arg)) in enumerate(func.parameters.items()): - if ((arg_kw in translate_kw) and - (arg.is_output == False) and - (arg.type == 'STRING')): - - func_translate_args.setdefault(func_id, []).append((arg_kw, - arg_pos)) - # print(func_translate_args) - - # ------------------------------------------------------------------------- - # Function definitions - - def extract_strings(fp_rel, node_container): - """ Recursively get strings, needed incase we have "Blah" + "Blah", - passed as an argument in that case it wont evaluate to a string. - """ - - for node in ast.walk(node_container): - if type(node) == ast.Str: - eval_str = ast.literal_eval(node) - if eval_str: - # print("%s:%d: %s" % (fp, node.lineno, eval_str)) - msgsrc = "%s:%s" % (fp_rel, node.lineno) - messages.setdefault(eval_str, []).append(msgsrc) - - def extract_strings_from_file(fp): - filedata = open(fp, 'r', encoding="utf8") - root_node = ast.parse(filedata.read(), fp, 'exec') - filedata.close() - - fp_rel = os.path.relpath(fp, SOURCE_DIR) - - for node in ast.walk(root_node): - if type(node) == ast.Call: - # print("found function at") - # print("%s:%d" % (fp, node.lineno)) - - # lambda's - if type(node.func) == ast.Name: - continue - - # getattr(self, con.type)(context, box, con) - if not hasattr(node.func, "attr"): - continue - - translate_args = func_translate_args.get(node.func.attr, ()) - - # do nothing if not found - for arg_kw, arg_pos in translate_args: - if arg_pos < len(node.args): - extract_strings(fp_rel, node.args[arg_pos]) - else: - for kw in node.keywords: - if kw.arg == arg_kw: - extract_strings(fp_rel, kw.value) - - # ------------------------------------------------------------------------- - # Dump Messages - - mod_dir = os.path.join(SOURCE_DIR, - "release", - "scripts", - "startup", - "bl_ui") - - files = [os.path.join(mod_dir, fn) - for fn in sorted(os.listdir(mod_dir)) - if not fn.startswith("_") - if fn.endswith("py") - ] - - for fp in files: - extract_strings_from_file(fp) - - -def dump_messages(): - - def filter_message(msg): - - # check for strings like ": %d" - msg_test = msg - for ignore in ("%d", "%s", "%r", # string formatting - "*", ".", "(", ")", "-", "/", "\\", "+", ":", "#", "%" - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", - "x", # used on its own eg: 100x200 - "X", "Y", "Z", # used alone. no need to include - ): - msg_test = msg_test.replace(ignore, "") - msg_test = msg_test.strip() - if not msg_test: - # print("Skipping: '%s'" % msg) - return True - - # we could filter out different strings here - - return False - - if 1: - import collections - messages = collections.OrderedDict() - else: - messages = {} - - messages[""] = [] - - # get strings from RNA - dump_messages_rna(messages) - - # get strings from UI layout definitions text="..." args - dump_messages_pytext(messages) - - del messages[""] - - message_file = open(FILE_NAME_MESSAGES, 'w', encoding="utf8") - # message_file.writelines("\n".join(sorted(messages))) - - for key, value in messages.items(): - - # filter out junk values - if filter_message(key): - continue - - for msgsrc in value: - message_file.write("%s%s\n" % (COMMENT_PREFIX, msgsrc)) - message_file.write("%s\n" % key) - - message_file.close() - - print("Written %d messages to: %r" % (len(messages), FILE_NAME_MESSAGES)) - - -def main(): - - try: - import bpy - except ImportError: - print("This script must run from inside blender") - return - - dump_messages() - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_po.py b/po/update_po.py deleted file mode 100755 index 0aab8c75646..00000000000 --- a/po/update_po.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update all po files in the LANGS - -import subprocess -import os -import sys - -GETTEXT_MSGMERGE_EXECUTABLE = "msgmerge" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -DOMAIN = "blender" - - -def process_po(po): - lang = os.path.basename(po)[:-3] - - # update po file - cmd = (GETTEXT_MSGMERGE_EXECUTABLE, - "--update", - "--backup=none", - "--lang=%s" % lang, - os.path.join(CURRENT_DIR, "%s.po" % lang), - os.path.join(CURRENT_DIR, "%s.pot" % DOMAIN), - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - -def main(): - if len(sys.argv) > 1: - for lang in sys.argv[1:]: - po = os.path.join(CURRENT_DIR, lang + '.po') - - if os.path.exists(po): - process_po(po) - else: - for po in os.listdir(CURRENT_DIR): - if po.endswith(".po"): - process_po(po) - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() diff --git a/po/update_pot.py b/po/update_pot.py deleted file mode 100755 index c5f9acb9f42..00000000000 --- a/po/update_pot.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python - -# ***** 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 ***** - -# - -# update the pot file according the POTFILES.in - -import subprocess -import os -from codecs import open - -GETTEXT_XGETTEXT_EXECUTABLE = "xgettext" -CURRENT_DIR = os.path.abspath(os.path.dirname(__file__)) -SOURCE_DIR = os.path.normpath(os.path.abspath(os.path.join(CURRENT_DIR, ".."))) -DOMAIN = "blender" -COMMENT_PREFIX = "#~ " # from update_msg.py - -FILE_NAME_POT = os.path.join(CURRENT_DIR, "blender.pot") -FILE_NAME_MESSAGES = os.path.join(CURRENT_DIR, "messages.txt") - - -def main(): - cmd = (GETTEXT_XGETTEXT_EXECUTABLE, - "--files-from=%s" % os.path.join(SOURCE_DIR, "po", "POTFILES.in"), - "--keyword=_", - "--keyword=N_", - "--directory=%s" % SOURCE_DIR, - "--output=%s" % os.path.join(SOURCE_DIR, "po", "%s.pot" % DOMAIN), - "--from-code=utf-8", - ) - - print(" ".join(cmd)) - process = subprocess.Popen(cmd) - process.wait() - - def stripeol(s): - return s.rstrip("\n\r") - - pot_messages = {} - reading_message = False - message = "" - with open(FILE_NAME_POT, 'r', "utf-8") as handle: - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - if line.startswith("msgid"): - reading_message = True - message = line[7:-1] - elif line.startswith("msgstr"): - reading_message = False - pot_messages[message] = True - elif reading_message: - message += line[1:-1] - - # add messages collected automatically from RNA - with open(FILE_NAME_POT, "a", "utf-8") as pot_handle: - with open(FILE_NAME_MESSAGES, 'r', "utf-8") as handle: - msgsrc_ls = [] - while True: - line = handle.readline() - - if not line: - break - - line = stripeol(line) - - # COMMENT_PREFIX - if line.startswith(COMMENT_PREFIX): - msgsrc_ls.append(line[len(COMMENT_PREFIX):].strip()) - else: - line = line.replace("\\", "\\\\") - line = line.replace("\"", "\\\"") - line = line.replace("\t", "\\t") - - if not pot_messages.get(line): - for msgsrc in msgsrc_ls: - pot_handle.write("#: %s\n" % msgsrc) - pot_handle.write("msgid \"%s\"\n" % line) - pot_handle.write("msgstr \"\"\n\n") - msgsrc_ls[:] = [] - - -if __name__ == "__main__": - print("\n\n *** Running %r *** \n" % __file__) - main() From 98841291173614410fca3b9db1cd0ee320d9eb84 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 5 Nov 2011 13:00:39 +0000 Subject: [PATCH 102/147] Code refactoring: split camera functions from object.c into new camera.c. --- source/blender/blenkernel/BKE_camera.h | 71 ++++ source/blender/blenkernel/BKE_object.h | 19 - source/blender/blenkernel/CMakeLists.txt | 2 + source/blender/blenkernel/intern/camera.c | 394 ++++++++++++++++++ source/blender/blenkernel/intern/library.c | 1 + source/blender/blenkernel/intern/object.c | 352 +--------------- source/blender/collada/DocumentImporter.cpp | 1 + source/blender/editors/object/object_add.c | 1 + .../blender/editors/object/object_relations.c | 1 + .../editors/sculpt_paint/paint_image.c | 1 + .../blender/editors/space_view3d/drawobject.c | 1 + .../editors/space_view3d/view3d_draw.c | 1 + .../blender/makesrna/intern/rna_camera_api.c | 2 + source/blender/makesrna/intern/rna_main_api.c | 1 + .../nodes/composite/node_composite_util.h | 1 + .../blender/render/intern/source/initrender.c | 1 + .../blender/render/intern/source/pipeline.c | 1 + 17 files changed, 481 insertions(+), 370 deletions(-) create mode 100644 source/blender/blenkernel/BKE_camera.h create mode 100644 source/blender/blenkernel/intern/camera.c diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h new file mode 100644 index 00000000000..d21c1092922 --- /dev/null +++ b/source/blender/blenkernel/BKE_camera.h @@ -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. + * + * 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_CAMERA_H +#define BKE_CAMERA_H + +/** \file BKE_camera.h + * \ingroup bke + * \brief Camera datablock and utility functions. + */ +#ifdef __cplusplus +extern "C" { +#endif + +struct Camera; +struct Object; +struct RenderData; +struct Scene; +struct rctf; + +void *add_camera(const char *name); +struct Camera *copy_camera(struct Camera *cam); +void make_local_camera(struct Camera *cam); +void free_camera(struct Camera *ca); + +float dof_camera(struct Object *ob); + +void object_camera_mode(struct RenderData *rd, struct Object *camera); +void object_camera_intrinsics(struct Object *camera, struct Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, + float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit); +void object_camera_matrix( + struct RenderData *rd, struct Object *camera, int winx, int winy, short field_second, + float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, + float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, + float *viewdx, float *viewdy); + +void camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float drawsize, const short do_clip, const float scale[3], + float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]); + +void camera_view_frame(struct Scene *scene, struct Camera *camera, float r_vec[4][3]); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index c5a24c1e5e9..f9cd7045e13 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -74,16 +74,11 @@ void object_copy_proxy_drivers(struct Object *ob, struct Object *target); void unlink_object(struct Object *ob); int exist_object(struct Object *obtest); -void *add_camera(const char *name); -struct Camera *copy_camera(struct Camera *cam); -void make_local_camera(struct Camera *cam); -float dof_camera(struct Object *ob); void *add_lamp(const char *name); struct Lamp *copy_lamp(struct Lamp *la); struct Lamp *localize_lamp(struct Lamp *la); void make_local_lamp(struct Lamp *la); -void free_camera(struct Camera *ca); void free_lamp(struct Lamp *la); struct Object *add_only_object(int type, const char *name); @@ -138,20 +133,6 @@ struct KeyBlock *object_insert_shape_key(struct Scene *scene, struct Object *ob, int object_is_modified(struct Scene *scene, struct Object *ob); -void object_camera_mode(struct RenderData *rd, struct Object *camera); -void object_camera_intrinsics(struct Object *camera, struct Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, - float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit); -void object_camera_matrix( - struct RenderData *rd, struct Object *camera, int winx, int winy, short field_second, - float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, - float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, - float *viewdx, float *viewdy); - -void camera_view_frame_ex(struct Scene *scene, struct Camera *camera, float drawsize, const short do_clip, const float scale[3], - float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]); - -void camera_view_frame(struct Scene *scene, struct Camera *camera, float r_vec[4][3]); - void object_relink(struct Object *ob); #ifdef __cplusplus diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 1b98dd914aa..ba6776e1864 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -76,6 +76,7 @@ set(SRC intern/brush.c intern/bullet.c intern/bvhutils.c + intern/camera.c intern/cdderivedmesh.c intern/cloth.c intern/collision.c @@ -160,6 +161,7 @@ set(SRC BKE_brush.h BKE_bullet.h BKE_bvhutils.h + BKE_camera.h BKE_cdderivedmesh.h BKE_cloth.h BKE_collision.h diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c new file mode 100644 index 00000000000..74cc5a76a75 --- /dev/null +++ b/source/blender/blenkernel/intern/camera.c @@ -0,0 +1,394 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/camera.c + * \ingroup bke + */ + +#include "DNA_camera_types.h" +#include "DNA_lamp_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_animsys.h" +#include "BKE_camera.h" +#include "BKE_global.h" +#include "BKE_library.h" +#include "BKE_main.h" + +void *add_camera(const char *name) +{ + Camera *cam; + + cam= alloc_libblock(&G.main->camera, ID_CA, name); + + cam->lens= 35.0f; + cam->sensor_x= 32.0f; + cam->sensor_y= 18.0f; + cam->clipsta= 0.1f; + cam->clipend= 100.0f; + cam->drawsize= 0.5f; + cam->ortho_scale= 6.0; + cam->flag |= CAM_SHOWPASSEPARTOUT; + cam->passepartalpha = 0.5f; + + return cam; +} + +Camera *copy_camera(Camera *cam) +{ + Camera *camn; + + camn= copy_libblock(cam); + + return camn; +} + +void make_local_camera(Camera *cam) +{ + Main *bmain= G.main; + Object *ob; + int is_local= FALSE, is_lib= FALSE; + + /* - only lib users: do nothing + * - only local users: set flag + * - mixed: make copy + */ + + if(cam->id.lib==NULL) return; + if(cam->id.us==1) { + id_clear_lib_data(bmain, &cam->id); + return; + } + + for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { + if(ob->data==cam) { + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; + } + } + + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &cam->id); + } + else if(is_local && is_lib) { + Camera *camn= copy_camera(cam); + + camn->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + BKE_id_lib_local_paths(bmain, &camn->id); + + for(ob= bmain->object.first; ob; ob= ob->id.next) { + if(ob->data == cam) { + if(ob->id.lib==NULL) { + ob->data= camn; + camn->id.us++; + cam->id.us--; + } + } + } + } +} + +/* get the camera's dof value, takes the dof object into account */ +float dof_camera(Object *ob) +{ + Camera *cam = (Camera *)ob->data; + if (ob->type != OB_CAMERA) + return 0.0f; + if (cam->dof_ob) { + /* too simple, better to return the distance on the view axis only + * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ + float mat[4][4], imat[4][4], obmat[4][4]; + + copy_m4_m4(obmat, ob->obmat); + normalize_m4(obmat); + invert_m4_m4(imat, obmat); + mul_m4_m4m4(mat, cam->dof_ob->obmat, imat); + return (float)fabs(mat[3][2]); + } + return cam->YF_dofdist; +} + +void free_camera(Camera *ca) +{ + BKE_free_animdata((ID *)ca); +} + +void object_camera_mode(RenderData *rd, Object *camera) +{ + rd->mode &= ~(R_ORTHO|R_PANORAMA); + if(camera && camera->type==OB_CAMERA) { + Camera *cam= camera->data; + if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO; + if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA; + } +} + +void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, + float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit) +{ + Camera *cam= NULL; + + (*shiftx)= 0.0f; + (*shifty)= 0.0f; + + (*sensor_x)= DEFAULT_SENSOR_WIDTH; + (*sensor_y)= DEFAULT_SENSOR_HEIGHT; + (*sensor_fit)= CAMERA_SENSOR_FIT_AUTO; + + if(camera->type==OB_CAMERA) { + cam= camera->data; + + if(cam->type == CAM_ORTHO) { + *is_ortho= TRUE; + } + + /* solve this too... all time depending stuff is in convertblender.c? + * Need to update the camera early because it's used for projection matrices + * and other stuff BEFORE the animation update loop is done + * */ +#if 0 // XXX old animation system + if(cam->ipo) { + calc_ipo(cam->ipo, frame_to_float(re->scene, re->r.cfra)); + execute_ipo(&cam->id, cam->ipo); + } +#endif // XXX old animation system + (*shiftx)=cam->shiftx; + (*shifty)=cam->shifty; + (*lens)= cam->lens; + (*sensor_x)= cam->sensor_x; + (*sensor_y)= cam->sensor_y; + (*clipsta)= cam->clipsta; + (*clipend)= cam->clipend; + (*sensor_fit)= cam->sensor_fit; + } + else if(camera->type==OB_LAMP) { + Lamp *la= camera->data; + float fac= cosf((float)M_PI*la->spotsize/360.0f); + float phi= acos(fac); + + (*lens)= 16.0f*fac/sinf(phi); + if((*lens)==0.0f) + (*lens)= 35.0f; + (*clipsta)= la->clipsta; + (*clipend)= la->clipend; + } + else { /* envmap exception... */; + if((*lens)==0.0f) /* is this needed anymore? */ + (*lens)= 16.0f; + + if((*clipsta)==0.0f || (*clipend)==0.0f) { + (*clipsta)= 0.1f; + (*clipend)= 1000.0f; + } + } + + (*cam_r)= cam; +} + +/* 'lens' may be set for envmap only */ +void object_camera_matrix( + RenderData *rd, Object *camera, int winx, int winy, short field_second, + float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, + float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, + float *viewdx, float *viewdy) +{ + Camera *cam=NULL; + float pixsize; + float shiftx=0.0, shifty=0.0, winside, viewfac; + short is_ortho= FALSE; + + /* question mark */ + (*ycor)= rd->yasp / rd->xasp; + if(rd->mode & R_FIELDS) + (*ycor) *= 2.0f; + + object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, sensor_fit); + + /* ortho only with camera available */ + if(cam && is_ortho) { + if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { + if(rd->xasp*winx >= rd->yasp*winy) viewfac= winx; + else viewfac= (*ycor) * winy; + } + else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { + viewfac= winx; + } + else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ + viewfac= (*ycor) * winy; + } + + /* ortho_scale == 1.0 means exact 1 to 1 mapping */ + pixsize= cam->ortho_scale/viewfac; + } + else { + if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { + if(rd->xasp*winx >= rd->yasp*winy) viewfac= ((*lens) * winx) / (*sensor_x); + else viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x); + } + else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { + viewfac= ((*lens) * winx) / (*sensor_x); + } + else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ + viewfac= ((*lens) * winy) / (*sensor_y); + } + + pixsize= (*clipsta) / viewfac; + } + + /* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */ + winside= MAX2(winx, winy); + + if(cam) { + if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) + winside= winx; + else if(cam->sensor_fit==CAMERA_SENSOR_FIT_VERT) + winside= winy; + } + + viewplane->xmin= -0.5f*(float)winx + shiftx*winside; + viewplane->ymin= -0.5f*(*ycor)*(float)winy + shifty*winside; + viewplane->xmax= 0.5f*(float)winx + shiftx*winside; + viewplane->ymax= 0.5f*(*ycor)*(float)winy + shifty*winside; + + if(field_second) { + if(rd->mode & R_ODDFIELD) { + viewplane->ymin-= 0.5f * (*ycor); + viewplane->ymax-= 0.5f * (*ycor); + } + else { + viewplane->ymin+= 0.5f * (*ycor); + viewplane->ymax+= 0.5f * (*ycor); + } + } + /* the window matrix is used for clipping, and not changed during OSA steps */ + /* using an offset of +0.5 here would give clip errors on edges */ + viewplane->xmin *= pixsize; + viewplane->xmax *= pixsize; + viewplane->ymin *= pixsize; + viewplane->ymax *= pixsize; + + (*viewdx)= pixsize; + (*viewdy)= (*ycor) * pixsize; + + if(is_ortho) + orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); + else + perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); + +} + +void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3], + float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]) +{ + float facx, facy; + float depth; + + /* aspect correcton */ + if (scene) { + float aspx= (float) scene->r.xsch*scene->r.xasp; + float aspy= (float) scene->r.ysch*scene->r.yasp; + + if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + if(aspx < aspy) { + r_asp[0]= aspx / aspy; + r_asp[1]= 1.0; + } + else { + r_asp[0]= 1.0; + r_asp[1]= aspy / aspx; + } + } + else if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { + r_asp[0]= aspx / aspy; + r_asp[1]= 1.0; + } + else { + r_asp[0]= 1.0; + r_asp[1]= aspy / aspx; + } + } + else { + r_asp[0]= 1.0f; + r_asp[1]= 1.0f; + } + + if(camera->type==CAM_ORTHO) { + facx= 0.5f * camera->ortho_scale * r_asp[0] * scale[0]; + facy= 0.5f * camera->ortho_scale * r_asp[1] * scale[1]; + r_shift[0]= camera->shiftx * camera->ortho_scale * scale[0]; + r_shift[1]= camera->shifty * camera->ortho_scale * scale[1]; + depth= do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : - drawsize * camera->ortho_scale * scale[2]; + + *r_drawsize= 0.5f * camera->ortho_scale; + } + else { + /* that way it's always visible - clipsta+0.1 */ + float fac; + float half_sensor= 0.5f*((camera->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x)); + + *r_drawsize= drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); + + if(do_clip) { + /* fixed depth, variable size (avoids exceeding clipping range) */ + depth = -(camera->clipsta + 0.1f); + fac = depth / (camera->lens/(-half_sensor) * scale[2]); + } + else { + /* fixed size, variable depth (stays a reasonable size in the 3D view) */ + depth= *r_drawsize * camera->lens/(-half_sensor) * scale[2]; + fac= *r_drawsize; + } + + facx= fac * r_asp[0] * scale[0]; + facy= fac * r_asp[1] * scale[1]; + r_shift[0]= camera->shiftx*fac*2 * scale[0]; + r_shift[1]= camera->shifty*fac*2 * scale[1]; + } + + r_vec[0][0]= r_shift[0] + facx; r_vec[0][1]= r_shift[1] + facy; r_vec[0][2]= depth; + r_vec[1][0]= r_shift[0] + facx; r_vec[1][1]= r_shift[1] - facy; r_vec[1][2]= depth; + r_vec[2][0]= r_shift[0] - facx; r_vec[2][1]= r_shift[1] - facy; r_vec[2][2]= depth; + r_vec[3][0]= r_shift[0] - facx; r_vec[3][1]= r_shift[1] + facy; r_vec[3][2]= depth; +} + +void camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3]) +{ + float dummy_asp[2]; + float dummy_shift[2]; + float dummy_drawsize; + const float dummy_scale[3]= {1.0f, 1.0f, 1.0f}; + + camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale, + dummy_asp, dummy_shift, &dummy_drawsize, r_vec); +} + diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 35b50730a31..36e2428ce24 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -77,6 +77,7 @@ #include "BLI_bpath.h" #include "BKE_animsys.h" +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_library.h" #include "BKE_main.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b09d1ea98aa..1ba06c02976 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -98,6 +98,7 @@ #include "BKE_speaker.h" #include "BKE_softbody.h" #include "BKE_material.h" +#include "BKE_camera.h" #include "LBM_fluidsim.h" @@ -715,103 +716,6 @@ int exist_object(Object *obtest) return 0; } -void *add_camera(const char *name) -{ - Camera *cam; - - cam= alloc_libblock(&G.main->camera, ID_CA, name); - - cam->lens= 35.0f; - cam->sensor_x= 32.0f; - cam->sensor_y= 18.0f; - cam->clipsta= 0.1f; - cam->clipend= 100.0f; - cam->drawsize= 0.5f; - cam->ortho_scale= 6.0; - cam->flag |= CAM_SHOWPASSEPARTOUT; - cam->passepartalpha = 0.5f; - - return cam; -} - -Camera *copy_camera(Camera *cam) -{ - Camera *camn; - - camn= copy_libblock(cam); - - return camn; -} - - - -void make_local_camera(Camera *cam) -{ - Main *bmain= G.main; - Object *ob; - int is_local= FALSE, is_lib= FALSE; - - /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ - - if(cam->id.lib==NULL) return; - if(cam->id.us==1) { - id_clear_lib_data(bmain, &cam->id); - return; - } - - for(ob= bmain->object.first; ob && ELEM(0, is_lib, is_local); ob= ob->id.next) { - if(ob->data==cam) { - if(ob->id.lib) is_lib= TRUE; - else is_local= TRUE; - } - } - - if(is_local && is_lib == FALSE) { - id_clear_lib_data(bmain, &cam->id); - } - else if(is_local && is_lib) { - Camera *camn= copy_camera(cam); - - camn->id.us= 0; - - /* Remap paths of new ID using old library as base. */ - BKE_id_lib_local_paths(bmain, &camn->id); - - for(ob= bmain->object.first; ob; ob= ob->id.next) { - if(ob->data == cam) { - if(ob->id.lib==NULL) { - ob->data= camn; - camn->id.us++; - cam->id.us--; - } - } - } - } -} - -/* get the camera's dof value, takes the dof object into account */ -float dof_camera(Object *ob) -{ - Camera *cam = (Camera *)ob->data; - if (ob->type != OB_CAMERA) - return 0.0f; - if (cam->dof_ob) { - /* too simple, better to return the distance on the view axis only - * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ - float mat[4][4], imat[4][4], obmat[4][4]; - - copy_m4_m4(obmat, ob->obmat); - normalize_m4(obmat); - invert_m4_m4(imat, obmat); - mul_m4_m4m4(mat, cam->dof_ob->obmat, imat); - return (float)fabs(mat[3][2]); - } - return cam->YF_dofdist; -} - void *add_lamp(const char *name) { Lamp *la; @@ -966,11 +870,6 @@ void make_local_lamp(Lamp *la) } } -void free_camera(Camera *ca) -{ - BKE_free_animdata((ID *)ca); -} - void free_lamp(Lamp *la) { MTex *mtex; @@ -2942,255 +2841,6 @@ int object_insert_ptcache(Object *ob) return i; } -void object_camera_mode(RenderData *rd, Object *camera) -{ - rd->mode &= ~(R_ORTHO|R_PANORAMA); - if(camera && camera->type==OB_CAMERA) { - Camera *cam= camera->data; - if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO; - if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA; - } -} - -void object_camera_intrinsics(Object *camera, Camera **cam_r, short *is_ortho, float *shiftx, float *shifty, - float *clipsta, float *clipend, float *lens, float *sensor_x, float *sensor_y, short *sensor_fit) -{ - Camera *cam= NULL; - - (*shiftx)= 0.0f; - (*shifty)= 0.0f; - - (*sensor_x)= DEFAULT_SENSOR_WIDTH; - (*sensor_y)= DEFAULT_SENSOR_HEIGHT; - (*sensor_fit)= CAMERA_SENSOR_FIT_AUTO; - - if(camera->type==OB_CAMERA) { - cam= camera->data; - - if(cam->type == CAM_ORTHO) { - *is_ortho= TRUE; - } - - /* solve this too... all time depending stuff is in convertblender.c? - * Need to update the camera early because it's used for projection matrices - * and other stuff BEFORE the animation update loop is done - * */ -#if 0 // XXX old animation system - if(cam->ipo) { - calc_ipo(cam->ipo, frame_to_float(re->scene, re->r.cfra)); - execute_ipo(&cam->id, cam->ipo); - } -#endif // XXX old animation system - (*shiftx)=cam->shiftx; - (*shifty)=cam->shifty; - (*lens)= cam->lens; - (*sensor_x)= cam->sensor_x; - (*sensor_y)= cam->sensor_y; - (*clipsta)= cam->clipsta; - (*clipend)= cam->clipend; - (*sensor_fit)= cam->sensor_fit; - } - else if(camera->type==OB_LAMP) { - Lamp *la= camera->data; - float fac= cosf((float)M_PI*la->spotsize/360.0f); - float phi= acos(fac); - - (*lens)= 16.0f*fac/sinf(phi); - if((*lens)==0.0f) - (*lens)= 35.0f; - (*clipsta)= la->clipsta; - (*clipend)= la->clipend; - } - else { /* envmap exception... */; - if((*lens)==0.0f) /* is this needed anymore? */ - (*lens)= 16.0f; - - if((*clipsta)==0.0f || (*clipend)==0.0f) { - (*clipsta)= 0.1f; - (*clipend)= 1000.0f; - } - } - - (*cam_r)= cam; -} - -/* 'lens' may be set for envmap only */ -void object_camera_matrix( - RenderData *rd, Object *camera, int winx, int winy, short field_second, - float winmat[][4], rctf *viewplane, float *clipsta, float *clipend, float *lens, - float *sensor_x, float *sensor_y, short *sensor_fit, float *ycor, - float *viewdx, float *viewdy) -{ - Camera *cam=NULL; - float pixsize; - float shiftx=0.0, shifty=0.0, winside, viewfac; - short is_ortho= FALSE; - - /* question mark */ - (*ycor)= rd->yasp / rd->xasp; - if(rd->mode & R_FIELDS) - (*ycor) *= 2.0f; - - object_camera_intrinsics(camera, &cam, &is_ortho, &shiftx, &shifty, clipsta, clipend, lens, sensor_x, sensor_y, sensor_fit); - - /* ortho only with camera available */ - if(cam && is_ortho) { - if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { - if(rd->xasp*winx >= rd->yasp*winy) viewfac= winx; - else viewfac= (*ycor) * winy; - } - else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { - viewfac= winx; - } - else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ - viewfac= (*ycor) * winy; - } - - /* ortho_scale == 1.0 means exact 1 to 1 mapping */ - pixsize= cam->ortho_scale/viewfac; - } - else { - if((*sensor_fit)==CAMERA_SENSOR_FIT_AUTO) { - if(rd->xasp*winx >= rd->yasp*winy) viewfac= ((*lens) * winx) / (*sensor_x); - else viewfac= (*ycor) * ((*lens) * winy) / (*sensor_x); - } - else if((*sensor_fit)==CAMERA_SENSOR_FIT_HOR) { - viewfac= ((*lens) * winx) / (*sensor_x); - } - else { /* if((*sensor_fit)==CAMERA_SENSOR_FIT_VERT) { */ - viewfac= ((*lens) * winy) / (*sensor_y); - } - - pixsize= (*clipsta) / viewfac; - } - - /* viewplane fully centered, zbuffer fills in jittered between -.5 and +.5 */ - winside= MAX2(winx, winy); - - if(cam) { - if(cam->sensor_fit==CAMERA_SENSOR_FIT_HOR) - winside= winx; - else if(cam->sensor_fit==CAMERA_SENSOR_FIT_VERT) - winside= winy; - } - - viewplane->xmin= -0.5f*(float)winx + shiftx*winside; - viewplane->ymin= -0.5f*(*ycor)*(float)winy + shifty*winside; - viewplane->xmax= 0.5f*(float)winx + shiftx*winside; - viewplane->ymax= 0.5f*(*ycor)*(float)winy + shifty*winside; - - if(field_second) { - if(rd->mode & R_ODDFIELD) { - viewplane->ymin-= 0.5f * (*ycor); - viewplane->ymax-= 0.5f * (*ycor); - } - else { - viewplane->ymin+= 0.5f * (*ycor); - viewplane->ymax+= 0.5f * (*ycor); - } - } - /* the window matrix is used for clipping, and not changed during OSA steps */ - /* using an offset of +0.5 here would give clip errors on edges */ - viewplane->xmin *= pixsize; - viewplane->xmax *= pixsize; - viewplane->ymin *= pixsize; - viewplane->ymax *= pixsize; - - (*viewdx)= pixsize; - (*viewdy)= (*ycor) * pixsize; - - if(is_ortho) - orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); - else - perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); - -} - -void camera_view_frame_ex(Scene *scene, Camera *camera, float drawsize, const short do_clip, const float scale[3], - float r_asp[2], float r_shift[2], float *r_drawsize, float r_vec[4][3]) -{ - float facx, facy; - float depth; - - /* aspect correcton */ - if (scene) { - float aspx= (float) scene->r.xsch*scene->r.xasp; - float aspy= (float) scene->r.ysch*scene->r.yasp; - - if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { - if(aspx < aspy) { - r_asp[0]= aspx / aspy; - r_asp[1]= 1.0; - } - else { - r_asp[0]= 1.0; - r_asp[1]= aspy / aspx; - } - } - else if(camera->sensor_fit==CAMERA_SENSOR_FIT_AUTO) { - r_asp[0]= aspx / aspy; - r_asp[1]= 1.0; - } - else { - r_asp[0]= 1.0; - r_asp[1]= aspy / aspx; - } - } - else { - r_asp[0]= 1.0f; - r_asp[1]= 1.0f; - } - - if(camera->type==CAM_ORTHO) { - facx= 0.5f * camera->ortho_scale * r_asp[0] * scale[0]; - facy= 0.5f * camera->ortho_scale * r_asp[1] * scale[1]; - r_shift[0]= camera->shiftx * camera->ortho_scale * scale[0]; - r_shift[1]= camera->shifty * camera->ortho_scale * scale[1]; - depth= do_clip ? -((camera->clipsta * scale[2]) + 0.1f) : - drawsize * camera->ortho_scale * scale[2]; - - *r_drawsize= 0.5f * camera->ortho_scale; - } - else { - /* that way it's always visible - clipsta+0.1 */ - float fac; - float half_sensor= 0.5f*((camera->sensor_fit==CAMERA_SENSOR_FIT_VERT) ? (camera->sensor_y) : (camera->sensor_x)); - - *r_drawsize= drawsize / ((scale[0] + scale[1] + scale[2]) / 3.0f); - - if(do_clip) { - /* fixed depth, variable size (avoids exceeding clipping range) */ - depth = -(camera->clipsta + 0.1f); - fac = depth / (camera->lens/(-half_sensor) * scale[2]); - } - else { - /* fixed size, variable depth (stays a reasonable size in the 3D view) */ - depth= *r_drawsize * camera->lens/(-half_sensor) * scale[2]; - fac= *r_drawsize; - } - - facx= fac * r_asp[0] * scale[0]; - facy= fac * r_asp[1] * scale[1]; - r_shift[0]= camera->shiftx*fac*2 * scale[0]; - r_shift[1]= camera->shifty*fac*2 * scale[1]; - } - - r_vec[0][0]= r_shift[0] + facx; r_vec[0][1]= r_shift[1] + facy; r_vec[0][2]= depth; - r_vec[1][0]= r_shift[0] + facx; r_vec[1][1]= r_shift[1] - facy; r_vec[1][2]= depth; - r_vec[2][0]= r_shift[0] - facx; r_vec[2][1]= r_shift[1] - facy; r_vec[2][2]= depth; - r_vec[3][0]= r_shift[0] - facx; r_vec[3][1]= r_shift[1] + facy; r_vec[3][2]= depth; -} - -void camera_view_frame(Scene *scene, Camera *camera, float r_vec[4][3]) -{ - float dummy_asp[2]; - float dummy_shift[2]; - float dummy_drawsize; - const float dummy_scale[3]= {1.0f, 1.0f, 1.0f}; - - camera_view_frame_ex(scene, camera, FALSE, 1.0, dummy_scale, - dummy_asp, dummy_shift, &dummy_drawsize, r_vec); -} - #if 0 static int pc_findindex(ListBase *listbase, int index) { diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index 8cdb1065699..ec22dfae7ba 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -54,6 +54,7 @@ #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BKE_camera.h" #include "BKE_main.h" #include "BKE_library.h" #include "BKE_texture.h" diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 7ff233fa609..1cafa9c0693 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -54,6 +54,7 @@ #include "BKE_anim.h" #include "BKE_animsys.h" #include "BKE_armature.h" +#include "BKE_camera.h" #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_curve.h" diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 74da705965a..0a0eadd58d3 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -56,6 +56,7 @@ #include "BKE_action.h" #include "BKE_animsys.h" #include "BKE_armature.h" +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_constraint.h" #include "BKE_curve.h" diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 6b6003fb098..4507ad96b9d 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -65,6 +65,7 @@ #include "DNA_scene_types.h" #include "DNA_texture_types.h" +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index c455c107b48..987c3984b77 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -55,6 +55,7 @@ #include "BLI_utildefines.h" #include "BKE_anim.h" //for the where_on_path function +#include "BKE_camera.h" #include "BKE_constraint.h" // for the get_constraint_target function #include "BKE_curve.h" #include "BKE_DerivedMesh.h" diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index aa69e7121e0..309578699f7 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -51,6 +51,7 @@ #include "BLI_utildefines.h" #include "BKE_anim.h" +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_image.h" diff --git a/source/blender/makesrna/intern/rna_camera_api.c b/source/blender/makesrna/intern/rna_camera_api.c index bf3db58e35e..2af0524861a 100644 --- a/source/blender/makesrna/intern/rna_camera_api.c +++ b/source/blender/makesrna/intern/rna_camera_api.c @@ -36,6 +36,8 @@ #ifdef RNA_RUNTIME #include "DNA_scene_types.h" + +#include "BKE_camera.h" #include "BKE_context.h" #include "BKE_object.h" diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 1b80e33b40c..83ce4d2da06 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -43,6 +43,7 @@ #ifdef RNA_RUNTIME #include "BKE_main.h" +#include "BKE_camera.h" #include "BKE_curve.h" #include "BKE_mesh.h" #include "BKE_armature.h" diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 9ebca8688b4..6da9b901e76 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -57,6 +57,7 @@ #include "BLI_utildefines.h" #include "BKE_blender.h" +#include "BKE_camera.h" #include "BKE_colortools.h" #include "BKE_global.h" #include "BKE_image.h" diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index f8e4ee8f6a7..7bd8dad6502 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -53,6 +53,7 @@ #include "DNA_scene_types.h" +#include "BKE_camera.h" #include "BKE_global.h" #include "BKE_material.h" #include "BKE_object.h" diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index de5d037675e..d4bd8f8a693 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -48,6 +48,7 @@ #include "MEM_guardedalloc.h" #include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */ +#include "BKE_camera.h" #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" From 647447db58ed7d3abd0ddeb627110069042e28fe Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 5 Nov 2011 13:11:49 +0000 Subject: [PATCH 103/147] Code refactoring: split lamp functions from object.c into new lamp.c. --- source/blender/blenkernel/BKE_lamp.h | 51 ++++ source/blender/blenkernel/BKE_object.h | 6 - source/blender/blenkernel/CMakeLists.txt | 2 + source/blender/blenkernel/intern/camera.c | 2 + source/blender/blenkernel/intern/lamp.c | 233 ++++++++++++++++++ source/blender/blenkernel/intern/library.c | 1 + source/blender/blenkernel/intern/object.c | 182 +------------- source/blender/collada/DocumentImporter.cpp | 1 + source/blender/editors/object/object_add.c | 1 + .../blender/editors/object/object_relations.c | 1 + .../blender/editors/render/render_preview.c | 1 + source/blender/makesrna/intern/rna_main_api.c | 1 + 12 files changed, 295 insertions(+), 187 deletions(-) create mode 100644 source/blender/blenkernel/BKE_lamp.h create mode 100644 source/blender/blenkernel/intern/lamp.c diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h new file mode 100644 index 00000000000..cc9452ae155 --- /dev/null +++ b/source/blender/blenkernel/BKE_lamp.h @@ -0,0 +1,51 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_LAMP_H +#define BKE_LAMP_H + +/** \file BKE_lamp.h + * \ingroup bke + * \brief General operations, lookup, etc. for blender lamps. + */ +#ifdef __cplusplus +extern "C" { +#endif + +struct Lamp; + +void *add_lamp(const char *name); +struct Lamp *copy_lamp(struct Lamp *la); +struct Lamp *localize_lamp(struct Lamp *la); +void make_local_lamp(struct Lamp *la); +void free_lamp(struct Lamp *la); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index f9cd7045e13..d6139a680ec 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -75,12 +75,6 @@ void object_copy_proxy_drivers(struct Object *ob, struct Object *target); void unlink_object(struct Object *ob); int exist_object(struct Object *obtest); -void *add_lamp(const char *name); -struct Lamp *copy_lamp(struct Lamp *la); -struct Lamp *localize_lamp(struct Lamp *la); -void make_local_lamp(struct Lamp *la); -void free_lamp(struct Lamp *la); - struct Object *add_only_object(int type, const char *name); struct Object *add_object(struct Scene *scene, int type); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index ba6776e1864..78b1b52e52c 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -104,6 +104,7 @@ set(SRC intern/implicit.c intern/ipo.c intern/key.c + intern/lamp.c intern/lattice.c intern/library.c intern/material.c @@ -187,6 +188,7 @@ set(SRC BKE_image.h BKE_ipo.h BKE_key.h + BKE_lamp.h BKE_lattice.h BKE_library.h BKE_main.h diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 74cc5a76a75..eeec82c3beb 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -29,6 +29,8 @@ * \ingroup bke */ +#include + #include "DNA_camera_types.h" #include "DNA_lamp_types.h" #include "DNA_object_types.h" diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c new file mode 100644 index 00000000000..974aa660e9f --- /dev/null +++ b/source/blender/blenkernel/intern/lamp.c @@ -0,0 +1,233 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/lamp.c + * \ingroup bke + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_lamp_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_texture_types.h" + +#include "BLI_listbase.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_animsys.h" +#include "BKE_colortools.h" +#include "BKE_icons.h" +#include "BKE_global.h" +#include "BKE_lamp.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" + +void *add_lamp(const char *name) +{ + Lamp *la; + + la= alloc_libblock(&G.main->lamp, ID_LA, name); + + la->r= la->g= la->b= la->k= 1.0f; + la->haint= la->energy= 1.0f; + la->dist= 25.0f; + la->spotsize= 45.0f; + la->spotblend= 0.15f; + la->att2= 1.0f; + la->mode= LA_SHAD_BUF; + la->bufsize= 512; + la->clipsta= 0.5f; + la->clipend= 40.0f; + la->shadspotsize= 45.0f; + la->samp= 3; + la->bias= 1.0f; + la->soft= 3.0f; + la->compressthresh= 0.05f; + la->ray_samp= la->ray_sampy= la->ray_sampz= 1; + la->area_size=la->area_sizey=la->area_sizez= 1.0f; + la->buffers= 1; + la->buftype= LA_SHADBUF_HALFWAY; + la->ray_samp_method = LA_SAMP_HALTON; + la->adapt_thresh = 0.001f; + la->preview=NULL; + la->falloff_type = LA_FALLOFF_INVSQUARE; + la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); + la->sun_effect_type = 0; + la->horizon_brightness = 1.0; + la->spread = 1.0; + la->sun_brightness = 1.0; + la->sun_size = 1.0; + la->backscattered_light = 1.0f; + la->atm_turbidity = 2.0f; + la->atm_inscattering_factor = 1.0f; + la->atm_extinction_factor = 1.0f; + la->atm_distance_factor = 1.0f; + la->sun_intensity = 1.0f; + la->skyblendtype= MA_RAMP_ADD; + la->skyblendfac= 1.0f; + la->sky_colorspace= BLI_XYZ_CIE; + la->sky_exposure= 1.0f; + + curvemapping_initialize(la->curfalloff); + return la; +} + +Lamp *copy_lamp(Lamp *la) +{ + Lamp *lan; + int a; + + lan= copy_libblock(la); + + for(a=0; amtex[a]) { + lan->mtex[a]= MEM_mallocN(sizeof(MTex), "copylamptex"); + memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); + id_us_plus((ID *)lan->mtex[a]->tex); + } + } + + lan->curfalloff = curvemapping_copy(la->curfalloff); + + if(la->nodetree) + lan->nodetree= ntreeCopyTree(la->nodetree); + + if(la->preview) + lan->preview = BKE_previewimg_copy(la->preview); + + return lan; +} + +Lamp *localize_lamp(Lamp *la) +{ + Lamp *lan; + int a; + + lan= copy_libblock(la); + BLI_remlink(&G.main->lamp, lan); + + for(a=0; amtex[a]) { + lan->mtex[a]= MEM_mallocN(sizeof(MTex), "localize_lamp"); + memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); + /* free lamp decrements */ + id_us_plus((ID *)lan->mtex[a]->tex); + } + } + + lan->curfalloff = curvemapping_copy(la->curfalloff); + + if(la->nodetree) + lan->nodetree= ntreeLocalize(la->nodetree); + + lan->preview= NULL; + + return lan; +} + +void make_local_lamp(Lamp *la) +{ + Main *bmain= G.main; + Object *ob; + int is_local= FALSE, is_lib= FALSE; + + /* - only lib users: do nothing + * - only local users: set flag + * - mixed: make copy + */ + + if(la->id.lib==NULL) return; + if(la->id.us==1) { + id_clear_lib_data(bmain, &la->id); + return; + } + + ob= bmain->object.first; + while(ob) { + if(ob->data==la) { + if(ob->id.lib) is_lib= TRUE; + else is_local= TRUE; + } + ob= ob->id.next; + } + + if(is_local && is_lib == FALSE) { + id_clear_lib_data(bmain, &la->id); + } + else if(is_local && is_lib) { + Lamp *lan= copy_lamp(la); + lan->id.us= 0; + + /* Remap paths of new ID using old library as base. */ + BKE_id_lib_local_paths(bmain, &lan->id); + + ob= bmain->object.first; + while(ob) { + if(ob->data==la) { + + if(ob->id.lib==NULL) { + ob->data= lan; + lan->id.us++; + la->id.us--; + } + } + ob= ob->id.next; + } + } +} + +void free_lamp(Lamp *la) +{ + MTex *mtex; + int a; + + for(a=0; amtex[a]; + if(mtex && mtex->tex) mtex->tex->id.us--; + if(mtex) MEM_freeN(mtex); + } + + BKE_free_animdata((ID *)la); + + curvemapping_free(la->curfalloff); + + /* is no lib link block, but lamp extension */ + if(la->nodetree) { + ntreeFreeTree(la->nodetree); + MEM_freeN(la->nodetree); + } + + BKE_previewimg_free(&la->preview); + BKE_icon_delete(&la->id); + la->id.icon_id = 0; +} + diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 36e2428ce24..0b01c3d6dd1 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -79,6 +79,7 @@ #include "BKE_animsys.h" #include "BKE_camera.h" #include "BKE_context.h" +#include "BKE_lamp.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_global.h" diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1ba06c02976..a78b010392e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -42,7 +42,6 @@ #include "DNA_constraint_types.h" #include "DNA_group_types.h" #include "DNA_key_types.h" -#include "DNA_lamp_types.h" #include "DNA_lattice_types.h" #include "DNA_material_types.h" #include "DNA_meta_types.h" @@ -81,6 +80,7 @@ #include "BKE_group.h" #include "BKE_icons.h" #include "BKE_key.h" +#include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_mesh.h" @@ -716,186 +716,6 @@ int exist_object(Object *obtest) return 0; } -void *add_lamp(const char *name) -{ - Lamp *la; - - la= alloc_libblock(&G.main->lamp, ID_LA, name); - - la->r= la->g= la->b= la->k= 1.0f; - la->haint= la->energy= 1.0f; - la->dist= 25.0f; - la->spotsize= 45.0f; - la->spotblend= 0.15f; - la->att2= 1.0f; - la->mode= LA_SHAD_BUF; - la->bufsize= 512; - la->clipsta= 0.5f; - la->clipend= 40.0f; - la->shadspotsize= 45.0f; - la->samp= 3; - la->bias= 1.0f; - la->soft= 3.0f; - la->compressthresh= 0.05f; - la->ray_samp= la->ray_sampy= la->ray_sampz= 1; - la->area_size=la->area_sizey=la->area_sizez= 1.0f; - la->buffers= 1; - la->buftype= LA_SHADBUF_HALFWAY; - la->ray_samp_method = LA_SAMP_HALTON; - la->adapt_thresh = 0.001f; - la->preview=NULL; - la->falloff_type = LA_FALLOFF_INVSQUARE; - la->curfalloff = curvemapping_add(1, 0.0f, 1.0f, 1.0f, 0.0f); - la->sun_effect_type = 0; - la->horizon_brightness = 1.0; - la->spread = 1.0; - la->sun_brightness = 1.0; - la->sun_size = 1.0; - la->backscattered_light = 1.0f; - la->atm_turbidity = 2.0f; - la->atm_inscattering_factor = 1.0f; - la->atm_extinction_factor = 1.0f; - la->atm_distance_factor = 1.0f; - la->sun_intensity = 1.0f; - la->skyblendtype= MA_RAMP_ADD; - la->skyblendfac= 1.0f; - la->sky_colorspace= BLI_XYZ_CIE; - la->sky_exposure= 1.0f; - - curvemapping_initialize(la->curfalloff); - return la; -} - -Lamp *copy_lamp(Lamp *la) -{ - Lamp *lan; - int a; - - lan= copy_libblock(la); - - for(a=0; amtex[a]) { - lan->mtex[a]= MEM_mallocN(sizeof(MTex), "copylamptex"); - memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); - id_us_plus((ID *)lan->mtex[a]->tex); - } - } - - lan->curfalloff = curvemapping_copy(la->curfalloff); - - if(la->nodetree) - lan->nodetree= ntreeCopyTree(la->nodetree); - - if(la->preview) - lan->preview = BKE_previewimg_copy(la->preview); - - return lan; -} - -Lamp *localize_lamp(Lamp *la) -{ - Lamp *lan; - int a; - - lan= copy_libblock(la); - BLI_remlink(&G.main->lamp, lan); - - for(a=0; amtex[a]) { - lan->mtex[a]= MEM_mallocN(sizeof(MTex), "localize_lamp"); - memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex)); - /* free lamp decrements */ - id_us_plus((ID *)lan->mtex[a]->tex); - } - } - - lan->curfalloff = curvemapping_copy(la->curfalloff); - - if(la->nodetree) - lan->nodetree= ntreeLocalize(la->nodetree); - - lan->preview= NULL; - - return lan; -} - -void make_local_lamp(Lamp *la) -{ - Main *bmain= G.main; - Object *ob; - int is_local= FALSE, is_lib= FALSE; - - /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ - - if(la->id.lib==NULL) return; - if(la->id.us==1) { - id_clear_lib_data(bmain, &la->id); - return; - } - - ob= bmain->object.first; - while(ob) { - if(ob->data==la) { - if(ob->id.lib) is_lib= TRUE; - else is_local= TRUE; - } - ob= ob->id.next; - } - - if(is_local && is_lib == FALSE) { - id_clear_lib_data(bmain, &la->id); - } - else if(is_local && is_lib) { - Lamp *lan= copy_lamp(la); - lan->id.us= 0; - - /* Remap paths of new ID using old library as base. */ - BKE_id_lib_local_paths(bmain, &lan->id); - - ob= bmain->object.first; - while(ob) { - if(ob->data==la) { - - if(ob->id.lib==NULL) { - ob->data= lan; - lan->id.us++; - la->id.us--; - } - } - ob= ob->id.next; - } - } -} - -void free_lamp(Lamp *la) -{ - MTex *mtex; - int a; - - for(a=0; amtex[a]; - if(mtex && mtex->tex) mtex->tex->id.us--; - if(mtex) MEM_freeN(mtex); - } - - BKE_free_animdata((ID *)la); - - curvemapping_free(la->curfalloff); - - /* is no lib link block, but lamp extension */ - if(la->nodetree) { - ntreeFreeTree(la->nodetree); - MEM_freeN(la->nodetree); - } - - BKE_previewimg_free(&la->preview); - BKE_icon_delete(&la->id); - la->id.icon_id = 0; -} - /* *************************************************** */ static void *add_obdata_from_type(int type) diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp index ec22dfae7ba..267aa925c74 100644 --- a/source/blender/collada/DocumentImporter.cpp +++ b/source/blender/collada/DocumentImporter.cpp @@ -56,6 +56,7 @@ #include "BKE_camera.h" #include "BKE_main.h" +#include "BKE_lamp.h" #include "BKE_library.h" #include "BKE_texture.h" #include "BKE_fcurve.h" diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 1cafa9c0693..a929144ed2e 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -63,6 +63,7 @@ #include "BKE_displist.h" #include "BKE_effect.h" #include "BKE_group.h" +#include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_key.h" diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 0a0eadd58d3..e9575c85c5f 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -64,6 +64,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_fcurve.h" +#include "BKE_lamp.h" #include "BKE_lattice.h" #include "BKE_library.h" #include "BKE_main.h" diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 9da160948cc..feff1e05d60 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -70,6 +70,7 @@ #include "BKE_idprop.h" #include "BKE_image.h" #include "BKE_icons.h" +#include "BKE_lamp.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 83ce4d2da06..dfa368d6b94 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -47,6 +47,7 @@ #include "BKE_curve.h" #include "BKE_mesh.h" #include "BKE_armature.h" +#include "BKE_lamp.h" #include "BKE_library.h" #include "BKE_object.h" #include "BKE_material.h" From 885d1e6ed37ff725d920cf7c7b05c4e0fede2102 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 13:21:03 +0000 Subject: [PATCH 104/147] update path loactions for external po/ --- GNUmakefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index f6a6ee91f31..30759f909fc 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -174,10 +174,10 @@ package_archive: # Other Targets # translations: - $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python po/update_msg.py - python3 po/update_pot.py - python3 po/update_po.py - python3 po/update_mo.py + $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python po/tools/update_msg.py + python3 po/tools/update_pot.py + python3 po/tools/update_po.py + python3 po/tools/update_mo.py # ----------------------------------------------------------------------------- From 2a7ade9de24860bbd13e4be8480e9285d1f3fe4c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 5 Nov 2011 14:26:18 +0000 Subject: [PATCH 105/147] remove po/ since the workflow for translations uses branches which isnt that useful to have within blenders source dir. For now treat translations as binary files - just access from 'release/datafiles/locale' --- GNUmakefile | 13 ------------- source/blender/blenkernel/intern/scene.c | 2 ++ source/blender/blenkernel/intern/sequencer.c | 2 ++ source/blender/blenloader/intern/readfile.c | 2 ++ source/blender/editors/animation/anim_markers.c | 4 ++++ source/blender/makesdna/DNA_scene_types.h | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 30759f909fc..640e90de74b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -135,9 +135,6 @@ help: @echo " * package_pacman - build an arch linux pacmanpackage" @echo " * package_archive - build an archive package" @echo "" - @echo "Other Targets (not assosiated with building blender)" - @echo " * translations - update blenders translation files in po/" - @echo "" @echo "Testing Targets (not assosiated with building blender)" @echo " * test - run ctest, currently tests import/export, operator execution and that python modules load" @echo " * test_cmake - runs our own cmake file checker which detects errors in the cmake file list definitions" @@ -170,16 +167,6 @@ package_archive: @echo archive in "$(BUILD_DIR)/release" -# ----------------------------------------------------------------------------- -# Other Targets -# -translations: - $(BUILD_DIR)/bin/blender --background -noaudio --factory-startup --python po/tools/update_msg.py - python3 po/tools/update_pot.py - python3 po/tools/update_po.py - python3 po/tools/update_mo.py - - # ----------------------------------------------------------------------------- # Tests # diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index a9de75dc7d0..f1e094c3909 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -806,6 +806,8 @@ int scene_camera_switch_update(Scene *scene) scene->camera= camera; return 1; } +#else + (void)scene; #endif return 0; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 9bde9374ab7..3e9b570d104 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1980,6 +1980,8 @@ static ImBuf * seq_render_scene_strip_impl( /* stooping to new low's in hackyness :( */ oldmarkers= scene->markers; scene->markers.first= scene->markers.last= NULL; +#else + (void)oldmarkers; #endif if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 13c21840459..75b5213d576 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4539,6 +4539,8 @@ static void lib_link_scene(FileData *fd, Main *main) marker->camera= newlibadr(fd, sce->id.lib, marker->camera); } } +#else + (void)marker; #endif if(sce->ed) diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 4a359acabd9..aa1af231afd 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -1069,6 +1069,8 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera) WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); } +#else + (void)camera; #endif WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); @@ -1493,6 +1495,8 @@ void ED_marker_keymap(wmKeyConfig *keyconf) kmi= WM_keymap_add_item(keymap, "MARKER_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_CTRL, 0); RNA_boolean_set(kmi->ptr, "extend", 1); RNA_boolean_set(kmi->ptr, "camera", 1); +#else + (void)kmi; #endif WM_keymap_verify_item(keymap, "MARKER_OT_select_border", BKEY, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index de04e83e569..cc77df7e679 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -31,7 +31,7 @@ * \ingroup DNA */ -// XXX, temp feature +// XXX, temp feature - campbell #define DURIAN_CAMERA_SWITCH #ifdef __cplusplus From 4c17f8e5de94f3abc65995e7a2964bb9e6ea7642 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 01:39:36 +0000 Subject: [PATCH 106/147] PyUnicode_From_STR_String utility function which passes STR_String to PyUnicode_FromStringAndSize (saves a call to strlen). Also made CValue::ConvertKeysToPython use faster list creation and improved some of the macro formatting. --- .../gameengine/Converter/BL_ActionActuator.h | 6 +- .../Converter/BL_ArmatureActuator.h | 2 +- .../Converter/BL_ArmatureConstraint.h | 2 +- .../gameengine/Converter/BL_ArmatureObject.h | 2 +- .../Converter/BL_ShapeActionActuator.h | 2 +- source/gameengine/Expressions/Expression.h | 32 ++- source/gameengine/Expressions/ListValue.h | 4 +- .../gameengine/Expressions/PyObjectPlus.cpp | 7 +- source/gameengine/Expressions/PyObjectPlus.h | 263 +++++++++++------- source/gameengine/Expressions/Value.cpp | 20 +- source/gameengine/Expressions/Value.h | 43 +-- .../GameLogic/SCA_2DFilterActuator.h | 2 +- .../gameengine/GameLogic/SCA_ANDController.h | 2 +- .../gameengine/GameLogic/SCA_ActuatorSensor.h | 2 +- .../gameengine/GameLogic/SCA_AlwaysSensor.h | 2 +- source/gameengine/GameLogic/SCA_DelaySensor.h | 2 +- .../GameLogic/SCA_ExpressionController.h | 2 +- source/gameengine/GameLogic/SCA_IController.h | 2 +- source/gameengine/GameLogic/SCA_ILogicBrick.h | 2 +- source/gameengine/GameLogic/SCA_IObject.h | 2 +- source/gameengine/GameLogic/SCA_ISensor.h | 2 +- .../gameengine/GameLogic/SCA_JoystickSensor.h | 6 +- .../gameengine/GameLogic/SCA_KeyboardSensor.h | 2 +- source/gameengine/GameLogic/SCA_MouseSensor.h | 2 +- .../gameengine/GameLogic/SCA_NANDController.h | 2 +- .../gameengine/GameLogic/SCA_NORController.h | 2 +- .../gameengine/GameLogic/SCA_ORController.h | 2 +- .../GameLogic/SCA_PropertyActuator.h | 2 +- .../gameengine/GameLogic/SCA_PropertySensor.h | 2 +- .../GameLogic/SCA_PythonController.cpp | 4 +- .../GameLogic/SCA_PythonController.h | 2 +- .../gameengine/GameLogic/SCA_PythonKeyboard.h | 2 +- source/gameengine/GameLogic/SCA_PythonMouse.h | 2 +- .../gameengine/GameLogic/SCA_RandomActuator.h | 2 +- .../gameengine/GameLogic/SCA_RandomSensor.h | 2 +- .../gameengine/GameLogic/SCA_XNORController.h | 2 +- .../gameengine/GameLogic/SCA_XORController.h | 2 +- source/gameengine/Ketsji/BL_Shader.h | 2 +- .../KXNetwork/KX_NetworkMessageActuator.h | 2 +- .../KXNetwork/KX_NetworkMessageSensor.h | 2 +- source/gameengine/Ketsji/KX_ArmatureSensor.h | 2 +- source/gameengine/Ketsji/KX_BlenderMaterial.h | 2 +- source/gameengine/Ketsji/KX_Camera.h | 2 +- source/gameengine/Ketsji/KX_CameraActuator.h | 2 +- .../gameengine/Ketsji/KX_ConstraintActuator.h | 2 +- .../gameengine/Ketsji/KX_ConstraintWrapper.h | 2 +- source/gameengine/Ketsji/KX_FontObject.h | 2 +- source/gameengine/Ketsji/KX_GameActuator.h | 2 +- source/gameengine/Ketsji/KX_GameObject.cpp | 4 +- source/gameengine/Ketsji/KX_GameObject.h | 2 +- source/gameengine/Ketsji/KX_IpoActuator.h | 2 +- source/gameengine/Ketsji/KX_Light.h | 2 +- source/gameengine/Ketsji/KX_MeshProxy.cpp | 4 +- source/gameengine/Ketsji/KX_MeshProxy.h | 2 +- .../gameengine/Ketsji/KX_MouseFocusSensor.h | 2 +- source/gameengine/Ketsji/KX_NavMeshObject.h | 2 +- source/gameengine/Ketsji/KX_NearSensor.h | 2 +- source/gameengine/Ketsji/KX_ObjectActuator.h | 2 +- source/gameengine/Ketsji/KX_ParentActuator.h | 2 +- .../Ketsji/KX_PhysicsObjectWrapper.h | 2 +- source/gameengine/Ketsji/KX_PolyProxy.cpp | 4 +- source/gameengine/Ketsji/KX_PolyProxy.h | 2 +- .../gameengine/Ketsji/KX_PolygonMaterial.cpp | 4 +- source/gameengine/Ketsji/KX_PolygonMaterial.h | 2 +- source/gameengine/Ketsji/KX_RadarSensor.h | 2 +- source/gameengine/Ketsji/KX_RaySensor.h | 2 +- .../Ketsji/KX_SCA_AddObjectActuator.h | 2 +- .../Ketsji/KX_SCA_DynamicActuator.h | 2 +- .../Ketsji/KX_SCA_EndObjectActuator.h | 2 +- .../Ketsji/KX_SCA_ReplaceMeshActuator.h | 2 +- source/gameengine/Ketsji/KX_Scene.cpp | 2 +- source/gameengine/Ketsji/KX_Scene.h | 2 +- source/gameengine/Ketsji/KX_SceneActuator.h | 2 +- source/gameengine/Ketsji/KX_SoundActuator.h | 2 +- source/gameengine/Ketsji/KX_StateActuator.h | 2 +- .../gameengine/Ketsji/KX_SteeringActuator.h | 2 +- source/gameengine/Ketsji/KX_TouchSensor.h | 2 +- source/gameengine/Ketsji/KX_TrackToActuator.h | 2 +- source/gameengine/Ketsji/KX_VehicleWrapper.h | 2 +- source/gameengine/Ketsji/KX_VertexProxy.h | 2 +- .../gameengine/Ketsji/KX_VisibilityActuator.h | 2 +- 81 files changed, 311 insertions(+), 226 deletions(-) diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h index 2fb774dad44..29300281bb5 100644 --- a/source/gameengine/Converter/BL_ActionActuator.h +++ b/source/gameengine/Converter/BL_ActionActuator.h @@ -40,7 +40,7 @@ class BL_ActionActuator : public SCA_IActuator { public: - Py_Header; + Py_Header BL_ActionActuator(SCA_IObject* gameobj, const STR_String& propname, const STR_String& framepropname, @@ -70,8 +70,8 @@ public: #ifdef WITH_PYTHON - KX_PYMETHOD_O(BL_ActionActuator,GetChannel); - KX_PYMETHOD_DOC(BL_ActionActuator,setChannel); + KX_PYMETHOD_O(BL_ActionActuator,GetChannel) + KX_PYMETHOD_DOC(BL_ActionActuator,setChannel) static PyObject* pyattr_get_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static int pyattr_set_action(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value); diff --git a/source/gameengine/Converter/BL_ArmatureActuator.h b/source/gameengine/Converter/BL_ArmatureActuator.h index 8390444613c..344b76ec278 100644 --- a/source/gameengine/Converter/BL_ArmatureActuator.h +++ b/source/gameengine/Converter/BL_ArmatureActuator.h @@ -46,7 +46,7 @@ class BL_ArmatureActuator : public SCA_IActuator { - Py_Header; + Py_Header public: BL_ArmatureActuator(SCA_IObject* gameobj, int type, diff --git a/source/gameengine/Converter/BL_ArmatureConstraint.h b/source/gameengine/Converter/BL_ArmatureConstraint.h index 49a331e78a5..2abb36ff937 100644 --- a/source/gameengine/Converter/BL_ArmatureConstraint.h +++ b/source/gameengine/Converter/BL_ArmatureConstraint.h @@ -52,7 +52,7 @@ struct bPose; */ class BL_ArmatureConstraint : public PyObjectPlus { - Py_Header; + Py_Header private: struct bConstraint* m_constraint; diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 9847558f708..745ffac0cb2 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -51,7 +51,7 @@ class KX_BlenderSceneConverter; class BL_ArmatureObject : public KX_GameObject { - Py_Header; + Py_Header public: double GetLastFrame (); diff --git a/source/gameengine/Converter/BL_ShapeActionActuator.h b/source/gameengine/Converter/BL_ShapeActionActuator.h index c4251b3c503..90f44acb672 100644 --- a/source/gameengine/Converter/BL_ShapeActionActuator.h +++ b/source/gameengine/Converter/BL_ShapeActionActuator.h @@ -42,7 +42,7 @@ struct Key; class BL_ShapeActionActuator : public SCA_IActuator { public: - Py_Header; + Py_Header BL_ShapeActionActuator(SCA_IObject* gameobj, const STR_String& propname, const STR_String& framepropname, diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h index 875bd758b68..b9232477c34 100644 --- a/source/gameengine/Expressions/Expression.h +++ b/source/gameengine/Expressions/Expression.h @@ -24,19 +24,25 @@ //extern int gRefCountExpr; // only for debugging purposes (detect mem.leaks) -#define PLUGIN_DECLARE_SERIAL_EXPRESSION(class_name,base_class_name) \ -public: \ - virtual base_class_name * Copy() { return new class_name; } \ - virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \ - virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \ -{ \ - if (bIsStoring) \ - { \ - unsigned char exprID = GetExpressionID(); \ - arch << exprID; \ - } \ - return true; \ -} \ +#define PLUGIN_DECLARE_SERIAL_EXPRESSION(class_name, base_class_name) \ +public: \ + virtual base_class_name * Copy() { \ + return new class_name; \ + } \ + virtual bool EdSerialize(CompressorArchive& arch, \ + class CFactoryManager* facmgr, \ + bool bIsStoring); \ + virtual bool EdIdSerialize(CompressorArchive& arch, \ + class CFactoryManager* facmgr, \ + bool bIsStoring) \ + { \ + if (bIsStoring) \ + { \ + unsigned char exprID = GetExpressionID(); \ + arch << exprID; \ + } \ + return true; \ + } \ diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h index 76451215f82..26c11cccc7a 100644 --- a/source/gameengine/Expressions/ListValue.h +++ b/source/gameengine/Expressions/ListValue.h @@ -23,7 +23,7 @@ class CListValue : public CPropValue { - Py_Header; + Py_Header //PLUGIN_DECLARE_SERIAL (CListValue,CValue) public: @@ -58,7 +58,7 @@ public: void Resize(int num); void SetValue(int i,CValue* val); CValue* GetValue(int i){ assertd(i < m_pValueArray.size()); return m_pValueArray[i];} - int GetCount() { return m_pValueArray.size();}; + int GetCount() { return m_pValueArray.size(); } virtual const STR_String & GetText(); bool CheckEqual(CValue* first,CValue* second); diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp index 87f776a726e..f263bf15f02 100644 --- a/source/gameengine/Expressions/PyObjectPlus.cpp +++ b/source/gameengine/Expressions/PyObjectPlus.cpp @@ -470,7 +470,7 @@ PyObject *PyObjectPlus::py_get_attrdef(PyObject *self_py, const PyAttributeDef * case KX_PYATTRIBUTE_TYPE_STRING: { STR_String *val = reinterpret_cast(ptr); - return PyUnicode_FromString(*val); + return PyUnicode_From_STR_String(*val); } case KX_PYATTRIBUTE_TYPE_CHAR: { @@ -1171,6 +1171,11 @@ PyObject *PyObjectPlus::NewProxyPlus_Ext(PyObjectPlus *self, PyTypeObject *tp, v return self->m_proxy; } +PyObject *PyUnicode_From_STR_String(const STR_String& str) +{ + return PyUnicode_FromStringAndSize(str.ReadPtr(), str.Length()); +} + /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// /* deprecation warning management */ diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h index f7bd1b91466..3e1c54b0cc7 100644 --- a/source/gameengine/Expressions/PyObjectPlus.h +++ b/source/gameengine/Expressions/PyObjectPlus.h @@ -29,11 +29,12 @@ * \ingroup expressions */ +#ifndef _PY_OBJECT_PLUS_H +#define _PY_OBJECT_PLUS_H + /* for now keep weakrefs optional */ #define USE_WEAKREFS -#ifndef _adr_py_lib_h_ // only process once, -#define _adr_py_lib_h_ // even if multiply included #ifndef __cplusplus // c++ only #error Must be compiled with C++ @@ -45,10 +46,6 @@ #include "SG_QList.h" #include -/*------------------------------ - * Python defines -------------------------------*/ - #ifdef WITH_PYTHON #ifdef USE_MATHUTILS extern "C" { @@ -110,7 +107,7 @@ typedef struct PyObjectPlus_Proxy { #define BGE_PROXY_PYOWNS(_self) (((PyObjectPlus_Proxy *)_self)->py_owns) #define BGE_PROXY_PYREF(_self) (((PyObjectPlus_Proxy *)_self)->py_ref) #ifdef USE_WEAKREFS - #define BGE_PROXY_WKREF(_self) (((PyObjectPlus_Proxy *)_self)->in_weakreflist) +# define BGE_PROXY_WKREF(_self) (((PyObjectPlus_Proxy *)_self)->in_weakreflist) #endif /* Note, sometimes we dont care what BGE type this is as long as its a proxy */ @@ -124,45 +121,61 @@ typedef struct PyObjectPlus_Proxy { // PyC++ class // AttributesPtr correspond to attributes of proxy generic pointer // each PyC++ class must be registered in KX_PythonInitTypes.cpp -#define __Py_Header \ - public: \ - static PyTypeObject Type; \ - static PyMethodDef Methods[]; \ - static PyAttributeDef Attributes[]; \ - virtual PyTypeObject *GetType(void) {return &Type;}; \ - virtual PyObject *GetProxy() {return GetProxyPlus_Ext(this, &Type, NULL);}; \ - virtual PyObject *NewProxy(bool py_owns) {return NewProxyPlus_Ext(this, &Type, NULL, py_owns);}; \ +#define __Py_Header \ +public: \ + static PyTypeObject Type; \ + static PyMethodDef Methods[]; \ + static PyAttributeDef Attributes[]; \ + virtual PyTypeObject *GetType(void) { \ + return &Type; \ + } \ + virtual PyObject *GetProxy() { \ + return GetProxyPlus_Ext(this, &Type, NULL); \ + } \ + virtual PyObject *NewProxy(bool py_owns) { \ + return NewProxyPlus_Ext(this, &Type, NULL, py_owns); \ + } \ // leave above line empty (macro)! // use this macro for class that use generic pointer in proxy // GetProxy() and NewProxy() must be defined to set the correct pointer in the proxy -#define __Py_HeaderPtr \ - public: \ - static PyTypeObject Type; \ - static PyMethodDef Methods[]; \ - static PyAttributeDef Attributes[]; \ - static PyAttributeDef AttributesPtr[]; \ - virtual PyTypeObject *GetType(void) {return &Type;}; \ - virtual PyObject *GetProxy(); \ - virtual PyObject *NewProxy(bool py_owns); \ +#define __Py_HeaderPtr \ +public: \ + static PyTypeObject Type; \ + static PyMethodDef Methods[]; \ + static PyAttributeDef Attributes[]; \ + static PyAttributeDef AttributesPtr[]; \ + virtual PyTypeObject *GetType(void) { \ + return &Type; \ + } \ + virtual PyObject *GetProxy(); \ + virtual PyObject *NewProxy(bool py_owns); \ // leave above line empty (macro)! #ifdef WITH_CXX_GUARDEDALLOC -#define Py_Header __Py_Header \ - void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \ - void operator delete(void *mem) { MEM_freeN(mem); } \ +#define Py_Header __Py_Header \ + void *operator new(size_t num_bytes) { \ + return MEM_mallocN(num_bytes, Type.tp_name); \ + } \ + void operator delete(void *mem) { \ + MEM_freeN(mem); \ + } \ #else -#define Py_Header __Py_Header +# define Py_Header __Py_Header #endif #ifdef WITH_CXX_GUARDEDALLOC -#define Py_HeaderPtr __Py_HeaderPtr \ - void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, Type.tp_name); } \ - void operator delete( void *mem ) { MEM_freeN(mem); } \ +#define Py_HeaderPtr __Py_HeaderPtr \ + void *operator new(size_t num_bytes) { \ + return MEM_mallocN(num_bytes, Type.tp_name); \ + } \ + void operator delete( void *mem ) { \ + MEM_freeN(mem); \ + } \ #else -#define Py_HeaderPtr __Py_HeaderPtr +# define Py_HeaderPtr __Py_HeaderPtr #endif /* @@ -180,65 +193,109 @@ typedef struct PyObjectPlus_Proxy { * These macros are helpfull when embedding Python routines. The second * macro is one that also requires a documentation string */ -#define KX_PYMETHOD(class_name, method_name) \ - PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ - }; \ +#define KX_PYMETHOD(class_name, method_name) \ + PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "() - " \ + BGE_PROXY_ERROR_MSG); \ + return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ + } \ -#define KX_PYMETHOD_VARARGS(class_name, method_name) \ - PyObject* Py##method_name(PyObject* args); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ - }; \ +#define KX_PYMETHOD_VARARGS(class_name, method_name) \ + PyObject* Py##method_name(PyObject* args); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "() - " \ + BGE_PROXY_ERROR_MSG); return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ + } \ -#define KX_PYMETHOD_NOARGS(class_name, method_name) \ - PyObject* Py##method_name(); \ - static PyObject* sPy##method_name( PyObject* self) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ - }; \ - -#define KX_PYMETHOD_O(class_name, method_name) \ - PyObject* Py##method_name(PyObject* value); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ - }; \ +#define KX_PYMETHOD_NOARGS(class_name, method_name) \ + PyObject* Py##method_name(); \ + static PyObject* \ + sPy##method_name(PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "() - " \ + BGE_PROXY_ERROR_MSG); return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ + } \ -#define KX_PYMETHOD_DOC(class_name, method_name) \ - PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ - }; \ - static const char method_name##_doc[]; \ +#define KX_PYMETHOD_O(class_name, method_name) \ + PyObject* Py##method_name(PyObject* value); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "(value) - " \ + BGE_PROXY_ERROR_MSG); return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ + } \ -#define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \ - PyObject* Py##method_name(PyObject* args); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* args) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "(...) - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ - }; \ - static const char method_name##_doc[]; \ +#define KX_PYMETHOD_DOC(class_name, method_name) \ + PyObject* Py##method_name(PyObject* args, PyObject* kwds); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* args, PyObject* kwds) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "(...) - " \ + BGE_PROXY_ERROR_MSG); return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args, kwds); \ + } \ + static const char method_name##_doc[]; \ -#define KX_PYMETHOD_DOC_O(class_name, method_name) \ - PyObject* Py##method_name(PyObject* value); \ - static PyObject* sPy##method_name( PyObject* self, PyObject* value) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "(value) - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ - }; \ - static const char method_name##_doc[]; \ +#define KX_PYMETHOD_DOC_VARARGS(class_name, method_name) \ + PyObject* Py##method_name(PyObject* args); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* args) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "(...) - " \ + BGE_PROXY_ERROR_MSG); \ + return NULL; \ + } \ + return((class_name*)BGE_PROXY_REF(self))->Py##method_name(args); \ + } \ + static const char method_name##_doc[]; \ -#define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \ - PyObject* Py##method_name(); \ - static PyObject* sPy##method_name( PyObject* self) { \ - if(BGE_PROXY_REF(self)==NULL) { PyErr_SetString(PyExc_RuntimeError, #class_name "." #method_name "() - " BGE_PROXY_ERROR_MSG); return NULL; } \ - return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ - }; \ - static const char method_name##_doc[]; \ +#define KX_PYMETHOD_DOC_O(class_name, method_name) \ + PyObject* Py##method_name(PyObject* value); \ + static PyObject* \ + sPy##method_name(PyObject* self, PyObject* value) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "(value) - " \ + BGE_PROXY_ERROR_MSG); \ + return NULL; \ + } \ + return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(value); \ + } \ + static const char method_name##_doc[]; \ + +#define KX_PYMETHOD_DOC_NOARGS(class_name, method_name) \ + PyObject* Py##method_name(); \ + static PyObject* \ + sPy##method_name(PyObject* self) { \ + if(BGE_PROXY_REF(self)==NULL) { \ + PyErr_SetString(PyExc_RuntimeError, \ + #class_name "." #method_name "() - " \ + BGE_PROXY_ERROR_MSG); \ + return NULL; \ + } \ + return ((class_name*)BGE_PROXY_REF(self))->Py##method_name(); \ + } \ + static const char method_name##_doc[]; \ /* The line above should remain empty */ @@ -290,7 +347,7 @@ enum KX_PYATTRIBUTE_TYPE { KX_PYATTRIBUTE_TYPE_FUNCTION, KX_PYATTRIBUTE_TYPE_VECTOR, KX_PYATTRIBUTE_TYPE_FLAG, - KX_PYATTRIBUTE_TYPE_CHAR, + KX_PYATTRIBUTE_TYPE_CHAR }; enum KX_PYATTRIBUTE_ACCESS { @@ -479,23 +536,31 @@ typedef PyTypeObject * PyParentObject; // Define the PyParent Object #else // WITH_PYTHON #ifdef WITH_CXX_GUARDEDALLOC -#define Py_Header \ - public: \ - void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:PyObjectPlus"); } \ - void operator delete( void *mem ) { MEM_freeN(mem); } \ +#define Py_Header \ +public: \ + void *operator new(size_t num_bytes) { \ + return MEM_mallocN(num_bytes, "GE:PyObjectPlus"); \ + } \ + void operator delete( void *mem ) { \ + MEM_freeN(mem); \ + } \ -#define Py_HeaderPtr \ - public: \ - void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:PyObjectPlusPtr"); } \ - void operator delete( void *mem ) { MEM_freeN(mem); } \ +#define Py_HeaderPtr \ +public: \ + void *operator new(size_t num_bytes) { \ + return MEM_mallocN(num_bytes, "GE:PyObjectPlusPtr"); \ + } \ + void operator delete( void *mem ) { \ + MEM_freeN(mem); \ + } \ #else // WITH_CXX_GUARDEDALLOC #define Py_Header \ - public: \ +public: \ #define Py_HeaderPtr \ - public: \ +public: \ #endif // WITH_CXX_GUARDEDALLOC @@ -515,7 +580,7 @@ typedef PyTypeObject * PyParentObject; // Define the PyParent Object // possibility to use them at SCA_ILogicBrick, CValue and PyObjectPlus level. class PyObjectPlus : public SG_QList { // The PyObjectPlus abstract class - Py_Header; // Always start with Py_Header + Py_Header // Always start with Py_Header public: PyObjectPlus(); @@ -580,6 +645,8 @@ public: #ifdef WITH_PYTHON PyObject *py_getattr_dict(PyObject *pydict, PyObject *tp_dict); + +PyObject *PyUnicode_From_STR_String(const STR_String& str); #endif -#endif // _adr_py_lib_h_ +#endif // _PY_OBJECT_PLUS_H diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index 41c0850a779..91fdbb0dabc 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -532,7 +532,7 @@ PyAttributeDef CValue::Attributes[] = { PyObject * CValue::pyattr_get_name(void * self_v, const KX_PYATTRIBUTE_DEF * attrdef) { CValue * self = static_cast (self_v); - return PyUnicode_FromString(self->GetName()); + return PyUnicode_From_STR_String(self->GetName()); } CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) @@ -596,22 +596,24 @@ CValue* CValue::ConvertPythonToValue(PyObject* pyobj, const char *error_prefix) } -PyObject* CValue::ConvertKeysToPython( void ) +PyObject* CValue::ConvertKeysToPython(void) { - PyObject *pylist = PyList_New( 0 ); - PyObject *pystr; - if (m_pNamedPropertyArray) { + PyObject *pylist= PyList_New(m_pNamedPropertyArray->size()); + Py_ssize_t i= 0; + std::map::iterator it; for (it= m_pNamedPropertyArray->begin(); (it != m_pNamedPropertyArray->end()); it++) { - pystr = PyUnicode_FromString( (*it).first ); - PyList_Append(pylist, pystr); - Py_DECREF( pystr ); + PyList_SET_ITEM(pylist, i++, PyUnicode_From_STR_String((*it).first)); } + + return pylist; + } + else { + return PyList_New(0); } - return pylist; } #endif // WITH_PYTHON diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 955e688ad7b..f9697a55d3f 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -200,7 +200,7 @@ public: class CValue : public PyObjectPlus { -Py_Header; +Py_Header public: enum AllocationTYPE { STACKVALUE = 0, @@ -319,7 +319,7 @@ public: virtual const STR_String & GetText() = 0; virtual double GetNumber() = 0; - double* ZeroVector() { return m_sZeroVec; }; + double* ZeroVector() { return m_sZeroVec; } virtual double* GetVector3(bool bGetTransformedVec = false); virtual STR_String& GetName() = 0; // Retrieve the name of the value @@ -348,11 +348,11 @@ public: virtual bool IsSelected() { return m_ValFlags.Selected; } inline bool IsReleaseRequested() { return m_ValFlags.ReleaseRequested; } virtual bool IsVisible() { return m_ValFlags.Visible;} - virtual void SetCustomFlag1(bool bCustomFlag) { m_ValFlags.CustomFlag1 = bCustomFlag;}; - virtual bool IsCustomFlag1() { return m_ValFlags.CustomFlag1;}; + virtual void SetCustomFlag1(bool bCustomFlag) { m_ValFlags.CustomFlag1 = bCustomFlag;} + virtual bool IsCustomFlag1() { return m_ValFlags.CustomFlag1;} - virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;}; - virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;}; + virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;} + virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;} protected: virtual void DisableRefCount(); // Disable reference counting for this value @@ -379,18 +379,23 @@ private: // of object. So, for *any* CValue-derived object this should be set to CValue, // for *any* CExpression-derived object this should be set to CExpression. // -#define PLUGIN_DECLARE_SERIAL(class_name, root_base_class_name) \ -public: \ - virtual root_base_class_name * Copy() { return new class_name; } \ - virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \ - virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \ -{ \ - if (bIsStoring) \ - arch.StoreString(#class_name); \ - \ - return false; \ -} \ - +#define PLUGIN_DECLARE_SERIAL(class_name, root_base_class_name) \ +public: \ + virtual root_base_class_name *Copy() { \ + return new class_name; \ + } \ + virtual bool EdSerialize(CompressorArchive& arch, \ + class CFactoryManager* facmgr, \ + bool bIsStoring); \ + virtual bool EdIdSerialize(CompressorArchive& arch, \ + class CFactoryManager* facmgr, \ + bool bIsStoring) \ + { \ + if (bIsStoring) \ + arch.StoreString(#class_name); \ + return false; \ + } \ + //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// @@ -424,7 +429,7 @@ public: //if (namefromprop.Length() > 0) // return namefromprop; return m_strNewName; - }; // name of Value + } // name of Value protected: STR_String m_strNewName; // Identification diff --git a/source/gameengine/GameLogic/SCA_2DFilterActuator.h b/source/gameengine/GameLogic/SCA_2DFilterActuator.h index ec4c4a1cbcf..42446b7a2b1 100644 --- a/source/gameengine/GameLogic/SCA_2DFilterActuator.h +++ b/source/gameengine/GameLogic/SCA_2DFilterActuator.h @@ -37,7 +37,7 @@ class SCA_2DFilterActuator : public SCA_IActuator { - Py_Header; + Py_Header private: vector m_propNames; diff --git a/source/gameengine/GameLogic/SCA_ANDController.h b/source/gameengine/GameLogic/SCA_ANDController.h index e39dea547a2..363bca630aa 100644 --- a/source/gameengine/GameLogic/SCA_ANDController.h +++ b/source/gameengine/GameLogic/SCA_ANDController.h @@ -39,7 +39,7 @@ class SCA_ANDController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_ANDController(SCA_IObject* gameobj); diff --git a/source/gameengine/GameLogic/SCA_ActuatorSensor.h b/source/gameengine/GameLogic/SCA_ActuatorSensor.h index 9b5793787a2..e7a7525bb40 100644 --- a/source/gameengine/GameLogic/SCA_ActuatorSensor.h +++ b/source/gameengine/GameLogic/SCA_ActuatorSensor.h @@ -40,7 +40,7 @@ class SCA_ActuatorSensor : public SCA_ISensor { - Py_Header; + Py_Header STR_String m_checkactname; bool m_lastresult; bool m_midresult; diff --git a/source/gameengine/GameLogic/SCA_AlwaysSensor.h b/source/gameengine/GameLogic/SCA_AlwaysSensor.h index 41e9a9612c6..8748793d9a3 100644 --- a/source/gameengine/GameLogic/SCA_AlwaysSensor.h +++ b/source/gameengine/GameLogic/SCA_AlwaysSensor.h @@ -38,7 +38,7 @@ class SCA_AlwaysSensor : public SCA_ISensor { - Py_Header; + Py_Header bool m_alwaysresult; public: SCA_AlwaysSensor(class SCA_EventManager* eventmgr, diff --git a/source/gameengine/GameLogic/SCA_DelaySensor.h b/source/gameengine/GameLogic/SCA_DelaySensor.h index fea713502b4..ccb8f00c548 100644 --- a/source/gameengine/GameLogic/SCA_DelaySensor.h +++ b/source/gameengine/GameLogic/SCA_DelaySensor.h @@ -38,7 +38,7 @@ class SCA_DelaySensor : public SCA_ISensor { - Py_Header; + Py_Header bool m_lastResult; bool m_repeat; int m_delay; diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 4e549c08ed1..93a3f08c95f 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -39,7 +39,7 @@ class SCA_ExpressionController : public SCA_IController { -// Py_Header; +// Py_Header STR_String m_exprText; CExpression* m_exprCache; diff --git a/source/gameengine/GameLogic/SCA_IController.h b/source/gameengine/GameLogic/SCA_IController.h index 795e02dcf78..5481f2ae8e4 100644 --- a/source/gameengine/GameLogic/SCA_IController.h +++ b/source/gameengine/GameLogic/SCA_IController.h @@ -42,7 +42,7 @@ */ class SCA_IController : public SCA_ILogicBrick { - Py_Header; + Py_Header protected: std::vector m_linkedsensors; std::vector m_linkedactuators; diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index 4016c557bf3..87b37a8ef39 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -43,7 +43,7 @@ class SCA_IScene; class SCA_ILogicBrick : public CValue { - Py_Header; + Py_Header protected: SCA_IObject* m_gameobj; int m_Execute_Priority; diff --git a/source/gameengine/GameLogic/SCA_IObject.h b/source/gameengine/GameLogic/SCA_IObject.h index 1d16d4f0af7..b0a03de1242 100644 --- a/source/gameengine/GameLogic/SCA_IObject.h +++ b/source/gameengine/GameLogic/SCA_IObject.h @@ -54,7 +54,7 @@ typedef std::vector SCA_ObjectList; class SCA_IObject : public CValue { - Py_Header; + Py_Header protected: friend class KX_StateActuator; diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 970faf7d29a..ef082095c0d 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -47,7 +47,7 @@ */ class SCA_ISensor : public SCA_ILogicBrick { - Py_Header; + Py_Header protected: class SCA_EventManager* m_eventmgr; diff --git a/source/gameengine/GameLogic/SCA_JoystickSensor.h b/source/gameengine/GameLogic/SCA_JoystickSensor.h index b4ed2c06d2f..db34ce4cc15 100644 --- a/source/gameengine/GameLogic/SCA_JoystickSensor.h +++ b/source/gameengine/GameLogic/SCA_JoystickSensor.h @@ -38,7 +38,7 @@ class SCA_JoystickSensor :public SCA_ISensor { - Py_Header; + Py_Header /** * Axis 1-JOYAXIS_MAX, MUST be followed by m_axisf @@ -128,8 +128,8 @@ public: /* --------------------------------------------------------------------- */ /* Joystick Index */ - KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButtonActiveList); - KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,GetButtonStatus); + KX_PYMETHOD_DOC_NOARGS(SCA_JoystickSensor,GetButtonActiveList) + KX_PYMETHOD_DOC_VARARGS(SCA_JoystickSensor,GetButtonStatus) static PyObject* pyattr_get_axis_values(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); static PyObject* pyattr_get_axis_single(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); diff --git a/source/gameengine/GameLogic/SCA_KeyboardSensor.h b/source/gameengine/GameLogic/SCA_KeyboardSensor.h index 37a42cdcbe6..e7283978ae1 100644 --- a/source/gameengine/GameLogic/SCA_KeyboardSensor.h +++ b/source/gameengine/GameLogic/SCA_KeyboardSensor.h @@ -44,7 +44,7 @@ * exclusive. */ class SCA_KeyboardSensor : public SCA_ISensor { - Py_Header; + Py_Header /** * the key this sensor is sensing for diff --git a/source/gameengine/GameLogic/SCA_MouseSensor.h b/source/gameengine/GameLogic/SCA_MouseSensor.h index ecfa776112a..4bac9c10e13 100644 --- a/source/gameengine/GameLogic/SCA_MouseSensor.h +++ b/source/gameengine/GameLogic/SCA_MouseSensor.h @@ -39,7 +39,7 @@ class SCA_MouseSensor : public SCA_ISensor { - Py_Header; + Py_Header /** * Use SCA_IInputDevice values to encode the mouse mode for now. diff --git a/source/gameengine/GameLogic/SCA_NANDController.h b/source/gameengine/GameLogic/SCA_NANDController.h index 8eb26127a51..723d2a5fe0d 100644 --- a/source/gameengine/GameLogic/SCA_NANDController.h +++ b/source/gameengine/GameLogic/SCA_NANDController.h @@ -36,7 +36,7 @@ class SCA_NANDController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_NANDController(SCA_IObject* gameobj); diff --git a/source/gameengine/GameLogic/SCA_NORController.h b/source/gameengine/GameLogic/SCA_NORController.h index 6580ad7bc8c..26d7e925923 100644 --- a/source/gameengine/GameLogic/SCA_NORController.h +++ b/source/gameengine/GameLogic/SCA_NORController.h @@ -36,7 +36,7 @@ class SCA_NORController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_NORController(SCA_IObject* gameobj); diff --git a/source/gameengine/GameLogic/SCA_ORController.h b/source/gameengine/GameLogic/SCA_ORController.h index 4edd34f6302..53debf894a3 100644 --- a/source/gameengine/GameLogic/SCA_ORController.h +++ b/source/gameengine/GameLogic/SCA_ORController.h @@ -36,7 +36,7 @@ class SCA_ORController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_ORController(SCA_IObject* gameobj); diff --git a/source/gameengine/GameLogic/SCA_PropertyActuator.h b/source/gameengine/GameLogic/SCA_PropertyActuator.h index f4a43a7e21c..17419e34c2a 100644 --- a/source/gameengine/GameLogic/SCA_PropertyActuator.h +++ b/source/gameengine/GameLogic/SCA_PropertyActuator.h @@ -36,7 +36,7 @@ class SCA_PropertyActuator : public SCA_IActuator { - Py_Header; + Py_Header enum KX_ACT_PROP_MODE { KX_ACT_PROP_NODEF = 0, diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index c1fe5320546..bf7b1e879f7 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -37,7 +37,7 @@ class SCA_PropertySensor : public SCA_ISensor { - Py_Header; + Py_Header //class CExpression* m_rightexpr; int m_checktype; STR_String m_checkpropval; diff --git a/source/gameengine/GameLogic/SCA_PythonController.cpp b/source/gameengine/GameLogic/SCA_PythonController.cpp index d69358928e6..8a87a734a1c 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.cpp +++ b/source/gameengine/GameLogic/SCA_PythonController.cpp @@ -164,7 +164,7 @@ void SCA_PythonController::SetNamespace(PyObject* pythondictionary) /* Without __file__ set the sys.argv[0] is used for the filename * which ends up with lines from the blender binary being printed in the console */ - PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_FromString(m_scriptName.Ptr())); + PyDict_SetItemString(m_pythondictionary, "__file__", PyUnicode_From_STR_String(m_scriptName)); } #endif @@ -490,7 +490,7 @@ PyObject* SCA_PythonController::pyattr_get_script(void *self_v, const KX_PYATTRI // static_cast(dynamic_cast(obj)) - static_cast(obj) SCA_PythonController* self= static_cast(self_v); - return PyUnicode_FromString(self->m_scriptText); + return PyUnicode_From_STR_String(self->m_scriptText); } diff --git a/source/gameengine/GameLogic/SCA_PythonController.h b/source/gameengine/GameLogic/SCA_PythonController.h index 0d22c347861..521a676bf4a 100644 --- a/source/gameengine/GameLogic/SCA_PythonController.h +++ b/source/gameengine/GameLogic/SCA_PythonController.h @@ -42,7 +42,7 @@ class SCA_IObject; class SCA_PythonController : public SCA_IController { - Py_Header; + Py_Header #ifdef WITH_PYTHON struct _object * m_bytecode; /* SCA_PYEXEC_SCRIPT only */ PyObject* m_function; /* SCA_PYEXEC_MODULE only */ diff --git a/source/gameengine/GameLogic/SCA_PythonKeyboard.h b/source/gameengine/GameLogic/SCA_PythonKeyboard.h index 9c761e054f2..7ecf76d1581 100644 --- a/source/gameengine/GameLogic/SCA_PythonKeyboard.h +++ b/source/gameengine/GameLogic/SCA_PythonKeyboard.h @@ -31,7 +31,7 @@ class SCA_PythonKeyboard : public PyObjectPlus { - Py_Header; + Py_Header private: class SCA_IInputDevice *m_keyboard; #ifdef WITH_PYTHON diff --git a/source/gameengine/GameLogic/SCA_PythonMouse.h b/source/gameengine/GameLogic/SCA_PythonMouse.h index dfdf00bc6e9..4ad655dce8f 100644 --- a/source/gameengine/GameLogic/SCA_PythonMouse.h +++ b/source/gameengine/GameLogic/SCA_PythonMouse.h @@ -31,7 +31,7 @@ class SCA_PythonMouse : public PyObjectPlus { - Py_Header; + Py_Header private: class SCA_IInputDevice *m_mouse; class RAS_ICanvas *m_canvas; diff --git a/source/gameengine/GameLogic/SCA_RandomActuator.h b/source/gameengine/GameLogic/SCA_RandomActuator.h index 66d22d5952b..c439b445a5b 100644 --- a/source/gameengine/GameLogic/SCA_RandomActuator.h +++ b/source/gameengine/GameLogic/SCA_RandomActuator.h @@ -38,7 +38,7 @@ class SCA_RandomActuator : public SCA_IActuator { - Py_Header; + Py_Header /** Property to assign to */ STR_String m_propname; diff --git a/source/gameengine/GameLogic/SCA_RandomSensor.h b/source/gameengine/GameLogic/SCA_RandomSensor.h index f0ae2fd2bde..cec8bcdb445 100644 --- a/source/gameengine/GameLogic/SCA_RandomSensor.h +++ b/source/gameengine/GameLogic/SCA_RandomSensor.h @@ -39,7 +39,7 @@ class SCA_RandomSensor : public SCA_ISensor { - Py_Header; + Py_Header unsigned int m_currentDraw; int m_iteration; diff --git a/source/gameengine/GameLogic/SCA_XNORController.h b/source/gameengine/GameLogic/SCA_XNORController.h index de0af2ba9d5..c2cdad2cdf4 100644 --- a/source/gameengine/GameLogic/SCA_XNORController.h +++ b/source/gameengine/GameLogic/SCA_XNORController.h @@ -36,7 +36,7 @@ class SCA_XNORController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_XNORController(SCA_IObject* gameobj); diff --git a/source/gameengine/GameLogic/SCA_XORController.h b/source/gameengine/GameLogic/SCA_XORController.h index 96098082165..1f38a510046 100644 --- a/source/gameengine/GameLogic/SCA_XORController.h +++ b/source/gameengine/GameLogic/SCA_XORController.h @@ -36,7 +36,7 @@ class SCA_XORController : public SCA_IController { - Py_Header; + Py_Header //virtual void Trigger(class SCA_LogicManager* logicmgr); public: SCA_XORController(SCA_IObject* gameobj); diff --git a/source/gameengine/Ketsji/BL_Shader.h b/source/gameengine/Ketsji/BL_Shader.h index 41802a0a19f..32872592cc5 100644 --- a/source/gameengine/Ketsji/BL_Shader.h +++ b/source/gameengine/Ketsji/BL_Shader.h @@ -116,7 +116,7 @@ public: */ class BL_Shader : public PyObjectPlus { - Py_Header; + Py_Header private: typedef std::vector BL_UniformVec; typedef std::vector BL_UniformVecDef; diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h index a7db2ed1660..f3447356055 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageActuator.h @@ -39,7 +39,7 @@ class KX_NetworkMessageActuator : public SCA_IActuator { - Py_Header; + Py_Header bool m_lastEvent; class NG_NetworkScene* m_networkscene; // needed for replication STR_String m_toPropName; diff --git a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h index 7ec8f26f8ce..75800d9b9fa 100644 --- a/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h +++ b/source/gameengine/Ketsji/KXNetwork/KX_NetworkMessageSensor.h @@ -40,7 +40,7 @@ class NG_NetworkScene; class KX_NetworkMessageSensor : public SCA_ISensor { // note: Py_Header MUST BE the first listed here - Py_Header; + Py_Header NG_NetworkScene *m_NetworkScene; // The subject we filter on. diff --git a/source/gameengine/Ketsji/KX_ArmatureSensor.h b/source/gameengine/Ketsji/KX_ArmatureSensor.h index 1b0168266a3..683a54f65de 100644 --- a/source/gameengine/Ketsji/KX_ArmatureSensor.h +++ b/source/gameengine/Ketsji/KX_ArmatureSensor.h @@ -40,7 +40,7 @@ struct bConstraint; class KX_ArmatureSensor : public SCA_ISensor { - Py_Header; + Py_Header //class CExpression* m_rightexpr; protected: diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 236bd6afdc8..2736516bf33 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -32,7 +32,7 @@ class KX_Scene; class KX_BlenderMaterial : public PyObjectPlus, public RAS_IPolyMaterial { - Py_Header; + Py_Header public: // -------------------------------- KX_BlenderMaterial(); diff --git a/source/gameengine/Ketsji/KX_Camera.h b/source/gameengine/Ketsji/KX_Camera.h index 236e914b9e5..e9c4e99aa3b 100644 --- a/source/gameengine/Ketsji/KX_Camera.h +++ b/source/gameengine/Ketsji/KX_Camera.h @@ -50,7 +50,7 @@ bool ConvertPythonToCamera(PyObject * value, KX_Camera **object, bool py_none_ok class KX_Camera : public KX_GameObject { - Py_Header; + Py_Header protected: friend class KX_Scene; /** Camera parameters (clips distances, focal length). These diff --git a/source/gameengine/Ketsji/KX_CameraActuator.h b/source/gameengine/Ketsji/KX_CameraActuator.h index c06904ea56b..a6344ae380a 100644 --- a/source/gameengine/Ketsji/KX_CameraActuator.h +++ b/source/gameengine/Ketsji/KX_CameraActuator.h @@ -49,7 +49,7 @@ class KX_CameraActuator : public SCA_IActuator { - Py_Header; + Py_Header private : /** Object that will be tracked. */ SCA_IObject *m_ob; diff --git a/source/gameengine/Ketsji/KX_ConstraintActuator.h b/source/gameengine/Ketsji/KX_ConstraintActuator.h index ebaeed9aafe..b513b141f3e 100644 --- a/source/gameengine/Ketsji/KX_ConstraintActuator.h +++ b/source/gameengine/Ketsji/KX_ConstraintActuator.h @@ -42,7 +42,7 @@ class KX_GameObject; class KX_ConstraintActuator : public SCA_IActuator { - Py_Header; + Py_Header protected: // Damp time (int), int m_posDampTime; diff --git a/source/gameengine/Ketsji/KX_ConstraintWrapper.h b/source/gameengine/Ketsji/KX_ConstraintWrapper.h index 8f559881a2e..980221bd4b3 100644 --- a/source/gameengine/Ketsji/KX_ConstraintWrapper.h +++ b/source/gameengine/Ketsji/KX_ConstraintWrapper.h @@ -37,7 +37,7 @@ class KX_ConstraintWrapper : public PyObjectPlus { - Py_Header; + Py_Header public: KX_ConstraintWrapper(PHY_ConstraintType ctype,int constraintId,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_ConstraintWrapper (); diff --git a/source/gameengine/Ketsji/KX_FontObject.h b/source/gameengine/Ketsji/KX_FontObject.h index 15d455b7313..8fc7a9e9f28 100644 --- a/source/gameengine/Ketsji/KX_FontObject.h +++ b/source/gameengine/Ketsji/KX_FontObject.h @@ -38,7 +38,7 @@ class KX_FontObject : public KX_GameObject { public: - Py_Header; + Py_Header KX_FontObject( void* sgReplicationInfo, SG_Callbacks callbacks, RAS_IRenderTools* rendertools, diff --git a/source/gameengine/Ketsji/KX_GameActuator.h b/source/gameengine/Ketsji/KX_GameActuator.h index 1c05d152d39..ebc6712a2dd 100644 --- a/source/gameengine/Ketsji/KX_GameActuator.h +++ b/source/gameengine/Ketsji/KX_GameActuator.h @@ -40,7 +40,7 @@ class KX_GameActuator : public SCA_IActuator { - Py_Header; + Py_Header protected: int m_mode; bool m_restart; diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index d3ed9991c31..c240a7fcf84 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1880,7 +1880,7 @@ PyTypeObject KX_GameObject::Type = { PyObject* KX_GameObject::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_GameObject* self= static_cast(self_v); - return PyUnicode_FromString(self->GetName().ReadPtr()); + return PyUnicode_From_STR_String(self->GetName()); } PyObject* KX_GameObject::pyattr_get_parent(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) @@ -2683,7 +2683,7 @@ PyObject* KX_GameObject::PyGetPhysicsId() PyObject* KX_GameObject::PyGetPropertyNames() { - PyObject *list= ConvertKeysToPython(); + PyObject *list= ConvertKeysToPython(); if(m_attr_dict) { PyObject *key, *value; diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h index 69bc394cbfc..245a92a96de 100644 --- a/source/gameengine/Ketsji/KX_GameObject.h +++ b/source/gameengine/Ketsji/KX_GameObject.h @@ -80,7 +80,7 @@ void KX_GameObject_Mathutils_Callback_Init(void); */ class KX_GameObject : public SCA_IObject { - Py_Header; + Py_Header protected: bool m_bDyna; diff --git a/source/gameengine/Ketsji/KX_IpoActuator.h b/source/gameengine/Ketsji/KX_IpoActuator.h index 5ee008ac5e3..fa26bbaa6e1 100644 --- a/source/gameengine/Ketsji/KX_IpoActuator.h +++ b/source/gameengine/Ketsji/KX_IpoActuator.h @@ -37,7 +37,7 @@ class KX_IpoActuator : public SCA_IActuator { - Py_Header; + Py_Header private: /** Computes the IPO start time from the current time and the current frame. */ diff --git a/source/gameengine/Ketsji/KX_Light.h b/source/gameengine/Ketsji/KX_Light.h index cd472311bcf..bb081e6a444 100644 --- a/source/gameengine/Ketsji/KX_Light.h +++ b/source/gameengine/Ketsji/KX_Light.h @@ -44,7 +44,7 @@ class MT_Transform; class KX_LightObject : public KX_GameObject { - Py_Header; + Py_Header protected: RAS_LightObject m_lightobj; class RAS_IRenderTools* m_rendertools; //needed for registering and replication of lightobj diff --git a/source/gameengine/Ketsji/KX_MeshProxy.cpp b/source/gameengine/Ketsji/KX_MeshProxy.cpp index 754ad511669..fec1d9d296c 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.cpp +++ b/source/gameengine/Ketsji/KX_MeshProxy.cpp @@ -129,7 +129,7 @@ PyObject* KX_MeshProxy::PyGetMaterialName(PyObject* args, PyObject* kwds) return NULL; } - return PyUnicode_FromString(matname.Ptr()); + return PyUnicode_From_STR_String(matname); } @@ -147,7 +147,7 @@ PyObject* KX_MeshProxy::PyGetTextureName(PyObject* args, PyObject* kwds) return NULL; } - return PyUnicode_FromString(matname.Ptr()); + return PyUnicode_From_STR_String(matname); } diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index d5292b5108d..f59418a5de2 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -41,7 +41,7 @@ bool ConvertPythonToMesh(PyObject * value, class RAS_MeshObject **object, bool p class KX_MeshProxy : public CValue { - Py_Header; + Py_Header class RAS_MeshObject* m_meshobj; public: diff --git a/source/gameengine/Ketsji/KX_MouseFocusSensor.h b/source/gameengine/Ketsji/KX_MouseFocusSensor.h index 5fb576eec28..277af87f9f2 100644 --- a/source/gameengine/Ketsji/KX_MouseFocusSensor.h +++ b/source/gameengine/Ketsji/KX_MouseFocusSensor.h @@ -47,7 +47,7 @@ class KX_RayCast; class KX_MouseFocusSensor : public SCA_MouseSensor { - Py_Header; + Py_Header public: diff --git a/source/gameengine/Ketsji/KX_NavMeshObject.h b/source/gameengine/Ketsji/KX_NavMeshObject.h index 287b2b24fa9..ad128a0891d 100644 --- a/source/gameengine/Ketsji/KX_NavMeshObject.h +++ b/source/gameengine/Ketsji/KX_NavMeshObject.h @@ -36,7 +36,7 @@ class MT_Transform; class KX_NavMeshObject: public KX_GameObject { - Py_Header; + Py_Header protected: dtStatNavMesh* m_navMesh; diff --git a/source/gameengine/Ketsji/KX_NearSensor.h b/source/gameengine/Ketsji/KX_NearSensor.h index 1caea59867a..26adcb993b8 100644 --- a/source/gameengine/Ketsji/KX_NearSensor.h +++ b/source/gameengine/Ketsji/KX_NearSensor.h @@ -41,7 +41,7 @@ struct PHY_CollData; class KX_NearSensor : public KX_TouchSensor { - Py_Header; + Py_Header protected: float m_Margin; float m_ResetMargin; diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.h b/source/gameengine/Ketsji/KX_ObjectActuator.h index fc6fcb66e28..aa0f844eb88 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.h +++ b/source/gameengine/Ketsji/KX_ObjectActuator.h @@ -80,7 +80,7 @@ struct KX_LocalFlags { class KX_ObjectActuator : public SCA_IActuator { - Py_Header; + Py_Header MT_Vector3 m_force; MT_Vector3 m_torque; diff --git a/source/gameengine/Ketsji/KX_ParentActuator.h b/source/gameengine/Ketsji/KX_ParentActuator.h index 8531675723a..484b137c2f5 100644 --- a/source/gameengine/Ketsji/KX_ParentActuator.h +++ b/source/gameengine/Ketsji/KX_ParentActuator.h @@ -41,7 +41,7 @@ class KX_ParentActuator : public SCA_IActuator { - Py_Header; + Py_Header /** Mode */ int m_mode; diff --git a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h index 0e4c2e71f3e..4f03c8fbfb1 100644 --- a/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h +++ b/source/gameengine/Ketsji/KX_PhysicsObjectWrapper.h @@ -37,7 +37,7 @@ class KX_PhysicsObjectWrapper : public PyObjectPlus { - Py_Header; + Py_Header public: KX_PhysicsObjectWrapper(class PHY_IPhysicsController* ctrl,class PHY_IPhysicsEnvironment* physenv); virtual ~KX_PhysicsObjectWrapper(); diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index 82a93e76cf3..caef8ba5e2e 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -216,13 +216,13 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, isCollider, KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getMaterialName, "getMaterialName() : returns the polygon material name, \"NoMaterial\" if no material\n") { - return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); + return PyUnicode_From_STR_String(m_polygon->GetMaterial()->GetPolyMaterial()->GetMaterialName()); } KX_PYMETHODDEF_DOC_NOARGS(KX_PolyProxy, getTextureName, "getTexturelName() : returns the polygon texture name, \"NULL\" if no texture\n") { - return PyUnicode_FromString(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); + return PyUnicode_From_STR_String(m_polygon->GetMaterial()->GetPolyMaterial()->GetTextureName()); } KX_PYMETHODDEF_DOC(KX_PolyProxy, getVertexIndex, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.h b/source/gameengine/Ketsji/KX_PolyProxy.h index d8046b3fec6..44945e58c2a 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.h +++ b/source/gameengine/Ketsji/KX_PolyProxy.h @@ -38,7 +38,7 @@ class KX_PolyProxy : public CValue { - Py_Header; + Py_Header protected: class RAS_Polygon* m_polygon; class RAS_MeshObject* m_mesh; diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index 3147d6ba4c9..29127ec11a0 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -346,13 +346,13 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, activate, "activate(rasty, cachingInfo)") PyObject* KX_PolygonMaterial::pyattr_get_texture(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyUnicode_FromString(self->m_texturename.ReadPtr()); + return PyUnicode_From_STR_String(self->m_texturename); } PyObject* KX_PolygonMaterial::pyattr_get_material(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_PolygonMaterial* self= static_cast(self_v); - return PyUnicode_FromString(self->m_materialname.ReadPtr()); + return PyUnicode_From_STR_String(self->m_materialname); } /* this does not seem useful */ diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 78876c60409..f20a90f7deb 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -55,7 +55,7 @@ struct Image; */ class KX_PolygonMaterial : public PyObjectPlus, public RAS_IPolyMaterial { - Py_Header; + Py_Header private: /** Blender texture face structure. */ MTFace* m_tface; diff --git a/source/gameengine/Ketsji/KX_RadarSensor.h b/source/gameengine/Ketsji/KX_RadarSensor.h index 422313fcfef..ee803d9bdb9 100644 --- a/source/gameengine/Ketsji/KX_RadarSensor.h +++ b/source/gameengine/Ketsji/KX_RadarSensor.h @@ -41,7 +41,7 @@ class KX_RadarSensor : public KX_NearSensor { protected: - Py_Header; + Py_Header float m_coneradius; diff --git a/source/gameengine/Ketsji/KX_RaySensor.h b/source/gameengine/Ketsji/KX_RaySensor.h index d797666d6ab..4c0009a5a4c 100644 --- a/source/gameengine/Ketsji/KX_RaySensor.h +++ b/source/gameengine/Ketsji/KX_RaySensor.h @@ -43,7 +43,7 @@ class KX_RayCast; class KX_RaySensor : public SCA_ISensor { - Py_Header; + Py_Header STR_String m_propertyname; bool m_bFindMaterial; bool m_bXRay; diff --git a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h index 4bb84663e9e..ec5cf305c3e 100644 --- a/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h @@ -45,7 +45,7 @@ class SCA_IScene; class KX_SCA_AddObjectActuator : public SCA_IActuator { - Py_Header; + Py_Header /// Time field: lifetime of the new object int m_timeProp; diff --git a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h index eaad67ad0ea..5fefbb8cca5 100644 --- a/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_DynamicActuator.h @@ -42,7 +42,7 @@ class KX_SCA_DynamicActuator : public SCA_IActuator { - Py_Header; + Py_Header // dynamics operation to apply to the game object short m_dyn_operation; diff --git a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h index a6bbf258398..7a325257e59 100644 --- a/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_EndObjectActuator.h @@ -41,7 +41,7 @@ class SCA_IScene; class KX_SCA_EndObjectActuator : public SCA_IActuator { - Py_Header; + Py_Header SCA_IScene* m_scene; public: diff --git a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h index 1e0e2155e62..3e07ec2665c 100644 --- a/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h +++ b/source/gameengine/Ketsji/KX_SCA_ReplaceMeshActuator.h @@ -44,7 +44,7 @@ class KX_SCA_ReplaceMeshActuator : public SCA_IActuator { - Py_Header; + Py_Header // mesh reference (mesh to replace) RAS_MeshObject* m_mesh; diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index f1e0fdc8a50..9b8f7f27d80 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -2117,7 +2117,7 @@ PySequenceMethods KX_Scene::Sequence = { PyObject* KX_Scene::pyattr_get_name(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) { KX_Scene* self= static_cast(self_v); - return PyUnicode_FromString(self->GetName().ReadPtr()); + return PyUnicode_From_STR_String(self->GetName()); } PyObject* KX_Scene::pyattr_get_objects(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef) diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 67508f5741b..c8070736b7f 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -101,7 +101,7 @@ class KX_ObstacleSimulation; * */ class KX_Scene : public PyObjectPlus, public SCA_IScene { - Py_Header; + Py_Header #ifdef WITH_PYTHON PyObject* m_attr_dict; diff --git a/source/gameengine/Ketsji/KX_SceneActuator.h b/source/gameengine/Ketsji/KX_SceneActuator.h index 30f325a775e..9064146a1d4 100644 --- a/source/gameengine/Ketsji/KX_SceneActuator.h +++ b/source/gameengine/Ketsji/KX_SceneActuator.h @@ -38,7 +38,7 @@ class KX_SceneActuator : public SCA_IActuator { - Py_Header; + Py_Header int m_mode; // (restart) has become a toggle internally... not in the interface though diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h index 174bcc8f990..b9119677f4f 100644 --- a/source/gameengine/Ketsji/KX_SoundActuator.h +++ b/source/gameengine/Ketsji/KX_SoundActuator.h @@ -57,7 +57,7 @@ typedef struct KX_3DSoundSettings class KX_SoundActuator : public SCA_IActuator { - Py_Header; + Py_Header bool m_isplaying; AUD_Reference m_sound; float m_volume; diff --git a/source/gameengine/Ketsji/KX_StateActuator.h b/source/gameengine/Ketsji/KX_StateActuator.h index 3d1dc64d891..aa17b687463 100644 --- a/source/gameengine/Ketsji/KX_StateActuator.h +++ b/source/gameengine/Ketsji/KX_StateActuator.h @@ -44,7 +44,7 @@ */ class KX_StateActuator : public SCA_IActuator { - Py_Header; + Py_Header /** Make visible? */ enum { diff --git a/source/gameengine/Ketsji/KX_SteeringActuator.h b/source/gameengine/Ketsji/KX_SteeringActuator.h index 38be7bce57b..a0ae8e0d1d9 100644 --- a/source/gameengine/Ketsji/KX_SteeringActuator.h +++ b/source/gameengine/Ketsji/KX_SteeringActuator.h @@ -47,7 +47,7 @@ const int MAX_PATH_LENGTH = 128; class KX_SteeringActuator : public SCA_IActuator { - Py_Header; + Py_Header /** Target object */ KX_GameObject *m_target; diff --git a/source/gameengine/Ketsji/KX_TouchSensor.h b/source/gameengine/Ketsji/KX_TouchSensor.h index a111bf31cf6..1fae766aa13 100644 --- a/source/gameengine/Ketsji/KX_TouchSensor.h +++ b/source/gameengine/Ketsji/KX_TouchSensor.h @@ -51,7 +51,7 @@ class KX_TouchEventManager; class KX_TouchSensor : public SCA_ISensor { protected: - Py_Header; + Py_Header /** * The sensor should only look for objects with this property. diff --git a/source/gameengine/Ketsji/KX_TrackToActuator.h b/source/gameengine/Ketsji/KX_TrackToActuator.h index 9d267bfe89a..30e276c0021 100644 --- a/source/gameengine/Ketsji/KX_TrackToActuator.h +++ b/source/gameengine/Ketsji/KX_TrackToActuator.h @@ -40,7 +40,7 @@ class KX_TrackToActuator : public SCA_IActuator { - Py_Header; + Py_Header // Object reference. Actually, we use the object's 'life' SCA_IObject* m_object; // 3d toggle diff --git a/source/gameengine/Ketsji/KX_VehicleWrapper.h b/source/gameengine/Ketsji/KX_VehicleWrapper.h index f750912c95b..f6e360d34a8 100644 --- a/source/gameengine/Ketsji/KX_VehicleWrapper.h +++ b/source/gameengine/Ketsji/KX_VehicleWrapper.h @@ -16,7 +16,7 @@ class PHY_IMotionState; ///Python interface to physics vehicles (primarily 4-wheel cars and 2wheel bikes) class KX_VehicleWrapper : public PyObjectPlus { - Py_Header; + Py_Header std::vector m_motionStates; diff --git a/source/gameengine/Ketsji/KX_VertexProxy.h b/source/gameengine/Ketsji/KX_VertexProxy.h index 4ae662faa12..905a4e0f4ab 100644 --- a/source/gameengine/Ketsji/KX_VertexProxy.h +++ b/source/gameengine/Ketsji/KX_VertexProxy.h @@ -38,7 +38,7 @@ class KX_VertexProxy : public CValue { - Py_Header; + Py_Header protected: class RAS_TexVert* m_vertex; diff --git a/source/gameengine/Ketsji/KX_VisibilityActuator.h b/source/gameengine/Ketsji/KX_VisibilityActuator.h index 0ffe1de6480..f5c45ecbd99 100644 --- a/source/gameengine/Ketsji/KX_VisibilityActuator.h +++ b/source/gameengine/Ketsji/KX_VisibilityActuator.h @@ -37,7 +37,7 @@ class KX_VisibilityActuator : public SCA_IActuator { - Py_Header; + Py_Header /** Make visible? */ bool m_visible; From 440c1c2c1745b6d4acd13f405643100cb913fb3b Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Nov 2011 05:46:45 +0000 Subject: [PATCH 107/147] As discussed on the mailing list, removing the non-functional, incompatible, and unmaintainable Time Offset cruft. - Slow Parenting lives another day (just), although it now carries appropriate cautionary disclaimers. It's only really for the Game Engine nowadays, as that's the only place where it can possibly work with any reliability. - "Animation Hacks" panel is now "Relations Extras". I could've merged the two panels, though I figured these options weren't that frequently used to justify taking up screen-space by default along with the panel --- .../startup/bl_ui/properties_object.py | 26 ++---- source/blender/blenkernel/BKE_object.h | 3 +- source/blender/blenkernel/intern/group.c | 8 +- source/blender/blenkernel/intern/object.c | 46 +++-------- source/blender/blenkernel/intern/pointcache.c | 2 +- source/blender/blenloader/intern/readfile.c | 4 +- source/blender/editors/animation/anim_draw.c | 22 ----- source/blender/editors/animation/keyframing.c | 28 ------- source/blender/editors/include/ED_anim_api.h | 4 +- .../blender/editors/object/object_relations.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 82 +------------------ source/blender/makesdna/DNA_object_types.h | 33 +++----- source/blender/makesrna/intern/rna_object.c | 44 +++------- 13 files changed, 53 insertions(+), 251 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 0779debb102..a359d58b59e 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -257,10 +257,8 @@ class OBJECT_PT_duplication(ObjectButtonsPanel, Panel): layout.prop(ob, "dupli_group", text="Group") -# XXX: the following options are all quite buggy, ancient hacks that should be dropped - -class OBJECT_PT_animation(ObjectButtonsPanel, Panel): - bl_label = "Animation Hacks" +class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): + bl_label = "Relations Extras" bl_options = {'DEFAULT_CLOSED'} def draw(self, context): @@ -269,23 +267,17 @@ class OBJECT_PT_animation(ObjectButtonsPanel, Panel): ob = context.object split = layout.split() - - col = split.column() - col.label(text="Time Offset:") - col.prop(ob, "use_time_offset_edit", text="Edit") - row = col.row() - row.prop(ob, "use_time_offset_parent", text="Parent") - row.active = (ob.parent is not None) - row = col.row() - row.prop(ob, "use_slow_parent") - row.active = (ob.parent is not None) - col.prop(ob, "time_offset", text="Offset") - - # XXX: these are still used for a few curve-related tracking features + col = split.column() col.label(text="Tracking Axes:") col.prop(ob, "track_axis", text="Axis") col.prop(ob, "up_axis", text="Up Axis") + + col = split.column() + col.prop(ob, "use_slow_parent") + row = col.row() + row.active = ((ob.parent is not None) and (ob.use_slow_parent)) + row.prop(ob, "slow_parent_offset", text="Offset") from bl_ui.properties_animviz import ( diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index d6139a680ec..725ebfaa645 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -86,7 +86,7 @@ void set_mblur_offs(float blur); void set_field_offs(float field); void disable_speed_curve(int val); -float bsystem_time(struct Scene *scene, struct Object *ob, float cfra, float ofs); +float bsystem_time(struct Scene *scene, struct Object *ob, float cfra, float ofs); // XXX: last arg unused? void object_scale_to_mat3(struct Object *ob, float mat[][3]); void object_rot_to_mat3(struct Object *ob, float mat[][3]); void object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat); @@ -118,7 +118,6 @@ void object_tfm_restore(struct Object *ob, void *obtfm_pt); void object_handle_update(struct Scene *scene, struct Object *ob); void object_sculpt_modifiers_changed(struct Object *ob); -float give_timeoffset(struct Object *ob); int give_obdata_texspace(struct Object *ob, short **texflag, float **loc, float **size, float **rot); int object_insert_ptcache(struct Object *ob); diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index cd025ecb559..76c3e6e5502 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -276,8 +276,9 @@ void group_tag_recalc(Group *group) int group_is_animated(Object *parent, Group *group) { GroupObject *go; - - if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first) + + // XXX: old animsys depreceated... + if(parent->nlastrips.first) return 1; for(go= group->gobject.first; go; go= go->next) @@ -343,12 +344,11 @@ void group_handle_recalc_and_update(Scene *scene, Object *UNUSED(parent), Group * but when its enabled at some point it will need to be changed so as not to update so much - campbell */ /* if animated group... */ - if(give_timeoffset(parent) != 0.0f || parent->nlastrips.first) { + if(parent->nlastrips.first) { int cfrao; /* switch to local time */ cfrao= scene->r.cfra; - scene->r.cfra -= (int)floor(give_timeoffset(parent) + 0.5f); /* we need a DAG per group... */ for(go= group->gobject.first; go; go= go->next) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a78b010392e..5782ae5f2d7 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1431,15 +1431,7 @@ float bsystem_time(struct Scene *scene, Object *UNUSED(ob), float cfra, float of /* global time */ if (scene) - cfra*= scene->r.framelen; - -#if 0 // XXX old animation system - if (ob) { - /* ofset frames */ - if ((ob->ipoflag & OB_OFFS_PARENT) && (ob->partype & PARSLOW)==0) - cfra-= give_timeoffset(ob); - } -#endif // XXX old animation system + cfra *= scene->r.framelen; cfra-= ofs; @@ -1592,12 +1584,6 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) makeDispListCurveTypes(scene, par, 0); if(cu->path==NULL) return; - /* exception, timeoffset is regarded as distance offset */ - if(cu->flag & CU_OFFS_PATHDIST) { - timeoffs = give_timeoffset(ob); - SWAP(float, sf_orig, ob->sf); - } - /* catch exceptions: feature for nla stride editing */ if(ob->ipoflag & OB_DISABLE_PATH) { ctime= 0.0f; @@ -1618,7 +1604,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) CLAMP(ctime, 0.0f, 1.0f); } else { - ctime= scene->r.cfra - give_timeoffset(ob); + ctime= scene->r.cfra; if (IS_EQF(cu->pathlen, 0.0f) == 0) ctime /= cu->pathlen; @@ -1862,9 +1848,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) if(ob->parent) { Object *par= ob->parent; - // XXX depreceated - animsys - if(ob->ipoflag & OB_OFFS_PARENT) ctime-= give_timeoffset(ob); - /* hurms, code below conflicts with depgraph... (ton) */ /* and even worse, it gives bad effects for NLA stride too (try ctime != par->ctime, with MBlur) */ if(no_parent_ipo==0 && stime != par->ctime) { @@ -1873,17 +1856,20 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) if(par->proxy_from); // was a copied matrix, no where_is! bad... else where_is_object_time(scene, par, ctime); - + solve_parenting(scene, ob, par, ob->obmat, slowmat, 0); - + *par= tmp; } else solve_parenting(scene, ob, par, ob->obmat, slowmat, 0); + /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around + * An old-fashioned hack which probably doesn't really cut it anymore + */ if(ob->partype & PARSLOW) { // include framerate - fac1= ( 1.0f / (1.0f + (float)fabs(give_timeoffset(ob))) ); + fac1= ( 1.0f / (1.0f + (float)fabs(ob->sf)) ); if(fac1 >= 1.0f) return; fac2= 1.0f-fac1; @@ -2006,7 +1992,6 @@ void where_is_object_simul(Scene *scene, Object *ob) for a lamp that is the child of another object */ { Object *par; - //Ipo *ipo; float *fp1, *fp2; float slowmat[4][4]; float fac1, fac2; @@ -2017,10 +2002,9 @@ for a lamp that is the child of another object */ par= ob->parent; solve_parenting(scene, ob, par, ob->obmat, slowmat, 1); - + if(ob->partype & PARSLOW) { - - fac1= (float)(1.0/(1.0+ fabs(give_timeoffset(ob)))); + fac1= (float)(1.0/(1.0+ fabs(ob->sf))); fac2= 1.0f-fac1; fp1= ob->obmat[0]; fp2= slowmat[0]; @@ -2028,7 +2012,6 @@ for a lamp that is the child of another object */ fp1[0]= fac1*fp1[0] + fac2*fp2[0]; } } - } else { object_to_mat4(ob, ob->obmat); @@ -2554,15 +2537,6 @@ void object_sculpt_modifiers_changed(Object *ob) } } -float give_timeoffset(Object *ob) -{ - if ((ob->ipoflag & OB_OFFS_PARENTADD) && ob->parent) { - return ob->sf + give_timeoffset(ob->parent); - } else { - return ob->sf; - } -} - int give_obdata_texspace(Object *ob, short **texflag, float **loc, float **size, float **rot) { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index ae12ad8e66f..b327afa7df7 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2163,7 +2163,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra * system timing. */ #if 0 if ((ob->partype & PARSLOW)==0) { - offset= give_timeoffset(ob); + offset= ob->sf; *startframe += (int)(offset+0.5f); *endframe += (int)(offset+0.5f); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 75b5213d576..e17f8c720a5 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -7155,7 +7155,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) while(ob) { if(ob->transflag & 1) { ob->transflag -= 1; - ob->ipoflag |= OB_OFFS_OB; + //ob->ipoflag |= OB_OFFS_OB; } ob= ob->id.next; } @@ -7186,7 +7186,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } ob= main->object.first; while(ob) { - ob->ipoflag |= OB_OFFS_PARENT; + //ob->ipoflag |= OB_OFFS_PARENT; if(ob->dt==0) ob->dt= OB_SOLID; ob= ob->id.next; } diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 2774bd2cda4..569125e1055 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -237,28 +237,6 @@ void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag) glVertex2fv(vec); glEnd(); - /* Draw dark green line if slow-parenting/time-offset is enabled */ - if (flag & DRAWCFRA_SHOW_TIMEOFS) { - Object *ob= OBACT; - if(ob) { - float timeoffset= give_timeoffset(ob); - // XXX ob->ipoflag is depreceated! - if ((ob->ipoflag & OB_OFFS_OB) && (timeoffset != 0.0f)) { - vec[0]-= timeoffset; /* could avoid calling twice */ - - UI_ThemeColorShade(TH_CFRAME, -30); - - glBegin(GL_LINE_STRIP); - /*vec[1]= v2d->cur.ymax;*/ // this is set already. this line is only included - glVertex2fv(vec); - - vec[1]= v2d->cur.ymin; - glVertex2fv(vec); - glEnd(); - } - } - } - glLineWidth(1.0); /* Draw current frame number in a little box */ diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index fb34245d338..9f466ef52d3 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -911,20 +911,6 @@ short insert_keyframe (ReportList *reports, ID *id, bAction *act, const char gro /* apply NLA-mapping to frame to use (if applicable) */ cfra= BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } - -#if 0 - /* apply special time tweaking */ - // XXX check on this stuff... - if (GS(id->name) == ID_OB) { - //Object *ob= (Object *)id; - - /* ancient time-offset cruft */ - //if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) { - // /* actually frametofloat calc again! */ - // cfra-= give_timeoffset(ob)*scene->r.framelen; - //} - } -#endif /* key entire array convenience method */ if (array_index == -1) { @@ -1018,20 +1004,6 @@ short delete_keyframe (ReportList *reports, ID *id, bAction *act, const char gro } } -#if 0 - /* apply special time tweaking */ - // XXX check on this stuff... - if (GS(id->name) == ID_OB) { - //Object *ob= (Object *)id; - - /* ancient time-offset cruft */ - //if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) { - // /* actually frametofloat calc again! */ - // cfra-= give_timeoffset(ob)*scene->r.framelen; - //} - } -#endif - /* key entire array convenience method */ if (array_index == -1) { array_index= 0; diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 0ac5a9e46ce..6b449f68e1d 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -462,10 +462,8 @@ enum { DRAWCFRA_SHOW_NUMBOX = (1<<0), /* time indication in seconds or frames */ DRAWCFRA_UNIT_SECONDS = (1<<1), - /* show time-offset line */ - DRAWCFRA_SHOW_TIMEOFS = (1<<2), /* draw indicator extra wide (for timeline) */ - DRAWCFRA_WIDE = (1<<3) + DRAWCFRA_WIDE = (1<<2) } eAnimEditDraw_CurrentFrame; /* main call to draw current-frame indicator in an Animation Editor */ diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index e9575c85c5f..94e2f0aae00 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -655,7 +655,7 @@ static int parent_set_exec(bContext *C, wmOperator *op) data = con->data; data->tar = par; - get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra - give_timeoffset(ob)); + get_constraint_target_matrix(scene, con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, scene->r.cfra); sub_v3_v3v3(vec, ob->obmat[3], cmat[3]); ob->loc[0] = vec[0]; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 987c3984b77..da33f48116d 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -5748,7 +5748,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) Object *ob; Curve *cu; RegionView3D *rv3d= ar->regiondata; - //float cfraont; float vec1[3], vec2[3]; unsigned int col=0; int /*sel, drawtype,*/ colindex= 0; @@ -5787,83 +5786,6 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* no return after this point, otherwise leaks */ view3d_cached_text_draw_begin(); - - /* draw keys? */ -#if 0 // XXX old animation system - if(base==(scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) { - if(flag==0 && warning_recursive==0 && ob!=scene->obedit) { - if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) { - ListBase elems; - CfraElem *ce; - float temp[7][3]; - - warning_recursive= 1; - - elems.first= elems.last= 0; - // warning: no longer checks for certain ob-keys only... (so does this need to use the proper ipokeys then?) - make_cfra_list(ob->ipo, &elems); - - cfraont= (scene->r.cfra); - drawtype= v3d->drawtype; - if(drawtype>OB_WIRE) v3d->drawtype= OB_WIRE; - sel= base->flag; - memcpy(temp, &ob->loc, 7*3*sizeof(float)); - - ipoflag= ob->ipoflag; - ob->ipoflag &= ~OB_OFFS_OB; - - set_no_parent_ipo(1); - disable_speed_curve(1); - - if ((ob->ipoflag & OB_DRAWKEYSEL)==0) { - ce= elems.first; - while(ce) { - if(!ce->sel) { - (scene->r.cfra)= ce->cfra/scene->r.framelen; - - base->flag= 0; - - where_is_object_time(scene, ob, (scene->r.cfra)); - draw_object(scene, ar, v3d, base, 0); - } - ce= ce->next; - } - } - - ce= elems.first; - while(ce) { - if(ce->sel) { - (scene->r.cfra)= ce->cfra/scene->r.framelen; - - base->flag= SELECT; - - where_is_object_time(scene, ob, (scene->r.cfra)); - draw_object(scene, ar, v3d, base, 0); - } - ce= ce->next; - } - - set_no_parent_ipo(0); - disable_speed_curve(0); - - base->flag= sel; - ob->ipoflag= ipoflag; - - /* restore icu->curval */ - (scene->r.cfra)= cfraont; - - memcpy(&ob->loc, temp, 7*3*sizeof(float)); - where_is_object(scene, ob); - v3d->drawtype= drawtype; - - BLI_freelistN(&elems); - - warning_recursive= 0; - } - } - } -#endif // XXX old animation system - /* patch? children objects with a timeoffs change the parents. How to solve! */ /* if( ((int)ob->ctime) != F_(scene->r.cfra)) where_is_object(scene, ob); */ @@ -5921,7 +5843,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) if(base->flag & (SELECT+BA_WAS_SEL)) { /* uses darker active color for non-active + selected*/ theme_id= TH_GROUP_ACTIVE; - + if(scene->basact != base) { theme_shade= -16; } @@ -6510,7 +6432,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) for (ct= targets.first; ct; ct= ct->next) { /* calculate target's matrix */ if (cti->get_target_matrix) - cti->get_target_matrix(curcon, cob, ct, bsystem_time(scene, ob, (float)(scene->r.cfra), give_timeoffset(ob))); + cti->get_target_matrix(curcon, cob, ct, bsystem_time(scene, ob, (float)(scene->r.cfra), 0.0f)); else unit_m4(ct->matrix); diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3306b9e97bc..29568fdd0fb 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -163,7 +163,8 @@ typedef struct Object { short transflag, protectflag; /* transformation settings and transform locks */ short trackflag, upflag; - short nlaflag, ipoflag; // xxx depreceated... old animation system + short nlaflag; /* used for DopeSheet filtering settings (expanded/collapsed) */ + short ipoflag; // xxx depreceated... old animation system short scaflag; /* ui state for game logic */ char scavisflag; /* more display settings for game logic */ char pad5; @@ -325,11 +326,12 @@ typedef struct DupliObject { #define PARVERT1 5 #define PARVERT3 6 #define PARBONE 7 + + /* slow parenting - is not threadsafe and/or may give errors after jumping */ #define PARSLOW 16 /* (short) transflag */ -/*#define OB_OFFS_LOCAL 1*/ /*UNUSED*/ -/* #define OB_QUAT 2 */ /* never used, free flag */ +/* flags 1 and 2 were unused or relics from past features */ #define OB_NEG_SCALE 4 #define OB_DUPLI (8+16+256+512+2048) #define OB_DUPLIFRAMES 8 @@ -345,24 +347,12 @@ typedef struct DupliObject { #define OB_NO_CONSTRAINTS 8192 /* runtime constraints disable */ /* (short) ipoflag */ - // XXX depreceated - old animation system crap -#define OB_DRAWKEY 1 -#define OB_DRAWKEYSEL 2 -#define OB_OFFS_OB 4 -/* #define OB_OFFS_MAT 8 */ /*UNUSED*/ -/* #define OB_OFFS_VKEY 16 */ /*UNUSED*/ -/* #define OB_OFFS_PATH 32 */ /*UNUSED*/ -#define OB_OFFS_PARENT 64 -#define OB_OFFS_PARTICLE 128 - /* get ipo from from action or not? */ -#define OB_ACTION_OB 256 -#define OB_ACTION_KEY 512 - /* for stride edit */ +/* XXX: many old flags for features removed due to incompatability + * with new system and/or other design issues were here + */ + /* for stride/path editing (XXX: NEEDS REVIEW) */ #define OB_DISABLE_PATH 1024 -#define OB_OFFS_PARENTADD 2048 - - /* (short) trackflag / upflag */ #define OB_POSX 0 #define OB_POSY 1 @@ -529,10 +519,7 @@ typedef struct DupliObject { #define OB_SHAPE_EDIT_MODE 4 /* ob->nlaflag */ - // XXX depreceated - old animation system -#define OB_NLA_OVERRIDE (1<<0) -#define OB_NLA_COLLAPSED (1<<1) - + /* WARNING: flags (1<<0) and (1<<1) were from old animsys */ /* object-channel expanded status */ #define OB_ADS_COLLAPSED (1<<10) /* object's ipo-block */ diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index be2375f5716..6e797146f12 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2210,13 +2210,20 @@ static void rna_def_object(BlenderRNA *brna) rna_def_animviz_common(srna); rna_def_motionpath_common(srna); - /* duplicates */ - // XXX: evil old crap + /* slow parenting */ + // XXX: evil old crap prop= RNA_def_property(srna, "use_slow_parent", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "partype", PARSLOW); - RNA_def_property_ui_text(prop, "Slow Parent", "Create a delay in the parent relationship"); + RNA_def_property_ui_text(prop, "Slow Parent", "Create a delay in the parent relationship (Beware: this isn't renderfarm safe and may be invalid after jumping around the timeline)"); RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Object_internal_update"); - + + prop= RNA_def_property(srna, "slow_parent_offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_TIME); + RNA_def_property_float_sdna(prop, NULL, "sf"); + RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); + RNA_def_property_ui_text(prop, "Slow Parent Offset", "Amount of delay in the parent relationship"); + RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); + + /* duplicates */ prop= RNA_def_property(srna, "dupli_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "transflag"); RNA_def_property_enum_items(prop, dupli_items); @@ -2285,34 +2292,7 @@ static void rna_def_object(BlenderRNA *brna) prop= RNA_def_property(srna, "is_duplicator", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "transflag", OB_DUPLI); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - - /* time offset */ - prop= RNA_def_property(srna, "time_offset", PROP_FLOAT, PROP_NONE|PROP_UNIT_TIME); - RNA_def_property_float_sdna(prop, NULL, "sf"); - RNA_def_property_range(prop, MINAFRAMEF, MAXFRAMEF); - RNA_def_property_ui_text(prop, "Time Offset", "Animation offset in frames for F-Curve and dupligroup instances"); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - - prop= RNA_def_property(srna, "use_time_offset_edit", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_OB); - RNA_def_property_ui_text(prop, "Time Offset Edit", - "Use time offset when inserting keys and display time offset for F-Curve and action views"); - - prop= RNA_def_property(srna, "use_time_offset_parent", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_PARENT); - RNA_def_property_ui_text(prop, "Time Offset Parent", "Apply the time offset to this object's parent relationship"); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - - prop= RNA_def_property(srna, "use_time_offset_particle", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_PARTICLE); - RNA_def_property_ui_text(prop, "Time Offset Particle", "Let the time offset work on the particle effect"); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - - prop= RNA_def_property(srna, "use_time_offset_add_parent", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "ipoflag", OB_OFFS_PARENTADD); - RNA_def_property_ui_text(prop, "Time Offset Add Parent", "Add the parent's time offset value"); - RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Object_internal_update"); - + /* drawing */ prop= RNA_def_property(srna, "draw_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "dt"); From 723484ec066d3e2d2b0943dc9dca156d63c07c39 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Nov 2011 06:08:18 +0000 Subject: [PATCH 108/147] Removed old "bsystem_time()" function, which by now is just a duplicate of BKE_curframe() which just takes two extra args. For the few calls in the physics engine where CFRA+1 instead of CFRA was being used, I've added a new BKE_nextframe() call, which will calculate for CFRA+1 instead of CFRA in much the same way that bsystem_time() would end up doing things (which means including subframe steps). --- source/blender/blenkernel/BKE_object.h | 1 - source/blender/blenkernel/BKE_scene.h | 1 + source/blender/blenkernel/intern/anim.c | 2 +- source/blender/blenkernel/intern/armature.c | 3 ++- source/blender/blenkernel/intern/key.c | 15 +++++++------- source/blender/blenkernel/intern/object.c | 20 ------------------- source/blender/blenkernel/intern/particle.c | 5 +++-- source/blender/blenkernel/intern/pointcache.c | 4 ++-- source/blender/blenkernel/intern/scene.c | 19 +++++++++++++----- .../blender/editors/space_view3d/drawobject.c | 5 +++-- source/blender/modifiers/intern/MOD_build.c | 7 +------ source/blender/modifiers/intern/MOD_explode.c | 5 +---- 12 files changed, 36 insertions(+), 51 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 725ebfaa645..85a986d3460 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -86,7 +86,6 @@ void set_mblur_offs(float blur); void set_field_offs(float field); void disable_speed_curve(int val); -float bsystem_time(struct Scene *scene, struct Object *ob, float cfra, float ofs); // XXX: last arg unused? void object_scale_to_mat3(struct Object *ob, float mat[][3]); void object_rot_to_mat3(struct Object *ob, float mat[][3]); void object_mat3_to_rot(struct Object *ob, float mat[][3], short use_compat); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 4806a288cee..a6bd90c4fd2 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -86,6 +86,7 @@ void scene_select_base(struct Scene *sce, struct Base *selbase); int scene_check_setscene(struct Main *bmain, struct Scene *sce); float BKE_curframe(struct Scene *scene); +float BKE_nextframe(struct Scene *scene); void scene_update_tagged(struct Main *bmain, struct Scene *sce); void scene_clear_tagged(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index f939c168f51..c1f294fb102 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -1230,7 +1230,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p if(G.rendering == 0) no_draw_flag |= PARS_NO_DISP; - ctime = bsystem_time(scene, par, (float)scene->r.cfra, 0.0); + ctime = BKE_curframe(scene); /* NOTE: in old animsys, used parent object's timeoffset... */ totpart = psys->totpart; totchild = psys->totchild; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index e9a19b50a81..f19ed859064 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -68,6 +68,7 @@ #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BIK_api.h" #include "BKE_sketch.h" @@ -2406,7 +2407,7 @@ void where_is_pose (Scene *scene, Object *ob) if((ob->pose==NULL) || (ob->pose->flag & POSE_RECALC)) armature_rebuild_pose(ob, arm); - ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0); /* not accurate... */ + ctime= BKE_curframe(scene); /* not accurate... */ /* In editmode or restposition we read the data from the bones */ if(arm->edbo || (arm->flag & ARM_RESTPOS)) { diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 6d095117136..c389800b0d1 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -59,6 +59,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_deform.h" +#include "BKE_scene.h" #include "RNA_access.h" @@ -1072,7 +1073,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int for(a=0; aipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; @@ -1106,7 +1107,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int } } else { - ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); // xxx old cruft + ctime= BKE_curframe(scene); #if 0 // XXX old animation system if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { @@ -1204,7 +1205,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in while (a < estep) { if (remain <= 0) { cfra+= delta; - ctime= bsystem_time(scene, NULL, cfra, 0.0f); // XXX old cruft + ctime= BKE_curframe(scene); ctime /= 100.0f; CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing @@ -1231,7 +1232,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in } else { - ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0); + ctime= BKE_curframe(scene); if(key->type==KEY_RELATIVE) { do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot); @@ -1267,7 +1268,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int for(a=0; aipo, KEY_SPEED, &ctime)==0) { ctime /= 100.0; @@ -1298,7 +1299,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int } } else { - ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0); + ctime= BKE_curframe(scene); #if 0 // XXX old animation system if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) { @@ -1462,7 +1463,7 @@ KeyBlock *add_keyblock(Key *key, const char *name) kb->pos= curpos + 0.1f; else { #if 0 // XXX old animation system - curpos= bsystem_time(scene, 0, (float)CFRA, 0.0); + curpos= BKE_curframe(scene); if(calc_ipo_spec(key->ipo, KEY_SPEED, &curpos)==0) { curpos /= 100.0; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5782ae5f2d7..a493120e320 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1419,25 +1419,6 @@ void object_make_proxy(Object *ob, Object *target, Object *gob) /* *************** CALC ****************** */ -/* there is also a timing calculation in drawobject() */ - - -// XXX THIS CRUFT NEEDS SERIOUS RECODING ASAP! -/* ob can be NULL */ -float bsystem_time(struct Scene *scene, Object *UNUSED(ob), float cfra, float ofs) -{ - /* returns float ( see BKE_curframe in scene.c) */ - cfra += scene->r.subframe; - - /* global time */ - if (scene) - cfra *= scene->r.framelen; - - cfra-= ofs; - - return cfra; -} - void object_scale_to_mat3(Object *ob, float mat[][3]) { float vec[3]; @@ -1445,7 +1426,6 @@ void object_scale_to_mat3(Object *ob, float mat[][3]) size_to_mat3( mat,vec); } - void object_rot_to_mat3(Object *ob, float mat[][3]) { float rmat[3][3], dmat[3][3]; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7678da1c7c4..f8d281c2951 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -77,6 +77,7 @@ #include "BKE_mesh.h" #include "BKE_cdderivedmesh.h" #include "BKE_pointcache.h" +#include "BKE_scene.h" #include "RE_render_ext.h" @@ -3426,7 +3427,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n psys->totpart=0; psys->flag = PSYS_ENABLED|PSYS_CURRENT; - psys->cfra=bsystem_time(scene,ob,scene->r.cfra+1,0.0); + psys->cfra = BKE_nextframe(scene); DAG_scene_sort(G.main, scene); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -4189,7 +4190,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta float timestep = psys_get_timestep(sim); /* negative time means "use current time" */ - cfra = state->time > 0 ? state->time : bsystem_time(sim->scene, 0, (float)sim->scene->r.cfra, 0.0); + cfra = state->time > 0 ? state->time : BKE_curframe(sim->scene); if(p>=totpart){ if(!psys->totchild) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index b327afa7df7..7a8162391d5 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2147,8 +2147,8 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra cache= pid->cache; if(timescale) { - time= bsystem_time(scene, ob, cfra, 0.0f); - nexttime= bsystem_time(scene, ob, cfra+1.0f, 0.0f); + time= BKE_curframe(scene); + nexttime= BKE_nextframe(scene); *timescale= MAX2(nexttime - time, 0.0f); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f1e094c3909..2f24b7e735d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -910,14 +910,23 @@ int scene_check_setscene(Main *bmain, Scene *sce) } /* This function is needed to cope with fractional frames - including two Blender rendering features -* mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. */ - -/* see also bsystem_time in object.c */ + * mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. + */ float BKE_curframe(Scene *scene) { float ctime = scene->r.cfra; - ctime+= scene->r.subframe; - ctime*= scene->r.framelen; + ctime += scene->r.subframe; + ctime *= scene->r.framelen; + + return ctime; +} + +/* Similar to BKE_curframe(), but is used by physics sims to get "next time", which is defined as cfra+1 */ +float BKE_nextframe(Scene *scene) +{ + float ctime = (float)(scene->r.cfra + 1); + ctime += scene->r.subframe; + ctime *= scene->r.framelen; return ctime; } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index da33f48116d..9f98a6c6b48 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -74,6 +74,7 @@ #include "BKE_paint.h" #include "BKE_particle.h" #include "BKE_pointcache.h" +#include "BKE_scene.h" #include "BKE_unit.h" #include "smoke_API.h" @@ -3672,7 +3673,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv totpart=psys->totpart; - cfra= bsystem_time(scene, NULL, (float)CFRA, 0.0f); + cfra= BKE_curframe(scene); if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL && psys->childcache==NULL) draw_as=PART_DRAW_DOT; @@ -6432,7 +6433,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) for (ct= targets.first; ct; ct= ct->next) { /* calculate target's matrix */ if (cti->get_target_matrix) - cti->get_target_matrix(curcon, cob, ct, bsystem_time(scene, ob, (float)(scene->r.cfra), 0.0f)); + cti->get_target_matrix(curcon, cob, ct, BKE_curframe(scene)); else unit_m4(ct->matrix); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 10c2f6019ed..10f5645ca3b 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -106,12 +106,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap"); for(i = 0; i < maxFaces; ++i) faceMap[i] = i; - if (ob) { - frac = bsystem_time(md->scene, ob, md->scene->r.cfra, - bmd->start - 1.0f) / bmd->length; - } else { - frac = BKE_curframe(md->scene) - bmd->start / bmd->length; - } + frac = BKE_curframe(md->scene) - bmd->start / bmd->length; CLAMP(frac, 0.0f, 1.0f); numFaces = dm->getNumFaces(dm) * frac; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 8dcb6f4b4d9..9821c0b3836 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -804,10 +804,7 @@ static DerivedMesh * explodeMesh(ExplodeModifierData *emd, /* timestep= psys_get_timestep(&sim); */ - //if(part->flag & PART_GLOB_TIME) - cfra= BKE_curframe(scene); - //else - // cfra=bsystem_time(scene, ob,(float)scene->r.cfra,0.0); + cfra= BKE_curframe(scene); /* hash table for vertice <-> particle relations */ vertpahash= BLI_edgehash_new(); From b18e661ffcd39b97ac0c8295d778a1cb31339ed8 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Nov 2011 06:19:00 +0000 Subject: [PATCH 109/147] Split off 3D Cursor settings from "View" panel in 3D View This means that you don't need to have the view panel open all the time, reducing the amount of scrolling required just to be able to precisely position the 3D cursor at specific coordinates while changing some other settings. While most of the settings in the View panel are less likely to be frequently changed, the 3D cursor can in some workflows end up needing to be accessed quite frequently. --- release/scripts/startup/bl_ui/space_view3d.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 3f5b7b86e89..7041e3f8c3d 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2063,7 +2063,22 @@ class VIEW3D_PT_view3d_properties(Panel): subcol.label(text="Local Camera:") subcol.prop(view, "camera", text="") - layout.column().prop(view, "cursor_location") + +class VIEW3D_PT_view3d_cursor(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_label = "3D Cursor" + + @classmethod + def poll(cls, context): + view = context.space_data + return (view) + + def draw(self, context): + layout = self.layout + + view = context.space_data + layout.column().prop(view, "cursor_location", text="Location") class VIEW3D_PT_view3d_name(Panel): From d738c8df1f9b608438162f2f9c24c4fd29dda3f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 12:11:50 +0000 Subject: [PATCH 110/147] use BLI math functions for kdopbvh (no functional change) --- source/blender/blenlib/BLI_kdopbvh.h | 12 ++++---- source/blender/blenlib/intern/BLI_kdopbvh.c | 34 ++++++++++----------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 4daa27a5c72..8ead7bf5f17 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -85,11 +85,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); /* construct: first insert points, then call balance */ -int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints); +int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints); void BLI_bvhtree_balance(BVHTree *tree); /* update: first update points/nodes, then call update_tree to refit the bounding volumes */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints); +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints); void BLI_bvhtree_update_tree(BVHTree *tree); /* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */ @@ -98,14 +98,14 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int float BLI_bvhtree_getepsilon(BVHTree *tree); /* find nearest node to the given coordinates (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ -int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata); +int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata); -int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); +int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); -float BLI_bvhtree_bb_raycast(float *bv, float *light_start, float *light_end, float *pos); +float BLI_bvhtree_bb_raycast(float *bv, const float light_start[3], const float light_end[3], float pos[3]); /* range query */ -int BLI_bvhtree_range_query(BVHTree *tree, const float *co, float radius, BVHTree_RangeQuery callback, void *userdata); +int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); #ifdef __cplusplus } diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index d1734151b4a..f01777bdce1 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -387,7 +387,7 @@ static void build_skip_links(BVHTree *tree, BVHNode *node, BVHNode *left, BVHNod /* * BVHTree bounding volumes functions */ -static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoints, int moving) +static void create_kdop_hull(BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving) { float newminmax; float *bv = node->bv; @@ -973,7 +973,7 @@ void BLI_bvhtree_balance(BVHTree *tree) //bvhtree_info(tree); } -int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints) +int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) { int i; BVHNode *node = NULL; @@ -1005,7 +1005,7 @@ int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints) // call before BLI_bvhtree_update_tree() -int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_moving, int numpoints) +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints) { int i; BVHNode *node= NULL; @@ -1194,7 +1194,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int } //Determines the nearest point of the given node BV. Returns the squared distance to that point. -static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest) +static float calc_nearest_point(const float proj[3], BVHNode *node, float *nearest) { int i; const float *bv = node->bv; @@ -1212,7 +1212,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest /* //nearest on a general hull - VECCOPY(nearest, data->co); + copy_v3_v3(nearest, data->co); for(i = data->tree->start_axis; i != data->tree->stop_axis; i++, bv+=2) { float proj = dot_v3v3( nearest, KDOP_AXES[i]); @@ -1221,11 +1221,11 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest if(dl > 0) { - VECADDFAC(nearest, nearest, KDOP_AXES[i], dl); + madd_v3_v3fl(nearest, KDOP_AXES[i], dl); } else if(du < 0) { - VECADDFAC(nearest, nearest, KDOP_AXES[i], du); + madd_v3_v3fl(nearest, KDOP_AXES[i], du); } } */ @@ -1377,7 +1377,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node) #endif -int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata) +int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata) { int i; @@ -1510,7 +1510,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node) { data->hit.index = node->index; data->hit.dist = dist; - VECADDFAC(data->hit.co, data->ray.origin, data->ray.direction, dist); + madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist); } } else @@ -1553,7 +1553,7 @@ static void iterative_raycast(BVHRayCastData *data, BVHNode *node) { data->hit.index = node->index; data->hit.dist = dist; - VECADDFAC(data->hit.co, data->ray.origin, data->ray.direction, dist); + madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist); } node = node->skip[1]; @@ -1566,7 +1566,7 @@ static void iterative_raycast(BVHRayCastData *data, BVHNode *node) } #endif -int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata) +int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata) { int i; BVHRayCastData data; @@ -1577,8 +1577,8 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float data.callback = callback; data.userdata = userdata; - VECCOPY(data.ray.origin, co); - VECCOPY(data.ray.direction, dir); + copy_v3_v3(data.ray.origin, co); + copy_v3_v3(data.ray.direction, dir); data.ray.radius = radius; normalize_v3(data.ray.direction); @@ -1620,7 +1620,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float return data.hit.index; } -float BLI_bvhtree_bb_raycast(float *bv, float *light_start, float *light_end, float *pos) +float BLI_bvhtree_bb_raycast(float *bv, const float light_start[3], const float light_end[3], float pos[3]) { BVHRayCastData data; float dist = 0.0; @@ -1639,13 +1639,13 @@ float BLI_bvhtree_bb_raycast(float *bv, float *light_start, float *light_end, fl data.ray.origin[2] = light_start[2]; normalize_v3(data.ray.direction); - VECCOPY(data.ray_dot_axis, data.ray.direction); + copy_v3_v3(data.ray_dot_axis, data.ray.direction); dist = ray_nearest_hit(&data, bv); if(dist > 0.0f) { - VECADDFAC(pos, light_start, data.ray.direction, dist); + madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist); } return dist; @@ -1706,7 +1706,7 @@ static void dfs_range_query(RangeQueryData *data, BVHNode *node) } } -int BLI_bvhtree_range_query(BVHTree *tree, const float *co, float radius, BVHTree_RangeQuery callback, void *userdata) +int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata) { BVHNode * root = tree->nodes[tree->totleaf]; From e03fdd81122edba048882f07bfef09a1764e1682 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 Nov 2011 12:12:14 +0000 Subject: [PATCH 111/147] Second attempt at getting rid of bsystem_time() Hopefully this fixes Collada. Can't really compile that to check here... --- source/blender/blenkernel/BKE_scene.h | 2 +- source/blender/blenkernel/intern/particle.c | 2 +- source/blender/blenkernel/intern/pointcache.c | 4 ++-- source/blender/blenkernel/intern/scene.c | 14 +++++--------- source/blender/collada/AnimationExporter.cpp | 4 ++-- source/blender/collada/AnimationExporter.h | 1 + 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index a6bd90c4fd2..ad394f9fb1a 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -86,7 +86,7 @@ void scene_select_base(struct Scene *sce, struct Base *selbase); int scene_check_setscene(struct Main *bmain, struct Scene *sce); float BKE_curframe(struct Scene *scene); -float BKE_nextframe(struct Scene *scene); +float BKE_frame_to_ctime(struct Scene *scene, const float frame); void scene_update_tagged(struct Main *bmain, struct Scene *sce); void scene_clear_tagged(struct Main *bmain, struct Scene *sce); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index f8d281c2951..76d08f6fff2 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3427,7 +3427,7 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n psys->totpart=0; psys->flag = PSYS_ENABLED|PSYS_CURRENT; - psys->cfra = BKE_nextframe(scene); + psys->cfra = BKE_frame_to_ctime(scene, CFRA + 1); DAG_scene_sort(G.main, scene); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7a8162391d5..ba5b98ee3cd 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2148,8 +2148,8 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra if(timescale) { time= BKE_curframe(scene); - nexttime= BKE_nextframe(scene); - + nexttime= BKE_frame_to_ctime(scene, CFRA+1); + *timescale= MAX2(nexttime - time, 0.0f); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 2f24b7e735d..66d29b02263 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -914,20 +914,16 @@ int scene_check_setscene(Main *bmain, Scene *sce) */ float BKE_curframe(Scene *scene) { - float ctime = scene->r.cfra; - ctime += scene->r.subframe; - ctime *= scene->r.framelen; - - return ctime; + return BKE_frame_to_ctime(scene, scene->r.cfra); } -/* Similar to BKE_curframe(), but is used by physics sims to get "next time", which is defined as cfra+1 */ -float BKE_nextframe(Scene *scene) +/* This function is used to obtain arbitrary fractional frames */ +float BKE_frame_to_ctime(Scene *scene, const float frame) { - float ctime = (float)(scene->r.cfra + 1); + float ctime = frame; ctime += scene->r.subframe; ctime *= scene->r.framelen; - + return ctime; } diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp index b115a96cfa1..7bd70e9f289 100644 --- a/source/blender/collada/AnimationExporter.cpp +++ b/source/blender/collada/AnimationExporter.cpp @@ -759,7 +759,7 @@ std::string AnimationExporter::create_4x4_source(std::vector &frames , Ob for (it = frames.begin(); it != frames.end(); it++) { float mat[4][4], ipar[4][4]; - float ctime = bsystem_time(scene, ob_arm, *it, 0.0f); + float ctime = BKE_frame_to_ctime(scene, *it); BKE_animsys_evaluate_animdata(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM); where_is_pose_bone(scene, ob_arm, pchan, ctime, 1); @@ -1265,7 +1265,7 @@ void AnimationExporter::sample_animation(float *v, std::vector &frames, i for (it = frames.begin(); it != frames.end(); it++) { float mat[4][4], ipar[4][4]; - float ctime = bsystem_time(scene, ob_arm, *it, 0.0f); + float ctime = BKE_frame_to_ctime(scene, *it); BKE_animsys_evaluate_animdata(scene , &ob_arm->id, ob_arm->adt, ctime, ADT_RECALC_ANIM); diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h index 7f6c99b108f..c3a5c7a5383 100644 --- a/source/blender/collada/AnimationExporter.h +++ b/source/blender/collada/AnimationExporter.h @@ -38,6 +38,7 @@ extern "C" #include "BKE_DerivedMesh.h" #include "BKE_fcurve.h" #include "BKE_animsys.h" +#include "BKE_scene.h" #ifdef NAN_BUILDINFO extern char build_rev[]; #endif From b82dee0cb42e1796b3d1f9d6e9c2d4bd5b94b0de Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 14:00:55 +0000 Subject: [PATCH 112/147] replace macros with bli math functions for particles code --- source/blender/blenkernel/BKE_object.h | 2 +- source/blender/blenkernel/BKE_particle.h | 8 +- source/blender/blenkernel/intern/particle.c | 197 +++++++++--------- .../blenkernel/intern/particle_system.c | 18 +- source/blender/editors/include/ED_particle.h | 2 +- .../blender/editors/physics/particle_edit.c | 182 ++++++++-------- .../blender/editors/physics/particle_object.c | 4 +- source/blender/modifiers/intern/MOD_build.c | 2 +- 8 files changed, 210 insertions(+), 205 deletions(-) diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 85a986d3460..9ccdd080158 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -106,7 +106,7 @@ struct BoundBox *object_get_boundbox(struct Object *ob); void object_get_dimensions(struct Object *ob, float *value); void object_set_dimensions(struct Object *ob, const float *value); void object_boundbox_flag(struct Object *ob, int flag, int set); -void minmax_object(struct Object *ob, float *min, float *max); +void minmax_object(struct Object *ob, float min[3], float max[3]); int minmax_object_duplis(struct Scene *scene, struct Object *ob, float *min, float *max); void solve_tracking (struct Object *ob, float targetmat[][4]); int ray_hit_boundbox(struct BoundBox *bb, float ray_start[3], float ray_normal[3]); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index c4284d2cf0a..c66e49f2906 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -254,8 +254,8 @@ void psys_render_restore(struct Object *ob, struct ParticleSystem *psys); int psys_render_simplify_distribution(struct ParticleThreadContext *ctx, int tot); int psys_render_simplify_params(struct ParticleSystem *psys, struct ChildParticle *cpa, float *params); -void psys_interpolate_uvs(struct MTFace *tface, int quad, float *uv, float *uvco); -void psys_interpolate_mcol(struct MCol *mcol, int quad, float *uv, struct MCol *mc); +void psys_interpolate_uvs(const struct MTFace *tface, int quad, const float w[4], float uvco[2]); +void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], struct MCol *mc); void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time); @@ -335,12 +335,12 @@ void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *r /* BLI_bvhtree_ray_cast callback */ void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); -void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]); /* particle_system.c */ void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys); -int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node); +int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node); void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 76d08f6fff2..3b6fc09ad4f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -619,13 +619,13 @@ static float psys_render_viewport_falloff(double rate, float dist, float width) return pow(rate, dist/width); } -static float psys_render_projected_area(ParticleSystem *psys, float *center, float area, double vprate, float *viewport) +static float psys_render_projected_area(ParticleSystem *psys, const float center[3], float area, double vprate, float *viewport) { ParticleRenderData *data= psys->renderdata; float co[4], view[3], ortho1[3], ortho2[3], w, dx, dy, radius; /* transform to view space */ - VECCOPY(co, center); + copy_v3_v3(co, center); co[3]= 1.0f; mul_m4_v4(data->viewmat, co); @@ -829,17 +829,17 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) b= (origindex)? origindex[a]: a; if(b != -1) { - VECCOPY(co1, mvert[mf->v1].co); - VECCOPY(co2, mvert[mf->v2].co); - VECCOPY(co3, mvert[mf->v3].co); + copy_v3_v3(co1, mvert[mf->v1].co); + copy_v3_v3(co2, mvert[mf->v2].co); + copy_v3_v3(co3, mvert[mf->v3].co); - VECADD(facecenter[b], facecenter[b], co1); - VECADD(facecenter[b], facecenter[b], co2); - VECADD(facecenter[b], facecenter[b], co3); + add_v3_v3(facecenter[b], co1); + add_v3_v3(facecenter[b], co2); + add_v3_v3(facecenter[b], co3); if(mf->v4) { - VECCOPY(co4, mvert[mf->v4].co); - VECADD(facecenter[b], facecenter[b], co4); + copy_v3_v3(co4, mvert[mf->v4].co); + add_v3_v3(facecenter[b], co4); facearea[b] += area_quad_v3(co1, co2, co3, co4); facetotvert[b] += 4; } @@ -998,7 +998,7 @@ int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float /************************************************/ /* Interpolation */ /************************************************/ -static float interpolate_particle_value(float v1, float v2, float v3, float v4, float *w, int four) +static float interpolate_particle_value(float v1, float v2, float v3, float v4, const float w[4], int four) { float value; @@ -1029,12 +1029,12 @@ void psys_interpolate_particle(short type, ParticleKey keys[4], float dt, Partic if(dt>0.999f){ key_curve_position_weights(dt-0.001f, t, type); interp_v3_v3v3v3v3(temp, keys[0].co, keys[1].co, keys[2].co, keys[3].co, t); - VECSUB(result->vel, result->co, temp); + sub_v3_v3v3(result->vel, result->co, temp); } else{ key_curve_position_weights(dt+0.001f, t, type); interp_v3_v3v3v3v3(temp, keys[0].co, keys[1].co, keys[2].co, keys[3].co, t); - VECSUB(result->vel, temp, result->co); + sub_v3_v3v3(result->vel, temp, result->co); } } } @@ -1180,21 +1180,21 @@ static void init_particle_interpolation(Object *ob, ParticleSystem *psys, Partic } static void edit_to_particle(ParticleKey *key, PTCacheEditKey *ekey) { - VECCOPY(key->co, ekey->co); + copy_v3_v3(key->co, ekey->co); if(ekey->vel) { - VECCOPY(key->vel, ekey->vel); + copy_v3_v3(key->vel, ekey->vel); } key->time = *(ekey->time); } static void hair_to_particle(ParticleKey *key, HairKey *hkey) { - VECCOPY(key->co, hkey->co); + copy_v3_v3(key->co, hkey->co); key->time = hkey->time; } static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey) { - VECCOPY(key->co, mvert->co); + copy_v3_v3(key->co, mvert->co); key->time = hkey->time; } @@ -1473,13 +1473,13 @@ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*or } } else { - VECCOPY(orco, vec); + copy_v3_v3(orco, vec); if(ornor && nor) - VECCOPY(ornor, nor); + copy_v3_v3(ornor, nor); } } } -void psys_interpolate_uvs(MTFace *tface, int quad, float *w, float *uvco) +void psys_interpolate_uvs(const MTFace *tface, int quad, const float w[4], float uvco[2]) { float v10= tface->uv[0][0]; float v11= tface->uv[0][1]; @@ -1502,7 +1502,7 @@ void psys_interpolate_uvs(MTFace *tface, int quad, float *w, float *uvco) } } -void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc) +void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *mc) { char *cp, *cp1, *cp2, *cp3, *cp4; @@ -1527,7 +1527,7 @@ void psys_interpolate_mcol(MCol *mcol, int quad, float *w, MCol *mc) } } -static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, float *fw, float *values) +static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int index, const float fw[4], const float *values) { if(values==0 || index==-1) return 0.0; @@ -1543,18 +1543,18 @@ static float psys_interpolate_value_from_verts(DerivedMesh *dm, short from, int } } - return 0.0; + return 0.0f; } /* conversion of pa->fw to origspace layer coordinates */ -static void psys_w_to_origspace(float *w, float *uv) +static void psys_w_to_origspace(const float w[4], float uv[2]) { uv[0]= w[1] + w[2]; uv[1]= w[2] + w[3]; } /* conversion of pa->fw to weights in face from origspace */ -static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, float *w, float *neww) +static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4], float neww[4]) { float v[4][3], co[3]; @@ -1567,17 +1567,17 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, float *w, float if(quad) { v[3][0]= osface->uv[3][0]; v[3][1]= osface->uv[3][1]; v[3][2]= 0.0f; - interp_weights_poly_v3( neww,v, 4, co); + interp_weights_poly_v3(neww, v, 4, co); } else { - interp_weights_poly_v3( neww,v, 3, co); + interp_weights_poly_v3(neww, v, 3, co); neww[3]= 0.0f; } } /* find the derived mesh face for a particle, set the mf passed. this is slow * and can be optimized but only for many lookups. returns the face index. */ -int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float *fw, struct LinkNode *node) +int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, const float fw[4], struct LinkNode *node) { Mesh *me= (Mesh*)ob->data; MFace *mface; @@ -1644,7 +1644,7 @@ int psys_particle_dm_face_lookup(Object *ob, DerivedMesh *dm, int index, float * return DMCACHE_NOTFOUND; } -static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float UNUSED(foffset), int *mapindex, float *mapfw) +static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float UNUSED(foffset), int *mapindex, float mapfw[4]) { if(index < 0) return 0; @@ -1704,7 +1704,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, float *fw, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1732,7 +1732,7 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache } if(orco) - VECCOPY(orco, orcodata[mapindex]) + copy_v3_v3(orco, orcodata[mapindex]); if(ornor) { dm->getVertNo(dm,mapindex,nor); @@ -1759,11 +1759,11 @@ void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache if(from==PART_FROM_VOLUME) { psys_interpolate_face(mvert,mface,mtface,orcodata,mapfw,vec,tmpnor,utan,vtan,orco,ornor); if(nor) - VECCOPY(nor,tmpnor); + copy_v3_v3(nor,tmpnor); normalize_v3(tmpnor); mul_v3_fl(tmpnor,-foffset); - VECADD(vec,vec,tmpnor); + add_v3_v3(vec, tmpnor); } else psys_interpolate_face(mvert,mface,mtface,orcodata,mapfw,vec,nor,utan,vtan,orco,ornor); @@ -1805,22 +1805,22 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float * /* TODO */ float zerovec[3]={0.0f,0.0f,0.0f}; if(vec){ - VECCOPY(vec,zerovec); + copy_v3_v3(vec,zerovec); } if(nor){ - VECCOPY(nor,zerovec); + copy_v3_v3(nor,zerovec); } if(utan){ - VECCOPY(utan,zerovec); + copy_v3_v3(utan,zerovec); } if(vtan){ - VECCOPY(vtan,zerovec); + copy_v3_v3(vtan,zerovec); } if(orco){ - VECCOPY(orco,zerovec); + copy_v3_v3(orco,zerovec); } if(ornor){ - VECCOPY(ornor,zerovec); + copy_v3_v3(ornor,zerovec); } } /************************************************/ @@ -1990,7 +1990,7 @@ static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float } else if(inp_z > 0.0f){ mul_v3_v3fl(state_co, z_vec, (float)sin((float)M_PI/3.f)); - VECADDFAC(state_co,state_co,y_vec,-0.5f); + madd_v3_v3fl(state_co, y_vec, -0.5f); mul_v3_fl(y_vec, -amplitude * (float)cos(t + (float)M_PI/3.f)); mul_v3_fl(z_vec, amplitude/2.f * (float)cos(2.f*t + (float)M_PI/6.f)); @@ -2088,7 +2088,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) data = eff->guide_data + p; - VECSUB(efd.vec_to_point, state.co, eff->guide_loc); + sub_v3_v3v3(efd.vec_to_point, state.co, eff->guide_loc); copy_v3_v3(efd.nor, eff->guide_dir); efd.distance = len_v3(efd.vec_to_point); @@ -2142,7 +2142,7 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time) normalize_v3(guidedir); - VECCOPY(vec_to_point, data->vec_to_point); + copy_v3_v3(vec_to_point, data->vec_to_point); if(guidetime != 0.0f) { /* curve direction */ @@ -2167,16 +2167,16 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time) } } par.co[0] = par.co[1] = par.co[2] = 0.0f; - VECCOPY(key.co, vec_to_point); + copy_v3_v3(key.co, vec_to_point); do_kink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, 0.f, pd->kink, pd->kink_axis, 0, 0); do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f); - VECCOPY(vec_to_point, key.co); + copy_v3_v3(vec_to_point, key.co); - VECADD(vec_to_point, vec_to_point, guidevec); + add_v3_v3(vec_to_point, guidevec); - //VECSUB(pa_loc,pa_loc,pa_zero); - VECADDFAC(effect, effect, vec_to_point, data->strength); - VECADDFAC(veffect, veffect, guidedir, data->strength); + //sub_v3_v3v3(pa_loc,pa_loc,pa_zero); + madd_v3_v3fl(effect, vec_to_point, data->strength); + madd_v3_v3fl(veffect, guidedir, data->strength); totstrength += data->strength; if(pd->flag & PFIELD_GUIDE_PATH_WEIGHT) @@ -2187,12 +2187,12 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time) if(totstrength > 1.0f) mul_v3_fl(effect, 1.0f / totstrength); CLAMP(totstrength, 0.0f, 1.0f); - //VECADD(effect,effect,pa_zero); + //add_v3_v3(effect,pa_zero); interp_v3_v3v3(state->co, state->co, effect, totstrength); normalize_v3(veffect); mul_v3_fl(veffect, len_v3(state->vel)); - VECCOPY(state->vel, veffect); + copy_v3_v3(state->vel, veffect); return 1; } return 0; @@ -2205,15 +2205,15 @@ static void do_rough(float *loc, float mat[4][4], float t, float fac, float size if(thres != 0.0f) if((float)fabs((float)(-1.5f+loc[0]+loc[1]+loc[2]))<1.5f*thres) return; - VECCOPY(rco,loc); + copy_v3_v3(rco,loc); mul_v3_fl(rco,t); rough[0]=-1.0f+2.0f*BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2,0,2); rough[1]=-1.0f+2.0f*BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2,0,2); rough[2]=-1.0f+2.0f*BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2,0,2); - VECADDFAC(state->co,state->co,mat[0],fac*rough[0]); - VECADDFAC(state->co,state->co,mat[1],fac*rough[1]); - VECADDFAC(state->co,state->co,mat[2],fac*rough[2]); + madd_v3_v3fl(state->co, mat[0], fac * rough[0]); + madd_v3_v3fl(state->co, mat[1], fac * rough[1]); + madd_v3_v3fl(state->co, mat[2], fac * rough[2]); } static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float shape, ParticleKey *state) { @@ -2226,8 +2226,8 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float rough[1]=-1.0f+2.0f*rough[1]; mul_v2_fl(rough,roughfac); - VECADDFAC(state->co,state->co,mat[0],rough[0]); - VECADDFAC(state->co,state->co,mat[1],rough[1]); + madd_v3_v3fl(state->co, mat[0], rough[0]); + madd_v3_v3fl(state->co, mat[1], rough[1]); } static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheKey *ca, int k, int steps, float *UNUSED(rootco), float effector, float UNUSED(dfra), float UNUSED(cfra), float *length, float *vec) { @@ -2239,9 +2239,9 @@ static void do_path_effectors(ParticleSimulationData *sim, int i, ParticleCacheK if(sim->psys->flag & PSYS_HAIR_DYNAMICS) return; - VECCOPY(eff_key.co,(ca-1)->co); - VECCOPY(eff_key.vel,(ca-1)->vel); - QUATCOPY(eff_key.rot,(ca-1)->rot); + copy_v3_v3(eff_key.co,(ca-1)->co); + copy_v3_v3(eff_key.vel,(ca-1)->vel); + copy_qt_qt(eff_key.rot,(ca-1)->rot); pd_point_from_particle(sim, sim->psys->particles+i, &eff_key, &epoint); pdDoEffectors(sim->psys->effectors, sim->colliders, sim->psys->part->effector_weights, &epoint, force, NULL); @@ -2264,7 +2264,7 @@ static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *st { if(*cur_length + length > max_length){ mul_v3_fl(dvec, (max_length - *cur_length) / length); - VECADD(state->co, (state - 1)->co, dvec); + add_v3_v3v3(state->co, (state - 1)->co, dvec); keys->steps = k; /* something over the maximum step value */ return k=100000; @@ -2364,8 +2364,9 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa interp_v3_v3v3(vnor, nstrand, surfnor, blend); normalize_v3(vnor); } - else - VECCOPY(vnor, nor) + else { + copy_v3_v3(vnor, nor); + } if(ma->strand_surfnor > 0.0f) { if(ma->strand_surfnor > surfdist) { @@ -2375,7 +2376,7 @@ static void get_strand_normal(Material *ma, float *surfnor, float surfdist, floa } } - VECCOPY(nor, vnor); + copy_v3_v3(nor, vnor); } static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float cfra, int editupdate) @@ -2716,7 +2717,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle } if(ctx->ma && (part->draw_col == PART_DRAW_COL_MAT)) { - VECCOPY(child->col, &ctx->ma->r) + copy_v3_v3(child->col, &ctx->ma->r); get_strand_normal(ctx->ma, ornor, cur_length, child->vel); } } @@ -2899,7 +2900,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) psys->lattice = psys_get_lattice(sim); ma= give_current_material(sim->ob, psys->part->omat); if(ma && (psys->part->draw_col == PART_DRAW_COL_MAT)) - VECCOPY(col, &ma->r) + copy_v3_v3(col, &ma->r); if((psys->flag & PSYS_GLOBAL_HAIR)==0) { if((psys->part->flag & PART_CHILD_EFFECT)==0) @@ -2933,9 +2934,9 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) /* hairmat is needed for for non-hair particle too so we get proper rotations */ psys_mat_hair_to_global(sim->ob, psmd->dm, psys->part->from, pa, hairmat); - VECCOPY(rotmat[0], hairmat[2]); - VECCOPY(rotmat[1], hairmat[1]); - VECCOPY(rotmat[2], hairmat[0]); + copy_v3_v3(rotmat[0], hairmat[2]); + copy_v3_v3(rotmat[1], hairmat[1]); + copy_v3_v3(rotmat[2], hairmat[0]); if(part->draw & PART_ABS_PATH_TIME) { birthtime = MAX2(pind.birthtime, part->path_start); @@ -3189,7 +3190,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf else { if((ekey + (pind.ekey[0] - point->keys))->flag & PEK_SELECT){ if((ekey + (pind.ekey[1] - point->keys))->flag & PEK_SELECT){ - VECCOPY(ca->col, sel_col); + copy_v3_v3(ca->col, sel_col); } else{ keytime = (t - (*pind.ekey[0]->time))/((*pind.ekey[1]->time) - (*pind.ekey[0]->time)); @@ -3202,7 +3203,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf interp_v3_v3v3(ca->col, nosel_col, sel_col, keytime); } else{ - VECCOPY(ca->col, nosel_col); + copy_v3_v3(ca->col, nosel_col); } } } @@ -3253,9 +3254,9 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time){ } } void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time){ - if(loc) VECCOPY(loc,key->co); - if(vel) VECCOPY(vel,key->vel); - if(rot) QUATCOPY(rot,key->rot); + if(loc) copy_v3_v3(loc,key->co); + if(vel) copy_v3_v3(vel,key->vel); + if(rot) copy_qt_qt(rot,key->rot); if(time) *time=key->time; } /*-------changing particle keys from space to another-------*/ @@ -3263,13 +3264,13 @@ void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, flo static void key_from_object(Object *ob, ParticleKey *key){ float q[4]; - VECADD(key->vel,key->vel,key->co); + add_v3_v3(key->vel, key->co); mul_m4_v3(ob->obmat,key->co); mul_m4_v3(ob->obmat,key->vel); mat4_to_quat(q,ob->obmat); - VECSUB(key->vel,key->vel,key->co); + sub_v3_v3v3(key->vel,key->vel,key->co); mul_qt_qtqt(key->rot,q,key->rot); } #endif @@ -3330,9 +3331,9 @@ static void psys_face_mat(Object *ob, DerivedMesh *dm, ParticleData *pa, float m osface=dm->getFaceData(dm,i,CD_ORIGSPACE); if(orco && (orcodata=dm->getVertDataArray(dm, CD_ORCO))) { - VECCOPY(v[0], orcodata[mface->v1]); - VECCOPY(v[1], orcodata[mface->v2]); - VECCOPY(v[2], orcodata[mface->v3]); + copy_v3_v3(v[0], orcodata[mface->v1]); + copy_v3_v3(v[1], orcodata[mface->v2]); + copy_v3_v3(v[2], orcodata[mface->v3]); /* ugly hack to use non-transformed orcos, since only those * give symmetric results for mirroring in particle mode */ @@ -3354,7 +3355,7 @@ void psys_mat_hair_to_object(Object *UNUSED(ob), DerivedMesh *dm, short from, Pa psys_face_mat(0, dm, pa, hairmat, 0); psys_particle_on_dm(dm, from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, vec, 0, 0, 0, 0, 0); - VECCOPY(hairmat[3],vec); + copy_v3_v3(hairmat[3],vec); } void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData *pa, float hairmat[][4]) @@ -3367,7 +3368,7 @@ void psys_mat_hair_to_orco(Object *ob, DerivedMesh *dm, short from, ParticleData /* see psys_face_mat for why this function is called */ if(DM_get_vert_data_layer(dm, CD_ORIGINDEX)) transform_mesh_orco_verts(ob->data, &orco, 1, 1); - VECCOPY(hairmat[3],orco); + copy_v3_v3(hairmat[3],orco); } void psys_vec_rot_to_face(DerivedMesh *dm, ParticleData *pa, float *vec) @@ -3658,7 +3659,7 @@ void make_local_particlesettings(ParticleSettings *part) /* Textures */ /************************************************/ -static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, float *fuv, char *name, float *texco) +static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, const float fuv[4], char *name, float *texco) { MFace *mf; MTFace *tf; @@ -3702,7 +3703,7 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, fl #define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) if(event & type) { if(pvalue < 0.f) pvalue = 1.f+pvalue; CLAMP(pvalue, 0.0f, 1.0f); } #define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) if(event & type) { CLAMP(pvalue, -1.0f, 1.0f); } -static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, float *fw, float *orco, ParticleTexture *ptex, int event, float cfra) +static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra) { MTex *mtex, **mtexp = part->mtex; int m; @@ -4071,7 +4072,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * psys_particle_on_emitter(psmd,cpa_from,cpa_num,DMCACHE_ISCHILD,cpa->fuv,foffset,co,0,0,0,orco,0); /* we need to save the actual root position of the child for positioning it accurately to the surface of the emitter */ - //VECCOPY(cpa_1st,co); + //copy_v3_v3(cpa_1st,co); //mul_m4_v3(ob->obmat,cpa_1st); @@ -4142,7 +4143,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * w++; } /* apply offset for correct positioning */ - //VECADD(state->co,state->co,cpa_1st); + //add_v3_v3(state->co, cpa_1st); } else{ /* offset the child from the parent position */ @@ -4165,13 +4166,13 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey * if(t>=0.001f){ tstate.time=t-0.001f; psys_get_particle_on_path(sim,p,&tstate,0); - VECSUB(state->vel,state->co,tstate.co); + sub_v3_v3v3(state->vel,state->co,tstate.co); normalize_v3(state->vel); } else{ tstate.time=t+0.001f; psys_get_particle_on_path(sim,p,&tstate,0); - VECSUB(state->vel,tstate.co,state->co); + sub_v3_v3v3(state->vel,tstate.co,state->co); normalize_v3(state->vel); } @@ -4422,9 +4423,9 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa cross_v3_v3v3(nor, vec, side); unit_m4(mat); - VECCOPY(mat[0], vec); - VECCOPY(mat[1], side); - VECCOPY(mat[2], nor); + copy_v3_v3(mat[0], vec); + copy_v3_v3(mat[1], side); + copy_v3_v3(mat[2], nor); } else { quat_to_mat4(mat, pa->state.rot); @@ -4470,12 +4471,12 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] normalize_v3_v3(temp, bb->vel); - VECSUB(zvec, bb->ob->obmat[3], bb->vec); + sub_v3_v3v3(zvec, bb->ob->obmat[3], bb->vec); if(bb->lock) { float fac = -dot_v3v3(zvec, temp); - VECADDFAC(zvec, zvec, temp, fac); + madd_v3_v3fl(zvec, temp, fac); } normalize_v3(zvec); @@ -4485,7 +4486,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] cross_v3_v3v3(yvec,zvec,xvec); } else { - VECSUB(zvec, bb->ob->obmat[3], bb->vec); + sub_v3_v3v3(zvec, bb->ob->obmat[3], bb->vec); if(bb->lock) zvec[bb->align] = 0.0f; normalize_v3(zvec); @@ -4499,22 +4500,22 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] cross_v3_v3v3(yvec,zvec,xvec); } - VECCOPY(tvec, xvec); - VECCOPY(tvec2, yvec); + copy_v3_v3(tvec, xvec); + copy_v3_v3(tvec2, yvec); mul_v3_fl(xvec, cos(bb->tilt * (float)M_PI)); mul_v3_fl(tvec2, sin(bb->tilt * (float)M_PI)); - VECADD(xvec, xvec, tvec2); + add_v3_v3(xvec, tvec2); mul_v3_fl(yvec, cos(bb->tilt * (float)M_PI)); mul_v3_fl(tvec, -sin(bb->tilt * (float)M_PI)); - VECADD(yvec, yvec, tvec); + add_v3_v3(yvec, tvec); mul_v3_fl(xvec, bb->size[0]); mul_v3_fl(yvec, bb->size[1]); - VECADDFAC(center, bb->vec, xvec, bb->offset[0]); - VECADDFAC(center, center, yvec, bb->offset[1]); + madd_v3_v3v3fl(center, bb->vec, xvec, bb->offset[0]); + madd_v3_v3fl(center, yvec, bb->offset[1]); } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index ec058b23050..f92fb4444cc 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -454,7 +454,7 @@ static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys) max[2]=MAX2(max[2],mv->co[2]); } - VECSUB(delta,max,min); + sub_v3_v3v3(delta, max, min); /* determine major axis */ axis = (delta[0]>=delta[1]) ? 0 : ((delta[1]>=delta[2]) ? 1 : 2); @@ -1588,15 +1588,15 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P if(part->tanfac!=0.0f){ //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f; float phase=0.0f; - mul_v3_fl(vtan,-(float)cos((float)M_PI*(part->tanphase+phase))); - fac=-(float)sin((float)M_PI*(part->tanphase+phase)); - VECADDFAC(vtan,vtan,utan,fac); + mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase))); + fac= -sinf((float)M_PI*(part->tanphase+phase)); + madd_v3_v3fl(vtan, utan, fac); mul_mat3_m4_v3(ob->obmat,vtan); - VECCOPY(utan,nor); + copy_v3_v3(utan, nor); mul_v3_fl(utan,dot_v3v3(vtan,nor)); - VECSUB(vtan,vtan,utan); + sub_v3_v3(vtan, utan); normalize_v3(vtan); } @@ -2606,7 +2606,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa if(do_guides(sim->psys->effectors, &tkey, p, time)) { VECCOPY(pa->state.co,tkey.co); /* guides don't produce valid velocity */ - VECSUB(pa->state.vel,tkey.co,pa->prev_state.co); + sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co); mul_v3_fl(pa->state.vel,1.0f/dtime); pa->state.time=tkey.time; } @@ -3471,7 +3471,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) /* create fake root before actual root to resist bending */ if(k==0) { float temp[3]; - VECSUB(temp, key->co, (key+1)->co); + sub_v3_v3v3(temp, key->co, (key+1)->co); VECCOPY(mvert->co, key->co); VECADD(mvert->co, mvert->co, temp); mul_m4_v3(hairmat, mvert->co); @@ -3589,7 +3589,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)){ mul_m4_v3(ob->imat, key->co); if(pa->totkey) { - VECSUB(key->co, key->co, root->co); + sub_v3_v3(key->co, root->co); psys_vec_rot_to_face(sim->psmd->dm, pa, key->co); } diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h index d1da9f308fb..3035aa44735 100644 --- a/source/blender/editors/include/ED_particle.h +++ b/source/blender/editors/include/ED_particle.h @@ -51,7 +51,7 @@ int PE_start_edit(struct PTCacheEdit *edit); struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob); struct PTCacheEdit *PE_create_current(struct Scene *scene, struct Object *ob); void PE_current_changed(struct Scene *scene, struct Object *ob); -int PE_minmax(struct Scene *scene, float *min, float *max); +int PE_minmax(struct Scene *scene, float min[3], float max[3]); struct ParticleEditSettings *PE_settings(struct Scene *scene); /* update calls */ diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index b0a17c6f9a9..52e6d4f6ab8 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -390,7 +390,7 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /*************************** selection utilities *******************************/ -static int key_test_depth(PEData *data, float co[3]) +static int key_test_depth(PEData *data, const float co[3]) { View3D *v3d= data->vc.v3d; double ux, uy, uz; @@ -407,7 +407,7 @@ static int key_test_depth(PEData *data, float co[3]) return 0; gluProject(co[0],co[1],co[2], data->mats.modelview, data->mats.projection, - (GLint *)data->mats.viewport, &ux, &uy, &uz); + (GLint *)data->mats.viewport, &ux, &uy, &uz); x=wco[0]; y=wco[1]; @@ -434,7 +434,7 @@ static int key_test_depth(PEData *data, float co[3]) return 1; } -static int key_inside_circle(PEData *data, float rad, float co[3], float *distance) +static int key_inside_circle(PEData *data, float rad, const float co[3], float *distance) { float dx, dy, dist; int sco[2]; @@ -461,7 +461,7 @@ static int key_inside_circle(PEData *data, float rad, float co[3], float *distan return 0; } -static int key_inside_rect(PEData *data, float co[3]) +static int key_inside_rect(PEData *data, const float co[3]) { int sco[2]; @@ -477,7 +477,7 @@ static int key_inside_rect(PEData *data, float co[3]) return 0; } -static int key_inside_test(PEData *data, float co[3]) +static int key_inside_test(PEData *data, const float co[3]) { if(data->mval) return key_inside_circle(data, data->rad, co, NULL); @@ -719,7 +719,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co, NULL); } @@ -733,7 +733,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; psys_mat_hair_to_orco(ob, psmd->dm, psys->part->from, pa, mat); - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0]= -co[0]; @@ -818,7 +818,7 @@ static void PE_mirror_particle(Object *ob, DerivedMesh *dm, ParticleSystem *psys key= point->keys; mkey= mpoint->keys; for(k=0; ktotkey; k++, hkey++, mhkey++, key++, mkey++) { - VECCOPY(mhkey->co, hkey->co); + copy_v3_v3(mhkey->co, hkey->co); mul_m4_v3(mat, mhkey->co); mhkey->co[0]= -mhkey->co[0]; mul_m4_v3(immat, mhkey->co); @@ -918,7 +918,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) sub_v3_v3v3(dvec, key->co, vec); dot=dot_v3v3(dvec,nor); - VECCOPY(dvec,nor); + copy_v3_v3(dvec,nor); if(dot>0.0f) { if(dotco, dv1); } - VECADD(dv1,dv0,dv2); + add_v3_v3v3(dv1, dv0, dv2); } } } @@ -1071,20 +1071,20 @@ static void recalc_emitter_field(Object *ob, ParticleSystem *psys) MVert *mvert; mvert=dm->getVertData(dm,mface->v1,CD_MVERT); - VECCOPY(vec,mvert->co); + copy_v3_v3(vec,mvert->co); VECCOPY(nor,mvert->no); mvert=dm->getVertData(dm,mface->v2,CD_MVERT); - VECADD(vec,vec,mvert->co); + add_v3_v3v3(vec,vec,mvert->co); VECADD(nor,nor,mvert->no); mvert=dm->getVertData(dm,mface->v3,CD_MVERT); - VECADD(vec,vec,mvert->co); + add_v3_v3v3(vec,vec,mvert->co); VECADD(nor,nor,mvert->no); if(mface->v4) { mvert=dm->getVertData(dm,mface->v4,CD_MVERT); - VECADD(vec,vec,mvert->co); + add_v3_v3v3(vec,vec,mvert->co); VECADD(nor,nor,mvert->no); mul_v3_fl(vec,0.25); @@ -1144,7 +1144,7 @@ static void update_world_cos(Object *ob, PTCacheEdit *edit) psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, hairmat); LOOP_KEYS { - VECCOPY(key->world_co,key->co); + copy_v3_v3(key->world_co,key->co); if(!(psys->flag & PSYS_GLOBAL_HAIR)) mul_m4_v3(hairmat, key->world_co); } @@ -1170,13 +1170,13 @@ static void update_velocities(PTCacheEdit *edit) if(dfra <= 0.0f) continue; - VECSUB(key->vel, (key+1)->co, key->co); + sub_v3_v3v3(key->vel, (key+1)->co, key->co); if(point->totkey>2) { - VECSUB(vec1, (key+1)->co, (key+2)->co); + sub_v3_v3v3(vec1, (key+1)->co, (key+2)->co); project_v3_v3v3(vec2, vec1, key->vel); - VECSUB(vec2, vec1, vec2); - VECADDFAC(key->vel, key->vel, vec2, 0.5f); + sub_v3_v3v3(vec2, vec1, vec2); + madd_v3_v3fl(key->vel, vec2, 0.5f); } } else if(k==point->totkey-1) { @@ -1185,13 +1185,13 @@ static void update_velocities(PTCacheEdit *edit) if(dfra <= 0.0f) continue; - VECSUB(key->vel, key->co, (key-1)->co); + sub_v3_v3v3(key->vel, key->co, (key-1)->co); if(point->totkey>2) { - VECSUB(vec1, (key-2)->co, (key-1)->co); + sub_v3_v3v3(vec1, (key-2)->co, (key-1)->co); project_v3_v3v3(vec2, vec1, key->vel); - VECSUB(vec2, vec1, vec2); - VECADDFAC(key->vel, key->vel, vec2, 0.5f); + sub_v3_v3v3(vec2, vec1, vec2); + madd_v3_v3fl(key->vel, vec2, 0.5f); } } else { @@ -1200,7 +1200,7 @@ static void update_velocities(PTCacheEdit *edit) if(dfra <= 0.0f) continue; - VECSUB(key->vel, (key+1)->co, (key-1)->co); + sub_v3_v3v3(key->vel, (key+1)->co, (key-1)->co); } mul_v3_fl(key->vel, frs_sec/dfra); } @@ -1623,7 +1623,7 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho if(pset->selectmode==SCE_SELECT_POINT) { LOOP_KEYS { - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); project_int(ar, co, vertco); if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1]) && key_test_depth(&data, co)) { @@ -1641,7 +1641,7 @@ int PE_lasso_select(bContext *C, int mcords[][2], short moves, short extend, sho else if(pset->selectmode==SCE_SELECT_END) { key= point->keys + point->totkey - 1; - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); project_int(ar, co,vertco); if((vertco[0] != IS_CLIPPED) && lasso_inside(mcords,moves,vertco[0],vertco[1]) && key_test_depth(&data, co)) { @@ -1934,8 +1934,8 @@ static void rekey_particle(PEData *data, int pa_index) okey = pa->hair; /* root and tip stay the same */ - VECCOPY(key->co, okey->co); - VECCOPY((key + data->totrekey - 1)->co, (okey + pa->totkey - 1)->co); + copy_v3_v3(key->co, okey->co); + copy_v3_v3((key + data->totrekey - 1)->co, (okey + pa->totkey - 1)->co); sta= key->time= okey->time; end= (key + data->totrekey - 1)->time= (okey + pa->totkey - 1)->time; @@ -1945,7 +1945,7 @@ static void rekey_particle(PEData *data, int pa_index) for(k=1,key++; ktotrekey-1; k++,key++) { state.time= (float)k / (float)(data->totrekey-1); psys_get_particle_on_path(&sim, pa_index, &state, 0); - VECCOPY(key->co, state.co); + copy_v3_v3(key->co, state.co); key->time= sta + k * dval; } @@ -2038,7 +2038,7 @@ static void rekey_particle_to_time(Scene *scene, Object *ob, int pa_index, float for(k=1, key++; k < pa->totkey; k++, key++) { state.time= path_time * (float)k / (float)(pa->totkey-1); psys_get_particle_on_path(&sim, pa_index, &state, 0); - VECCOPY(key->co, state.co); + copy_v3_v3(key->co, state.co); } /* replace hair keys */ @@ -2188,7 +2188,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys) } if(hkey < pa->hair + pa->totkey) { - VECCOPY(nhkey->co, hkey->co); + copy_v3_v3(nhkey->co, hkey->co); nhkey->editflag = hkey->editflag; nhkey->time= hkey->time; nhkey->weight= hkey->weight; @@ -2199,7 +2199,7 @@ static void remove_tagged_keys(Object *ob, ParticleSystem *psys) nkey->flag = key->flag; nkey->ftime = key->ftime; nkey->length = key->length; - VECCOPY(nkey->world_co, key->world_co); + copy_v3_v3(nkey->world_co, key->world_co); } nkey++; nhkey++; @@ -2275,7 +2275,7 @@ static void subdivide_particle(PEData *data, int pa_index) nkey->time= (key->time + (key+1)->time)*0.5f; state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f; psys_get_particle_on_path(&sim, pa_index, &state, 0); - VECCOPY(nkey->co, state.co); + copy_v3_v3(nkey->co, state.co); nekey->co= nkey->co; nekey->time= &nkey->time; @@ -2365,7 +2365,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat); - VECCOPY(co, point->keys->co); + copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_insert(tree, p, co, NULL); } @@ -2375,7 +2375,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { psys_mat_hair_to_object(ob, psmd->dm, psys->part->from, psys->particles+p, mat); - VECCOPY(co, point->keys->co); + copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); totn= BLI_kdtree_find_n_nearest(tree,10,co,NULL,nearest); @@ -2747,10 +2747,10 @@ static void brush_comb(PEData *data, float UNUSED(mat[][4]), float imat[][4], in fac= (float)pow((double)(1.0f - data->dist / data->rad), (double)data->combfac); - VECCOPY(cvec,data->dvec); + copy_v3_v3(cvec,data->dvec); mul_mat3_m4_v3(imat,cvec); mul_v3_fl(cvec, fac); - VECADD(key->co, key->co, cvec); + add_v3_v3(key->co, cvec); (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; } @@ -2861,13 +2861,13 @@ static void brush_length(PEData *data, int point_index) LOOP_KEYS { if(k==0) { - VECCOPY(pvec,key->co); + copy_v3_v3(pvec,key->co); } else { - VECSUB(dvec,key->co,pvec); - VECCOPY(pvec,key->co); + sub_v3_v3v3(dvec,key->co,pvec); + copy_v3_v3(pvec,key->co); mul_v3_fl(dvec,data->growfac); - VECADD(key->co,(key-1)->co,dvec); + add_v3_v3v3(key->co,(key-1)->co,dvec); } } @@ -2904,14 +2904,14 @@ static void brush_puff(PEData *data, int point_index) LOOP_KEYS { if(k==0) { /* find root coordinate and normal on emitter */ - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); mul_v3_m4v3(kco, data->ob->imat, co); /* use 'kco' as the object space version of worldspace 'co', ob->imat is set before calling */ point_index= BLI_kdtree_find_nearest(edit->emitter_field, kco, NULL, NULL); if(point_index == -1) return; - VECCOPY(rootco, co); + copy_v3_v3(rootco, co); copy_v3_v3(nor, &edit->emitter_cosnos[point_index*6+3]); mul_mat3_m4_v3(data->ob->obmat, nor); /* normal into worldspace */ @@ -2926,19 +2926,19 @@ static void brush_puff(PEData *data, int point_index) else { /* compute position as if hair was standing up straight. * */ - VECCOPY(lastco, co); - VECCOPY(co, key->co); + copy_v3_v3(lastco, co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); length += len_v3v3(lastco, co); if((data->select==0 || (key->flag & PEK_SELECT)) && !(key->flag & PEK_HIDE)) { - VECADDFAC(kco, rootco, nor, length); + madd_v3_v3v3fl(kco, rootco, nor, length); /* blend between the current and straight position */ - VECSUB(dco, kco, co); - VECADDFAC(co, co, dco, fac); + sub_v3_v3v3(dco, kco, co); + madd_v3_v3fl(co, dco, fac); /* re-use dco to compare before and after translation and add to the offset */ - VECCOPY(dco, key->co); + copy_v3_v3(dco, key->co); mul_v3_m4v3(key->co, imat, co); @@ -2965,7 +2965,7 @@ static void brush_puff(PEData *data, int point_index) /* Move the unselected point on a vector based on the * hair direction and the offset */ float c1[3], c2[3]; - VECSUB(dco, lastco, co); + sub_v3_v3v3(dco, lastco, co); mul_mat3_m4_v3(imat, dco); /* into particle space */ /* move the point along a vector perpendicular to the @@ -2979,7 +2979,7 @@ static void brush_puff(PEData *data, int point_index) /* Move the unselected point on a vector based on the * the normal of the closest geometry */ float oco[3], onor[3]; - VECCOPY(oco, key->co); + copy_v3_v3(oco, key->co); mul_m4_v3(mat, oco); mul_v3_m4v3(kco, data->ob->imat, oco); /* use 'kco' as the object space version of worldspace 'co', ob->imat is set before calling */ @@ -3028,7 +3028,7 @@ static void brush_smooth_get(PEData *data, float mat[][4], float UNUSED(imat[][4 sub_v3_v3v3(dvec,key->co,(key-1)->co); mul_mat3_m4_v3(mat,dvec); - VECADD(data->vec,data->vec,dvec); + add_v3_v3(data->vec, dvec); data->tot++; } } @@ -3038,57 +3038,61 @@ static void brush_smooth_do(PEData *data, float UNUSED(mat[][4]), float imat[][4 float vec[3], dvec[3]; if(key_index) { - VECCOPY(vec,data->vec); + copy_v3_v3(vec, data->vec); mul_mat3_m4_v3(imat,vec); sub_v3_v3v3(dvec,key->co,(key-1)->co); - VECSUB(dvec,vec,dvec); + sub_v3_v3v3(dvec,vec,dvec); mul_v3_fl(dvec,data->smoothfac); - VECADD(key->co,key->co,dvec); + add_v3_v3(key->co, dvec); } (data->edit->points + point_index)->flag |= PEP_EDIT_RECALC; } /* convert from triangle barycentric weights to quad mean value weights */ -static void intersect_dm_quad_weights(float *v1, float *v2, float *v3, float *v4, float *w) +static void intersect_dm_quad_weights(const float v1[3], const float v2[3], const float v3[3], const float v4[3], float w[4]) { float co[3], vert[4][3]; - VECCOPY(vert[0], v1); - VECCOPY(vert[1], v2); - VECCOPY(vert[2], v3); - VECCOPY(vert[3], v4); + copy_v3_v3(vert[0], v1); + copy_v3_v3(vert[1], v2); + copy_v3_v3(vert[2], v3); + copy_v3_v3(vert[3], v4); co[0]= v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3]; co[1]= v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3]; co[2]= v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3]; - interp_weights_poly_v3( w,vert, 4, co); + interp_weights_poly_v3(w, vert, 4, co); } /* check intersection with a derivedmesh */ -static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_w, - float *face_minmax, float *pa_minmax, float radius, float *ipoint) +static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, + float *vert_cos, + const float co1[3], const float co2[3], + float *min_d, int *min_face, float *min_w, + float *face_minmax, float *pa_minmax, + float radius, float *ipoint) { - MFace *mface=0; - MVert *mvert=0; + MFace *mface= NULL; + MVert *mvert= NULL; int i, totface, intersect=0; float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3],p_max[3]; float cur_ipoint[3]; - if(dm==0){ + if(dm == NULL){ psys_disable_all(ob); dm=mesh_get_derived_final(scene, ob, 0); - if(dm==0) + if(dm == NULL) dm=mesh_get_derived_deform(scene, ob, 0); psys_enable_all(ob); - if(dm==0) + if(dm == NULL) return 0; } @@ -3100,8 +3104,8 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, floa DO_MINMAX(co2,p_min,p_max); } else{ - VECCOPY(p_min,pa_minmax); - VECCOPY(p_max,pa_minmax+3); + copy_v3_v3(p_min,pa_minmax); + copy_v3_v3(p_max,pa_minmax+3); } totface=dm->getNumFaces(dm); @@ -3111,18 +3115,18 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, floa /* lets intersect the faces */ for(i=0; iv1); - VECCOPY(v2,vert_cos+3*mface->v2); - VECCOPY(v3,vert_cos+3*mface->v3); + copy_v3_v3(v1,vert_cos+3*mface->v1); + copy_v3_v3(v2,vert_cos+3*mface->v2); + copy_v3_v3(v3,vert_cos+3*mface->v3); if(mface->v4) - VECCOPY(v4,vert_cos+3*mface->v4) + copy_v3_v3(v4,vert_cos+3*mface->v4); } else{ - VECCOPY(v1,mvert[mface->v1].co); - VECCOPY(v2,mvert[mface->v2].co); - VECCOPY(v3,mvert[mface->v3].co); + copy_v3_v3(v1,mvert[mface->v1].co); + copy_v3_v3(v2,mvert[mface->v2].co); + copy_v3_v3(v3,mvert[mface->v3].co); if(mface->v4) - VECCOPY(v4,mvert[mface->v4].co) + copy_v3_v3(v4,mvert[mface->v4].co); } if(face_minmax==0){ @@ -3136,8 +3140,8 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, floa continue; } else{ - VECCOPY(min, face_minmax+6*i); - VECCOPY(max, face_minmax+6*i+3); + copy_v3_v3(min, face_minmax+6*i); + copy_v3_v3(max, face_minmax+6*i+3); if(isect_aabb_aabb_v3(min,max,p_min,p_max)==0) continue; } @@ -3146,7 +3150,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, floa if(isect_sweeping_sphere_tri_v3(co1, co2, radius, v2, v3, v1, &cur_d, cur_ipoint)){ if(cur_d<*min_d){ *min_d=cur_d; - VECCOPY(ipoint,cur_ipoint); + copy_v3_v3(ipoint,cur_ipoint); *min_face=i; intersect=1; } @@ -3155,7 +3159,7 @@ static int particle_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, floa if(isect_sweeping_sphere_tri_v3(co1, co2, radius, v4, v1, v3, &cur_d, cur_ipoint)){ if(cur_d<*min_d){ *min_d=cur_d; - VECCOPY(ipoint,cur_ipoint); + copy_v3_v3(ipoint,cur_ipoint); *min_face=i; intersect=1; } @@ -3363,27 +3367,27 @@ static int brush_add(PEData *data, short number) key3[1].time= key3[0].time; psys_get_particle_on_path(&sim, ptn[1].index, &key3[1], 0); mul_v3_fl(key3[1].co, weight[1]); - VECADD(key3[0].co, key3[0].co, key3[1].co); + add_v3_v3(key3[0].co, key3[1].co); if(maxw>2) { key3[2].time= key3[0].time; psys_get_particle_on_path(&sim, ptn[2].index, &key3[2], 0); mul_v3_fl(key3[2].co, weight[2]); - VECADD(key3[0].co, key3[0].co, key3[2].co); + add_v3_v3(key3[0].co, key3[2].co); } } if(k==0) - VECSUB(co1, pa->state.co, key3[0].co); + sub_v3_v3v3(co1, pa->state.co, key3[0].co); - VECADD(thkey->co, key3[0].co, co1); + add_v3_v3v3(thkey->co, key3[0].co, co1); thkey->time= key3[0].time; } } else { for(k=0, hkey=pa->hair; ktotaddkey; k++, hkey++) { - VECADDFAC(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep); + madd_v3_v3v3fl(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep); hkey->time += k * framestep; hkey->weight = 1.f - (float)k/(float)(pset->totaddkey-1); } @@ -4043,7 +4047,7 @@ const char *PE_undo_get_name(Scene *scene, int nr, int *active) /************************ utilities ******************************/ -int PE_minmax(Scene *scene, float *min, float *max) +int PE_minmax(Scene *scene, float min[3], float max[3]) { Object *ob= OBACT; PTCacheEdit *edit= PE_get_current(scene, ob); @@ -4065,7 +4069,7 @@ int PE_minmax(Scene *scene, float *min, float *max) psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, psys->particles+p, mat); LOOP_SELECTED_KEYS { - VECCOPY(co, key->co); + copy_v3_v3(co, key->co); mul_m4_v3(mat, co); DO_MINMAX(co, min, max); ok= 1; diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 101a6744e9a..bbff2239a38 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -688,7 +688,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat); invert_m4_m4(imat,hairmat); - VECSUB(vec, nearest.co, key->co); + sub_v3_v3v3(vec, nearest.co, key->co); if(point) { ekey = point->keys; @@ -696,7 +696,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys) } for(k=0,key=pa->hair; ktotkey; k++,key++) { - VECADD(key->co, key->co, vec); + add_v3_v3(key->co, vec); mul_m4_v3(imat,key->co); if(ekey) { diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 10f5645ca3b..266bff35bbd 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -75,7 +75,7 @@ static int dependsOnTime(ModifierData *UNUSED(md)) return 1; } -static DerivedMesh *applyModifier(ModifierData *md, Object *ob, +static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) From 0634d8a7458c9fed536f3240edf610587ec63067 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 14:36:37 +0000 Subject: [PATCH 113/147] replace macros with math functions for render code --- .../render/intern/source/convertblender.c | 54 ++-- .../blender/render/intern/source/occlusion.c | 256 +++++++++--------- .../render/intern/source/render_texture.c | 2 +- .../render/intern/source/volume_precache.c | 6 +- 4 files changed, 159 insertions(+), 159 deletions(-) diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 7ef726a5330..f48d4e0d64a 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -478,11 +478,11 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr if(do_tangent) { tav= RE_vertren_get_tangent(obr, v1, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); tav= RE_vertren_get_tangent(obr, v2, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); tav= RE_vertren_get_tangent(obr, v3, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); } if(do_nmap_tangent) { @@ -496,11 +496,11 @@ static void calc_tangent_vector(ObjectRen *obr, VertexTangent **vtangents, MemAr if(do_tangent) { tav= RE_vertren_get_tangent(obr, v1, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); tav= RE_vertren_get_tangent(obr, v3, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); tav= RE_vertren_get_tangent(obr, v4, 1); - VECADD(tav, tav, tang); + add_v3_v3(tav, tang); } if(do_nmap_tangent) { @@ -1357,20 +1357,20 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - VECADD(vlr->v1->co, bb_center, xvec); - VECADD(vlr->v1->co, vlr->v1->co, yvec); + add_v3_v3v3(vlr->v1->co, bb_center, xvec); + add_v3_v3(vlr->v1->co, yvec); mul_m4_v3(re->viewmat, vlr->v1->co); - VECSUB(vlr->v2->co, bb_center, xvec); - VECADD(vlr->v2->co, vlr->v2->co, yvec); + sub_v3_v3v3(vlr->v2->co, bb_center, xvec); + add_v3_v3(vlr->v2->co, yvec); mul_m4_v3(re->viewmat, vlr->v2->co); - VECSUB(vlr->v3->co, bb_center, xvec); - VECSUB(vlr->v3->co, vlr->v3->co, yvec); + sub_v3_v3v3(vlr->v3->co, bb_center, xvec); + sub_v3_v3v3(vlr->v3->co, vlr->v3->co, yvec); mul_m4_v3(re->viewmat, vlr->v3->co); - VECADD(vlr->v4->co, bb_center, xvec); - VECSUB(vlr->v4->co, vlr->v4->co, yvec); + add_v3_v3v3(vlr->v4->co, bb_center, xvec); + sub_v3_v3(vlr->v4->co, yvec); mul_m4_v3(re->viewmat, vlr->v4->co); normal_quad_v3( vlr->n,vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co); @@ -1968,8 +1968,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(k==1){ sd.first = 1; sd.time = 0.0f; - VECSUB(loc0,loc1,loc); - VECADD(loc0,loc1,loc0); + sub_v3_v3v3(loc0,loc1,loc); + add_v3_v3v3(loc0,loc1,loc0); particle_curve(re, obr, psmd->dm, ma, &sd, loc1, loc0, seed, pa_co); } @@ -3475,7 +3475,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1); for(vindex=0; vindexco, lar->co); + VECCOPY(shb->co, lar->co); /* int copy */ /* percentage render: keep track of min and max */ shb->size= (lar->bufsize*re->r.size)/100; @@ -4190,7 +4190,7 @@ static void check_non_flat_quads(ObjectRen *obr) v2= vlr->v2; v3= vlr->v3; v4= vlr->v4; - VECSUB(nor, v1->co, v2->co); + sub_v3_v3v3(nor, v1->co, v2->co); if( ABS(nor[0])v1= v2; vlr->v2= v3; @@ -4198,19 +4198,19 @@ static void check_non_flat_quads(ObjectRen *obr) vlr->v4= NULL; } else { - VECSUB(nor, v2->co, v3->co); + sub_v3_v3v3(nor, v2->co, v3->co); if( ABS(nor[0])v2= v3; vlr->v3= v4; vlr->v4= NULL; } else { - VECSUB(nor, v3->co, v4->co); + sub_v3_v3v3(nor, v3->co, v4->co); if( ABS(nor[0])v4= NULL; } else { - VECSUB(nor, v4->co, v1->co); + sub_v3_v3v3(nor, v4->co, v1->co); if( ABS(nor[0])v4= NULL; } @@ -5397,12 +5397,12 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve interp_weights_face_v3( w,co1, co2, co3, co4, strand->vert->co); - speed[0]= speed[1]= speed[2]= speed[3]= 0.0f; - QUATADDFAC(speed, speed, winspeed[face[0]], w[0]); - QUATADDFAC(speed, speed, winspeed[face[1]], w[1]); - QUATADDFAC(speed, speed, winspeed[face[2]], w[2]); + zero_v4(speed); + madd_v4_v4fl(speed, winspeed[face[0]], w[0]); + madd_v4_v4fl(speed, winspeed[face[1]], w[1]); + madd_v4_v4fl(speed, winspeed[face[2]], w[2]); if(face[3]) - QUATADDFAC(speed, speed, winspeed[face[3]], w[3]); + madd_v4_v4fl(speed, winspeed[face[3]], w[3]); } } diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index a2363472694..b0a6e428b18 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -172,7 +172,7 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); /* set up view vector */ - VECCOPY(shi->view, shi->co); + copy_v3_v3(shi->view, shi->co); normalize_v3(shi->view); /* cache for shadow */ @@ -205,7 +205,7 @@ static void occ_shade(ShadeSample *ssamp, ObjectInstanceRen *obi, VlakRen *vlr, shade_input_set_shade_texco(shi); shade_material_loop(shi, shr); /* todo: nodes */ - VECCOPY(rad, shr->combined); + copy_v3_v3(rad, shr->combined); } static void occ_build_shade(Render *re, OcclusionTree *tree) @@ -339,10 +339,10 @@ static void occ_face(const OccFace *face, float co[3], float normal[3], float *a } if(area) { - VECCOPY(v1, vlr->v1->co); - VECCOPY(v2, vlr->v2->co); - VECCOPY(v3, vlr->v3->co); - if(vlr->v4) VECCOPY(v4, vlr->v4->co); + copy_v3_v3(v1, vlr->v1->co); + copy_v3_v3(v2, vlr->v2->co); + copy_v3_v3(v3, vlr->v3->co); + if(vlr->v4) copy_v3_v3(v4, vlr->v4->co); if(obi->flag & R_TRANSFORMED) { mul_m4_v3(obi->mat, v1); @@ -439,14 +439,14 @@ static void occ_build_dco(OcclusionTree *tree, OccNode *node, const float co[3], else if(node->child[b].node) { OccNode *child= node->child[b].node; occ_build_dco(tree, child, co, dco); - VECCOPY(nco, child->co); + copy_v3_v3(nco, child->co); } else { continue; } - VECSUB(d, nco, co); - dist= INPR(d, d); + sub_v3_v3v3(d, nco, co); + dist= dot_v3v3(d, d); if(dist > *dco) *dco= dist; } @@ -604,7 +604,7 @@ static void occ_build_recursive(OcclusionTree *tree, OccNode *node, int begin, i if(child) { node->area += child->area; sh_add(node->sh, node->sh, child->sh); - VECADDFAC(node->co, node->co, child->co, child->area); + madd_v3_v3fl(node->co, child->co, child->area); } } @@ -745,7 +745,7 @@ static void occ_free_tree(OcclusionTree *tree) /* ------------------------- Traversal --------------------------- */ -static float occ_solid_angle(OccNode *node, float *v, float d2, float invd2, float *receivenormal) +static float occ_solid_angle(OccNode *node, const float v[3], float d2, float invd2, const float receivenormal[3]) { float dotreceive, dotemit; float ev[3]; @@ -754,7 +754,7 @@ static float occ_solid_angle(OccNode *node, float *v, float d2, float invd2, flo ev[1]= -v[1]*invd2; ev[2]= -v[2]*invd2; dotemit= sh_eval(node->sh, ev); - dotreceive= INPR(receivenormal, v)*invd2; + dotreceive= dot_v3v3(receivenormal, v)*invd2; CLAMP(dotemit, 0.0f, 1.0f); CLAMP(dotreceive, 0.0f, 1.0f); @@ -762,24 +762,24 @@ static float occ_solid_angle(OccNode *node, float *v, float d2, float invd2, flo return ((node->area*dotemit*dotreceive)/(d2 + node->area*INVPI))*INVPI; } -static void VecAddDir(float *result, float *v1, float *v2, float fac) +static void VecAddDir(float result[3], const float v1[3], const float v2[3], const float fac) { result[0]= v1[0] + fac*(v2[0] - v1[0]); result[1]= v1[1] + fac*(v2[1] - v1[1]); result[2]= v1[2] + fac*(v2[2] - v1[2]); } -static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, float *q0, float *q1, float *q2, float *q3) +static int occ_visible_quad(float *p, const float n[3], const float v0[3], const float *v1, const float *v2, float q0[3], float q1[3], float q2[3], float q3[3]) { static const float epsilon = 1e-6f; float c, sd[3]; - c= INPR(n, p); + c= dot_v3v3(n, p); /* signed distances from the vertices to the plane. */ - sd[0]= INPR(n, v0) - c; - sd[1]= INPR(n, v1) - c; - sd[2]= INPR(n, v2) - c; + sd[0]= dot_v3v3(n, v0) - c; + sd[1]= dot_v3v3(n, v1) - c; + sd[2]= dot_v3v3(n, v2) - c; if(fabsf(sd[0]) < epsilon) sd[0] = 0.0f; if(fabsf(sd[1]) < epsilon) sd[1] = 0.0f; @@ -789,70 +789,70 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, if(sd[1] > 0) { if(sd[2] > 0) { // +++ - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // ++- - VECCOPY(q0, v0); - VECCOPY(q1, v1); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2]))); VecAddDir(q3, v0, v2, (sd[0]/(sd[0]-sd[2]))); } else { // ++0 - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } } else if(sd[1] < 0) { if(sd[2] > 0) { // +-+ - VECCOPY(q0, v0); + copy_v3_v3(q0, v0); VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1]))); VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2]))); - VECCOPY(q3, v2); + copy_v3_v3(q3, v2); } else if(sd[2] < 0) { // +-- - VECCOPY(q0, v0); + copy_v3_v3(q0, v0); VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1]))); VecAddDir(q2, v0, v2, (sd[0]/(sd[0]-sd[2]))); - VECCOPY(q3, q2); + copy_v3_v3(q3, q2); } else { // +-0 - VECCOPY(q0, v0); + copy_v3_v3(q0, v0); VecAddDir(q1, v0, v1, (sd[0]/(sd[0]-sd[1]))); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } } else { if(sd[2] > 0) { // +0+ - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // +0- - VECCOPY(q0, v0); - VECCOPY(q1, v1); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); VecAddDir(q2, v0, v2, (sd[0]/(sd[0]-sd[2]))); - VECCOPY(q3, q2); + copy_v3_v3(q3, q2); } else { // +00 - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } } } @@ -861,23 +861,23 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, if(sd[2] > 0) { // -++ VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1]))); - VECCOPY(q1, v1); - VECCOPY(q2, v2); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); VecAddDir(q3, v0, v2, (sd[0]/(sd[0]-sd[2]))); } else if(sd[2] < 0) { // -+- VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1]))); - VECCOPY(q1, v1); + copy_v3_v3(q1, v1); VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2]))); - VECCOPY(q3, q2); + copy_v3_v3(q3, q2); } else { // -+0 VecAddDir(q0, v0, v1, (sd[0]/(sd[0]-sd[1]))); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } } else if(sd[1] < 0) { @@ -885,8 +885,8 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, // --+ VecAddDir(q0, v0, v2, (sd[0]/(sd[0]-sd[2]))); VecAddDir(q1, v1, v2, (sd[1]/(sd[1]-sd[2]))); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // --- @@ -901,9 +901,9 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, if(sd[2] > 0) { // -0+ VecAddDir(q0, v0, v2, (sd[0]/(sd[0]-sd[2]))); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // -0- @@ -919,33 +919,33 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, if(sd[1] > 0) { if(sd[2] > 0) { // 0++ - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // 0+- - VECCOPY(q0, v0); - VECCOPY(q1, v1); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); VecAddDir(q2, v1, v2, (sd[1]/(sd[1]-sd[2]))); - VECCOPY(q3, q2); + copy_v3_v3(q3, q2); } else { // 0+0 - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } } else if(sd[1] < 0) { if(sd[2] > 0) { // 0-+ - VECCOPY(q0, v0); + copy_v3_v3(q0, v0); VecAddDir(q1, v1, v2, (sd[1]/(sd[1]-sd[2]))); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // 0-- @@ -959,10 +959,10 @@ static int occ_visible_quad(float *p, float *n, float *v0, float *v1, float *v2, else { if(sd[2] > 0) { // 00+ - VECCOPY(q0, v0); - VECCOPY(q1, v1); - VECCOPY(q2, v2); - VECCOPY(q3, q2); + copy_v3_v3(q0, v0); + copy_v3_v3(q1, v1); + copy_v3_v3(q2, v2); + copy_v3_v3(q3, q2); } else if(sd[2] < 0) { // 00- @@ -1117,7 +1117,7 @@ static void normalizef(float *n) { float d; - d= INPR(n, n); + d= dot_v3v3(n, n); if(d > 1.0e-35F) { d= 1.0f/sqrtf(d); @@ -1128,15 +1128,15 @@ static void normalizef(float *n) } } -static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3) +static float occ_quad_form_factor(const float p[3], const float n[3], const float q0[3], const float q1[3], const float q2[3], const float q3[3]) { float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3]; float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result; - VECSUB(r0, q0, p); - VECSUB(r1, q1, p); - VECSUB(r2, q2, p); - VECSUB(r3, q3, p); + sub_v3_v3v3(r0, q0, p); + sub_v3_v3v3(r1, q1, p); + sub_v3_v3v3(r2, q2, p); + sub_v3_v3v3(r3, q3, p); normalizef(r0); normalizef(r1); @@ -1148,15 +1148,15 @@ static float occ_quad_form_factor(float *p, float *n, float *q0, float *q1, floa cross_v3_v3v3(g2, r3, r2); normalizef(g2); cross_v3_v3v3(g3, r0, r3); normalizef(g3); - a1= saacosf(INPR(r0, r1)); - a2= saacosf(INPR(r1, r2)); - a3= saacosf(INPR(r2, r3)); - a4= saacosf(INPR(r3, r0)); + a1= saacosf(dot_v3v3(r0, r1)); + a2= saacosf(dot_v3v3(r1, r2)); + a3= saacosf(dot_v3v3(r2, r3)); + a4= saacosf(dot_v3v3(r3, r0)); - dot1= INPR(n, g0); - dot2= INPR(n, g1); - dot3= INPR(n, g2); - dot4= INPR(n, g3); + dot1= dot_v3v3(n, g0); + dot2= dot_v3v3(n, g1); + dot3= dot_v3v3(n, g2); + dot4= dot_v3v3(n, g3); result= (a1*dot1 + a2*dot2 + a3*dot3 + a4*dot4)*0.5f/(float)M_PI; result= MAX2(result, 0.0f); @@ -1173,9 +1173,9 @@ static float occ_form_factor(OccFace *face, float *p, float *n) obi= &R.objectinstance[face->obi]; vlr= RE_findOrAddVlak(obi->obr, face->facenr); - VECCOPY(v1, vlr->v1->co); - VECCOPY(v2, vlr->v2->co); - VECCOPY(v3, vlr->v3->co); + copy_v3_v3(v1, vlr->v1->co); + copy_v3_v3(v2, vlr->v2->co); + copy_v3_v3(v3, vlr->v3->co); if(obi->flag & R_TRANSFORMED) { mul_m4_v3(obi->mat, v1); @@ -1187,7 +1187,7 @@ static float occ_form_factor(OccFace *face, float *p, float *n) contrib += occ_quad_form_factor(p, n, q0, q1, q2, q3); if(vlr->v4) { - VECCOPY(v4, vlr->v4->co); + copy_v3_v3(v4, vlr->v4->co); if(obi->flag & R_TRANSFORMED) mul_m4_v3(obi->mat, v4); @@ -1207,9 +1207,9 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float int b, f, totstack; /* init variables */ - VECCOPY(p, pp); - VECCOPY(n, pn); - VECADDFAC(p, p, n, 1e-4f); + copy_v3_v3(p, pp); + copy_v3_v3(n, pn); + madd_v3_v3fl(p, n, 1e-4f); if(bentn) copy_v3_v3(bentn, n); @@ -1230,7 +1230,7 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float node= stack[--totstack]; VECSUB(v, node->co, p); - d2= INPR(v, v) + 1e-16f; + d2= dot_v3v3(v, v) + 1e-16f; emitarea= MAX2(node->area, node->dco); if(d2*error > emitarea) { @@ -1270,8 +1270,8 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float if(!exclude || !(face->obi == exclude->obi && face->facenr == exclude->facenr)) { if(bentn || distfac != 0.0f) { occ_face(face, co, NULL, NULL); - VECSUB(v, co, p); - d2= INPR(v, v) + 1e-16f; + sub_v3_v3v3(v, co, p); + d2= dot_v3v3(v, v) + 1e-16f; fac= (distfac == 0.0f)? 1.0f: 1.0f/(1.0f + distfac*d2); if(fac < 0.01f) @@ -1368,7 +1368,7 @@ static void occ_compute_passes(Render *re, OcclusionTree *tree, int totpass) for(i=0; itotface; i++) { occ_face(&tree->face[i], co, n, NULL); negate_v3(n); - VECADDFAC(co, co, n, 1e-8f); + madd_v3_v3fl(co, n, 1e-8f); occ_lookup(tree, 0, &tree->face[i], co, n, &occ[i], NULL, NULL); if(re->test_break(re->tbh)) @@ -1485,11 +1485,11 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int sample= &cache->sample[(y-cache->y)*cache->w + (x-cache->x)]; if(sample->filled) { VECSUB(d, sample->co, co); - dist2= INPR(d, d); - if(dist2 < 0.5f*sample->dist2 && INPR(sample->n, n) > 0.98f) { - VECCOPY(ao, sample->ao); - VECCOPY(env, sample->env); - VECCOPY(indirect, sample->indirect); + dist2= dot_v3v3(d, d); + if(dist2 < 0.5f*sample->dist2 && dot_v3v3(sample->n, n) > 0.98f) { + copy_v3_v3(ao, sample->ao); + copy_v3_v3(env, sample->env); + copy_v3_v3(indirect, sample->indirect); return 1; } } @@ -1535,10 +1535,10 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int for(i=0; i<4; i++) { VECSUB(d, samples[i]->co, co); - //dist2= INPR(d, d); + //dist2= dot_v3v3(d, d); wz[i]= 1.0f; //(samples[i]->dist2/(1e-4f + dist2)); - wn[i]= pow(INPR(samples[i]->n, n), 32.0f); + wn[i]= pow(dot_v3v3(samples[i]->n, n), 32.0f); w= wb[i]*wn[i]*wz[i]; @@ -1633,9 +1633,9 @@ static void *exec_strandsurface_sample(void *data) negate_v3(n); sample_occ_tree(re, re->occlusiontree, NULL, co, n, othread->thread, 0, ao, env, indirect); - VECCOPY(othread->faceao[a], ao); - VECCOPY(othread->faceenv[a], env); - VECCOPY(othread->faceindirect[a], indirect); + copy_v3_v3(othread->faceao[a], ao); + copy_v3_v3(othread->faceenv[a], env); + copy_v3_v3(othread->faceindirect[a], indirect); } return 0; @@ -1701,27 +1701,27 @@ void make_occ_tree(Render *re) for(a=0; atotface; a++) { face= mesh->face[a]; - VECCOPY(ao, faceao[a]); - VECCOPY(env, faceenv[a]); - VECCOPY(indirect, faceindirect[a]); + copy_v3_v3(ao, faceao[a]); + copy_v3_v3(env, faceenv[a]); + copy_v3_v3(indirect, faceindirect[a]); - VECADD(mesh->ao[face[0]], mesh->ao[face[0]], ao); - VECADD(mesh->env[face[0]], mesh->env[face[0]], env); - VECADD(mesh->indirect[face[0]], mesh->indirect[face[0]], indirect); + add_v3_v3(mesh->ao[face[0]], ao); + add_v3_v3(mesh->env[face[0]], env); + add_v3_v3(mesh->indirect[face[0]], indirect); count[face[0]]++; - VECADD(mesh->ao[face[1]], mesh->ao[face[1]], ao); - VECADD(mesh->env[face[1]], mesh->env[face[1]], env); - VECADD(mesh->indirect[face[1]], mesh->indirect[face[1]], indirect); + add_v3_v3(mesh->ao[face[1]], ao); + add_v3_v3(mesh->env[face[1]], env); + add_v3_v3(mesh->indirect[face[1]], indirect); count[face[1]]++; - VECADD(mesh->ao[face[2]], mesh->ao[face[2]], ao); - VECADD(mesh->env[face[2]], mesh->env[face[2]], env); - VECADD(mesh->indirect[face[2]], mesh->indirect[face[2]], indirect); + add_v3_v3(mesh->ao[face[2]], ao); + add_v3_v3(mesh->env[face[2]], env); + add_v3_v3(mesh->indirect[face[2]], indirect); count[face[2]]++; if(face[3]) { - VECADD(mesh->ao[face[3]], mesh->ao[face[3]], ao); - VECADD(mesh->env[face[3]], mesh->env[face[3]], env); - VECADD(mesh->indirect[face[3]], mesh->indirect[face[3]], indirect); + add_v3_v3(mesh->ao[face[3]], ao); + add_v3_v3(mesh->env[face[3]], env); + add_v3_v3(mesh->indirect[face[3]], indirect); count[face[3]]++; } } @@ -1784,7 +1784,7 @@ void sample_occ(Render *re, ShadeInput *shi) sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]); sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2])); sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2])); - sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco); + sample->dist2= dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco); sample->filled= 1; } } @@ -1879,7 +1879,7 @@ void cache_occ_samples(Render *re, RenderPart *pa, ShadeSample *ssamp) sample->intensity= MAX3(sample->ao[0], sample->ao[1], sample->ao[2]); sample->intensity= MAX2(sample->intensity, MAX3(sample->env[0], sample->env[1], sample->env[2])); sample->intensity= MAX2(sample->intensity, MAX3(sample->indirect[0], sample->indirect[1], sample->indirect[2])); - sample->dist2= INPR(shi->dxco, shi->dxco) + INPR(shi->dyco, shi->dyco); + sample->dist2= dot_v3v3(shi->dxco, shi->dxco) + dot_v3v3(shi->dyco, shi->dyco); sample->x= shi->xs; sample->y= shi->ys; sample->filled= 1; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 14b02920439..b5386dde623 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -2297,7 +2297,7 @@ void do_material_tex(ShadeInput *shi) else texres.nor= NULL; if(warpdone) { - VECADD(tempvec, co, warpvec); + add_v3_v3v3(tempvec, co, warpvec); co= tempvec; } diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 850db5a55d4..11d7d9342f7 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -102,8 +102,8 @@ static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), flo int final_depth=0, depth=0, limit=20; /* set up the isect */ - VECCOPY(isect.start, co); - VECCOPY(isect.dir, dir); + copy_v3_v3(isect.start, co); + copy_v3_v3(isect.dir, dir); isect.mode= RE_RAY_MIRROR; isect.last_hit= NULL; isect.lay= -1; @@ -623,7 +623,7 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob copy_v3_v3(pa->bbmin, bbmin); copy_v3_v3(pa->voxel, voxel); - VECCOPY(pa->res, res); + VECCOPY(pa->res, res); /* int's */ pa->minx = minx; pa->maxx = maxx; pa->miny = miny; pa->maxy = maxy; From ec3b0c6a968210512e0c36e1e62eefcbe0cf1ea0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 15:17:43 +0000 Subject: [PATCH 114/147] misc macro --> bli math lib functions --- source/blender/blenkernel/intern/bvhutils.c | 81 +++++++++---------- source/blender/blenkernel/intern/colortools.c | 4 +- source/blender/blenkernel/intern/displist.c | 12 +-- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/shrinkwrap.c | 2 +- source/blender/editors/curve/editcurve.c | 56 ++++++------- source/blender/editors/sculpt_paint/sculpt.c | 5 +- .../blender/editors/space_view3d/drawvolume.c | 2 +- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/uvedit/uvedit_draw.c | 28 +++---- .../composite/nodes/node_composite_normal.c | 2 +- .../Converter/BL_ActionActuator.cpp | 6 +- 12 files changed, 101 insertions(+), 101 deletions(-) diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index ee160a13fa2..93abad8858f 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -48,27 +48,27 @@ /* 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) +static float ray_tri_intersection(const BVHTreeRay *ray, const float UNUSED(m_dist), const float v0[3], const float v1[3], const float v2[3]) { float dist; - if(isect_ray_tri_v3((float*)ray->origin, (float*)ray->direction, (float*)v0, (float*)v1, (float*)v2, &dist, NULL)) + if(isect_ray_tri_v3(ray->origin, ray->direction, v0, v1, v2, &dist, NULL)) return dist; return FLT_MAX; } -static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float *v0, const float *v1, const float *v2) +static float sphereray_tri_intersection(const BVHTreeRay *ray, float radius, const float m_dist, const float v0[3], const float v1[3], const float v2[3]) { float idist; float p1[3]; float plane_normal[3], hit_point[3]; - normal_tri_v3( plane_normal,(float*)v0, (float*)v1, (float*)v2); + normal_tri_v3(plane_normal, v0, v1, v2); - VECADDFAC( p1, ray->origin, ray->direction, m_dist); - if(isect_sweeping_sphere_tri_v3((float*)ray->origin, p1, radius, (float*)v0, (float*)v1, (float*)v2, &idist, hit_point)) + madd_v3_v3v3fl(p1, ray->origin, ray->direction, m_dist); + if(isect_sweeping_sphere_tri_v3(ray->origin, p1, radius, v0, v1, v2, &idist, hit_point)) { return idist * m_dist; } @@ -81,7 +81,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 ) +static float nearest_point_in_tri_surface(const float v0[3], const float v1[3], const float v2[3], const float p[3], int *v, int *e, float nearest[3]) { float diff[3]; float e0[3]; @@ -98,16 +98,16 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const float sqrDist; int lv = -1, le = -1; - VECSUB(diff, v0, p); - VECSUB(e0, v1, v0); - VECSUB(e1, v2, v0); + sub_v3_v3v3(diff, v0, p); + sub_v3_v3v3(e0, v1, v0); + sub_v3_v3v3(e1, v2, v0); - A00 = INPR ( e0, e0 ); - A01 = INPR( e0, e1 ); - A11 = INPR ( e1, e1 ); - B0 = INPR( diff, e0 ); - B1 = INPR( diff, e1 ); - C = INPR( diff, diff ); + A00 = dot_v3v3(e0, e0); + A01 = dot_v3v3(e0, e1 ); + A11 = dot_v3v3(e1, e1 ); + B0 = dot_v3v3(diff, e0 ); + B1 = dot_v3v3(diff, e1 ); + C = dot_v3v3(diff, diff ); Det = fabs( A00 * A11 - A01 * A01 ); S = A01 * B1 - A11 * B0; T = A01 * B0 - A00 * B1; @@ -123,7 +123,7 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const T = 0.0f; if ( -B0 >= A00 ) { - S = (float)1.0; + S = 1.0f; sqrDist = A00 + 2.0f * B0 + C; lv = 1; } @@ -379,15 +379,15 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const { float w[3], x[3], y[3], z[3]; - VECCOPY(w, v0); - VECCOPY(x, e0); + copy_v3_v3(w, v0); + copy_v3_v3(x, e0); mul_v3_fl(x, S); - VECCOPY(y, e1); + copy_v3_v3(y, e1); mul_v3_fl(y, T); VECADD(z, w, x); VECADD(z, z, y); - //VECSUB(d, p, z); - VECCOPY(nearest, z); + //sub_v3_v3v3(d, p, z); + copy_v3_v3(nearest, z); // d = p - ( v0 + S * e0 + T * e1 ); } *v = lv; @@ -403,7 +403,7 @@ static float nearest_point_in_tri_surface(const float *v0,const float *v1,const // 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. -static void mesh_faces_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest) +static void mesh_faces_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata; MVert *vert = data->vert; @@ -426,7 +426,7 @@ static void mesh_faces_nearest_point(void *userdata, int index, const float *co, { nearest->index = index; nearest->dist = dist; - VECCOPY(nearest->co, nearest_tmp); + copy_v3_v3(nearest->co, nearest_tmp); normal_tri_v3( nearest->no,t0, t1, t2); } @@ -464,7 +464,7 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r { hit->index = index; hit->dist = dist; - VECADDFAC(hit->co, ray->origin, ray->direction, dist); + madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); normal_tri_v3( hit->no,t0, t1, t2); } @@ -478,7 +478,7 @@ static void mesh_faces_spherecast(void *userdata, int index, const BVHTreeRay *r // Callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_edges. // userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. -static void mesh_edges_nearest_point(void *userdata, int index, const float *co, BVHTreeNearest *nearest) +static void mesh_edges_nearest_point(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata; MVert *vert = data->vert; @@ -488,16 +488,15 @@ static void mesh_edges_nearest_point(void *userdata, int index, const float *co, float *t0, *t1; t0 = vert[ edge->v1 ].co; t1 = vert[ edge->v2 ].co; - - // NOTE: casts to "float*" here are due to co being "const float*" - closest_to_line_segment_v3(nearest_tmp, (float*)co, t0, t1); - dist = len_squared_v3v3(nearest_tmp, (float*)co); + + closest_to_line_segment_v3(nearest_tmp, co, t0, t1); + dist = len_squared_v3v3(nearest_tmp, co); if(dist < nearest->dist) { nearest->index = index; nearest->dist = dist; - VECCOPY(nearest->co, nearest_tmp); + copy_v3_v3(nearest->co, nearest_tmp); sub_v3_v3v3(nearest->no, t0, t1); normalize_v3(nearest->no); } @@ -590,11 +589,11 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float for(i = 0; i < numFaces; i++, efa= efa->next) { if(!(efa->f & 1) && efa->h==0 && !((efa->v1->f&1)+(efa->v2->f&1)+(efa->v3->f&1)+(efa->v4?efa->v4->f&1:0))) { float co[4][3]; - VECCOPY(co[0], vert[ face[i].v1 ].co); - VECCOPY(co[1], vert[ face[i].v2 ].co); - VECCOPY(co[2], vert[ face[i].v3 ].co); + copy_v3_v3(co[0], vert[ face[i].v1 ].co); + copy_v3_v3(co[1], vert[ face[i].v2 ].co); + copy_v3_v3(co[2], vert[ face[i].v3 ].co); if(face[i].v4) - VECCOPY(co[3], vert[ face[i].v4 ].co); + copy_v3_v3(co[3], vert[ face[i].v4 ].co); BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); } @@ -603,11 +602,11 @@ BVHTree* bvhtree_from_mesh_faces(BVHTreeFromMesh *data, DerivedMesh *mesh, float else { for(i = 0; i < numFaces; i++) { float co[4][3]; - VECCOPY(co[0], vert[ face[i].v1 ].co); - VECCOPY(co[1], vert[ face[i].v2 ].co); - VECCOPY(co[2], vert[ face[i].v3 ].co); + copy_v3_v3(co[0], vert[ face[i].v1 ].co); + copy_v3_v3(co[1], vert[ face[i].v2 ].co); + copy_v3_v3(co[2], vert[ face[i].v3 ].co); if(face[i].v4) - VECCOPY(co[3], vert[ face[i].v4 ].co); + copy_v3_v3(co[3], vert[ face[i].v4 ].co); BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); } @@ -669,8 +668,8 @@ BVHTree* bvhtree_from_mesh_edges(BVHTreeFromMesh *data, DerivedMesh *mesh, float for(i = 0; i < numEdges; i++) { float co[4][3]; - VECCOPY(co[0], vert[ edge[i].v1 ].co); - VECCOPY(co[1], vert[ edge[i].v2 ].co); + copy_v3_v3(co[0], vert[ edge[i].v1 ].co); + copy_v3_v3(co[1], vert[ edge[i].v2 ].co); BLI_bvhtree_insert(tree, i, co[0], 2); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 98a434a7d8b..2f568aa01eb 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -501,7 +501,7 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) hlen= len_v3v3(bezt[0].vec[1], bezt[0].vec[2]); /* original handle length */ /* clip handle point */ - VECCOPY(vec, bezt[1].vec[0]); + copy_v3_v3(vec, bezt[1].vec[0]); if(vec[0] < bezt[0].vec[1][0]) vec[0]= bezt[0].vec[1][0]; @@ -518,7 +518,7 @@ static void curvemap_make_table(CurveMap *cuma, rctf *clipr) hlen= len_v3v3(bezt[a].vec[1], bezt[a].vec[0]); /* original handle length */ /* clip handle point */ - VECCOPY(vec, bezt[a-1].vec[2]); + copy_v3_v3(vec, bezt[a-1].vec[2]); if(vec[0] > bezt[a].vec[1][0]) vec[0]= bezt[a].vec[1][0]; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 6ae556874bb..a5be056bc16 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -346,7 +346,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i if(a==0 && dl->type== DL_POLY) bezt= nu->bezt; if(prevbezt->h2==HD_VECT && bezt->h1==HD_VECT) { - VECCOPY(data, prevbezt->vec[1]); + copy_v3_v3(data, prevbezt->vec[1]); data+= 3; } else { @@ -363,7 +363,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i } if(a==0 && dl->type==DL_SEGM) { - VECCOPY(data, bezt->vec[1]); + copy_v3_v3(data, bezt->vec[1]); } prevbezt= bezt; @@ -404,7 +404,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i a= len; bp= nu->bp; while(a--) { - VECCOPY(data, bp->vec); + copy_v3_v3(data, bp->vec); bp++; data+= 3; } @@ -486,7 +486,7 @@ void filldisplist(ListBase *dispbase, ListBase *to, int flipnormal) totvert= 0; eve= fillvertbase.first; while(eve) { - VECCOPY(f1, eve->co); + copy_v3_v3(f1, eve->co); f1+= 3; /* index number */ @@ -559,7 +559,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) a= dl->parts; while(a--) { - VECCOPY(fp1, fp); + copy_v3_v3(fp1, fp); fp1+= 3; fp+= dpoly; } @@ -579,7 +579,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) a= dl->parts; while(a--) { - VECCOPY(fp1, fp); + copy_v3_v3(fp1, fp); fp1+= 3; fp+= dpoly; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a493120e320..ae4e6ea81b8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -2120,7 +2120,7 @@ void object_set_dimensions(Object *ob, const float *value) } } -void minmax_object(Object *ob, float *min, float *max) +void minmax_object(Object *ob, float min[3], float max[3]) { BoundBox bb; float vec[3]; diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index e47dcd68ce1..3d788b40a17 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -469,7 +469,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) if(calc->smd->shrinkOpts & MOD_SHRINKWRAP_KEEP_ABOVE_SURFACE) { //Make the vertex stay on the front side of the face - VECADDFAC(tmp_co, nearest.co, nearest.no, calc->keepDist); + madd_v3_v3v3fl(tmp_co, nearest.co, nearest.no, calc->keepDist); } else { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 4a12206d404..0556291c197 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -816,7 +816,7 @@ static void calc_shapeKeys(Object *obedit) if (oldbezt) { int j; for (j= 0; j < 3; ++j) { - VECSUB(ofs[i], bezt->vec[j], oldbezt->vec[j]); + sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]); i++; } ofs[i++][0]= bezt->alfa - oldbezt->alfa; @@ -832,7 +832,7 @@ static void calc_shapeKeys(Object *obedit) while(a--) { oldbp= getKeyIndexOrig_bp(editnurb, bp); if (oldbp) { - VECSUB(ofs[i], bp->vec, oldbp->vec); + sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec); ofs[i+1][0]= bp->alfa - oldbp->alfa; } i += 2; @@ -866,10 +866,10 @@ static void calc_shapeKeys(Object *obedit) oldbezt= getKeyIndexOrig_bezt(editnurb, bezt); for (j= 0; j < 3; ++j, ++i) { - VECCOPY(fp, bezt->vec[j]); + copy_v3_v3(fp, bezt->vec[j]); if (restore && oldbezt) { - VECCOPY(bezt->vec[j], oldbezt->vec[j]); + copy_v3_v3(bezt->vec[j], oldbezt->vec[j]); } fp+= 3; @@ -890,12 +890,12 @@ static void calc_shapeKeys(Object *obedit) while(a--) { oldbp= getKeyIndexOrig_bp(editnurb, bp); - VECCOPY(fp, bp->vec); + copy_v3_v3(fp, bp->vec); fp[3]= bp->alfa; if(restore && oldbp) { - VECCOPY(bp->vec, oldbp->vec); + copy_v3_v3(bp->vec, oldbp->vec); bp->alfa= oldbp->alfa; } @@ -921,10 +921,10 @@ static void calc_shapeKeys(Object *obedit) curofp= ofp + index; for (j= 0; j < 3; ++j, ++i) { - VECCOPY(fp, curofp); + copy_v3_v3(fp, curofp); if(apply_offset) { - VECADD(fp, fp, ofs[i]); + add_v3_v3(fp, ofs[i]); } fp+= 3; curofp+= 3; @@ -933,7 +933,7 @@ static void calc_shapeKeys(Object *obedit) if(apply_offset) { /* apply alfa offsets */ - VECADD(fp, fp, ofs[i]); + add_v3_v3(fp, ofs[i]); ++i; } @@ -941,7 +941,7 @@ static void calc_shapeKeys(Object *obedit) } else { int j; for (j= 0; j < 3; ++j, ++i) { - VECCOPY(fp, bezt->vec[j]); + copy_v3_v3(fp, bezt->vec[j]); fp+= 3; } fp[0]= bezt->alfa; @@ -959,15 +959,15 @@ static void calc_shapeKeys(Object *obedit) if (index >= 0) { curofp= ofp + index; - VECCOPY(fp, curofp); + copy_v3_v3(fp, curofp); fp[3]= curofp[3]; if(apply_offset) { - VECADD(fp, fp, ofs[i]); + add_v3_v3(fp, ofs[i]); fp[3]+=ofs[i+1][0]; } } else { - VECCOPY(fp, bp->vec); + copy_v3_v3(fp, bp->vec); fp[3]= bp->alfa; } @@ -2890,14 +2890,14 @@ static void subdividenurb(Object *obedit, int number_cuts) interp_v3_v3v3(vec+12, vec+3, vec+6, factor); /* change handle of prev beztn */ - VECCOPY((beztn-1)->vec[2], vec); + copy_v3_v3((beztn-1)->vec[2], vec); /* new point */ - VECCOPY(beztn->vec[0], vec+9); + copy_v3_v3(beztn->vec[0], vec+9); interp_v3_v3v3(beztn->vec[1], vec+9, vec+12, factor); - VECCOPY(beztn->vec[2], vec+12); + copy_v3_v3(beztn->vec[2], vec+12); /* handle of next bezt */ - if(a==0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) {VECCOPY(beztnew->vec[0], vec+6);} - else {VECCOPY(bezt->vec[0], vec+6);} + if(a==0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) {copy_v3_v3(beztnew->vec[0], vec+6);} + else {copy_v3_v3(bezt->vec[0], vec+6);} beztn->radius = (prevbezt->radius + bezt->radius)/2; beztn->weight = (prevbezt->weight + bezt->weight)/2; @@ -3381,7 +3381,7 @@ static int convertspline(short type, Nurb *nu) a= nr; bp= nu->bp; while(a--) { - VECCOPY(bezt->vec[1], bp->vec); + copy_v3_v3(bezt->vec[1], bp->vec); bezt->f1=bezt->f2=bezt->f3= bp->f1; bezt->h1= bezt->h2= HD_VECT; bezt->weight= bp->weight; @@ -3418,7 +3418,7 @@ static int convertspline(short type, Nurb *nu) while(a--) { if(type==CU_POLY && bezt->h1==HD_VECT && bezt->h2==HD_VECT) { /* vector handle becomes 1 poly vertice */ - VECCOPY(bp->vec, bezt->vec[1]); + copy_v3_v3(bp->vec, bezt->vec[1]); bp->vec[3]= 1.0; bp->f1= bezt->f2; nr-= 2; @@ -3428,7 +3428,7 @@ static int convertspline(short type, Nurb *nu) } else { for(c=0;c<3;c++) { - VECCOPY(bp->vec, bezt->vec[c]); + copy_v3_v3(bp->vec, bezt->vec[c]); bp->vec[3]= 1.0; if(c==0) bp->f1= bezt->f1; else if(c==1) bp->f1= bezt->f2; @@ -3475,13 +3475,13 @@ static int convertspline(short type, Nurb *nu) a= nr; bp= nu->bp; while(a--) { - VECCOPY(bezt->vec[0], bp->vec); + copy_v3_v3(bezt->vec[0], bp->vec); bezt->f1= bp->f1; bp++; - VECCOPY(bezt->vec[1], bp->vec); + copy_v3_v3(bezt->vec[1], bp->vec); bezt->f2= bp->f1; bp++; - VECCOPY(bezt->vec[2], bp->vec); + copy_v3_v3(bezt->vec[2], bp->vec); bezt->f3= bp->f1; bezt->radius= bp->radius; bezt->weight= bp->weight; @@ -4472,7 +4472,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) (BezTriple*)MEM_callocN((nu->pntsu+1) * sizeof(BezTriple), "addvert_Nurb"); ED_curve_beztcpy(editnurb, newbezt, nu->bezt, nu->pntsu); *(newbezt+nu->pntsu)= *bezt; - VECCOPY(temp, bezt->vec[1]); + copy_v3_v3(temp, bezt->vec[1]); MEM_freeN(nu->bezt); nu->bezt= newbezt; newbezt+= nu->pntsu; @@ -4491,7 +4491,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) BEZ_SEL(newbezt); cu->lastsel= newbezt; newbezt->h2= newbezt->h1; - VECCOPY(temp, bezt->vec[1]); + copy_v3_v3(temp, bezt->vec[1]); MEM_freeN(nu->bezt); nu->bezt= newbezt; bezt= newbezt+1; @@ -4503,7 +4503,7 @@ static int addvert_Nurb(bContext *C, short mode, float location[3]) *newbezt= *bezt; BEZ_SEL(newbezt); newbezt->h2= newbezt->h1; - VECCOPY(temp, bezt->vec[1]); + copy_v3_v3(temp, bezt->vec[1]); newnu= (Nurb*)MEM_mallocN(sizeof(Nurb), "addvert_Nurb newnu"); memcpy(newnu, nu, sizeof(Nurb)); @@ -6189,7 +6189,7 @@ Nurb *add_nurbs_primitive(bContext *C, float mat[4][4], int type, int newob) if(rv3d) { copy_m4_m4(viewmat, rv3d->viewmat); - VECCOPY(zvec, rv3d->viewinv[2]); + copy_v3_v3(zvec, rv3d->viewinv[2]); } setflagsNurb(editnurb, 0); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c26a4d52a9e..754ccd1fd5e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2297,8 +2297,9 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) ofs= key_to_vertcos(ob, kb); /* calculate key coord offsets (from previous location) */ - for (a= 0; a < me->totvert; a++) - VECSUB(ofs[a], vertCos[a], ofs[a]); + for (a= 0; a < me->totvert; a++) { + sub_v3_v3v3(ofs[a], vertCos[a], ofs[a]); + } /* apply offsets on other keys */ currkey = me->key->block.first; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 7c89ce0f689..6605d488d36 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -242,7 +242,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 tstart(); - VECSUB(size, max, min); + sub_v3_v3v3(size, max, min); // maxx, maxy, maxz cv[0][0] = max[0]; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c3a77dc67a5..5d3e05dcaab 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -3882,7 +3882,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2])) else { d = distance; } - VECADDFAC(td->loc,td->center,td->axismtx[0],(*td->val)*d); + madd_v3_v3v3fl(td->loc, td->center, td->axismtx[0], (*td->val) * d); } recalcData(t); diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 8a50ec28bd6..0f21aa3759c 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -267,10 +267,10 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac #endif /* uv angles */ - VECSUB2D(av1, tf_uv[3], tf_uv[0]); normalize_v2(av1); - VECSUB2D(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2); - VECSUB2D(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3); - VECSUB2D(av4, tf_uv[2], tf_uv[3]); normalize_v2(av4); + sub_v2_v2v2(av1, tf_uv[3], tf_uv[0]); normalize_v2(av1); + sub_v2_v2v2(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2); + sub_v2_v2v2(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3); + sub_v2_v2v2(av4, tf_uv[2], tf_uv[3]); normalize_v2(av4); /* This is the correct angle however we are only comparing angles * uvang1 = 90-((angle_normalized_v2v2(av1, av2) * RAD2DEGF(1.0f))-90);*/ @@ -280,10 +280,10 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac uvang4 = angle_normalized_v2v2(av4, av1); /* 3d angles */ - VECSUB(av1, efa->v4->co, efa->v1->co); normalize_v3(av1); - VECSUB(av2, efa->v1->co, efa->v2->co); normalize_v3(av2); - VECSUB(av3, efa->v2->co, efa->v3->co); normalize_v3(av3); - VECSUB(av4, efa->v3->co, efa->v4->co); normalize_v3(av4); + sub_v3_v3v3(av1, efa->v4->co, efa->v1->co); normalize_v3(av1); + sub_v3_v3v3(av2, efa->v1->co, efa->v2->co); normalize_v3(av2); + sub_v3_v3v3(av3, efa->v2->co, efa->v3->co); normalize_v3(av3); + sub_v3_v3v3(av4, efa->v3->co, efa->v4->co); normalize_v3(av4); /* This is the correct angle however we are only comparing angles * ang1 = 90-((angle_normalized_v3v3(av1, av2) * RAD2DEGF(1.0f))-90);*/ @@ -328,9 +328,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac #endif /* uv angles */ - VECSUB2D(av1, tf_uv[2], tf_uv[0]); normalize_v2(av1); - VECSUB2D(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2); - VECSUB2D(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3); + sub_v2_v2v2(av1, tf_uv[2], tf_uv[0]); normalize_v2(av1); + sub_v2_v2v2(av2, tf_uv[0], tf_uv[1]); normalize_v2(av2); + sub_v2_v2v2(av3, tf_uv[1], tf_uv[2]); normalize_v2(av3); /* This is the correct angle however we are only comparing angles * uvang1 = 90-((angle_normalized_v2v2(av1, av2) * 180.0/M_PI)-90); */ @@ -339,9 +339,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, EditMesh *em, MTFac uvang3 = angle_normalized_v2v2(av3, av1); /* 3d angles */ - VECSUB(av1, efa->v3->co, efa->v1->co); normalize_v3(av1); - VECSUB(av2, efa->v1->co, efa->v2->co); normalize_v3(av2); - VECSUB(av3, efa->v2->co, efa->v3->co); normalize_v3(av3); + sub_v3_v3v3(av1, efa->v3->co, efa->v1->co); normalize_v3(av1); + sub_v3_v3v3(av2, efa->v1->co, efa->v2->co); normalize_v3(av2); + sub_v3_v3v3(av3, efa->v2->co, efa->v3->co); normalize_v3(av3); /* This is the correct angle however we are only comparing angles * ang1 = 90-((angle_normalized_v3v3(av1, av2) * 180.0/M_PI)-90); */ ang1 = angle_normalized_v3v3(av1, av2); diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c index a19b339e674..499f8ce300f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normal.c +++ b/source/blender/nodes/composite/nodes/node_composite_normal.c @@ -66,7 +66,7 @@ static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStac if(in[0]->data==NULL) { VECCOPY(out[0]->vec, nor); /* render normals point inside... the widget points outside */ - out[1]->vec[0]= -INPR(out[0]->vec, in[0]->vec); + out[1]->vec[0]= -dot_v3v3(out[0]->vec, in[0]->vec); } else if(out[1]->hasoutput) { /* make output size of input image */ diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp index a6d02db8cea..abc45293542 100644 --- a/source/gameengine/Converter/BL_ActionActuator.cpp +++ b/source/gameengine/Converter/BL_ActionActuator.cpp @@ -445,9 +445,9 @@ KX_PYMETHODDEF_DOC(BL_ActionActuator, setChannel, pchan= get_pose_channel(m_userpose, string); // adds the channel if its not there. if(pchan) { - VECCOPY (pchan->loc, matrix[3]); - mat4_to_size( pchan->size,matrix); - mat4_to_quat( pchan->quat,matrix); + copy_v3_v3(pchan->loc, matrix[3]); + mat4_to_size(pchan->size, matrix); + mat4_to_quat(pchan->quat, matrix); } } else { From d8717d2628b3b57f2c5a60a417806d903a531179 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 15:39:20 +0000 Subject: [PATCH 115/147] more macro --> bli math lib replacements. --- source/blender/blenkernel/BKE_effect.h | 2 +- .../blender/blenkernel/intern/DerivedMesh.c | 21 +-- source/blender/blenkernel/intern/boids.c | 126 +++++++++--------- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/effect.c | 24 ++-- source/blender/blenkernel/intern/fluidsim.c | 2 +- source/blender/blenkernel/intern/smoke.c | 83 ++++++------ source/blender/blenkernel/intern/softbody.c | 2 +- source/blender/editors/mesh/editmesh.c | 5 +- .../blender/render/intern/source/occlusion.c | 6 +- 10 files changed, 137 insertions(+), 136 deletions(-) diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 59a361c010d..7f4e809718c 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -129,7 +129,7 @@ void pd_point_from_soft(struct Scene *scene, float *loc, float *vel, int index, /* needed for boids */ float effector_falloff(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, struct EffectorWeights *weights); -int closest_point_on_surface(struct SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel); +int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], float surface_co[3], float surface_nor[3], float surface_vel[3]); int get_effector_data(struct EffectorCache *eff, struct EffectorData *efd, struct EffectedPoint *point, int real_velocity); /* required for particle_system.c */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 0c99735f73e..aaed0381b2e 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -292,7 +292,7 @@ void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb) mvert=dm->getVertDataArray(dm, CD_MVERT); for(a=0; atotelem; a++, fp+=3, mvert++) { - VECCOPY(fp, mvert->co); + copy_v3_v3(fp, mvert->co); } } @@ -604,12 +604,12 @@ static void emDM_drawUVEdges(DerivedMesh *dm) static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3]) { if (vertexCos) { - VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]); + copy_v3_v3(cent, vertexCos[(int) efa->v1->tmp.l]); add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]); add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]); if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]); } else { - VECCOPY(cent, efa->v1->co); + copy_v3_v3(cent, efa->v1->co); add_v3_v3(cent, efa->v2->co); add_v3_v3(cent, efa->v3->co); if (efa->v4) add_v3_v3(cent, efa->v4->co); @@ -1184,7 +1184,7 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r) for(i = 0; i < index; ++i) ev = ev->next; - VECCOPY(vert_r->co, ev->co); + copy_v3_v3(vert_r->co, ev->co); normal_float_to_short_v3(vert_r->no, ev->no); @@ -1539,8 +1539,9 @@ static float *get_editmesh_orco_verts(EditMesh *em) orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco"); - for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) - VECCOPY(orco+a, eve->co); + for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3) { + copy_v3_v3(orco+a, eve->co); + } return orco; } @@ -2146,7 +2147,7 @@ float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3] cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos"); for (i=0,eve=em->verts.first; inext) { - VECCOPY(cos[i], eve->co); + copy_v3_v3(cos[i], eve->co); } return cos; @@ -2654,7 +2655,7 @@ static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const //assert(vert_index>=0 && vert_index<4); SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; const float *co= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co; - VECCOPY(fPos, co); + copy_v3_v3(fPos, co); } static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index) @@ -2680,7 +2681,7 @@ static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH); if(!smoothnormal) { // flat if(pMesh->precomputedFaceNormals) { - VECCOPY(fNorm, &pMesh->precomputedFaceNormals[3*face_num]); + copy_v3_v3(fNorm, &pMesh->precomputedFaceNormals[3*face_num]); } else { MFace *mf= &pMesh->mface[face_num]; @@ -2707,7 +2708,7 @@ static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent //assert(vert_index>=0 && vert_index<4); SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; float * pRes = pMesh->tangent[4*face_num+iVert]; - VECCOPY(pRes, fvTangent); + copy_v3_v3(pRes, fvTangent); pRes[3]=fSign; } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 3ae81c70d4f..c9868bd900f 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -162,7 +162,7 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, negate_v3_v3(efd.vec_to_point, bpa->gravity); } - VECCOPY(bbd->wanted_co, efd.vec_to_point); + copy_v3_v3(bbd->wanted_co, efd.vec_to_point); mul_v3_fl(bbd->wanted_co, mul); bbd->wanted_speed = val->max_speed * priority; @@ -204,7 +204,7 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * BVHTreeRayHit hit; float radius = val->personal_space * pa->size, ray_dir[3]; - VECCOPY(col.co1, pa->prev_state.co); + copy_v3_v3(col.co1, pa->prev_state.co); add_v3_v3v3(col.co2, pa->prev_state.co, pa->prev_state.vel); sub_v3_v3v3(ray_dir, col.co2, col.co1); mul_v3_fl(ray_dir, acbr->look_ahead); @@ -254,10 +254,10 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * { neighbors = BLI_kdtree_range_search(bbd->sim->psys->tree, acbr->look_ahead * len_v3(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn); if(neighbors > 1) for(n=1; nprev_state.co); - VECCOPY(vel1, pa->prev_state.vel); - VECCOPY(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co); - VECCOPY(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel); + copy_v3_v3(co1, pa->prev_state.co); + copy_v3_v3(vel1, pa->prev_state.vel); + copy_v3_v3(co2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.co); + copy_v3_v3(vel2, (bbd->sim->psys->particles + ptn[n].index)->prev_state.vel); sub_v3_v3v3(loc, co1, co2); @@ -270,8 +270,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * t = -dot_v3v3(loc, vec)/inp; /* cpa is not too far in the future so investigate further */ if(t > 0.0f && t < t_min) { - VECADDFAC(co1, co1, vel1, t); - VECADDFAC(co2, co2, vel2, t); + madd_v3_v3fl(co1, vel1, t); + madd_v3_v3fl(co2, vel2, t); sub_v3_v3v3(vec, co2, co1); @@ -300,10 +300,10 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * if(epsys) { neighbors = BLI_kdtree_range_search(epsys->tree, acbr->look_ahead * len_v3(pa->prev_state.vel), pa->prev_state.co, pa->prev_state.ave, &ptn); if(neighbors > 0) for(n=0; nprev_state.co); - VECCOPY(vel1, pa->prev_state.vel); - VECCOPY(co2, (epsys->particles + ptn[n].index)->prev_state.co); - VECCOPY(vel2, (epsys->particles + ptn[n].index)->prev_state.vel); + copy_v3_v3(co1, pa->prev_state.co); + copy_v3_v3(vel1, pa->prev_state.vel); + copy_v3_v3(co2, (epsys->particles + ptn[n].index)->prev_state.co); + copy_v3_v3(vel2, (epsys->particles + ptn[n].index)->prev_state.vel); sub_v3_v3v3(loc, co1, co2); @@ -316,8 +316,8 @@ static int rule_avoid_collision(BoidRule *rule, BoidBrainData *bbd, BoidValues * t = -dot_v3v3(loc, vec)/inp; /* cpa is not too far in the future so investigate further */ if(t > 0.0f && t < t_min) { - VECADDFAC(co1, co1, vel1, t); - VECADDFAC(co2, co2, vel2, t); + madd_v3_v3fl(co1, vel1, t); + madd_v3_v3fl(co2, vel2, t); sub_v3_v3v3(vec, co2, co1); @@ -439,7 +439,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va len = len_v3(loc); /* too close to leader */ if(len < 2.0f * val->personal_space * pa->size) { - VECCOPY(bbd->wanted_co, loc); + copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed; return 1; } @@ -449,7 +449,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* possible blocking of leader in near future */ if(t > 0.0f && t < 3.0f) { - VECCOPY(vec2, vec); + copy_v3_v3(vec2, vec); mul_v3_fl(vec2, t); sub_v3_v3v3(vec2, loc, vec2); @@ -457,7 +457,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va len = len_v3(vec2); if(len < 2.0f * val->personal_space * pa->size) { - VECCOPY(bbd->wanted_co, vec2); + copy_v3_v3(bbd->wanted_co, vec2); bbd->wanted_speed = val->max_speed * (3.0f - t)/3.0f; return 1; } @@ -466,17 +466,17 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* not blocking so try to follow leader */ if(p && flbr->options & BRULE_LEADER_IN_LINE) { - VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel); - VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co); + copy_v3_v3(vec, bbd->sim->psys->particles[p-1].prev_state.vel); + copy_v3_v3(loc, bbd->sim->psys->particles[p-1].prev_state.co); } else { - VECCOPY(loc, flbr->oloc); + copy_v3_v3(loc, flbr->oloc); sub_v3_v3v3(vec, flbr->loc, flbr->oloc); mul_v3_fl(vec, 1.0f/bbd->timestep); } /* fac is seconds behind leader */ - VECADDFAC(loc, loc, vec, -flbr->distance); + madd_v3_v3fl(loc, vec, -flbr->distance); sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co); bbd->wanted_speed = len_v3(bbd->wanted_co); @@ -488,7 +488,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* first check we're not blocking any leaders */ for(i = 0; i< bbd->sim->psys->totpart; i+=n){ - VECCOPY(vec, bbd->sim->psys->particles[i].prev_state.vel); + copy_v3_v3(vec, bbd->sim->psys->particles[i].prev_state.vel); sub_v3_v3v3(loc, pa->prev_state.co, bbd->sim->psys->particles[i].prev_state.co); @@ -499,7 +499,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va len = len_v3(loc); /* too close to leader */ if(len < 2.0f * val->personal_space * pa->size) { - VECCOPY(bbd->wanted_co, loc); + copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed; return 1; } @@ -509,7 +509,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* possible blocking of leader in near future */ if(t > 0.0f && t < t_min) { - VECCOPY(vec2, vec); + copy_v3_v3(vec2, vec); mul_v3_fl(vec2, t); sub_v3_v3v3(vec2, loc, vec2); @@ -518,7 +518,7 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va if(len < 2.0f * val->personal_space * pa->size) { t_min = t; - VECCOPY(bbd->wanted_co, loc); + copy_v3_v3(bbd->wanted_co, loc); bbd->wanted_speed = val->max_speed * (3.0f - t)/3.0f; ret = 1; } @@ -530,16 +530,16 @@ static int rule_follow_leader(BoidRule *rule, BoidBrainData *bbd, BoidValues *va /* not blocking so try to follow leader */ if(flbr->options & BRULE_LEADER_IN_LINE) { - VECCOPY(vec, bbd->sim->psys->particles[p-1].prev_state.vel); - VECCOPY(loc, bbd->sim->psys->particles[p-1].prev_state.co); + copy_v3_v3(vec, bbd->sim->psys->particles[p-1].prev_state.vel); + copy_v3_v3(loc, bbd->sim->psys->particles[p-1].prev_state.co); } else { - VECCOPY(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel); - VECCOPY(loc, bbd->sim->psys->particles[p - p%n].prev_state.co); + copy_v3_v3(vec, bbd->sim->psys->particles[p - p%n].prev_state.vel); + copy_v3_v3(loc, bbd->sim->psys->particles[p - p%n].prev_state.co); } /* fac is seconds behind leader */ - VECADDFAC(loc, loc, vec, -flbr->distance); + madd_v3_v3fl(loc, vec, -flbr->distance); sub_v3_v3v3(bbd->wanted_co, loc, pa->prev_state.co); bbd->wanted_speed = len_v3(bbd->wanted_co); @@ -563,11 +563,11 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va normalize_v3(bpa->wander); - VECCOPY(vec, bpa->wander); + copy_v3_v3(vec, bpa->wander); mul_qt_v3(pa->prev_state.rot, vec); - VECCOPY(bbd->wanted_co, pa->prev_state.ave); + copy_v3_v3(bbd->wanted_co, pa->prev_state.ave); mul_v3_fl(bbd->wanted_co, 1.1f); @@ -581,7 +581,7 @@ static int rule_average_speed(BoidRule *rule, BoidBrainData *bbd, BoidValues *va } } else { - VECCOPY(bbd->wanted_co, pa->prev_state.ave); + copy_v3_v3(bbd->wanted_co, pa->prev_state.ave); /* may happen at birth */ if(dot_v2v2(bbd->wanted_co,bbd->wanted_co)==0.0f) { @@ -643,7 +643,7 @@ static int rule_fight(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, Parti health += bpa->data.health; if(n==0 && pt->mode==PTARGET_MODE_ENEMY && ptn[n].dist < closest_dist) { - VECCOPY(closest_enemy, ptn[n].co); + copy_v3_v3(closest_enemy, ptn[n].co); closest_dist = ptn[n].dist; enemy_pa = epars + ptn[n].index; } @@ -741,7 +741,7 @@ static void set_boid_values(BoidValues *val, BoidSettings *boids, ParticleData * } } -static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *ground_co, float *ground_nor) +static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float ground_co[3], float ground_nor[3]) { BoidParticle *bpa = pa->boid; @@ -820,7 +820,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, ParticleData *pa, float *gro } /* default to z=0 */ - VECCOPY(ground_co, pa->state.co); + copy_v3_v3(ground_co, pa->state.co); ground_co[2] = 0; ground_nor[0] = ground_nor[1] = 0.0f; ground_nor[2] = 1.0f; @@ -853,8 +853,8 @@ void boids_precalc_rules(ParticleSettings *part, float cfra) if(flbr->ob && flbr->cfra != cfra) { /* save object locations for velocity calculations */ - VECCOPY(flbr->oloc, flbr->loc); - VECCOPY(flbr->loc, flbr->ob->obmat[3]); + copy_v3_v3(flbr->oloc, flbr->loc); + copy_v3_v3(flbr->loc, flbr->ob->obmat[3]); flbr->cfra = cfra; } } @@ -868,7 +868,7 @@ static void boid_climb(BoidSettings *boids, ParticleData *pa, float *surface_co, copy_v3_v3(nor, surface_nor); /* gather apparent gravity */ - VECADDFAC(bpa->gravity, bpa->gravity, surface_nor, -1.0f); + madd_v3_v3fl(bpa->gravity, surface_nor, -1.0f); normalize_v3(bpa->gravity); /* raise boid it's size from surface */ @@ -997,7 +997,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) wanted_speed /= (float)n; } - VECCOPY(bbd->wanted_co, wanted_co); + copy_v3_v3(bbd->wanted_co, wanted_co); bbd->wanted_speed = wanted_speed; break; } @@ -1012,10 +1012,10 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) if(boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f) { float cvel[3], dir[3]; - VECCOPY(dir, pa->prev_state.ave); + copy_v3_v3(dir, pa->prev_state.ave); normalize_v2(dir); - VECCOPY(cvel, bbd->wanted_co); + copy_v3_v3(cvel, bbd->wanted_co); normalize_v2(cvel); if(dot_v2v2(cvel, dir) > 0.95f / mul) @@ -1031,10 +1031,10 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) float z_v, ground_v, cur_v; float len; - VECCOPY(dir, pa->prev_state.ave); + copy_v3_v3(dir, pa->prev_state.ave); normalize_v2(dir); - VECCOPY(cvel, bbd->wanted_co); + copy_v3_v3(cvel, bbd->wanted_co); normalize_v2(cvel); len = len_v2(pa->prev_state.vel); @@ -1054,7 +1054,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) len = MIN2(len, val.jump_speed); - VECCOPY(jump_v, dir); + copy_v3_v3(jump_v, dir); jump_v[2] = z_v; mul_v3_fl(jump_v, ground_v); @@ -1071,7 +1071,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) } if(jump) { - VECCOPY(pa->prev_state.vel, jump_v); + copy_v3_v3(pa->prev_state.vel, jump_v); bpa->data.mode = eBoidMode_Falling; } } @@ -1143,12 +1143,12 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) } } - VECCOPY(old_dir, pa->prev_state.ave); + copy_v3_v3(old_dir, pa->prev_state.ave); new_speed = normalize_v3_v3(wanted_dir, bbd->wanted_co); /* first check if we have valid direction we want to go towards */ if(new_speed == 0.0f) { - VECCOPY(new_dir, old_dir); + copy_v3_v3(new_dir, old_dir); } else { float old_dir2[2], wanted_dir2[2], nor[3], angle; @@ -1172,13 +1172,13 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) cross_v3_v3v3(nor, old_dir, wanted_dir); axis_angle_to_quat( q,nor, angle); - VECCOPY(new_dir, old_dir); + copy_v3_v3(new_dir, old_dir); mul_qt_v3(q, new_dir); normalize_v3(new_dir); /* save direction in case resulting velocity too small */ axis_angle_to_quat( q,nor, angle*dtime); - VECCOPY(pa->state.ave, old_dir); + copy_v3_v3(pa->state.ave, old_dir); mul_qt_v3(q, pa->state.ave); normalize_v3(pa->state.ave); } @@ -1192,7 +1192,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) new_speed = MIN2(bbd->wanted_speed, old_speed + val.max_acc); /* combine direction and speed */ - VECCOPY(new_vel, new_dir); + copy_v3_v3(new_vel, new_dir); mul_v3_fl(new_vel, new_speed); /* maintain minimum flying velocity if not landing */ @@ -1236,7 +1236,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) add_v3_v3(acc, force); /* store smoothed acceleration for nice banking etc. */ - VECADDFAC(bpa->data.acc, bpa->data.acc, acc, dtime); + madd_v3_v3fl(bpa->data.acc, acc, dtime); mul_v3_fl(bpa->data.acc, 1.0f / (1.0f + dtime)); /* integrate new location & velocity */ @@ -1245,15 +1245,15 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* can get better control allthough it's a bit unphysical */ mul_v3_fl(acc, 1.0f/pa_mass); - VECCOPY(dvec, acc); + copy_v3_v3(dvec, acc); mul_v3_fl(dvec, dtime*dtime*0.5f); - VECCOPY(bvec, pa->prev_state.vel); + copy_v3_v3(bvec, pa->prev_state.vel); mul_v3_fl(bvec, dtime); add_v3_v3(dvec, bvec); add_v3_v3(pa->state.co, dvec); - VECADDFAC(pa->state.vel, pa->state.vel, acc, dtime); + madd_v3_v3fl(pa->state.vel, acc, dtime); //if(bpa->data.mode != eBoidMode_InAir) bpa->ground = boid_find_ground(bbd, pa, ground_co, ground_nor); @@ -1274,11 +1274,11 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) sub_v3_v3v3(dvec, bpa->data.acc, dvec); } else { - VECCOPY(dvec, bpa->data.acc); + copy_v3_v3(dvec, bpa->data.acc); } /* gather apparent gravity */ - VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + madd_v3_v3v3fl(bpa->gravity, grav, dvec, -boids->banking); normalize_v3(bpa->gravity); /* stick boid on goal when close enough */ @@ -1313,7 +1313,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* gather apparent gravity */ - VECADDFAC(bpa->gravity, bpa->gravity, grav, dtime); + madd_v3_v3fl(bpa->gravity, grav, dtime); normalize_v3(bpa->gravity); if(boids->options & BOID_ALLOW_LAND) { @@ -1345,7 +1345,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) //copy_v3_v3(nor, ground_nor); ///* gather apparent gravity to r_ve */ - //VECADDFAC(pa->r_ve, pa->r_ve, ground_nor, -1.0); + //madd_v3_v3fl(pa->r_ve, ground_nor, -1.0); //normalize_v3(pa->r_ve); ///* raise boid it's size from surface */ @@ -1385,12 +1385,12 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) sub_v3_v3v3(dvec, bpa->data.acc, dvec); /* gather apparent gravity */ - VECADDFAC(bpa->gravity, grav, dvec, -boids->banking); + madd_v3_v3v3fl(bpa->gravity, grav, dvec, -boids->banking); normalize_v3(bpa->gravity); } else { /* gather negative surface normal */ - VECADDFAC(bpa->gravity, bpa->gravity, ground_nor, -1.0f); + madd_v3_v3fl(bpa->gravity, ground_nor, -1.0f); normalize_v3(bpa->gravity); } break; @@ -1411,7 +1411,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) /* calculate rotation matrix based on forward & down vectors */ if(bpa->data.mode == eBoidMode_InAir) { - VECCOPY(mat[0], pa->state.ave); + copy_v3_v3(mat[0], pa->state.ave); project_v3_v3v3(dvec, bpa->gravity, pa->state.ave); sub_v3_v3v3(mat[2], bpa->gravity, dvec); @@ -1422,7 +1422,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) sub_v3_v3v3(mat[0], pa->state.ave, dvec); normalize_v3(mat[0]); - VECCOPY(mat[2], bpa->gravity); + copy_v3_v3(mat[2], bpa->gravity); } negate_v3(mat[2]); cross_v3_v3v3(mat[1], mat[2], mat[0]); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 444d17ad004..f917a0fe68c 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -190,7 +190,7 @@ static BVHTree *bvhselftree_build_from_cloth (ClothModifierData *clmd, float eps // fill tree for(i = 0; i < cloth->numverts; i++, verts++) { - VECCOPY(&co[0*3], verts->xold); + copy_v3_v3(&co[0*3], verts->xold); BLI_bvhtree_insert(bvhtree, i, co, 1); } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index bb14a1ddeaf..7b58c0bc00b 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -555,7 +555,7 @@ float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *UNU if(falloff == 0.0f) break; - VECADDFAC(temp, efd->vec_to_point, efd->nor, -fac); + madd_v3_v3v3fl(temp, efd->vec_to_point, efd->nor, -fac); r_fac= len_v3(temp); falloff*= falloff_func_rad(eff->pd, r_fac); break; @@ -573,7 +573,7 @@ float effector_falloff(EffectorCache *eff, EffectorData *efd, EffectedPoint *UNU return falloff; } -int closest_point_on_surface(SurfaceModifierData *surmd, float *co, float *surface_co, float *surface_nor, float *surface_vel) +int closest_point_on_surface(SurfaceModifierData *surmd, const float co[3], float surface_co[3], float surface_nor[3], float surface_vel[3]) { BVHTreeNearest nearest; @@ -797,7 +797,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP if(eff->pd->flag & PFIELD_TEX_2D) { float fac=-dot_v3v3(tex_co, efd->nor); - VECADDFAC(tex_co, tex_co, efd->nor, fac); + madd_v3_v3fl(tex_co, efd->nor, fac); } if(eff->pd->flag & PFIELD_TEX_OBJECT) { @@ -848,7 +848,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP if(eff->pd->flag & PFIELD_TEX_2D){ float fac = -dot_v3v3(force, efd->nor); - VECADDFAC(force, force, efd->nor, fac); + madd_v3_v3fl(force, efd->nor, fac); } add_v3_v3(total_force, force); @@ -897,7 +897,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected cross_v3_v3v3(force, efd->nor2, temp); mul_v3_fl(force, strength * efd->falloff); - VECADDFAC(temp, temp, point->vel, -point->vel_to_sec); + madd_v3_v3fl(temp, point->vel, -point->vel_to_sec); add_v3_v3(force, temp); } break; @@ -940,7 +940,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected copy_v3_v3(temp, point->loc); } else { - VECADD(temp, efd->vec_to_point2, efd->nor2); + add_v3_v3v3(temp, efd->vec_to_point2, efd->nor2); } force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2,0,2); force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2,0,2); @@ -959,10 +959,10 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected } if(pd->flag & PFIELD_DO_LOCATION) { - VECADDFAC(total_force, total_force, force, 1.0f/point->vel_to_sec); + madd_v3_v3fl(total_force, force, 1.0f/point->vel_to_sec); if(ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { - VECADDFAC(total_force, total_force, point->vel, -pd->f_flow * efd->falloff); + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); } } @@ -972,7 +972,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_qt_v3(point->rot, xvec); cross_v3_v3v3(dave, xvec, force); if(pd->f_flow != 0.0f) { - VECADDFAC(dave, dave, point->ave, -pd->f_flow * efd->falloff); + madd_v3_v3fl(dave, point->ave, -pd->f_flow * efd->falloff); } add_v3_v3(point->ave, dave); } @@ -1038,14 +1038,14 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we // for softbody backward compatibility if(point->flag & PE_WIND_AS_SPEED && impulse){ - VECSUB(temp2, force, temp1); - VECSUB(impulse, impulse, temp2); + sub_v3_v3v3(temp2, force, temp1); + sub_v3_v3v3(impulse, impulse, temp2); } } } else if(eff->flag & PE_VELOCITY_TO_IMPULSE && impulse) { /* special case for harmonic effector */ - VECADD(impulse, impulse, efd.vel); + add_v3_v3v3(impulse, impulse, efd.vel); } } } diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c index bf432785064..cdb2b194b43 100644 --- a/source/blender/blenkernel/intern/fluidsim.c +++ b/source/blender/blenkernel/intern/fluidsim.c @@ -92,7 +92,7 @@ void initElbeemMesh(struct Scene *scene, struct Object *ob, *numVertices = totvert; verts = MEM_callocN( totvert*3*sizeof(float), "elbeemmesh_vertices"); for(i=0; iobmat, &verts[i*3]); } } *vertices = verts; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 7174126a00c..60941ef78a3 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -172,7 +172,7 @@ static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, { float tmp[3]; - VECCOPY(tmp, verts[i].co); + copy_v3_v3(tmp, verts[i].co); mul_m4_v3(ob->obmat, tmp); // min BB @@ -186,11 +186,11 @@ static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, max[2] = MAX2(max[2], tmp[2]); } - VECCOPY(smd->domain->p0, min); - VECCOPY(smd->domain->p1, max); + copy_v3_v3(smd->domain->p0, min); + copy_v3_v3(smd->domain->p1, max); // calc other res with max_res provided - VECSUB(size, max, min); + sub_v3_v3v3(size, max, min); // printf("size: %f, %f, %f\n", size[0], size[1], size[2]); @@ -354,9 +354,9 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) for(i = 0; i < dm->getNumVerts(dm); i++) { float tmpvec[3]; - VECCOPY(tmpvec, mvert[i].co); + copy_v3_v3(tmpvec, mvert[i].co); mul_m4_v3(ob->obmat, tmpvec); - VECCOPY(&scs->points[i * 3], tmpvec); + copy_v3_v3(&scs->points[i * 3], tmpvec); } for(i = 0, facecounter = 0; i < dm->getNumFaces(dm); i++) @@ -372,18 +372,18 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) if(again == 1 && mface[i].v4) { - VECSUB(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - VECSUB(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); + sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); + sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); } else { - VECSUB(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - VECSUB(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); + sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); + sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); } cross_v3_v3v3(trinormorg, side1, side2); normalize_v3(trinormorg); - VECCOPY(trinorm, trinormorg); + copy_v3_v3(trinorm, trinormorg); mul_v3_fl(trinorm, 0.25 * cell_len); for(j = 0; j <= divs1; j++) @@ -401,43 +401,42 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) continue; } - VECCOPY(p1, mvert[ mface[i].v1 ].co); + copy_v3_v3(p1, mvert[ mface[i].v1 ].co); if(again == 1 && mface[i].v4) { - VECCOPY(p2, mvert[ mface[i].v3 ].co); - VECCOPY(p3, mvert[ mface[i].v4 ].co); + copy_v3_v3(p2, mvert[ mface[i].v3 ].co); + copy_v3_v3(p3, mvert[ mface[i].v4 ].co); } else { - VECCOPY(p2, mvert[ mface[i].v2 ].co); - VECCOPY(p3, mvert[ mface[i].v3 ].co); + copy_v3_v3(p2, mvert[ mface[i].v2 ].co); + copy_v3_v3(p3, mvert[ mface[i].v3 ].co); } mul_v3_fl(p1, (1.0-uf-vf)); mul_v3_fl(p2, uf); mul_v3_fl(p3, vf); - VECADD(p, p1, p2); - VECADD(p, p, p3); + add_v3_v3v3(p, p1, p2); + add_v3_v3(p, p3); if(newdivs > divs) printf("mem problem\n"); // mMovPoints.push_back(p + trinorm); - VECCOPY(tmpvec, p); - VECADD(tmpvec, tmpvec, trinorm); + add_v3_v3v3(tmpvec, p, trinorm); mul_m4_v3(ob->obmat, tmpvec); - VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); + copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); newdivs++; if(newdivs > divs) printf("mem problem\n"); // mMovPoints.push_back(p - trinorm); - VECCOPY(tmpvec, p); - VECSUB(tmpvec, tmpvec, trinorm); + copy_v3_v3(tmpvec, p); + sub_v3_v3(tmpvec, trinorm); mul_m4_v3(ob->obmat, tmpvec); - VECCOPY(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); + copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); newdivs++; } } @@ -488,23 +487,23 @@ static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFa float side3[3]; int divs1=0, divs2=0, divs3=0; - VECCOPY(p0, verts[faces[i].v1].co); + copy_v3_v3(p0, verts[faces[i].v1].co); mul_m4_v3(ob->obmat, p0); - VECCOPY(p1, verts[faces[i].v2].co); + copy_v3_v3(p1, verts[faces[i].v2].co); mul_m4_v3(ob->obmat, p1); - VECCOPY(p2, verts[faces[i].v3].co); + copy_v3_v3(p2, verts[faces[i].v3].co); mul_m4_v3(ob->obmat, p2); - VECSUB(side1, p1, p0); - VECSUB(side2, p2, p0); - VECSUB(side3, p1, p2); + sub_v3_v3v3(side1, p1, p0); + sub_v3_v3v3(side2, p2, p0); + sub_v3_v3v3(side3, p1, p2); - if(INPR(side1, side1) > fsTri*fsTri) + if(dot_v3v3(side1, side1) > fsTri*fsTri) { float tmp = normalize_v3(side1); divs1 = (int)ceil(tmp/fsTri); } - if(INPR(side2, side2) > fsTri*fsTri) + if(dot_v3v3(side2, side2) > fsTri*fsTri) { float tmp = normalize_v3(side2); divs2 = (int)ceil(tmp/fsTri); @@ -527,23 +526,23 @@ static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFa facecounter++; - VECCOPY(p0, verts[faces[i].v3].co); + copy_v3_v3(p0, verts[faces[i].v3].co); mul_m4_v3(ob->obmat, p0); - VECCOPY(p1, verts[faces[i].v4].co); + copy_v3_v3(p1, verts[faces[i].v4].co); mul_m4_v3(ob->obmat, p1); - VECCOPY(p2, verts[faces[i].v1].co); + copy_v3_v3(p2, verts[faces[i].v1].co); mul_m4_v3(ob->obmat, p2); - VECSUB(side1, p1, p0); - VECSUB(side2, p2, p0); - VECSUB(side3, p1, p2); + sub_v3_v3v3(side1, p1, p0); + sub_v3_v3v3(side2, p2, p0); + sub_v3_v3v3(side3, p1, p2); - if(INPR(side1, side1) > fsTri*fsTri) + if(dot_v3v3(side1, side1) > fsTri*fsTri) { float tmp = normalize_v3(side1); divs1 = (int)ceil(tmp/fsTri); } - if(INPR(side2, side2) > fsTri*fsTri) + if(dot_v3v3(side2, side2) > fsTri*fsTri) { float tmp = normalize_v3(side2); divs2 = (int)ceil(tmp/fsTri); @@ -1050,7 +1049,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd) if(psys_get_particle_state(&sim, p, &state, 0) == 0) continue; - // VECCOPY(pos, pa->state.co); + // copy_v3_v3(pos, pa->state.co); // mul_m4_v3(ob->imat, pos); // 1. get corresponding cell get_cell(smd->domain->p0, smd->domain->res, smd->domain->dx, state.co, cell, 0); @@ -1589,7 +1588,7 @@ static void get_cell(float *p0, int res[3], float dx, float *pos, int *cell, int { float tmp[3]; - VECSUB(tmp, pos, p0); + sub_v3_v3v3(tmp, pos, p0); mul_v3_fl(tmp, 1.0 / dx); if(correct) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 28925a7b170..accf3e442e8 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2697,7 +2697,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* gravitation */ - VECADDFAC(bp->force, bp->force, gravity, _final_mass(ob,bp)); /* individual mass of node here */ + madd_v3_v3fl(bp->force, gravity, _final_mass(ob,bp)); /* individual mass of node here */ /* particle field & vortex */ diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index 85ac87d8bcb..f6aae0e20ae 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1181,8 +1181,9 @@ void load_editMesh(Scene *scene, Object *obedit) eve= em->verts.first; mvert = me->mvert; while(eve) { - if(eve->keyindex>=0) - VECSUB(ofs[i], mvert->co, fp[eve->keyindex]); + if(eve->keyindex>=0) { + sub_v3_v3v3(ofs[i], mvert->co, fp[eve->keyindex]); + } eve= eve->next; i++; diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index b0a6e428b18..7434425d24b 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -1229,7 +1229,7 @@ static void occ_lookup(OcclusionTree *tree, int thread, OccFace *exclude, float /* pop point off the stack */ node= stack[--totstack]; - VECSUB(v, node->co, p); + sub_v3_v3v3(v, node->co, p); d2= dot_v3v3(v, v) + 1e-16f; emitarea= MAX2(node->area, node->dco); @@ -1484,7 +1484,7 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int if(cache->sample && cache->step) { sample= &cache->sample[(y-cache->y)*cache->w + (x-cache->x)]; if(sample->filled) { - VECSUB(d, sample->co, co); + sub_v3_v3v3(d, sample->co, co); dist2= dot_v3v3(d, d); if(dist2 < 0.5f*sample->dist2 && dot_v3v3(sample->n, n) > 0.98f) { copy_v3_v3(ao, sample->ao); @@ -1534,7 +1534,7 @@ static int sample_occ_cache(OcclusionTree *tree, float *co, float *n, int x, int wb[0]= tx*ty; for(i=0; i<4; i++) { - VECSUB(d, samples[i]->co, co); + sub_v3_v3v3(d, samples[i]->co, co); //dist2= dot_v3v3(d, d); wz[i]= 1.0f; //(samples[i]->dist2/(1e-4f + dist2)); From b05ee8b65f453d97edb4dbe59fac5c996fbf78d2 Mon Sep 17 00:00:00 2001 From: Lukas Toenne Date: Sun, 6 Nov 2011 15:40:00 +0000 Subject: [PATCH 116/147] Fix for bug #29046, the factor buffer input was not used correctly in curve nodes. Curve Map exec function (for RGB curves) used a broken test condition for constant factor=1.0f eval. This must take the factor buffer into account, checking the factor vec for default value is not sufficient. These kinds of test should use a function interface, there are probably a lot more bugs like this hidden in the code. --- source/blender/nodes/composite/nodes/node_composite_curves.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/composite/nodes/node_composite_curves.c b/source/blender/nodes/composite/nodes/node_composite_curves.c index 675710942fb..7faf10138ad 100644 --- a/source/blender/nodes/composite/nodes/node_composite_curves.c +++ b/source/blender/nodes/composite/nodes/node_composite_curves.c @@ -175,7 +175,7 @@ static void node_composit_exec_curve_rgb(void *UNUSED(data), bNode *node, bNodeS curvemapping_set_black_white(node->storage, in[2]->vec, in[3]->vec); - if(in[0]->vec[0] == 1.0) + if(in[0]->data==NULL && in[0]->vec[0] == 1.0) composit1_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, do_curves, CB_RGBA); else composit2_pixel_processor(node, stackbuf, in[1]->data, in[1]->vec, in[0]->data, in[0]->vec, do_curves_fac, CB_RGBA, CB_VAL); From 3d1e45c414f81a690ad33e1ee4feacbf313c45b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 16:23:28 +0000 Subject: [PATCH 117/147] replace macros with bli math functions for nodes --- .../nodes/composite/node_composite_util.c | 10 +++++----- .../nodes/node_composite_alphaOver.c | 12 +++++------ .../composite/nodes/node_composite_blur.c | 2 +- .../nodes/node_composite_colorMatte.c | 2 +- .../composite/nodes/node_composite_curves.c | 2 +- .../nodes/node_composite_diffMatte.c | 2 +- .../nodes/node_composite_distanceMatte.c | 2 +- .../composite/nodes/node_composite_filter.c | 12 +++++------ .../nodes/node_composite_hueSatVal.c | 2 +- .../composite/nodes/node_composite_invert.c | 4 ++-- .../composite/nodes/node_composite_mixrgb.c | 4 ++-- .../composite/nodes/node_composite_normal.c | 2 +- .../nodes/node_composite_normalize.c | 2 +- .../composite/nodes/node_composite_rgb.c | 2 +- .../nodes/node_composite_splitViewer.c | 4 ++-- .../composite/nodes/node_composite_texture.c | 14 ++++++------- .../composite/nodes/node_composite_zcombine.c | 4 ++-- .../blender/nodes/shader/node_shader_util.c | 20 +++++++++---------- .../nodes/shader/nodes/node_shader_camera.c | 2 +- .../nodes/shader/nodes/node_shader_geom.c | 2 +- .../shader/nodes/node_shader_hueSatVal.c | 2 +- .../nodes/shader/nodes/node_shader_invert.c | 2 +- .../nodes/shader/nodes/node_shader_material.c | 14 ++++++------- .../nodes/shader/nodes/node_shader_mixRgb.c | 2 +- .../nodes/shader/nodes/node_shader_normal.c | 2 +- .../nodes/shader/nodes/node_shader_output.c | 4 ++-- .../nodes/shader/nodes/node_shader_rgb.c | 2 +- .../nodes/shader/nodes/node_shader_texture.c | 4 ++-- .../nodes/texture/nodes/node_texture_bricks.c | 4 ++-- .../texture/nodes/node_texture_hueSatVal.c | 2 +- .../nodes/texture/nodes/node_texture_image.c | 2 +- .../nodes/texture/nodes/node_texture_invert.c | 2 +- .../nodes/texture/nodes/node_texture_mixRgb.c | 2 +- .../nodes/texture/nodes/node_texture_proc.c | 4 ++-- .../texture/nodes/node_texture_texture.c | 6 +++--- 35 files changed, 80 insertions(+), 80 deletions(-) diff --git a/source/blender/nodes/composite/node_composite_util.c b/source/blender/nodes/composite/node_composite_util.c index 929b87618d8..0356ed394f1 100644 --- a/source/blender/nodes/composite/node_composite_util.c +++ b/source/blender/nodes/composite/node_composite_util.c @@ -317,8 +317,8 @@ CompBuf *typecheck_compbuf(CompBuf *inbuf, int type) if(inbuf->rect_procedural) { outbuf->rect_procedural= inbuf->rect_procedural; - VECCOPY(outbuf->procedural_size, inbuf->procedural_size); - VECCOPY(outbuf->procedural_offset, inbuf->procedural_offset); + copy_v3_v3(outbuf->procedural_size, inbuf->procedural_size); + copy_v3_v3(outbuf->procedural_offset, inbuf->procedural_offset); outbuf->procedural_type= inbuf->procedural_type; outbuf->node= inbuf->node; return outbuf; @@ -707,12 +707,12 @@ void do_ycca_to_rgba(bNode *UNUSED(node), float *out, float *in) void do_copy_rgba(bNode *UNUSED(node), float *out, float *in) { - QUATCOPY(out, in); + copy_v4_v4(out, in); } void do_copy_rgb(bNode *UNUSED(node), float *out, float *in) { - VECCOPY(out, in); + copy_v3_v3(out, in); out[3]= 1.0f; } @@ -723,7 +723,7 @@ void do_copy_value(bNode *UNUSED(node), float *out, float *in) void do_copy_a_rgba(bNode *UNUSED(node), float *out, float *in, float *fac) { - VECCOPY(out, in); + copy_v3_v3(out, in); out[3]= *fac; } diff --git a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c index b542954948a..4fd4b750178 100644 --- a/source/blender/nodes/composite/nodes/node_composite_alphaOver.c +++ b/source/blender/nodes/composite/nodes/node_composite_alphaOver.c @@ -48,10 +48,10 @@ static void do_alphaover_premul(bNode *UNUSED(node), float *out, float *src, flo { if(over[3]<=0.0f) { - QUATCOPY(out, src); + copy_v4_v4(out, src); } else if(fac[0]==1.0f && over[3]>=1.0f) { - QUATCOPY(out, over); + copy_v4_v4(out, over); } else { float mul= 1.0f - fac[0]*over[3]; @@ -68,10 +68,10 @@ static void do_alphaover_key(bNode *UNUSED(node), float *out, float *src, float { if(over[3]<=0.0f) { - QUATCOPY(out, src); + copy_v4_v4(out, src); } else if(fac[0]==1.0f && over[3]>=1.0f) { - QUATCOPY(out, over); + copy_v4_v4(out, over); } else { float premul= fac[0]*over[3]; @@ -89,10 +89,10 @@ static void do_alphaover_mixed(bNode *node, float *out, float *src, float *over, { if(over[3]<=0.0f) { - QUATCOPY(out, src); + copy_v4_v4(out, src); } else if(fac[0]==1.0f && over[3]>=1.0f) { - QUATCOPY(out, over); + copy_v4_v4(out, over); } else { NodeTwoFloats *ntf= node->storage; diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.c b/source/blender/nodes/composite/nodes/node_composite_blur.c index 188ac653506..d0ddfb47f08 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.c +++ b/source/blender/nodes/composite/nodes/node_composite_blur.c @@ -512,7 +512,7 @@ static void blur_with_reference(bNode *node, CompBuf *new, CompBuf *img, CompBuf if(pix==1) dest[0]= src[0]; else - QUATCOPY(dest, src); + copy_v4_v4(dest, src); } else { int minxr= x-refradx<0?-x:-refradx; diff --git a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c index 3dfc3a193a8..b226e562799 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorMatte.c @@ -52,7 +52,7 @@ static void do_color_key(bNode *node, float *out, float *in) c=node->storage; - VECCOPY(out, in); + copy_v3_v3(out, in); if( /* do hue last because it needs to wrap, and does some more checks */ diff --git a/source/blender/nodes/composite/nodes/node_composite_curves.c b/source/blender/nodes/composite/nodes/node_composite_curves.c index 7faf10138ad..6f4d32f6573 100644 --- a/source/blender/nodes/composite/nodes/node_composite_curves.c +++ b/source/blender/nodes/composite/nodes/node_composite_curves.c @@ -144,7 +144,7 @@ static void do_curves_fac(bNode *node, float *out, float *in, float *fac) if(*fac>=1.0) curvemapping_evaluate_premulRGBF(node->storage, out, in); else if(*fac<=0.0) { - VECCOPY(out, in); + copy_v3_v3(out, in); } else { float col[4], mfac= 1.0f-*fac; diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c index c621d524044..17156ab3492 100644 --- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c @@ -60,7 +60,7 @@ static void do_diff_matte(bNode *node, float *outColor, float *inColor1, float * /*average together the distances*/ difference=difference/3.0; - VECCOPY(outColor, inColor1); + copy_v3_v3(outColor, inColor1); /*make 100% transparent*/ if(difference < tolerence) { diff --git a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c index 401b143aac3..27fe66cbe0d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_distanceMatte.c @@ -59,7 +59,7 @@ static void do_distance_matte(bNode *node, float *out, float *in) (c->key[1]-in[1])*(c->key[1]-in[1]) + (c->key[2]-in[2])*(c->key[2]-in[2])); - VECCOPY(out, in); + copy_v3_v3(out, in); /*make 100% transparent */ if(distance < tolerence) { diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.c b/source/blender/nodes/composite/nodes/node_composite_filter.c index 071ee84377c..1a0c51fab53 100644 --- a/source/blender/nodes/composite/nodes/node_composite_filter.c +++ b/source/blender/nodes/composite/nodes/node_composite_filter.c @@ -64,7 +64,7 @@ static void do_filter_edge(CompBuf *out, CompBuf *in, float *filter, float fac) fp= out->rect + pix*y*rowlen; if(pix==CB_RGBA) { - QUATCOPY(fp, row2); + copy_v4_v4(fp, row2); fp+= pix; for(x=2; xcustom1 & CMP_CHAN_A) out[3] = 1.0f - in[3]; @@ -75,7 +75,7 @@ static void do_invert_fac(bNode *node, float *out, float *in, float *fac) if(node->custom1 & CMP_CHAN_A) col[3] = fac[0]*col[3] + (facm*in[3]); - QUATCOPY(out, col); + copy_v4_v4(out, col); } static void node_composit_exec_invert(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) diff --git a/source/blender/nodes/composite/nodes/node_composite_mixrgb.c b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c index 0f5a2b61b87..275d949da28 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mixrgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_mixrgb.c @@ -47,12 +47,12 @@ static void do_mix_rgb(bNode *node, float *out, float *in1, float *in2, float *f { float col[3]; - VECCOPY(col, in1); + copy_v3_v3(col, in1); if(node->custom2) ramp_blend(node->custom1, col, col+1, col+2, in2[3]*fac[0], in2); else ramp_blend(node->custom1, col, col+1, col+2, fac[0], in2); - VECCOPY(out, col); + copy_v3_v3(out, col); out[3]= in1[3]; } diff --git a/source/blender/nodes/composite/nodes/node_composite_normal.c b/source/blender/nodes/composite/nodes/node_composite_normal.c index 499f8ce300f..4c43871d867 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normal.c +++ b/source/blender/nodes/composite/nodes/node_composite_normal.c @@ -64,7 +64,7 @@ static void node_composit_exec_normal(void *UNUSED(data), bNode *node, bNodeStac /* input no image? then only vector op */ if(in[0]->data==NULL) { - VECCOPY(out[0]->vec, nor); + copy_v3_v3(out[0]->vec, nor); /* render normals point inside... the widget points outside */ out[1]->vec[0]= -dot_v3v3(out[0]->vec, in[0]->vec); } diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c index 36206d82d0b..a6220fbd20d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normalize.c +++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c @@ -69,7 +69,7 @@ static void node_composit_exec_normalize(void *UNUSED(data), bNode *node, bNodeS /* Input has no image buffer? Then pass the value */ if(in[0]->data==NULL) { - QUATCOPY(out[0]->vec, in[0]->vec); + copy_v4_v4(out[0]->vec, in[0]->vec); } else { float min = 1.0f+BLENDER_ZMAX; diff --git a/source/blender/nodes/composite/nodes/node_composite_rgb.c b/source/blender/nodes/composite/nodes/node_composite_rgb.c index a7c820ddce6..12f073a816d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rgb.c +++ b/source/blender/nodes/composite/nodes/node_composite_rgb.c @@ -55,7 +55,7 @@ static void node_composit_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack * bNodeSocket *sock= node->outputs.first; float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; - QUATCOPY(out[0]->vec, col); + copy_v4_v4(out[0]->vec, col); } void register_node_type_cmp_rgb(ListBase *lb) diff --git a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c index 22f3dd3a7b0..b63b42224e2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_splitViewer.c +++ b/source/blender/nodes/composite/nodes/node_composite_splitViewer.c @@ -42,10 +42,10 @@ static bNodeSocketTemplate cmp_node_splitviewer_in[]= { static void do_copy_split_rgba(bNode *UNUSED(node), float *out, float *in1, float *in2, float *fac) { if(*fac==0.0f) { - QUATCOPY(out, in1); + copy_v4_v4(out, in1); } else { - QUATCOPY(out, in2); + copy_v4_v4(out, in2); } } diff --git a/source/blender/nodes/composite/nodes/node_composite_texture.c b/source/blender/nodes/composite/nodes/node_composite_texture.c index 24d7b30f11d..2f54f27e481 100644 --- a/source/blender/nodes/composite/nodes/node_composite_texture.c +++ b/source/blender/nodes/composite/nodes/node_composite_texture.c @@ -80,7 +80,7 @@ static void texture_procedural(CompBuf *cbuf, float *out, float xco, float yco) else col[0]= col[1]= col[2]= col[3]; } else { - VECCOPY(col, nor); + copy_v3_v3(col, nor); } typecheck_compbuf_color(out, col, cbuf->type, cbuf->procedural_type); @@ -101,8 +101,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, prevbuf->rect_procedural= texture_procedural; prevbuf->node= node; - VECCOPY(prevbuf->procedural_offset, in[0]->vec); - VECCOPY(prevbuf->procedural_size, in[1]->vec); + copy_v3_v3(prevbuf->procedural_offset, in[0]->vec); + copy_v3_v3(prevbuf->procedural_size, in[1]->vec); prevbuf->procedural_type= CB_RGBA; composit1_pixel_processor(node, prevbuf, prevbuf, out[0]->vec, do_copy_rgba, CB_RGBA); @@ -118,8 +118,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->rect_procedural= texture_procedural; stackbuf->node= node; - VECCOPY(stackbuf->procedural_offset, in[0]->vec); - VECCOPY(stackbuf->procedural_size, in[1]->vec); + copy_v3_v3(stackbuf->procedural_offset, in[0]->vec); + copy_v3_v3(stackbuf->procedural_size, in[1]->vec); stackbuf->procedural_type= CB_VAL; composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_value, CB_VAL); stackbuf->rect_procedural= NULL; @@ -131,8 +131,8 @@ static void node_composit_exec_texture(void *data, bNode *node, bNodeStack **in, stackbuf->rect_procedural= texture_procedural; stackbuf->node= node; - VECCOPY(stackbuf->procedural_offset, in[0]->vec); - VECCOPY(stackbuf->procedural_size, in[1]->vec); + copy_v3_v3(stackbuf->procedural_offset, in[0]->vec); + copy_v3_v3(stackbuf->procedural_size, in[1]->vec); stackbuf->procedural_type= CB_RGBA; composit1_pixel_processor(node, stackbuf, stackbuf, out[0]->vec, do_copy_rgba, CB_RGBA); stackbuf->rect_procedural= NULL; diff --git a/source/blender/nodes/composite/nodes/node_composite_zcombine.c b/source/blender/nodes/composite/nodes/node_composite_zcombine.c index 7aac3539960..868c0d2b5f3 100644 --- a/source/blender/nodes/composite/nodes/node_composite_zcombine.c +++ b/source/blender/nodes/composite/nodes/node_composite_zcombine.c @@ -65,7 +65,7 @@ static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float * } else { // do combination based solely on z value - QUATCOPY(out, src1); + copy_v4_v4(out, src1); } } else { @@ -80,7 +80,7 @@ static void do_zcombine(bNode *node, float *out, float *src1, float *z1, float * } else { // do combination based solely on z value - QUATCOPY(out, src1); + copy_v4_v4(out, src1); } if(node->custom2) diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c index 1acb04c9b41..0c86d8fd5e4 100644 --- a/source/blender/nodes/shader/node_shader_util.c +++ b/source/blender/nodes/shader/node_shader_util.c @@ -55,12 +55,12 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) in[2]= from[0]; } else { - VECCOPY(in, from); + copy_v3_v3(in, from); } } else { /* type_in==SOCK_RGBA */ if(ns->sockettype==SOCK_RGBA) { - QUATCOPY(in, from); + copy_v4_v4(in, from); } else if(ns->sockettype==SOCK_FLOAT) { in[0]= from[0]; @@ -69,7 +69,7 @@ void nodestack_get_vec(float *in, short type_in, bNodeStack *ns) in[3]= 1.0f; } else { - VECCOPY(in, from); + copy_v3_v3(in, from); in[3]= 1.0f; } } @@ -140,13 +140,13 @@ void nodeShaderSynchronizeID(bNode *node, int copyto) if(copyto) { switch(a) { case MAT_IN_COLOR: - VECCOPY(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + copy_v3_v3(&ma->r, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; case MAT_IN_SPEC: - VECCOPY(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + copy_v3_v3(&ma->specr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; case MAT_IN_REFL: ma->ref= ((bNodeSocketValueFloat*)sock->default_value)->value; break; case MAT_IN_MIR: - VECCOPY(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; + copy_v3_v3(&ma->mirr, ((bNodeSocketValueRGBA*)sock->default_value)->value); break; case MAT_IN_AMB: ma->amb= ((bNodeSocketValueFloat*)sock->default_value)->value; break; case MAT_IN_EMIT: @@ -164,13 +164,13 @@ void nodeShaderSynchronizeID(bNode *node, int copyto) else { switch(a) { case MAT_IN_COLOR: - VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break; + copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->r); break; case MAT_IN_SPEC: - VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break; + copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->specr); break; case MAT_IN_REFL: ((bNodeSocketValueFloat*)sock->default_value)->value= ma->ref; break; case MAT_IN_MIR: - VECCOPY(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break; + copy_v3_v3(((bNodeSocketValueRGBA*)sock->default_value)->value, &ma->mirr); break; case MAT_IN_AMB: ((bNodeSocketValueFloat*)sock->default_value)->value= ma->amb; break; case MAT_IN_EMIT: @@ -196,7 +196,7 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns) { memset(gs, 0, sizeof(*gs)); - QUATCOPY(gs->vec, ns->vec); + copy_v4_v4(gs->vec, ns->vec); gs->link= ns->data; if (type == SOCK_FLOAT) diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c index c7882a6e0e2..02efbd63aba 100644 --- a/source/blender/nodes/shader/nodes/node_shader_camera.c +++ b/source/blender/nodes/shader/nodes/node_shader_camera.c @@ -46,7 +46,7 @@ static void node_shader_exec_camera(void *data, bNode *UNUSED(node), bNodeStack if(data) { ShadeInput *shi= ((ShaderCallData *)data)->shi; /* Data we need for shading. */ - VECCOPY(out[0]->vec, shi->co); /* get view vector */ + copy_v3_v3(out[0]->vec, shi->co); /* get view vector */ out[1]->vec[0]= fabs(shi->co[2]); /* get view z-depth */ out[2]->vec[0]= normalize_v3(out[0]->vec); /* get view distance */ } diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c index dedc25092c1..5c4ba75ae67 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geom.c +++ b/source/blender/nodes/shader/nodes/node_shader_geom.c @@ -90,7 +90,7 @@ static void node_shader_exec_geom(void *data, bNode *node, bNodeStack **UNUSED(i } } - VECCOPY(out[GEOM_OUT_VCOL]->vec, scol->col); + copy_v3_v3(out[GEOM_OUT_VCOL]->vec, scol->col); out[GEOM_OUT_VCOL]->vec[3]= 1.0f; } else diff --git a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c index 7fb31d80ffc..1207196381d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c +++ b/source/blender/nodes/shader/nodes/node_shader_hueSatVal.c @@ -65,7 +65,7 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float *hue, float *s out[2]= mfac*in[2] + *fac*col[2]; } else { - QUATCOPY(out, in); + copy_v4_v4(out, in); } } diff --git a/source/blender/nodes/shader/nodes/node_shader_invert.c b/source/blender/nodes/shader/nodes/node_shader_invert.c index 066ff14a870..e3dacefbcf2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_invert.c +++ b/source/blender/nodes/shader/nodes/node_shader_invert.c @@ -64,7 +64,7 @@ bNodeStack **out) col[2] = in[0]->vec[0]*col[2] + (facm*in[1]->vec[2]); } - VECCOPY(out[0]->vec, col); + copy_v3_v3(out[0]->vec, col); } static int gpu_shader_invert(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_material.c b/source/blender/nodes/shader/nodes/node_shader_material.c index f93928d8884..a74a2567844 100644 --- a/source/blender/nodes/shader/nodes/node_shader_material.c +++ b/source/blender/nodes/shader/nodes/node_shader_material.c @@ -148,13 +148,13 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, /* write to outputs */ if(node->custom1 & SH_NODE_MAT_DIFF) { - VECCOPY(col, shrnode.combined); + copy_v3_v3(col, shrnode.combined); if(!(node->custom1 & SH_NODE_MAT_SPEC)) { sub_v3_v3(col, shrnode.spec); } } else if(node->custom1 & SH_NODE_MAT_SPEC) { - VECCOPY(col, shrnode.spec); + copy_v3_v3(col, shrnode.spec); } else col[0]= col[1]= col[2]= 0.0f; @@ -164,7 +164,7 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, if(shi->do_preview) nodeAddToPreview(node, col, shi->xs, shi->ys, shi->do_manage); - VECCOPY(out[MAT_OUT_COLOR]->vec, col); + copy_v3_v3(out[MAT_OUT_COLOR]->vec, col); out[MAT_OUT_ALPHA]->vec[0]= shrnode.alpha; if(node->custom1 & SH_NODE_MAT_NEG) { @@ -173,15 +173,15 @@ static void node_shader_exec_material(void *data, bNode *node, bNodeStack **in, shi->vn[2]= -shi->vn[2]; } - VECCOPY(out[MAT_OUT_NORMAL]->vec, shi->vn); + copy_v3_v3(out[MAT_OUT_NORMAL]->vec, shi->vn); /* Extended material options */ if (node->type == SH_NODE_MATERIAL_EXT) { /* Shadow, Reflect, Refract, Radiosity, Speed seem to cause problems inside * a node tree :( */ - VECCOPY(out[MAT_OUT_DIFFUSE]->vec, shrnode.diff); - VECCOPY(out[MAT_OUT_SPEC]->vec, shrnode.spec); - VECCOPY(out[MAT_OUT_AO]->vec, shrnode.ao); + copy_v3_v3(out[MAT_OUT_DIFFUSE]->vec, shrnode.diff); + copy_v3_v3(out[MAT_OUT_SPEC]->vec, shrnode.spec); + copy_v3_v3(out[MAT_OUT_AO]->vec, shrnode.ao); } /* copy passes, now just active node */ diff --git a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c index 7aed6bce4c4..7692956368c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mixRgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_mixRgb.c @@ -59,7 +59,7 @@ static void node_shader_exec_mix_rgb(void *UNUSED(data), bNode *node, bNodeStack nodestack_get_vec(vec, SOCK_VECTOR, in[2]); ramp_blend(node->custom1, col, col+1, col+2, fac, vec); - VECCOPY(out[0]->vec, col); + copy_v3_v3(out[0]->vec, col); } static int gpu_shader_mix_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_normal.c b/source/blender/nodes/shader/nodes/node_shader_normal.c index c23c6d328cf..40f2f65a193 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal.c @@ -66,7 +66,7 @@ static void node_shader_exec_normal(void *UNUSED(data), bNode *node, bNodeStack nodestack_get_vec(vec, SOCK_VECTOR, in[0]); - VECCOPY(out[0]->vec, ((bNodeSocketValueVector*)sock->default_value)->value); + copy_v3_v3(out[0]->vec, ((bNodeSocketValueVector*)sock->default_value)->value); /* render normals point inside... the widget points outside */ out[1]->vec[0]= -INPR(out[0]->vec, vec); } diff --git a/source/blender/nodes/shader/nodes/node_shader_output.c b/source/blender/nodes/shader/nodes/node_shader_output.c index ea7fae8f961..22e3cab532d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_output.c +++ b/source/blender/nodes/shader/nodes/node_shader_output.c @@ -57,10 +57,10 @@ static void node_shader_exec_output(void *data, bNode *node, bNodeStack **in, bN if(node->flag & NODE_DO_OUTPUT) { ShadeResult *shr= ((ShaderCallData *)data)->shr; - QUATCOPY(shr->combined, col); + copy_v4_v4(shr->combined, col); shr->alpha= col[3]; - // VECCOPY(shr->nor, in[3]->vec); + // copy_v3_v3(shr->nor, in[3]->vec); } } } diff --git a/source/blender/nodes/shader/nodes/node_shader_rgb.c b/source/blender/nodes/shader/nodes/node_shader_rgb.c index 1a0b4ea616b..67c0ec165ca 100644 --- a/source/blender/nodes/shader/nodes/node_shader_rgb.c +++ b/source/blender/nodes/shader/nodes/node_shader_rgb.c @@ -54,7 +54,7 @@ static void node_shader_exec_rgb(void *UNUSED(data), bNode *node, bNodeStack **U bNodeSocket *sock= node->outputs.first; float *col= ((bNodeSocketValueRGBA*)sock->default_value)->value; - VECCOPY(out[0]->vec, col); + copy_v3_v3(out[0]->vec, col); } static int gpu_shader_rgb(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index 588cdc1da83..42460e141e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -82,7 +82,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL); } else { - VECCOPY(vec, shi->lo); + copy_v3_v3(vec, shi->lo); retval= multitex_nodes((Tex *)node->id, vec, NULL, NULL, 0, &texres, thread, which_output, NULL, NULL); } @@ -111,7 +111,7 @@ static void node_shader_exec_texture(void *data, bNode *node, bNodeStack **in, b out[1]->vec[3]= 1.0f; } - VECCOPY(out[2]->vec, nor); + copy_v3_v3(out[2]->vec, nor); if(shi->do_preview) nodeAddToPreview(node, out[1]->vec, shi->xs, shi->ys, shi->do_manage); diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c index 2011426b845..0700085a787 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.c +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c @@ -107,9 +107,9 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor if( ins_x < mortar_thickness || ins_y < mortar_thickness || ins_x > (brick_width - mortar_thickness) || ins_y > (row_height - mortar_thickness) ) { - QUATCOPY( out, mortar ); + copy_v4_v4( out, mortar ); } else { - QUATCOPY( out, bricks1 ); + copy_v4_v4( out, bricks1 ); ramp_blend( MA_RAMP_BLEND, out, out+1, out+2, tint, bricks2 ); } } diff --git a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c index 111d6e78023..3346592f7d3 100644 --- a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c +++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.c @@ -66,7 +66,7 @@ static void do_hue_sat_fac(bNode *UNUSED(node), float *out, float hue, float sat out[2]= mfac*in[2] + fac*col[2]; } else { - QUATCOPY(out, in); + copy_v4_v4(out, in); } } diff --git a/source/blender/nodes/texture/nodes/node_texture_image.c b/source/blender/nodes/texture/nodes/node_texture_image.c index 3a81ecb1466..0ead3a3dec2 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.c +++ b/source/blender/nodes/texture/nodes/node_texture_image.c @@ -76,7 +76,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(i while( py >= ibuf->y ) py -= ibuf->y; result = ibuf->rect_float + py*ibuf->x*4 + px*4; - QUATCOPY( out, result ); + copy_v4_v4( out, result ); } } } diff --git a/source/blender/nodes/texture/nodes/node_texture_invert.c b/source/blender/nodes/texture/nodes/node_texture_invert.c index 3ad11026f28..5ee60d02e32 100644 --- a/source/blender/nodes/texture/nodes/node_texture_invert.c +++ b/source/blender/nodes/texture/nodes/node_texture_invert.c @@ -54,7 +54,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** col[1] = 1.0f - col[1]; col[2] = 1.0f - col[2]; - VECCOPY(out, col); + copy_v3_v3(out, col); out[3] = col[3]; } diff --git a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c index c68adf2f4aa..e3b5119c797 100644 --- a/source/blender/nodes/texture/nodes/node_texture_mixRgb.c +++ b/source/blender/nodes/texture/nodes/node_texture_mixRgb.c @@ -55,7 +55,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor CLAMP(fac, 0.0f, 1.0f); - QUATCOPY(out, col1); + copy_v4_v4(out, col1); ramp_blend(node->custom1, out, out+1, out+2, fac, col2); } diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index d9ac8700be1..3012d313db5 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -75,10 +75,10 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char return; if(textype & TEX_RGB) { - QUATCOPY(result, &texres.tr); + copy_v4_v4(result, &texres.tr); } else { - QUATCOPY(result, col1); + copy_v4_v4(result, col1); ramp_blend(MA_RAMP_BLEND, result, result+1, result+2, texres.tin, col2); } } diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.c b/source/blender/nodes/texture/nodes/node_texture_texture.c index 1b8eb3aabc6..667570582fe 100644 --- a/source/blender/nodes/texture/nodes/node_texture_texture.c +++ b/source/blender/nodes/texture/nodes/node_texture_texture.c @@ -65,7 +65,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor if(node->custom2 || node->need_exec==0) { /* this node refers to its own texture tree! */ - QUATCOPY(out, (fabs(co[0] - co[1]) < .01) ? white : red ); + copy_v4_v4(out, (fabs(co[0] - co[1]) < .01) ? white : red ); } else if(nodetex) { TexResult texres; @@ -81,10 +81,10 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor &texres, thread, 0, p->shi, p->mtex); if(textype & TEX_RGB) { - QUATCOPY(out, &texres.tr); + copy_v4_v4(out, &texres.tr); } else { - QUATCOPY(out, col1); + copy_v4_v4(out, col1); ramp_blend(MA_RAMP_BLEND, out, out+1, out+2, texres.tin, col2); } } From 7c88bc5952c7e9f8a7f48d00d94b335bd0169c2e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 16:34:44 +0000 Subject: [PATCH 118/147] replace macros for bli math functions in editors --- .../blender/editors/armature/meshlaplacian.c | 4 +- .../editors/interface/interface_handlers.c | 6 +- .../editors/interface/interface_regions.c | 2 +- .../editors/interface/interface_widgets.c | 50 ++++++------ source/blender/editors/object/object_edit.c | 18 ++--- .../blender/editors/object/object_transform.c | 2 +- .../editors/sculpt_paint/paint_image.c | 76 +++++++++---------- .../editors/sculpt_paint/paint_utils.c | 4 +- source/blender/editors/sculpt_paint/sculpt.c | 2 +- source/blender/editors/transform/transform.c | 6 +- .../editors/transform/transform_conversions.c | 8 +- .../transform/transform_orientations.c | 8 +- source/blender/editors/uvedit/uvedit_ops.c | 8 +- 13 files changed, 97 insertions(+), 97 deletions(-) diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 53d0141f44d..40d2d80f2b7 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1241,8 +1241,8 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float memset(&isec, 0, sizeof(isec)); isec.labda= 1e10f; - VECADD(isec.start, co1, epsilon); - VECADD(end, co2, epsilon); + add_v3_v3v3(isec.start, co1, epsilon); + add_v3_v3v3(end, co2, epsilon); sub_v3_v3v3(isec.vec, end, isec.start); if(meshdeform_intersect(mdb, &isec)) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 0ba141163b3..c34c10bf1a7 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -944,7 +944,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut data->origstr= NULL; data->value= data->origvalue; data->origvalue= 0.0; - VECCOPY(data->vec, data->origvec); + copy_v3_v3(data->vec, data->origvec); data->origvec[0]= data->origvec[1]= data->origvec[2]= 0.0f; } else { @@ -2121,7 +2121,7 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data break; case COL: ui_get_but_vectorf(but, data->origvec); - VECCOPY(data->vec, data->origvec); + copy_v3_v3(data->vec, data->origvec); but->editvec= data->vec; handlefunc= ui_block_func_COL; @@ -5727,7 +5727,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut * /* copy over return values from the closing menu */ if(menu->menuretval == UI_RETURN_OK || menu->menuretval == UI_RETURN_UPDATE) { if(but->type == COL) - VECCOPY(data->vec, menu->retvec) + copy_v3_v3(data->vec, menu->retvec); else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW)) data->value= menu->retvalue; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4791d2652dc..edbd5c5684e 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2126,7 +2126,7 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT); - VECCOPY(handle->retvec, but->editvec); + copy_v3_v3(handle->retvec, but->editvec); uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index c5ac4f5aa88..ed018830a0a 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1874,38 +1874,38 @@ void ui_draw_gradient(rcti *rect, float *hsv, int type, float alpha) break; case UI_GRAD_H: hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); - VECCOPY(col1[1], col1[0]); - VECCOPY(col1[2], col1[0]); - VECCOPY(col1[3], col1[0]); + copy_v3_v3(col1[1], col1[0]); + copy_v3_v3(col1[2], col1[0]); + copy_v3_v3(col1[3], col1[0]); break; case UI_GRAD_S: hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]); - VECCOPY(col1[0], col1[1]); - VECCOPY(col1[2], col1[1]); - VECCOPY(col1[3], col1[1]); + copy_v3_v3(col1[0], col1[1]); + copy_v3_v3(col1[2], col1[1]); + copy_v3_v3(col1[3], col1[1]); break; case UI_GRAD_V: hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]); - VECCOPY(col1[0], col1[2]); - VECCOPY(col1[1], col1[2]); - VECCOPY(col1[3], col1[2]); + copy_v3_v3(col1[0], col1[2]); + copy_v3_v3(col1[1], col1[2]); + copy_v3_v3(col1[3], col1[2]); break; default: assert(!"invalid 'type' argument"); hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]); - VECCOPY(col1[0], col1[2]); - VECCOPY(col1[1], col1[2]); - VECCOPY(col1[3], col1[2]); + copy_v3_v3(col1[0], col1[2]); + copy_v3_v3(col1[1], col1[2]); + copy_v3_v3(col1[3], col1[2]); } /* old below */ for(dx=0.0f; dx<1.0f; dx+= 0.05f) { // previous color - VECCOPY(col0[0], col1[0]); - VECCOPY(col0[1], col1[1]); - VECCOPY(col0[2], col1[2]); - VECCOPY(col0[3], col1[3]); + copy_v3_v3(col0[0], col1[0]); + copy_v3_v3(col0[1], col1[1]); + copy_v3_v3(col0[2], col1[2]); + copy_v3_v3(col0[3], col1[3]); // new color switch(type) { @@ -1929,21 +1929,21 @@ void ui_draw_gradient(rcti *rect, float *hsv, int type, float alpha) break; case UI_GRAD_H: hsv_to_rgb(dx, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); - VECCOPY(col1[1], col1[0]); - VECCOPY(col1[2], col1[0]); - VECCOPY(col1[3], col1[0]); + copy_v3_v3(col1[1], col1[0]); + copy_v3_v3(col1[2], col1[0]); + copy_v3_v3(col1[3], col1[0]); break; case UI_GRAD_S: hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]); - VECCOPY(col1[0], col1[1]); - VECCOPY(col1[2], col1[1]); - VECCOPY(col1[3], col1[1]); + copy_v3_v3(col1[0], col1[1]); + copy_v3_v3(col1[2], col1[1]); + copy_v3_v3(col1[3], col1[1]); break; case UI_GRAD_V: hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]); - VECCOPY(col1[0], col1[2]); - VECCOPY(col1[1], col1[2]); - VECCOPY(col1[3], col1[2]); + copy_v3_v3(col1[0], col1[2]); + copy_v3_v3(col1[1], col1[2]); + copy_v3_v3(col1[3], col1[2]); break; } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index f2997dc743d..4fbb5e0d51c 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1130,19 +1130,19 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->recalc |= OB_RECALC_OB; if(event==1) { /* loc */ - VECCOPY(base->object->loc, ob->loc); - VECCOPY(base->object->dloc, ob->dloc); + copy_v3_v3(base->object->loc, ob->loc); + copy_v3_v3(base->object->dloc, ob->dloc); } else if(event==2) { /* rot */ - VECCOPY(base->object->rot, ob->rot); - VECCOPY(base->object->drot, ob->drot); + copy_v3_v3(base->object->rot, ob->rot); + copy_v3_v3(base->object->drot, ob->drot); - QUATCOPY(base->object->quat, ob->quat); - QUATCOPY(base->object->dquat, ob->dquat); + copy_qt_qt(base->object->quat, ob->quat); + copy_qt_qt(base->object->dquat, ob->dquat); } else if(event==3) { /* size */ - VECCOPY(base->object->size, ob->size); - VECCOPY(base->object->dsize, ob->dsize); + copy_v3_v3(base->object->size, ob->size); + copy_v3_v3(base->object->dsize, ob->dsize); } else if(event==4) { /* drawtype */ base->object->dt= ob->dt; @@ -1331,7 +1331,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) base->object->index= ob->index; } else if(event==31) { /* object color */ - QUATCOPY(base->object->col, ob->col); + copy_v4_v4(base->object->col, ob->col); } } } diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index a82ed95079f..e2039739be2 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -133,7 +133,7 @@ static void object_clear_rot(Object *ob) float eul[3], oldeul[3], quat1[4] = {0}; if (ob->rotmode == ROT_MODE_QUAT) { - QUATCOPY(quat1, ob->quat); + copy_qt_qt(quat1, ob->quat); quat_to_eul(oldeul, ob->quat); } else if (ob->rotmode == ROT_MODE_AXISANGLE) { diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 4507ad96b9d..3c9edb2fcfe 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -607,7 +607,7 @@ static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w best_face_index = face_index; best_side = 0; z_depth_best = z_depth; - VECCOPY(w, w_tmp); + copy_v3_v3(w, w_tmp); } } else if (mf->v4) { @@ -621,7 +621,7 @@ static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w best_face_index = face_index; best_side= 1; z_depth_best = z_depth; - VECCOPY(w, w_tmp); + copy_v3_v3(w, w_tmp); } } } @@ -722,7 +722,7 @@ static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float if (rgba_fp) { if (ibuf->rect_float) { - QUATCOPY(rgba_fp, ((float *)ibuf->rect_float + ((xi + yi * ibuf->x) * 4))); + copy_v4_v4(rgba_fp, ((float *)ibuf->rect_float + ((xi + yi * ibuf->x) * 4))); } else { char *tmp_ch= ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4); @@ -1431,7 +1431,7 @@ static ProjPixel *project_paint_uvpixel_init( } /* screenspace unclamped, we could keep its z and w values but dont need them at the moment */ - VECCOPY2D(projPixel->projCoSS, pixelScreenCo); + copy_v2_v2(projPixel->projCoSS, pixelScreenCo); projPixel->x_px = x_px; projPixel->y_px = y_px; @@ -1530,8 +1530,8 @@ static int line_clip_rect2f( if (fabsf(l1[0]-l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { - VECCOPY2D(l1_clip, l1); - VECCOPY2D(l2_clip, l2); + copy_v2_v2(l1_clip, l1); + copy_v2_v2(l2_clip, l2); return 1; } else { @@ -1539,8 +1539,8 @@ static int line_clip_rect2f( } } - VECCOPY2D(l1_clip, l1); - VECCOPY2D(l2_clip, l2); + copy_v2_v2(l1_clip, l1); + copy_v2_v2(l2_clip, l2); CLAMP(l1_clip[0], rect->xmin, rect->xmax); CLAMP(l2_clip[0], rect->xmin, rect->xmax); return 1; @@ -1558,8 +1558,8 @@ static int line_clip_rect2f( if (fabsf(l1[1]-l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/ if (BLI_in_rctf(rect, l1[0], l1[1])) { - VECCOPY2D(l1_clip, l1); - VECCOPY2D(l2_clip, l2); + copy_v2_v2(l1_clip, l1); + copy_v2_v2(l2_clip, l2); return 1; } else { @@ -1567,8 +1567,8 @@ static int line_clip_rect2f( } } - VECCOPY2D(l1_clip, l1); - VECCOPY2D(l2_clip, l2); + copy_v2_v2(l1_clip, l1); + copy_v2_v2(l2_clip, l2); CLAMP(l1_clip[1], rect->ymin, rect->ymax); CLAMP(l2_clip[1], rect->ymin, rect->ymax); return 1; @@ -1582,12 +1582,12 @@ static int line_clip_rect2f( /* are either of the points inside the rectangle ? */ if (BLI_in_rctf(rect, l1[0], l1[1])) { - VECCOPY2D(l1_clip, l1); + copy_v2_v2(l1_clip, l1); ok1 = 1; } if (BLI_in_rctf(rect, l2[0], l2[1])) { - VECCOPY2D(l2_clip, l2); + copy_v2_v2(l2_clip, l2); ok2 = 1; } @@ -1912,14 +1912,14 @@ static void project_bucket_clip_face( if (inside_bucket_flag == ISECT_ALL3) { /* all screenspace points are inside the bucket bounding box, this means we dont need to clip and can simply return the UVs */ if (flip) { /* facing the back? */ - VECCOPY2D(bucket_bounds_uv[0], uv3co); - VECCOPY2D(bucket_bounds_uv[1], uv2co); - VECCOPY2D(bucket_bounds_uv[2], uv1co); + copy_v2_v2(bucket_bounds_uv[0], uv3co); + copy_v2_v2(bucket_bounds_uv[1], uv2co); + copy_v2_v2(bucket_bounds_uv[2], uv1co); } else { - VECCOPY2D(bucket_bounds_uv[0], uv1co); - VECCOPY2D(bucket_bounds_uv[1], uv2co); - VECCOPY2D(bucket_bounds_uv[2], uv3co); + copy_v2_v2(bucket_bounds_uv[0], uv1co); + copy_v2_v2(bucket_bounds_uv[1], uv2co); + copy_v2_v2(bucket_bounds_uv[2], uv3co); } *tot = 3; @@ -1983,33 +1983,33 @@ static void project_bucket_clip_face( (*tot) = 0; - if (inside_face_flag & ISECT_1) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; } - if (inside_face_flag & ISECT_2) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; } - if (inside_face_flag & ISECT_3) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; } - if (inside_face_flag & ISECT_4) { VECCOPY2D(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; } + if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; } + if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; } + if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; } + if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; } - if (inside_bucket_flag & ISECT_1) { VECCOPY2D(isectVCosSS[*tot], v1coSS); (*tot)++; } - if (inside_bucket_flag & ISECT_2) { VECCOPY2D(isectVCosSS[*tot], v2coSS); (*tot)++; } - if (inside_bucket_flag & ISECT_3) { VECCOPY2D(isectVCosSS[*tot], v3coSS); (*tot)++; } + if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; } + if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; } + if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; } if ((inside_bucket_flag & (ISECT_1|ISECT_2)) != (ISECT_1|ISECT_2)) { if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) { - if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; } - if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_1)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_2)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; } } } if ((inside_bucket_flag & (ISECT_2|ISECT_3)) != (ISECT_2|ISECT_3)) { if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) { - if ((inside_bucket_flag & ISECT_2)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; } - if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_2)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_3)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; } } } if ((inside_bucket_flag & (ISECT_3|ISECT_1)) != (ISECT_3|ISECT_1)) { if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) { - if ((inside_bucket_flag & ISECT_3)==0) { VECCOPY2D(isectVCosSS[*tot], v1_clipSS); (*tot)++; } - if ((inside_bucket_flag & ISECT_1)==0) { VECCOPY2D(isectVCosSS[*tot], v2_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_3)==0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; } + if ((inside_bucket_flag & ISECT_1)==0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; } } } @@ -2538,8 +2538,8 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]); fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]); - if (fac < 0.0f) { VECCOPY(pixelScreenCo, edge_verts_inset_clip[0]); } - else if (fac > 1.0f) { VECCOPY(pixelScreenCo, edge_verts_inset_clip[1]); } + if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); } + else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); } else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); } if (!is_ortho) { @@ -3035,7 +3035,7 @@ static void project_paint_begin(ProjPaintState *ps) normalize_v3(ps->viewDir); /* viewPos - object relative */ - VECCOPY(ps->viewPos, viewinv[3]); + copy_v3_v3(ps->viewPos, viewinv[3]); copy_m3_m4(mat, ps->ob->imat); mul_m3_v3(mat, ps->viewPos); add_v3_v3(ps->viewPos, ps->ob->imat[3]); @@ -3393,7 +3393,7 @@ static void project_paint_end(ProjPaintState *ps) if (is_float) { float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4; - QUATCOPY(rgba_fp, projPixel->origColor.f); + copy_v4_v4(rgba_fp, projPixel->origColor.f); } else { ((unsigned int *)tilerect)[ (projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE ] = projPixel->origColor.uint; @@ -3728,7 +3728,7 @@ static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, flo srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb); } else { - VECCOPY(rgba, ps->brush->rgb); + copy_v3_v3(rgba, ps->brush->rgb); } rgba[3] = 1.0; } diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index b1c0b571d49..ed2956ff054 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -124,7 +124,7 @@ float paint_get_tex_pixel(Brush* br, float u, float v) static void imapaint_project(Object *ob, float *model, float *proj, float *co, float *pco) { - VECCOPY(pco, co); + copy_v3_v3(pco, co); pco[3]= 1.0f; mul_m4_v3(ob->obmat, pco); @@ -166,7 +166,7 @@ static void imapaint_tri_weights(Object *ob, float *v1, float *v2, float *v3, fl invert_m3_m3(invwmat, wmat); mul_m3_v3(invwmat, h); - VECCOPY(w, h); + copy_v3_v3(w, h); /* w is still divided by perspdiv, make it sum to one */ divw= w[0] + w[1] + w[2]; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 754ccd1fd5e..ac2efcb2ec2 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2320,7 +2320,7 @@ void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]) MVert *mvert= me->mvert; for (a= 0; a < me->totvert; a++, mvert++) - VECCOPY(mvert->co, vertCos[a]); + copy_v3_v3(mvert->co, vertCos[a]); mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5d3e05dcaab..b5f0a4a071e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4847,7 +4847,7 @@ int doEdgeSlide(TransInfo *t, float perc) interp_v2_v2v2(uv_tmp, suv->origuv, (perc>=0)?suv->uv_up:suv->uv_down, fabs(perc)); fuv_link = suv->fuv_list; while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); + copy_v2_v2(((float *)fuv_link->link), uv_tmp); fuv_link = fuv_link->next; } } @@ -4878,7 +4878,7 @@ int doEdgeSlide(TransInfo *t, float perc) interp_v2_v2v2(uv_tmp, suv->uv_down, suv->uv_up, fabs(newlen)); fuv_link = suv->fuv_list; while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); + copy_v2_v2(((float *)fuv_link->link), uv_tmp); fuv_link = fuv_link->next; } } @@ -4895,7 +4895,7 @@ int doEdgeSlide(TransInfo *t, float perc) interp_v2_v2v2(uv_tmp, suv->uv_up, suv->uv_down, fabs(newlen)); fuv_link = suv->fuv_list; while (fuv_link) { - VECCOPY2D(((float *)fuv_link->link), uv_tmp); + copy_v2_v2(((float *)fuv_link->link), uv_tmp); fuv_link = fuv_link->next; } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 6de854ff6c9..7eb8dc11a43 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2960,8 +2960,8 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC td2d->h1 = bezt->vec[0]; td2d->h2 = bezt->vec[2]; - VECCOPY2D(td2d->ih1, td2d->h1); - VECCOPY2D(td2d->ih2, td2d->h2); + copy_v2_v2(td2d->ih1, td2d->h1); + copy_v2_v2(td2d->ih2, td2d->h2); td++; td2d++; @@ -3217,14 +3217,14 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, if (td->flag & TD_MOVEHANDLE1) { td2d->h1 = bezt->vec[0]; - VECCOPY2D(td2d->ih1, td2d->h1); + copy_v2_v2(td2d->ih1, td2d->h1); } else td2d->h1 = NULL; if (td->flag & TD_MOVEHANDLE2) { td2d->h2 = bezt->vec[2]; - VECCOPY2D(td2d->ih2, td2d->h2); + copy_v2_v2(td2d->ih2, td2d->h2); } else td2d->h2 = NULL; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index a09778726d5..5d61d2a1ebb 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -606,9 +606,9 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], { if(efa->f & SELECT) { - VECADD(normal, normal, efa->n); + add_v3_v3(normal, efa->n); sub_v3_v3v3(vec, efa->v2->co, efa->v1->co); - VECADD(plane, plane, vec); + add_v3_v3(plane, vec); } } @@ -662,7 +662,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], if(eed->f & SELECT) { /* use average vert normals as plane and edge vector as normal */ copy_v3_v3(plane, eed->v1->no); - VECADD(plane, plane, eed->v2->no); + add_v3_v3(plane, eed->v2->no); sub_v3_v3v3(normal, eed->v2->co, eed->v1->co); break; } @@ -683,7 +683,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], v2 = eve; copy_v3_v3(plane, v1->no); - VECADD(plane, plane, v2->no); + add_v3_v3(plane, v2->no); sub_v3_v3v3(normal, v2->co, v1->co); break; } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 3593d94b400..62b875c82de 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2530,11 +2530,11 @@ static int snap_uvs_to_cursor(Scene *scene, Image *ima, Object *obedit, SpaceIma for(efa= em->faces.first; efa; efa= efa->next) { tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if(uvedit_face_visible(scene, ima, efa, tface)) { - if(uvedit_uv_selected(scene, efa, tface, 0)) VECCOPY2D(tface->uv[0], sima->cursor); - if(uvedit_uv_selected(scene, efa, tface, 1)) VECCOPY2D(tface->uv[1], sima->cursor); - if(uvedit_uv_selected(scene, efa, tface, 2)) VECCOPY2D(tface->uv[2], sima->cursor); + if(uvedit_uv_selected(scene, efa, tface, 0)) copy_v2_v2(tface->uv[0], sima->cursor); + if(uvedit_uv_selected(scene, efa, tface, 1)) copy_v2_v2(tface->uv[1], sima->cursor); + if(uvedit_uv_selected(scene, efa, tface, 2)) copy_v2_v2(tface->uv[2], sima->cursor); if(efa->v4) - if(uvedit_uv_selected(scene, efa, tface, 3)) VECCOPY2D(tface->uv[3], sima->cursor); + if(uvedit_uv_selected(scene, efa, tface, 3)) copy_v2_v2(tface->uv[3], sima->cursor); change= 1; } From 85540d5aa7abb487e546b5483fffeef2e6075af5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 6 Nov 2011 16:38:21 +0000 Subject: [PATCH 119/147] more macro --> BLI math lib, mainly replace VECCOPY in render and blenkernel. --- source/blender/blenkernel/intern/bvhutils.c | 4 +- source/blender/blenkernel/intern/cloth.c | 62 ++-- source/blender/blenkernel/intern/particle.c | 4 +- .../blenkernel/intern/particle_system.c | 42 +-- source/blender/blenkernel/intern/softbody.c | 270 +++++++++--------- .../blender/blenkernel/intern/subsurf_ccg.c | 2 +- source/blender/blenkernel/intern/texture.c | 2 +- source/blender/blenlib/intern/graph.c | 4 +- source/blender/blenloader/intern/readfile.c | 18 +- source/blender/gpu/intern/gpu_material.c | 2 +- .../modifiers/intern/MOD_particleinstance.c | 2 +- .../modifiers/intern/MOD_simpledeform.c | 4 +- .../python/mathutils/mathutils_geometry.c | 18 +- source/blender/render/intern/include/zbuf.h | 2 +- .../render/intern/source/imagetexture.c | 2 +- .../blender/render/intern/source/rayshade.c | 2 +- .../blender/render/intern/source/rendercore.c | 6 +- .../render/intern/source/shadeoutput.c | 18 +- source/blender/render/intern/source/sss.c | 16 +- source/blender/render/intern/source/strand.c | 30 +- source/blender/render/intern/source/zbuf.c | 88 +++--- .../Converter/BL_ArmatureObject.cpp | 4 +- 22 files changed, 298 insertions(+), 304 deletions(-) diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c index 93abad8858f..1a27a640797 100644 --- a/source/blender/blenkernel/intern/bvhutils.c +++ b/source/blender/blenkernel/intern/bvhutils.c @@ -384,8 +384,8 @@ static float nearest_point_in_tri_surface(const float v0[3], const float v1[3], mul_v3_fl(x, S); copy_v3_v3(y, e1); mul_v3_fl(y, T); - VECADD(z, w, x); - VECADD(z, z, y); + add_v3_v3v3(z, w, x); + add_v3_v3v3(z, z, y); //sub_v3_v3v3(d, p, z); copy_v3_v3(nearest, z); // d = p - ( v0 + S * e0 + T * e1 ); diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f917a0fe68c..ae6a6ec012a 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -231,12 +231,12 @@ static BVHTree *bvhtree_build_from_cloth (ClothModifierData *clmd, float epsilon // fill tree for(i = 0; i < cloth->numfaces; i++, mfaces++) { - VECCOPY(&co[0*3], verts[mfaces->v1].xold); - VECCOPY(&co[1*3], verts[mfaces->v2].xold); - VECCOPY(&co[2*3], verts[mfaces->v3].xold); + copy_v3_v3(&co[0*3], verts[mfaces->v1].xold); + copy_v3_v3(&co[1*3], verts[mfaces->v2].xold); + copy_v3_v3(&co[2*3], verts[mfaces->v3].xold); if(mfaces->v4) - VECCOPY(&co[3*3], verts[mfaces->v4].xold); + copy_v3_v3(&co[3*3], verts[mfaces->v4].xold); BLI_bvhtree_insert(bvhtree, i, co, (mfaces->v4 ? 4 : 3)); } @@ -267,23 +267,23 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving) { for(i = 0; i < cloth->numfaces; i++, mfaces++) { - VECCOPY(&co[0*3], verts[mfaces->v1].txold); - VECCOPY(&co[1*3], verts[mfaces->v2].txold); - VECCOPY(&co[2*3], verts[mfaces->v3].txold); + copy_v3_v3(&co[0*3], verts[mfaces->v1].txold); + copy_v3_v3(&co[1*3], verts[mfaces->v2].txold); + copy_v3_v3(&co[2*3], verts[mfaces->v3].txold); if(mfaces->v4) - VECCOPY(&co[3*3], verts[mfaces->v4].txold); + copy_v3_v3(&co[3*3], verts[mfaces->v4].txold); // copy new locations into array if(moving) { // update moving positions - VECCOPY(&co_moving[0*3], verts[mfaces->v1].tx); - VECCOPY(&co_moving[1*3], verts[mfaces->v2].tx); - VECCOPY(&co_moving[2*3], verts[mfaces->v3].tx); + copy_v3_v3(&co_moving[0*3], verts[mfaces->v1].tx); + copy_v3_v3(&co_moving[1*3], verts[mfaces->v2].tx); + copy_v3_v3(&co_moving[2*3], verts[mfaces->v3].tx); if(mfaces->v4) - VECCOPY(&co_moving[3*3], verts[mfaces->v4].tx); + copy_v3_v3(&co_moving[3*3], verts[mfaces->v4].tx); ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, (mfaces->v4 ? 4 : 3)); } @@ -321,13 +321,13 @@ void bvhselftree_update_from_cloth(ClothModifierData *clmd, int moving) { for(i = 0; i < cloth->numverts; i++, verts++) { - VECCOPY(&co[0*3], verts->txold); + copy_v3_v3(&co[0*3], verts->txold); // copy new locations into array if(moving) { // update moving positions - VECCOPY(&co_moving[0*3], verts->tx); + copy_v3_v3(&co_moving[0*3], verts->tx); ret = BLI_bvhtree_update_node(bvhtree, i, co, co_moving, 1); } @@ -399,11 +399,11 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul /* force any pinned verts to their constrained location. */ for(i = 0; i < clmd->clothObject->numverts; i++, verts++) { /* save the previous position. */ - VECCOPY(verts->xold, verts->xconst); - VECCOPY(verts->txold, verts->x); + copy_v3_v3(verts->xold, verts->xconst); + copy_v3_v3(verts->txold, verts->x); /* Get the current position. */ - VECCOPY(verts->xconst, mvert[i].co); + copy_v3_v3(verts->xconst, mvert[i].co); mul_m4_v3(ob->obmat, verts->xconst); } @@ -712,7 +712,7 @@ static void cloth_to_object (Object *ob, ClothModifierData *clmd, DerivedMesh * for (i = 0; i < numverts; i++) { - VECCOPY (mvert[i].co, cloth->verts[i].x); + copy_v3_v3 (mvert[i].co, cloth->verts[i].x); mul_m4_v3(ob->imat, mvert[i].co); /* cloth is in global coords */ } } @@ -880,14 +880,14 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d verts->goal= 0.0f; verts->flags = 0; - VECCOPY ( verts->xold, verts->x ); - VECCOPY ( verts->xconst, verts->x ); - VECCOPY ( verts->txold, verts->x ); - VECCOPY ( verts->tx, verts->x ); + copy_v3_v3 ( verts->xold, verts->x ); + copy_v3_v3 ( verts->xconst, verts->x ); + copy_v3_v3 ( verts->txold, verts->x ); + copy_v3_v3 ( verts->tx, verts->x ); mul_v3_fl( verts->v, 0.0f ); verts->impulse_count = 0; - VECCOPY ( verts->impulse, tnull ); + copy_v3_v3 ( verts->impulse, tnull ); } // apply / set vertex groups @@ -1053,7 +1053,6 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) LinkNode **edgelist = NULL; EdgeHash *edgehash = NULL; LinkNode *search = NULL, *search2 = NULL; - float temp[3]; // error handling if ( numedges==0 ) @@ -1086,8 +1085,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) { spring->ij = MIN2(medge[i].v1, medge[i].v2); spring->kl = MAX2(medge[i].v2, medge[i].v1); - VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); clmd->sim_parms->avg_spring_len += spring->restlen; cloth->verts[spring->ij].avg_spring_len += spring->restlen; cloth->verts[spring->kl].avg_spring_len += spring->restlen; @@ -1132,8 +1130,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(mface[i].v1, mface[i].v3); spring->kl = MAX2(mface[i].v3, mface[i].v1); - VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_SHEAR; spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; @@ -1155,8 +1152,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(mface[i].v2, mface[i].v4); spring->kl = MAX2(mface[i].v4, mface[i].v2); - VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_SHEAR; spring->stiffness = (cloth->verts[spring->kl].shear_stiff + cloth->verts[spring->ij].shear_stiff) / 2.0; @@ -1197,8 +1193,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = MIN2(tspring2->ij, index2); spring->kl = MAX2(tspring2->ij, index2); - VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; BLI_edgehash_insert ( edgehash, spring->ij, spring->kl, NULL ); @@ -1237,8 +1232,7 @@ static int cloth_build_springs ( ClothModifierData *clmd, DerivedMesh *dm ) spring->ij = tspring2->ij; spring->kl = tspring->kl; - VECSUB ( temp, cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest ); - spring->restlen = sqrt ( INPR ( temp, temp ) ); + spring->restlen = len_v3v3(cloth->verts[spring->kl].xrest, cloth->verts[spring->ij].xrest); spring->type = CLOTH_SPRING_TYPE_BENDING; spring->stiffness = (cloth->verts[spring->kl].bend_stiff + cloth->verts[spring->ij].bend_stiff) / 2.0; bend_springs++; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 3b6fc09ad4f..56e4c91ba5e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1663,7 +1663,7 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ return 0; *mapindex = index; - QUATCOPY(mapfw, fw); + copy_v4_v4(mapfw, fw); } } else { /* for other meshes that have been modified, we try to map the particle @@ -2835,7 +2835,7 @@ static void cache_key_incremental_rotation(ParticleCacheKey *key0, ParticleCache * angle, since floating point accuracy makes it give * different results across platforms */ if(cosangle > 0.999999f) { - QUATCOPY(key1->rot, key2->rot); + copy_v4_v4(key1->rot, key2->rot); } else { angle= saacos(cosangle); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index f92fb4444cc..3e88fb7d65e 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -815,7 +815,7 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch normalize_v3(nor); mul_v3_fl(nor,-100.0); - VECADD(co2,co1,nor); + add_v3_v3v3(co2,co1,nor); min_d=2.0; intersect=0; @@ -1099,11 +1099,11 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D for(p=0; pdata, &co, 1, 1); } else - VECCOPY(co,mv[p].co) + copy_v3_v3(co,mv[p].co); BLI_kdtree_insert(tree,p,co,NULL); } @@ -1141,14 +1141,14 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D MFace *mf=dm->getFaceData(dm,i,CD_MFACE); if(orcodata) { - VECCOPY(co1, orcodata[mf->v1]); - VECCOPY(co2, orcodata[mf->v2]); - VECCOPY(co3, orcodata[mf->v3]); + copy_v3_v3(co1, orcodata[mf->v1]); + copy_v3_v3(co2, orcodata[mf->v2]); + copy_v3_v3(co3, orcodata[mf->v3]); transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1); transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1); transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1); if(mf->v4) { - VECCOPY(co4, orcodata[mf->v4]); + copy_v3_v3(co4, orcodata[mf->v4]); transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1); } } @@ -1156,12 +1156,12 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT); v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT); v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT); - VECCOPY(co1, v1->co); - VECCOPY(co2, v2->co); - VECCOPY(co3, v3->co); + copy_v3_v3(co1, v1->co); + copy_v3_v3(co2, v2->co); + copy_v3_v3(co3, v3->co); if(mf->v4) { v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT); - VECCOPY(co4, v4->co); + copy_v3_v3(co4, v4->co); } } @@ -1648,7 +1648,7 @@ void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, P normalize_v3(state->ave); } else { - VECCOPY(state->ave, nor); + copy_v3_v3(state->ave, nor); } /* calculate rotation matrix */ @@ -2423,7 +2423,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa pfr.element_size = MAXFLOAT; } sphdata->element_size = pfr.element_size; - VECCOPY(sphdata->flow, pfr.flow); + copy_v3_v3(sphdata->flow, pfr.flow); pressure = stiffness * (pfr.density - rest_density); near_pressure = stiffness_near_fac * pfr.near_density; @@ -2520,7 +2520,7 @@ static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float d integrate_particle(part, pa, dtime, effector_acceleration, sph_force_cb, &sphdata); *element_size = sphdata.element_size; - VECCOPY(flow, sphdata.flow); + copy_v3_v3(flow, sphdata.flow); } /************************************************/ @@ -2592,19 +2592,19 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa if(part->dampfac != 0.f) mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime); - //VECCOPY(pa->state.ave, states->ave); + //copy_v3_v3(pa->state.ave, states->ave); /* finally we do guides */ time=(cfra-pa->time)/pa->lifetime; CLAMP(time, 0.0f, 1.0f); - VECCOPY(tkey.co,pa->state.co); - VECCOPY(tkey.vel,pa->state.vel); + copy_v3_v3(tkey.co,pa->state.co); + copy_v3_v3(tkey.vel,pa->state.vel); tkey.time=pa->state.time; if(part->type != PART_HAIR) { if(do_guides(sim->psys->effectors, &tkey, p, time)) { - VECCOPY(pa->state.co,tkey.co); + copy_v3_v3(pa->state.co,tkey.co); /* guides don't produce valid velocity */ sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co); mul_v3_fl(pa->state.vel,1.0f/dtime); @@ -3472,8 +3472,8 @@ static void do_hair_dynamics(ParticleSimulationData *sim) if(k==0) { float temp[3]; sub_v3_v3v3(temp, key->co, (key+1)->co); - VECCOPY(mvert->co, key->co); - VECADD(mvert->co, mvert->co, temp); + copy_v3_v3(mvert->co, key->co); + add_v3_v3v3(mvert->co, mvert->co, temp); mul_m4_v3(hairmat, mvert->co); mvert++; @@ -3492,7 +3492,7 @@ static void do_hair_dynamics(ParticleSimulationData *sim) } } - VECCOPY(mvert->co, key->co); + copy_v3_v3(mvert->co, key->co); mul_m4_v3(hairmat, mvert->co); mvert++; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index accf3e442e8..5b02731050e 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -321,7 +321,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) /* determine the ortho BB */ for(i=0; i < pccd_M->totvert; i++){ /* evaluate limits */ - VECCOPY(v,pccd_M->mvert[i].co); + copy_v3_v3(v,pccd_M->mvert[i].co); pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull); pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull); pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull); @@ -345,7 +345,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->minx=mima->miny=mima->minz=1e30f; mima->maxx=mima->maxy=mima->maxz=-1e30f; - VECCOPY(v,pccd_M->mvert[mface->v1].co); + copy_v3_v3(v,pccd_M->mvert[mface->v1].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -353,7 +353,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mvert[mface->v2].co); + copy_v3_v3(v,pccd_M->mvert[mface->v2].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -361,7 +361,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mvert[mface->v3].co); + copy_v3_v3(v,pccd_M->mvert[mface->v3].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -370,7 +370,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->maxz = MAX2(mima->maxz,v[2]+hull); if(mface->v4){ - VECCOPY(v,pccd_M->mvert[mface->v4].co); + copy_v3_v3(v,pccd_M->mvert[mface->v4].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -419,7 +419,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) /* determine the ortho BB */ for(i=0; i < pccd_M->totvert; i++){ /* evaluate limits */ - VECCOPY(v,pccd_M->mvert[i].co); + copy_v3_v3(v,pccd_M->mvert[i].co); pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull); pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull); pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull); @@ -429,7 +429,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) pccd_M->bbmax[2] = MAX2(pccd_M->bbmax[2],v[2]+hull); /* evaluate limits */ - VECCOPY(v,pccd_M->mprevvert[i].co); + copy_v3_v3(v,pccd_M->mprevvert[i].co); pccd_M->bbmin[0] = MIN2(pccd_M->bbmin[0],v[0]-hull); pccd_M->bbmin[1] = MIN2(pccd_M->bbmin[1],v[1]-hull); pccd_M->bbmin[2] = MIN2(pccd_M->bbmin[2],v[2]-hull); @@ -449,7 +449,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->minx=mima->miny=mima->minz=1e30f; mima->maxx=mima->maxy=mima->maxz=-1e30f; - VECCOPY(v,pccd_M->mvert[mface->v1].co); + copy_v3_v3(v,pccd_M->mvert[mface->v1].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -457,7 +457,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mvert[mface->v2].co); + copy_v3_v3(v,pccd_M->mvert[mface->v2].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -465,7 +465,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mvert[mface->v3].co); + copy_v3_v3(v,pccd_M->mvert[mface->v3].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -474,7 +474,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxz = MAX2(mima->maxz,v[2]+hull); if(mface->v4){ - VECCOPY(v,pccd_M->mvert[mface->v4].co); + copy_v3_v3(v,pccd_M->mvert[mface->v4].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -484,7 +484,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) } - VECCOPY(v,pccd_M->mprevvert[mface->v1].co); + copy_v3_v3(v,pccd_M->mprevvert[mface->v1].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -492,7 +492,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mprevvert[mface->v2].co); + copy_v3_v3(v,pccd_M->mprevvert[mface->v2].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -500,7 +500,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxy = MAX2(mima->maxy,v[1]+hull); mima->maxz = MAX2(mima->maxz,v[2]+hull); - VECCOPY(v,pccd_M->mprevvert[mface->v3].co); + copy_v3_v3(v,pccd_M->mprevvert[mface->v3].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -509,7 +509,7 @@ static void ccd_mesh_update(Object *ob,ccd_Mesh *pccd_M) mima->maxz = MAX2(mima->maxz,v[2]+hull); if(mface->v4){ - VECCOPY(v,pccd_M->mprevvert[mface->v4].co); + copy_v3_v3(v,pccd_M->mprevvert[mface->v4].co); mima->minx = MIN2(mima->minx,v[0]-hull); mima->miny = MIN2(mima->miny,v[1]-hull); mima->minz = MIN2(mima->minz,v[2]-hull); @@ -1024,8 +1024,8 @@ static int sb_detect_aabb_collisionCached( float UNUSED(force[3]), unsigned int #endif if ((sb == NULL) || (sb->scratch ==NULL)) return 0; - VECCOPY(aabbmin,sb->scratch->aabbmin); - VECCOPY(aabbmax,sb->scratch->aabbmax); + copy_v3_v3(aabbmin,sb->scratch->aabbmin); + copy_v3_v3(aabbmax,sb->scratch->aabbmax); hash = vertexowner->soft->scratch->colliderhash; ihash = BLI_ghashIterator_new(hash); @@ -1099,8 +1099,8 @@ static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float fa aabbmax[2] = MAX3(face_v1[2],face_v2[2],face_v3[2]); /* calculate face normal once again SIGH */ - VECSUB(edge1, face_v1, face_v2); - VECSUB(edge2, face_v3, face_v2); + sub_v3_v3v3(edge1, face_v1, face_v2); + sub_v3_v3v3(edge2, face_v3, face_v2); cross_v3_v3v3(d_nvect, edge2, edge1); normalize_v3(d_nvect); @@ -1143,13 +1143,13 @@ static int sb_detect_face_pointCached(float face_v1[3],float face_v2[3],float fa /* use mesh*/ if (mvert) { while(a){ - VECCOPY(nv1,mvert[a-1].co); + copy_v3_v3(nv1,mvert[a-1].co); if(mprevvert){ mul_v3_fl(nv1,time); Vec3PlusStVec(nv1,(1.0f-time),mprevvert[a-1].co); } /* origin to face_v2*/ - VECSUB(nv1, nv1, face_v2); + sub_v3_v3(nv1, face_v2); facedist = dot_v3v3(nv1,d_nvect); if (ABS(facedist)v1].co); - VECCOPY(nv2,mvert[mface->v2].co); - VECCOPY(nv3,mvert[mface->v3].co); + copy_v3_v3(nv1,mvert[mface->v1].co); + copy_v3_v3(nv2,mvert[mface->v2].co); + copy_v3_v3(nv3,mvert[mface->v3].co); if (mface->v4){ - VECCOPY(nv4,mvert[mface->v4].co); + copy_v3_v3(nv4,mvert[mface->v4].co); } if (mprevvert){ mul_v3_fl(nv1,time); @@ -1277,8 +1277,8 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa } /* switch origin to be nv2*/ - VECSUB(edge1, nv1, nv2); - VECSUB(edge2, nv3, nv2); + sub_v3_v3v3(edge1, nv1, nv2); + sub_v3_v3v3(edge2, nv3, nv2); cross_v3_v3v3(d_nvect, edge2, edge1); normalize_v3(d_nvect); if ( @@ -1291,8 +1291,8 @@ static int sb_detect_face_collisionCached(float face_v1[3],float face_v2[3],floa } if (mface->v4){ /* quad */ /* switch origin to be nv4 */ - VECSUB(edge1, nv3, nv4); - VECSUB(edge2, nv1, nv4); + sub_v3_v3v3(edge1, nv3, nv4); + sub_v3_v3v3(edge2, nv1, nv4); cross_v3_v3v3(d_nvect, edge2, edge1); normalize_v3(d_nvect); if ( @@ -1481,11 +1481,11 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa if (mvert){ - VECCOPY(nv1,mvert[mface->v1].co); - VECCOPY(nv2,mvert[mface->v2].co); - VECCOPY(nv3,mvert[mface->v3].co); + copy_v3_v3(nv1,mvert[mface->v1].co); + copy_v3_v3(nv2,mvert[mface->v2].co); + copy_v3_v3(nv3,mvert[mface->v3].co); if (mface->v4){ - VECCOPY(nv4,mvert[mface->v4].co); + copy_v3_v3(nv4,mvert[mface->v4].co); } if (mprevvert){ mul_v3_fl(nv1,time); @@ -1505,16 +1505,16 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa } /* switch origin to be nv2*/ - VECSUB(edge1, nv1, nv2); - VECSUB(edge2, nv3, nv2); + sub_v3_v3v3(edge1, nv1, nv2); + sub_v3_v3v3(edge2, nv3, nv2); cross_v3_v3v3(d_nvect, edge2, edge1); normalize_v3(d_nvect); if ( isect_line_tri_v3(edge_v1, edge_v2, nv1, nv2, nv3, &t, NULL)){ float v1[3],v2[3]; float intrusiondepth,i1,i2; - VECSUB(v1, edge_v1, nv2); - VECSUB(v2, edge_v2, nv2); + sub_v3_v3v3(v1, edge_v1, nv2); + sub_v3_v3v3(v2, edge_v2, nv2); i1 = dot_v3v3(v1,d_nvect); i2 = dot_v3v3(v2,d_nvect); intrusiondepth = -MIN2(i1,i2)/el; @@ -1524,16 +1524,16 @@ static int sb_detect_edge_collisionCached(float edge_v1[3],float edge_v2[3],floa } if (mface->v4){ /* quad */ /* switch origin to be nv4 */ - VECSUB(edge1, nv3, nv4); - VECSUB(edge2, nv1, nv4); + sub_v3_v3v3(edge1, nv3, nv4); + sub_v3_v3v3(edge2, nv1, nv4); cross_v3_v3v3(d_nvect, edge2, edge1); normalize_v3(d_nvect); if (isect_line_tri_v3( edge_v1, edge_v2,nv1, nv3, nv4, &t, NULL)){ float v1[3],v2[3]; float intrusiondepth,i1,i2; - VECSUB(v1, edge_v1, nv4); - VECSUB(v2, edge_v2, nv4); + sub_v3_v3v3(v1, edge_v1, nv4); + sub_v3_v3v3(v2, edge_v2, nv4); i1 = dot_v3v3(v1,d_nvect); i2 = dot_v3v3(v2,d_nvect); intrusiondepth = -MIN2(i1,i2)/el; @@ -1602,16 +1602,16 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, } /* media in rest */ else{ - VECADD(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec); + add_v3_v3v3(vel, sb->bpoint[bs->v1].vec , sb->bpoint[bs->v2].vec); } f = normalize_v3(vel); f = -0.0001f*f*f*sb->aeroedge; /* (todo) add a nice angle dependant function done for now BUT */ /* still there could be some nice drag/lift function, but who needs it */ - VECSUB(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos); + sub_v3_v3v3(sp, sb->bpoint[bs->v1].pos , sb->bpoint[bs->v2].pos); project_v3_v3v3(pr,vel,sp); - VECSUB(vel,vel,pr); + sub_v3_v3(vel, pr); normalize_v3(vel); if (ob->softflag & OB_SB_AERO_ANGLE){ normalize_v3(sp); @@ -1725,9 +1725,9 @@ static int choose_winner(float*w, float* pos,float*a,float*b,float*c,float*ca,fl winner =3; } switch (winner){ - case 1: VECCOPY(w,ca); break; - case 2: VECCOPY(w,cb); break; - case 3: VECCOPY(w,cc); + case 1: copy_v3_v3(w,ca); break; + case 2: copy_v3_v3(w,cb); break; + case 3: copy_v3_v3(w,cc); } return(winner); } @@ -1824,11 +1824,11 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], if (mvert){ - VECCOPY(nv1,mvert[mface->v1].co); - VECCOPY(nv2,mvert[mface->v2].co); - VECCOPY(nv3,mvert[mface->v3].co); + copy_v3_v3(nv1,mvert[mface->v1].co); + copy_v3_v3(nv2,mvert[mface->v2].co); + copy_v3_v3(nv3,mvert[mface->v3].co); if (mface->v4){ - VECCOPY(nv4,mvert[mface->v4].co); + copy_v3_v3(nv4,mvert[mface->v4].co); } if (mprevvert){ @@ -1838,11 +1838,11 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], since the AABB reduced propabitlty to get here drasticallly it might be a nice tradeof CPU <--> memory */ - VECSUB(vv1,nv1,mprevvert[mface->v1].co); - VECSUB(vv2,nv2,mprevvert[mface->v2].co); - VECSUB(vv3,nv3,mprevvert[mface->v3].co); + sub_v3_v3v3(vv1,nv1,mprevvert[mface->v1].co); + sub_v3_v3v3(vv2,nv2,mprevvert[mface->v2].co); + sub_v3_v3v3(vv3,nv3,mprevvert[mface->v3].co); if (mface->v4){ - VECSUB(vv4,nv4,mprevvert[mface->v4].co); + sub_v3_v3v3(vv4,nv4,mprevvert[mface->v4].co); } mul_v3_fl(nv1,time); @@ -1862,9 +1862,9 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], } /* switch origin to be nv2*/ - VECSUB(edge1, nv1, nv2); - VECSUB(edge2, nv3, nv2); - VECSUB(dv1,opco,nv2); /* abuse dv1 to have vertex in question at *origin* of triangle */ + sub_v3_v3v3(edge1, nv1, nv2); + sub_v3_v3v3(edge2, nv3, nv2); + sub_v3_v3v3(dv1,opco,nv2); /* abuse dv1 to have vertex in question at *origin* of triangle */ cross_v3_v3v3(d_nvect, edge2, edge1); /* n_mag = */ /* UNUSED */ normalize_v3(d_nvect); @@ -1890,7 +1890,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], } if ((mprevvert) && (*damp > 0.0f)){ choose_winner(ve,opco,nv1,nv2,nv3,vv1,vv2,vv3); - VECADD(avel,avel,ve); + add_v3_v3(avel, ve); cavel ++; } *intrusion += facedist; @@ -1899,9 +1899,9 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], } if (mface->v4){ /* quad */ /* switch origin to be nv4 */ - VECSUB(edge1, nv3, nv4); - VECSUB(edge2, nv1, nv4); - VECSUB(dv1,opco,nv4); /* abuse dv1 to have vertex in question at *origin* of triangle */ + sub_v3_v3v3(edge1, nv3, nv4); + sub_v3_v3v3(edge2, nv1, nv4); + sub_v3_v3v3(dv1,opco,nv4); /* abuse dv1 to have vertex in question at *origin* of triangle */ cross_v3_v3v3(d_nvect, edge2, edge1); /* n_mag = */ /* UNUSED */ normalize_v3(d_nvect); @@ -1926,7 +1926,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], if ((mprevvert) && (*damp > 0.0f)){ choose_winner(ve,opco,nv1,nv3,nv4,vv1,vv3,vv4); - VECADD(avel,avel,ve); + add_v3_v3(avel, ve); cavel ++; } *intrusion += facedist; @@ -1939,46 +1939,46 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float dist; closest_to_line_segment_v3(ve, opco, nv1, nv2); - VECSUB(ve,opco,ve); + sub_v3_v3v3(ve,opco,ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )){ - VECCOPY(coledge,ve); + copy_v3_v3(coledge,ve); mindistedge = dist, deflected=1; } closest_to_line_segment_v3(ve, opco, nv2, nv3); - VECSUB(ve,opco,ve); + sub_v3_v3v3(ve,opco,ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )){ - VECCOPY(coledge,ve); + copy_v3_v3(coledge,ve); mindistedge = dist, deflected=1; } closest_to_line_segment_v3(ve, opco, nv3, nv1); - VECSUB(ve,opco,ve); + sub_v3_v3v3(ve,opco,ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )){ - VECCOPY(coledge,ve); + copy_v3_v3(coledge,ve); mindistedge = dist, deflected=1; } if (mface->v4){ /* quad */ closest_to_line_segment_v3(ve, opco, nv3, nv4); - VECSUB(ve,opco,ve); + sub_v3_v3v3(ve,opco,ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )){ - VECCOPY(coledge,ve); + copy_v3_v3(coledge,ve); mindistedge = dist, deflected=1; } closest_to_line_segment_v3(ve, opco, nv1, nv4); - VECSUB(ve,opco,ve); + sub_v3_v3v3(ve,opco,ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )){ - VECCOPY(coledge,ve); + copy_v3_v3(coledge,ve); mindistedge = dist, deflected=1; } @@ -2007,15 +2007,15 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], } if (deflected == 2){ // face inner detected - VECADD(force,force,innerforceaccu); + add_v3_v3(force, innerforceaccu); } if (deflected == 3){ // face outer detected - VECADD(force,force,outerforceaccu); + add_v3_v3(force, outerforceaccu); } BLI_ghashIterator_free(ihash); if (cavel) mul_v3_fl(avel,1.0f/(float)cavel); - VECCOPY(vel,avel); + copy_v3_v3(vel,avel); if (ci) *intrusion /= ci; if (deflected){ normalize_v3_v3(facenormal, force); @@ -2029,7 +2029,7 @@ static int sb_deflect_face(Object *ob,float *actpos,float *facenormal,float *for { float s_actpos[3]; int deflected; - VECCOPY(s_actpos,actpos); + copy_v3_v3(s_actpos,actpos); deflected= sb_detect_vertex_collisionCached(s_actpos, facenormal, cf, force , ob->lay, ob,time,vel,intrusion); //deflected= sb_detect_vertex_collisionCachedEx(s_actpos, facenormal, cf, force , ob->lay, ob,time,vel,intrusion); return(deflected); @@ -2286,7 +2286,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* gravitation */ if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){ float gravity[3]; - VECCOPY(gravity, scene->physics_settings.gravity); + copy_v3_v3(gravity, scene->physics_settings.gravity); mul_v3_fl(gravity, sb_grav_force_scale(ob)*_final_mass(ob,bp)*sb->effector_weights->global_gravity); /* individual mass of node here */ add_v3_v3(bp->force, gravity); } @@ -2303,7 +2303,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* apply forcefield*/ mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale); - VECADD(bp->force, bp->force, force); + add_v3_v3(bp->force, force); /* BP friction in moving media */ kd= sb->mediafrict* eval_sb_fric_force_scale; @@ -2337,7 +2337,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo bp->choke = sb->choke*0.01f; } - VECSUB(cfforce,bp->vec,vel); + sub_v3_v3v3(cfforce,bp->vec,vel); Vec3PlusStVec(bp->force,-cf*50.0f,cfforce); Vec3PlusStVec(bp->force,kd,defforce); @@ -2524,7 +2524,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY){ - VECCOPY(gravity, scene->physics_settings.gravity); + copy_v3_v3(gravity, scene->physics_settings.gravity); mul_v3_fl(gravity, sb_grav_force_scale(ob)*sb->effector_weights->global_gravity); } @@ -2711,7 +2711,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa /* apply forcefield*/ mul_v3_fl(force,fieldfactor* eval_sb_fric_force_scale); - VECADD(bp->force, bp->force, force); + add_v3_v3(bp->force, force); /* BP friction in moving media */ kd= sb->mediafrict* eval_sb_fric_force_scale; @@ -2764,7 +2764,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa } else{ - VECSUB(cfforce,bp->vec,vel); + sub_v3_v3v3(cfforce,bp->vec,vel); Vec3PlusStVec(bp->force,-cf*50.0f,cfforce); } @@ -2774,7 +2774,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa bp->choke = sb->choke*0.01f; } else{ - VECSUB(cfforce,bp->vec,vel); + sub_v3_v3v3(cfforce,bp->vec,vel); Vec3PlusStVec(bp->force,-cf*50.0f,cfforce); } Vec3PlusStVec(bp->force,kd,defforce); @@ -2876,7 +2876,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa else{ printf("Matrix inversion failed \n"); for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(bp->impdv,bp->force); + copy_v3_v3(bp->impdv,bp->force); } } @@ -2923,7 +2923,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * if(_final_goal(ob,bp) < SOFTGOALSNAP){ /* this makes t~ = t */ - if(mid_flags & MID_PRESERVE) VECCOPY(dx,bp->vec); + if(mid_flags & MID_PRESERVE) copy_v3_v3(dx,bp->vec); /* so here is (v)' = a(cceleration) = sum(F_springs)/m + gravitation + some friction forces + more forces*/ /* the ( ... )' operator denotes derivate respective time */ @@ -2931,11 +2931,11 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * /* v(t + dt) = v(t) + a(t) * dt */ mul_v3_fl(bp->force,timeovermass);/* individual mass of node here */ /* some nasty if's to have heun in here too */ - VECCOPY(dv,bp->force); + copy_v3_v3(dv,bp->force); if (mode == 1){ - VECCOPY(bp->prevvec, bp->vec); - VECCOPY(bp->prevdv, dv); + copy_v3_v3(bp->prevvec, bp->vec); + copy_v3_v3(bp->prevdv, dv); } if (mode ==2){ @@ -2948,10 +2948,10 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * maxerrvel = MAX2(maxerrvel,ABS(dv[1] - bp->prevdv[1])); maxerrvel = MAX2(maxerrvel,ABS(dv[2] - bp->prevdv[2])); } - else {VECADD(bp->vec, bp->vec, bp->force);} + else { add_v3_v3(bp->vec, bp->force); } /* this makes t~ = t+dt */ - if(!(mid_flags & MID_PRESERVE)) VECCOPY(dx,bp->vec); + if(!(mid_flags & MID_PRESERVE)) copy_v3_v3(dx,bp->vec); /* so here is (x)'= v(elocity) */ /* the euler step for location then becomes */ @@ -2970,8 +2970,8 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * */ /* again some nasty if's to have heun in here too */ if (mode ==1){ - VECCOPY(bp->prevpos,bp->pos); - VECCOPY(bp->prevdx ,dx); + copy_v3_v3(bp->prevpos,bp->pos); + copy_v3_v3(bp->prevdx ,dx); } if (mode ==2){ @@ -2994,7 +2994,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * } } - else { VECADD(bp->pos, bp->pos, dx);} + else { add_v3_v3(bp->pos, dx);} }/*snap*/ /* so while we are looping BPs anyway do statistics on the fly */ aabbmin[0] = MIN2(aabbmin[0],bp->pos[0]); @@ -3008,8 +3008,8 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * if (sb->totpoint) mul_v3_fl(cm,1.0f/sb->totpoint); if (sb->scratch){ - VECCOPY(sb->scratch->aabbmin,aabbmin); - VECCOPY(sb->scratch->aabbmax,aabbmax); + copy_v3_v3(sb->scratch->aabbmin,aabbmin); + copy_v3_v3(sb->scratch->aabbmax,aabbmax); } if (err){ /* so step size will be controlled by biggest difference in slope */ @@ -3032,8 +3032,8 @@ static void softbody_restore_prev_step(Object *ob) int a; for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(bp->vec, bp->prevvec); - VECCOPY(bp->pos, bp->prevpos); + copy_v3_v3(bp->vec, bp->prevvec); + copy_v3_v3(bp->pos, bp->prevpos); } } @@ -3045,8 +3045,8 @@ static void softbody_store_step(Object *ob) int a; for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(bp->prevvec,bp->vec); - VECCOPY(bp->prevpos,bp->pos); + copy_v3_v3(bp->prevvec,bp->vec); + copy_v3_v3(bp->prevpos,bp->pos); } } @@ -3061,10 +3061,10 @@ static void softbody_store_state(Object *ob,float *ppos,float *pvel) for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(pv, bp->vec); + copy_v3_v3(pv, bp->vec); pv+=3; - VECCOPY(pp, bp->pos); + copy_v3_v3(pp, bp->pos); pp+=3; } } @@ -3079,10 +3079,10 @@ static void softbody_retrieve_state(Object *ob,float *ppos,float *pvel) for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(bp->vec,pv); + copy_v3_v3(bp->vec,pv); pv+=3; - VECCOPY(bp->pos,pp); + copy_v3_v3(bp->pos,pp); pp+=3; } } @@ -3098,14 +3098,14 @@ static void softbody_swap_state(Object *ob,float *ppos,float *pvel) for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { - VECCOPY(temp, bp->vec); - VECCOPY(bp->vec,pv); - VECCOPY(pv,temp); + copy_v3_v3(temp, bp->vec); + copy_v3_v3(bp->vec,pv); + copy_v3_v3(pv,temp); pv+=3; - VECCOPY(temp, bp->pos); - VECCOPY(bp->pos,pp); - VECCOPY(pp,temp); + copy_v3_v3(temp, bp->pos); + copy_v3_v3(bp->pos,pp); + copy_v3_v3(pp,temp); pp+=3; } } @@ -3126,8 +3126,8 @@ static void softbody_apply_goalsnap(Object *ob) for(a=sb->totpoint, bp= sb->bpoint; a>0; a--, bp++) { if (_final_goal(ob,bp) >= SOFTGOALSNAP){ - VECCOPY(bp->prevpos,bp->pos); - VECCOPY(bp->pos,bp->origT); + copy_v3_v3(bp->prevpos,bp->pos); + copy_v3_v3(bp->pos,bp->origT); } } } @@ -3238,7 +3238,7 @@ static void springs_from_mesh(Object *ob) if(me->totvert) { bp= ob->soft->bpoint; for(a=0; atotvert; a++, bp++) { - VECCOPY(bp->origS, me->mvert[a].co); + copy_v3_v3(bp->origS, me->mvert[a].co); mul_m4_v3(ob->obmat, bp->origS); } @@ -3399,12 +3399,12 @@ static void reference_to_scratch(Object *ob) bp= ob->soft->bpoint; rp= sb->scratch->Ref.ivert; for(a=0; atotpoint; a++, rp++, bp++) { - VECCOPY(rp->pos,bp->pos); - VECADD(accu_pos,accu_pos,bp->pos); + copy_v3_v3(rp->pos,bp->pos); + add_v3_v3(accu_pos, bp->pos); accu_mass += _final_mass(ob,bp); } mul_v3_fl(accu_pos,1.0f/accu_mass); - VECCOPY(sb->scratch->Ref.com,accu_pos); + copy_v3_v3(sb->scratch->Ref.com,accu_pos); /* printf("reference_to_scratch \n"); */ } @@ -3415,9 +3415,9 @@ when object is rescaled static float globallen(float *v1,float *v2,Object *ob) { float p1[3],p2[3]; - VECCOPY(p1,v1); + copy_v3_v3(p1,v1); mul_m4_v3(ob->obmat, p1); - VECCOPY(p2,v2); + copy_v3_v3(p2,v2); mul_m4_v3(ob->obmat, p2); return len_v3v3(p1,p2); } @@ -3656,7 +3656,7 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, invert_m4_m4(ob->imat, ob->obmat); for(a=0; apos); + copy_v3_v3(vertexCos[a], bp->pos); if(local==0) mul_m4_v3(ob->imat, vertexCos[a]); /* softbody is in global coords, baked optionally not */ } @@ -3784,14 +3784,14 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo for(a=0,bp=sb->bpoint; aorigS, bp->origE); + copy_v3_v3(bp->origS, bp->origE); /* copy the position of the goals at desired end time */ - VECCOPY(bp->origE, vertexCos[a]); + copy_v3_v3(bp->origE, vertexCos[a]); /* vertexCos came from local world, go global */ mul_m4_v3(ob->obmat, bp->origE); /* just to be save give bp->origT a defined value will be calulated in interpolate_exciter()*/ - VECCOPY(bp->origT, bp->origE); + copy_v3_v3(bp->origT, bp->origE); } } @@ -3828,14 +3828,14 @@ void SB_estimate_transform(Object *ob,float lloc[3],float lrot[3][3],float lscal rpos= MEM_callocN( (sb->totpoint)*3*sizeof(float), "SB_RPOS"); /* might filter vertex selection with a vertex group */ for(a=0, bp=sb->bpoint, rp=sb->scratch->Ref.ivert; atotpoint; a++, bp++, rp++) { - VECCOPY(rpos[a],rp->pos); - VECCOPY(opos[a],bp->pos); + copy_v3_v3(rpos[a],rp->pos); + copy_v3_v3(opos[a],bp->pos); } vcloud_estimate_transform(sb->totpoint, opos, NULL, rpos, NULL, com, rcom,lrot,lscale); - //VECSUB(com,com,rcom); - if (lloc) VECCOPY(lloc,com); - VECCOPY(sb->lcom,com); + //sub_v3_v3(com,rcom); + if (lloc) copy_v3_v3(lloc,com); + copy_v3_v3(sb->lcom,com); if (lscale) copy_m3_m3(sb->lscale,lscale); if (lrot) copy_m3_m3(sb->lrot,lrot); @@ -3850,11 +3850,11 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int int a; for(a=0,bp=sb->bpoint; apos, vertexCos[a]); + copy_v3_v3(bp->pos, vertexCos[a]); mul_m4_v3(ob->obmat, bp->pos); /* yep, sofbody is global coords*/ - VECCOPY(bp->origS, bp->pos); - VECCOPY(bp->origE, bp->pos); - VECCOPY(bp->origT, bp->pos); + copy_v3_v3(bp->origS, bp->pos); + copy_v3_v3(bp->origE, bp->pos); + copy_v3_v3(bp->origT, bp->pos); bp->vec[0]= bp->vec[1]= bp->vec[2]= 0.0f; /* the bp->prev*'s are for rolling back from a canceled try to propagate in time @@ -3869,10 +3869,10 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int 4.b yup we're done */ - VECCOPY(bp->prevpos, bp->pos); - VECCOPY(bp->prevvec, bp->vec); - VECCOPY(bp->prevdx, bp->vec); - VECCOPY(bp->prevdv, bp->vec); + copy_v3_v3(bp->prevpos, bp->pos); + copy_v3_v3(bp->prevvec, bp->vec); + copy_v3_v3(bp->prevdx, bp->vec); + copy_v3_v3(bp->prevdv, bp->vec); } /* make a nice clean scratch struc */ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 986e0e2b552..9848b27d32e 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -668,7 +668,7 @@ static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float co_r[3]) MVert mvert; ccgDM_getFinalVert(dm, vertNum, &mvert); - VECCOPY(co_r, mvert.co); + copy_v3_v3(co_r, mvert.co); } static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float no_r[3]) diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index d3bd7d7b766..3aa289d0ef8 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -227,7 +227,7 @@ void init_mapping(TexMapping *texmap) mul_m3_m3m3(mat, rmat, smat); copy_m4_m3(texmap->mat, mat); - VECCOPY(texmap->mat[3], texmap->loc); + copy_v3_v3(texmap->mat[3], texmap->loc); } diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 6dd278ed777..d0d3d0e137e 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -823,14 +823,14 @@ static void testAxialSymmetry(BGraph *graph, BNode* root_node, BNode* node1, BNo } /* mirror node2 along axis */ - VECCOPY(p, node2->p); + copy_v3_v3(p, node2->p); BLI_mirrorAlongAxis(p, root_node->p, nor); /* check if it's within limit before continuing */ if (len_v3v3(node1->p, p) <= limit) { /* mark node as symmetric physically */ - VECCOPY(root_node->symmetry_axis, nor); + copy_v3_v3(root_node->symmetry_axis, nor); root_node->symmetry_flag |= SYM_PHYSICAL; root_node->symmetry_flag |= SYM_AXIAL; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index e17f8c720a5..3a03a11b849 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4412,7 +4412,7 @@ static void direct_link_object(FileData *fd, Object *ob) * a hook we need to make sure it gets converted * and free'd, regardless of version. */ - VECCOPY(hmd->cent, hook->cent); + copy_v3_v3(hmd->cent, hook->cent); hmd->falloff = hook->falloff; hmd->force = hook->force; hmd->indexar = hook->indexar; @@ -9607,7 +9607,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) part->obfac = paf->obfac; part->randfac = paf->randfac * 25.0f; part->dampfac = paf->damp; - VECCOPY(part->acc, paf->force); + copy_v3_v3(part->acc, paf->force); /* flags */ if(paf->stype & PAF_VECT) { @@ -10658,7 +10658,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) tot= MIN2(me->totvert, key->refkey->totelem); for(a=0; amvert[a].co, data) + copy_v3_v3(me->mvert[a].co, data); } } @@ -10668,7 +10668,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) tot= MIN2(lt->pntsu*lt->pntsv*lt->pntsw, key->refkey->totelem); for(a=0; adef[a].vec, data) + copy_v3_v3(lt->def[a].vec, data); } } @@ -10681,9 +10681,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) BezTriple *bezt = nu->bezt; for(a=0; apntsu; a++, bezt++) { - VECCOPY(bezt->vec[0], data); data+=3; - VECCOPY(bezt->vec[1], data); data+=3; - VECCOPY(bezt->vec[2], data); data+=3; + copy_v3_v3(bezt->vec[0], data); data+=3; + copy_v3_v3(bezt->vec[1], data); data+=3; + copy_v3_v3(bezt->vec[2], data); data+=3; bezt->alfa= *data; data++; } } @@ -10691,7 +10691,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) BPoint *bp = nu->bp; for(a=0; apntsu*nu->pntsv; a++, bp++) { - VECCOPY(bp->vec, data); data+=3; + copy_v3_v3(bp->vec, data); data+=3; bp->alfa= *data; data++; } } @@ -13376,7 +13376,7 @@ static void give_base_to_groups(Main *mainvar, Scene *scene) ob->dup_group= group; ob->transflag |= OB_DUPLIGROUP; rename_id(&ob->id, group->id.name+2); - VECCOPY(ob->loc, scene->cursor); + copy_v3_v3(ob->loc, scene->cursor); } } } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 26c08f6cae5..a438d5c86e9 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -296,7 +296,7 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat); } if(material->builtins & GPU_OBCOLOR) { - QUATCOPY(col, obcol); + copy_v4_v4(col, obcol); CLAMP(col[3], 0.0f, 1.0f); GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col); } diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index f93e0469686..509c916941f 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -257,7 +257,7 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, mul_qt_v3(state.rot,mv->co); if(pimd->flag & eParticleInstanceFlag_UseSize) mul_v3_fl(mv->co, size[i/totvert]); - VECADD(mv->co,mv->co,state.co); + add_v3_v3(mv->co, state.co); } mface=result->getFaceArray(result); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 4609ee221a4..2c056ad4021 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -198,7 +198,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object for(i=0; imode != MOD_SIMPLEDEFORM_MODE_BEND) //Bend mode shoulnt have any lock axis diff --git a/source/blender/python/mathutils/mathutils_geometry.c b/source/blender/python/mathutils/mathutils_geometry.c index e8721a3a91d..3518c8008c6 100644 --- a/source/blender/python/mathutils/mathutils_geometry.c +++ b/source/blender/python/mathutils/mathutils_geometry.c @@ -97,14 +97,14 @@ static PyObject *M_Geometry_intersect_ray_tri(PyObject *UNUSED(self), PyObject* if (BaseMath_ReadCallback(vec1) == -1 || BaseMath_ReadCallback(vec2) == -1 || BaseMath_ReadCallback(vec3) == -1 || BaseMath_ReadCallback(ray) == -1 || BaseMath_ReadCallback(ray_off) == -1) return NULL; - VECCOPY(v1, vec1->vec); - VECCOPY(v2, vec2->vec); - VECCOPY(v3, vec3->vec); + copy_v3_v3(v1, vec1->vec); + copy_v3_v3(v2, vec2->vec); + copy_v3_v3(v3, vec3->vec); - VECCOPY(dir, ray->vec); + copy_v3_v3(dir, ray->vec); normalize_v3(dir); - VECCOPY(orig, ray_off->vec); + copy_v3_v3(orig, ray_off->vec); /* find vectors for two edges sharing v1 */ sub_v3_v3v3(e1, v2, v1); @@ -189,10 +189,10 @@ static PyObject *M_Geometry_intersect_line_line(PyObject *UNUSED(self), PyObject int result; if (vec1->size == 3) { - VECCOPY(v1, vec1->vec); - VECCOPY(v2, vec2->vec); - VECCOPY(v3, vec3->vec); - VECCOPY(v4, vec4->vec); + copy_v3_v3(v1, vec1->vec); + copy_v3_v3(v2, vec2->vec); + copy_v3_v3(v3, vec3->vec); + copy_v3_v3(v4, vec4->vec); } else { v1[0]= vec1->vec[0]; diff --git a/source/blender/render/intern/include/zbuf.h b/source/blender/render/intern/include/zbuf.h index 6567cdacf0e..c467c31b5a6 100644 --- a/source/blender/render/intern/include/zbuf.h +++ b/source/blender/render/intern/include/zbuf.h @@ -135,7 +135,7 @@ void zbufclipwire(struct ZSpan *zspan, int obi, int zvlnr, int ec, float *ho1, f /* exported to shadeinput.c */ void zbuf_make_winmat(Render *re, float winmat[][4]); -void zbuf_render_project(float winmat[][4], float *co, float *ho); +void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]); #endif diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 719b9674b80..1887f22198d 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -88,7 +88,7 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y) if(ibuf->rect_float) { if(ibuf->channels==4) { float *fp= ibuf->rect_float + 4*ofs; - QUATCOPY(col, fp); + copy_v4_v4(col, fp); } else if(ibuf->channels==3) { float *fp= ibuf->rect_float + 3*ofs; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index a02c5681e5e..1a58a665e0a 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -1593,7 +1593,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) } /* put back together */ if(shi->combinedflag & SCE_PASS_SPEC) - VECADD(shr->combined, diff, shr->spec) /* no ; */ + add_v3_v3v3(shr->combined, diff, shr->spec); else copy_v3_v3(shr->combined, diff); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index d2683f26c3a..48134c46c61 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -562,7 +562,7 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult float *fp; fp= rl->rectf + 4*offset; - QUATCOPY(fp, shr->combined); + copy_v4_v4(fp, shr->combined); for(rpass= rl->passes.first; rpass; rpass= rpass->next) { float *col= NULL, uvcol[3]; @@ -695,7 +695,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl) } if(pass[3]==0.0f) { - QUATCOPY(pass, col); + copy_v4_v4(pass, col); } else { addAlphaUnderFloat(pass, col); @@ -2345,7 +2345,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) { shade_input_set_shade_texco(shi); VECCOPY(tvn, shi->nmapnorm); - QUATCOPY(ttang, shi->nmaptang); + copy_v4_v4(ttang, shi->nmaptang); } /* if we are doing selected to active baking, find point on other face */ diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index ddfe3199d30..0ed3a094cf8 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -495,10 +495,10 @@ static float area_lamp_energy_multisample(LampRen *lar, float *co, float *vn) vec[2]= 0.0f; mul_m3_v3(lar->mat, vec); - VECADD(area[0], lar->area[0], vec); - VECADD(area[1], lar->area[1], vec); - VECADD(area[2], lar->area[2], vec); - VECADD(area[3], lar->area[3], vec); + add_v3_v3v3(area[0], lar->area[0], vec); + add_v3_v3v3(area[1], lar->area[1], vec); + add_v3_v3v3(area[2], lar->area[2], vec); + add_v3_v3v3(area[3], lar->area[3], vec); intens+= area_lamp_energy(area, co, vn); @@ -1111,12 +1111,12 @@ void lamp_get_shadow(LampRen *lar, ShadeInput *shi, float inp, float shadfac[4], } if(shi->depth==0) { - QUATCOPY(lss->shadfac, shadfac); + copy_v4_v4(lss->shadfac, shadfac); lss->samplenr= shi->samplenr; } } else { - QUATCOPY(shadfac, lss->shadfac); + copy_v4_v4(shadfac, lss->shadfac); } } @@ -1879,16 +1879,16 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr) /* and add emit and spec */ if(shi->combinedflag & SCE_PASS_EMIT) - VECADD(shr->combined, shr->combined, shr->emit); + add_v3_v3(shr->combined, shr->emit); if(shi->combinedflag & SCE_PASS_SPEC) - VECADD(shr->combined, shr->combined, shr->spec); + add_v3_v3(shr->combined, shr->spec); /* modulate by the object color */ if((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) { if(!(ma->sss_flag & MA_DIFF_SSS) || !sss_pass_done(&R, ma)) { float obcol[4]; - QUATCOPY(obcol, shi->obr->ob->col); + copy_v4_v4(obcol, shi->obr->ob->col); CLAMP(obcol[3], 0.0f, 1.0f); shr->combined[0] *= obcol[0]; diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index cf97a63d8a0..4192aaf42aa 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -1,4 +1,4 @@ -/* +/* * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -452,11 +452,11 @@ static void compute_radiance(ScatterTree *tree, float *co, float *rad) mul_v3_fl(result.rad, tree->ss[0]->frontweight); mul_v3_fl(result.backrad, tree->ss[0]->backweight); - VECCOPY(rad, result.rad); - VECADD(backrad, result.rad, result.backrad); + copy_v3_v3(rad, result.rad); + add_v3_v3v3(backrad, result.rad, result.backrad); - VECCOPY(rdsum, result.rdsum); - VECADD(backrdsum, result.rdsum, result.backrdsum); + copy_v3_v3(rdsum, result.rdsum); + add_v3_v3v3(backrdsum, result.rdsum, result.backrdsum); if(rdsum[0] > 1e-16f) rad[0]= tree->ss[0]->color*rad[0]/rdsum[0]; if(rdsum[1] > 1e-16f) rad[1]= tree->ss[1]->color*rad[1]/rdsum[1]; @@ -761,8 +761,8 @@ ScatterTree *scatter_tree_new(ScatterSettings *ss[3], float scale, float error, INIT_MINMAX(tree->min, tree->max); for(i=0; iscale*tree->scale); points[i].back= (area[i] < 0.0f); @@ -818,7 +818,7 @@ void scatter_tree_sample(ScatterTree *tree, float *co, float *color) { float sco[3]; - VECCOPY(sco, co); + copy_v3_v3(sco, co); mul_v3_fl(sco, 1.0f/tree->scale); compute_radiance(tree, sco, color); diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index ed12c08c193..ddcffcc303b 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -98,10 +98,10 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) t= spoint->t; type= (strandbuf->flag & R_STRAND_BSPLINE)? KEY_BSPLINE: KEY_CARDINAL; - VECCOPY(p[0], sseg->v[0]->co); - VECCOPY(p[1], sseg->v[1]->co); - VECCOPY(p[2], sseg->v[2]->co); - VECCOPY(p[3], sseg->v[3]->co); + copy_v3_v3(p[0], sseg->v[0]->co); + copy_v3_v3(p[1], sseg->v[1]->co); + copy_v3_v3(p[2], sseg->v[2]->co); + copy_v3_v3(p[3], sseg->v[3]->co); if(sseg->obi->flag & R_TRANSFORMED) { mul_m4_v3(sseg->obi->mat, p[0]); @@ -111,7 +111,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) } if(t == 0.0f) { - VECCOPY(spoint->co, p[1]); + copy_v3_v3(spoint->co, p[1]); spoint->strandco= sseg->v[1]->strandco; spoint->dtstrandco= (sseg->v[2]->strandco - sseg->v[0]->strandco); @@ -119,7 +119,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) spoint->dtstrandco *= 0.5f; } else if(t == 1.0f) { - VECCOPY(spoint->co, p[2]); + copy_v3_v3(spoint->co, p[2]); spoint->strandco= sseg->v[2]->strandco; spoint->dtstrandco= (sseg->v[3]->strandco - sseg->v[1]->strandco); @@ -139,10 +139,10 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; - VECCOPY(spoint->tan, spoint->dtco); + copy_v3_v3(spoint->tan, spoint->dtco); normalize_v3(spoint->tan); - VECCOPY(spoint->nor, spoint->co); + copy_v3_v3(spoint->nor, spoint->co); VECMUL(spoint->nor, -1.0f); normalize_v3(spoint->nor); @@ -183,7 +183,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) sub_v3_v3v3(spoint->co1, spoint->co, cross); add_v3_v3v3(spoint->co2, spoint->co, cross); - VECCOPY(spoint->dsco, cross); + copy_v3_v3(spoint->dsco, cross); } /* *************** */ @@ -617,10 +617,10 @@ static void do_scanconvert_strand(Render *UNUSED(re), StrandPart *spart, ZSpan * { float jco1[3], jco2[3], jco3[3], jco4[3], jx, jy; - VECCOPY(jco1, co1); - VECCOPY(jco2, co2); - VECCOPY(jco3, co3); - VECCOPY(jco4, co4); + copy_v3_v3(jco1, co1); + copy_v3_v3(jco2, co2); + copy_v3_v3(jco3, co3); + copy_v3_v3(jco4, co4); if(spart->jit) { jx= -spart->jit[sample][0]; @@ -1008,7 +1008,7 @@ StrandSurface *cache_strand_surface(Render *re, ObjectRen *obr, DerivedMesh *dm, mvert= dm->getVertArray(dm); for(a=0; atotvert; a++, mvert++) { - VECCOPY(co[a], mvert->co); + copy_v3_v3(co[a], mvert->co); mul_m4_v3(mat, co[a]); } @@ -1047,7 +1047,7 @@ void strand_minmax(StrandRen *strand, float *min, float *max, float width) int a; for(a=0, svert=strand->vert; atotvert; a++, svert++) { - VECCOPY(vec, svert->co); + copy_v3_v3(vec, svert->co); DO_MINMAX(vec, min, max); if(width!=0.0f) { diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index 7a8779ee969..8b383992e65 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -444,12 +444,12 @@ static void zbuflineAc(ZSpan *zspan, int obi, int zvlnr, float *vec1, float *vec /* all lines from left to right */ if(vec1[0] bounds[3]*wco) clipflag |= 4; else if(ho[1] < bounds[2]*wco) clipflag |= 8; - QUATCOPY(cache[cindex].ho, ho); + copy_v4_v4(cache[cindex].ho, ho); cache[cindex].clip= clipflag; cache[cindex].index= index; @@ -1801,11 +1801,11 @@ static int zbuf_part_project(ZbufProjectCache *cache, int index, float winmat[][ } } -void zbuf_render_project(float winmat[][4], float *co, float *ho) +void zbuf_render_project(float winmat[][4], const float co[3], float ho[4]) { float vec[3]; - VECCOPY(vec, co) + copy_v3_v3(vec, co); projectvert(vec, winmat, ho); } @@ -3348,7 +3348,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase * mul= 0x7FFFFFFF; zval= mul*(1.0f+ho1[2]/ho1[3]); - VECCOPY(vec, v1->co); + copy_v3_v3(vec, v1->co); /* z is negative, otherwise its being clipped */ vec[2]-= ma->zoffs; projectverto(vec, obwinmat, hoco); @@ -3474,7 +3474,7 @@ void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, in if(fp[3]==PASS_VECTOR_MAX) fp[3]= 0.0f; } else if(rdrect==NULL || rdrect[offset]==0 || alpha>0.95f) { - QUATCOPY(fp, speed); + copy_v4_v4(fp, speed); } else { /* add minimum speed in pixel */ @@ -3866,7 +3866,7 @@ static int addtosamp_shr(ShadeResult *samp_shr, ShadeSample *ssamp, int addpassf samp_shr->z= MIN2(samp_shr->z, shr->z); if(addpassflag & SCE_PASS_VECTOR) { - QUATCOPY(samp_shr->winspeed, shr->winspeed); + copy_v4_v4(samp_shr->winspeed, shr->winspeed); } /* optim... */ if(addpassflag & ~(SCE_PASS_VECTOR)) { diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index 836cfab6b49..5a44e1022ff 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -162,8 +162,8 @@ void game_blend_poses(bPose *dst, bPose *src, float srcweight/*, short mode*/) if (schan->rotmode == ROT_MODE_QUAT) { float dquat[4], squat[4]; - QUATCOPY(dquat, dchan->quat); - QUATCOPY(squat, schan->quat); + copy_qt_qt(dquat, dchan->quat); + copy_qt_qt(squat, schan->quat); if (mode==ACTSTRIPMODE_BLEND) interp_qt_qtqt(dchan->quat, dquat, squat, srcweight); else { From 96d73bfdcfd74bfccd58bf02ae25b64577fce904 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 01:38:32 +0000 Subject: [PATCH 120/147] replace VECCOPY with copy_v3_v3, same for 2d copy, also added vec copy functions for int & char. --- .../blender/blenkernel/intern/cdderivedmesh.c | 58 +++++++++---------- source/blender/blenkernel/intern/pointcache.c | 20 +++---- source/blender/blenkernel/intern/shrinkwrap.c | 32 +++++----- source/blender/blenlib/BLI_math_vector.h | 9 ++- .../blenlib/intern/math_vector_inline.c | 44 ++++++++++++++ .../editors/animation/anim_channels_defines.c | 6 +- .../editors/armature/editarmature_retarget.c | 54 ++++++++--------- .../editors/armature/editarmature_sketch.c | 36 ++++++------ .../blender/editors/gpencil/gpencil_paint.c | 2 +- source/blender/editors/interface/interface.c | 4 +- .../editors/interface/interface_widgets.c | 30 +++++----- .../blender/editors/object/object_lattice.c | 3 +- .../blender/editors/object/object_modifier.c | 4 +- .../editors/sculpt_paint/paint_image.c | 28 +++++++-- source/blender/editors/space_info/textview.c | 5 +- .../editors/space_view3d/drawarmature.c | 18 +++--- .../blender/editors/space_view3d/drawobject.c | 8 +-- .../editors/space_view3d/view3d_edit.c | 4 +- .../blender/editors/space_view3d/view3d_fly.c | 4 +- source/blender/editors/transform/transform.c | 2 +- .../editors/transform/transform_generics.c | 2 +- .../editors/transform/transform_input.c | 2 +- source/blender/editors/util/crazyspace.c | 2 +- source/blender/gpu/intern/gpu_material.c | 10 ++-- .../blender/ikplugin/intern/iksolver_plugin.c | 12 ++-- .../blender/ikplugin/intern/itasc_plugin.cpp | 10 ++-- source/blender/makesrna/intern/rna_armature.c | 12 ++-- .../render/intern/include/rendercore.h | 1 - source/blender/render/intern/source/envmap.c | 2 +- .../render/intern/source/imagetexture.c | 2 +- .../render/intern/source/pixelshading.c | 10 ++-- .../render/intern/source/pointdensity.c | 12 ++-- .../blender/render/intern/source/rendercore.c | 51 ++++++++-------- source/blender/render/intern/source/shadbuf.c | 8 +-- .../blender/render/intern/source/shadeinput.c | 4 +- source/blender/render/intern/source/strand.c | 9 +-- .../render/intern/source/volume_precache.c | 2 +- .../blender/render/intern/source/voxeldata.c | 6 +- 38 files changed, 296 insertions(+), 232 deletions(-) diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 25f9f17f201..d2c86a14572 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -152,7 +152,7 @@ static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3]) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; - VECCOPY(co_r, cddm->mvert[index].co); + copy_v3_v3(co_r, cddm->mvert[index].co); } static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) @@ -161,7 +161,7 @@ static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) int i; for(i = 0; i < dm->numVertData; i++, mv++) - VECCOPY(cos_r[i], mv->co); + copy_v3_v3(cos_r[i], mv->co); } static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) @@ -1246,39 +1246,39 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo if( numdata != 0 ) { offset = 0; if(attribs.totorco) { - VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]); - VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]); - VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]); + copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]); + copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]); offset += sizeof(float)*3; } for(b = 0; b < attribs.tottface; b++) { MTFace *tf = &attribs.tface[b].array[a]; - VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[0]); - VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]); - VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]); offset += sizeof(float)*2; } for(b = 0; b < attribs.totmcol; b++) { MCol *cp = &attribs.mcol[b].array[a*4 + 0]; GLubyte col[4]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col); cp = &attribs.mcol[b].array[a*4 + 1]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col); cp = &attribs.mcol[b].array[a*4 + 2]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col); offset += sizeof(unsigned char)*4; } if(attribs.tottang) { float *tang = attribs.tang.array[a*4 + 0]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang); tang = attribs.tang.array[a*4 + 1]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang); tang = attribs.tang.array[a*4 + 2]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); offset += sizeof(float)*4; } (void)offset; @@ -1288,38 +1288,38 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo if( numdata != 0 ) { offset = 0; if(attribs.totorco) { - VECCOPY((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]); - VECCOPY((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]); - VECCOPY((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]); + copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]); + copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]); + copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]); offset += sizeof(float)*3; } for(b = 0; b < attribs.tottface; b++) { MTFace *tf = &attribs.tface[b].array[a]; - VECCOPY2D((float *)&varray[elementsize*curface*3+offset],tf->uv[2]); - VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]); - VECCOPY2D((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]); + copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]); offset += sizeof(float)*2; } for(b = 0; b < attribs.totmcol; b++) { MCol *cp = &attribs.mcol[b].array[a*4 + 2]; GLubyte col[4]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col); cp = &attribs.mcol[b].array[a*4 + 3]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col); cp = &attribs.mcol[b].array[a*4 + 0]; col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; - QUATCOPY((unsigned char *)&varray[elementsize*curface*3+offset+elementsize*2], col); + copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col); offset += sizeof(unsigned char)*4; } if(attribs.tottang) { float *tang = attribs.tang.array[a*4 + 2]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang); tang = attribs.tang.array[a*4 + 3]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang); tang = attribs.tang.array[a*4 + 0]; - QUATCOPY((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); + copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang); offset += sizeof(float)*4; } (void)offset; @@ -1439,7 +1439,7 @@ static void cdDM_foreachMappedFaceCenter( else orig = i; - VECCOPY(cent, mv[mf->v1].co); + copy_v3_v3(cent, mv[mf->v1].co); add_v3_v3(cent, mv[mf->v2].co); add_v3_v3(cent, mv[mf->v3].co); @@ -1625,7 +1625,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *UNUSED(me)) i++, eve = eve->next, index++) { MVert *mv = &mvert[i]; - VECCOPY(mv->co, eve->co); + copy_v3_v3(mv->co, eve->co); normal_float_to_short_v3(mv->no, eve->no); mv->bweight = (unsigned char) (eve->bweight * 255.0f); @@ -1793,7 +1793,7 @@ void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3]) cddm->mvert = vert; for(i = 0; i < dm->numVertData; ++i, ++vert) - VECCOPY(vert->co, vertCoords[i]); + copy_v3_v3(vert->co, vertCoords[i]); } void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3]) diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index ba5b98ee3cd..9deaa19429f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -183,8 +183,8 @@ static void ptcache_softbody_interpolate(int index, void *soft_v, void **data, f if(cfra1 == cfra2) return; - VECCOPY(keys[1].co, bp->pos); - VECCOPY(keys[1].vel, bp->vec); + copy_v3_v3(keys[1].co, bp->pos); + copy_v3_v3(keys[1].vel, bp->vec); if(old_data) { memcpy(keys[2].co, old_data, 3 * sizeof(float)); @@ -202,8 +202,8 @@ static void ptcache_softbody_interpolate(int index, void *soft_v, void **data, f mul_v3_fl(keys->vel, 1.0f / dfra); - VECCOPY(bp->pos, keys->co); - VECCOPY(bp->vec, keys->vel); + copy_v3_v3(bp->pos, keys->co); + copy_v3_v3(bp->vec, keys->vel); } static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra)) { @@ -483,8 +483,8 @@ static void ptcache_cloth_interpolate(int index, void *cloth_v, void **data, flo if(cfra1 == cfra2) return; - VECCOPY(keys[1].co, vert->x); - VECCOPY(keys[1].vel, vert->v); + copy_v3_v3(keys[1].co, vert->x); + copy_v3_v3(keys[1].vel, vert->v); if(old_data) { memcpy(keys[2].co, old_data, 3 * sizeof(float)); @@ -502,8 +502,8 @@ static void ptcache_cloth_interpolate(int index, void *cloth_v, void **data, flo mul_v3_fl(keys->vel, 1.0f / dfra); - VECCOPY(vert->x, keys->co); - VECCOPY(vert->v, keys->vel); + copy_v3_v3(vert->x, keys->co); + copy_v3_v3(vert->v, keys->vel); /* should vert->xconst be interpolated somehow too? - jahka */ } @@ -2126,7 +2126,7 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra) } void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startframe, int *endframe, float *timescale) { - Object *ob; + /* Object *ob; */ /* UNUSED */ PointCache *cache; /* float offset; unused for now */ float time, nexttime; @@ -2143,7 +2143,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra * is probably to interpolate results from two frames for that .. */ - ob= pid->ob; + /* ob= pid->ob; */ /* UNUSED */ cache= pid->cache; if(timescale) { diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 3d788b40a17..aed246690bd 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -167,13 +167,11 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) //Convert the vertex to tree coordinates - if(calc->vert) - { - VECCOPY(tmp_co, calc->vert[i].co); + if(calc->vert) { + copy_v3_v3(tmp_co, calc->vert[i].co); } - else - { - VECCOPY(tmp_co, co); + else { + copy_v3_v3(tmp_co, co); } space_transform_apply(&calc->local2target, tmp_co); @@ -198,7 +196,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc) if(dist > FLT_EPSILON) weight *= (dist - calc->keepDist)/dist; //Convert the coordinates back to mesh coordinates - VECCOPY(tmp_co, nearest.co); + copy_v3_v3(tmp_co, nearest.co); space_transform_invert(&calc->local2target, tmp_co); interp_v3_v3v3(co, co, tmp_co, weight); //linear interpolation @@ -228,11 +226,11 @@ int normal_projection_project_vertex(char options, const float *vert, const floa //Apply space transform (TODO readjust dist) if(transf) { - VECCOPY( tmp_co, vert ); + copy_v3_v3( tmp_co, vert ); space_transform_apply( transf, tmp_co ); co = tmp_co; - VECCOPY( tmp_no, dir ); + copy_v3_v3( tmp_no, dir ); space_transform_apply_normal( transf, tmp_no ); no = tmp_no; @@ -350,17 +348,17 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) /* this coordinated are deformed by vertexCos only for normal projection (to get correct normals) */ /* for other cases calc->varts contains undeformed coordinates and vertexCos should be used */ if(calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { - VECCOPY(tmp_co, calc->vert[i].co); + copy_v3_v3(tmp_co, calc->vert[i].co); normal_short_to_float_v3(tmp_no, calc->vert[i].no); } else { - VECCOPY(tmp_co, co); - VECCOPY(tmp_no, proj_axis); + copy_v3_v3(tmp_co, co); + copy_v3_v3(tmp_no, proj_axis); } } else { - VECCOPY(tmp_co, co); - VECCOPY(tmp_no, proj_axis); + copy_v3_v3(tmp_co, co); + copy_v3_v3(tmp_no, proj_axis); } @@ -443,11 +441,11 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) //Convert the vertex to tree coordinates if(calc->vert) { - VECCOPY(tmp_co, calc->vert[i].co); + copy_v3_v3(tmp_co, calc->vert[i].co); } else { - VECCOPY(tmp_co, co); + copy_v3_v3(tmp_co, co); } space_transform_apply(&calc->local2target, tmp_co); @@ -478,7 +476,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc) if(dist > FLT_EPSILON) interp_v3_v3v3(tmp_co, tmp_co, nearest.co, (dist - calc->keepDist)/dist); //linear interpolation else - VECCOPY( tmp_co, nearest.co ); + copy_v3_v3( tmp_co, nearest.co ); } //Convert the coordinates back to mesh coordinates diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index e259071a27a..2b9d6d2d6d6 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -54,11 +54,18 @@ MINLINE void swap_v2_v2(float a[2], float b[2]); MINLINE void swap_v3_v3(float a[3], float b[3]); MINLINE void swap_v4_v4(float a[4], float b[4]); +/* char */ +MINLINE void copy_v2_v2_char(char r[2], const char a[2]); +MINLINE void copy_v3_v3_char(char r[3], const char a[3]); +MINLINE void copy_v4_v4_char(char r[4], const char a[4]); /* short */ MINLINE void copy_v2_v2_short(short r[2], const short a[2]); MINLINE void copy_v3_v3_short(short r[3], const short a[3]); MINLINE void copy_v4_v4_short(short r[4], const short a[4]); - +/* int */ +MINLINE void copy_v2_v2_int(int r[2], const int a[2]); +MINLINE void copy_v3_v3_int(int r[3], const int a[3]); +MINLINE void copy_v4_v4_int(int r[4], const int a[4]); /********************************* Arithmetic ********************************/ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index c460b69679b..1c7d131c750 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -77,6 +77,28 @@ MINLINE void copy_v4_v4(float r[4], const float a[4]) r[3]= a[3]; } +/* short */ +MINLINE void copy_v2_v2_char(char r[2], const char a[2]) +{ + r[0]= a[0]; + r[1]= a[1]; +} + +MINLINE void copy_v3_v3_char(char r[3], const char a[3]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; +} + +MINLINE void copy_v4_v4_char(char r[4], const char a[4]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; + r[3]= a[3]; +} + /* short */ MINLINE void copy_v2_v2_short(short r[2], const short a[2]) { @@ -99,6 +121,28 @@ MINLINE void copy_v4_v4_short(short r[4], const short a[4]) r[3]= a[3]; } +/* int */ +MINLINE void copy_v2_v2_int(int r[2], const int a[2]) +{ + r[0]= a[0]; + r[1]= a[1]; +} + +MINLINE void copy_v3_v3_int(int r[3], const int a[3]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; +} + +MINLINE void copy_v4_v4_int(int r[4], const int a[4]) +{ + r[0]= a[0]; + r[1]= a[1]; + r[2]= a[2]; + r[3]= a[3]; +} + MINLINE void swap_v2_v2(float a[2], float b[2]) { SWAP(float, a[0], b[0]); diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index e8af5a8f290..f0f3b8f4123 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -176,13 +176,13 @@ static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, floa unsigned char cp[3]; if (indent == 2) { - VECCOPY(cp, grp->cs.solid); + copy_v3_v3_char((char *)cp, grp->cs.solid); } else if (indent == 1) { - VECCOPY(cp, grp->cs.select); + copy_v3_v3_char((char *)cp, grp->cs.select); } else { - VECCOPY(cp, grp->cs.active); + copy_v3_v3_char((char *)cp, grp->cs.active); } /* copy the colors over, transforming from bytes to floats */ diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 6f1da5757c6..b1651886620 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -157,14 +157,14 @@ static void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3]) sub_v3_v3v3(nor, bone->tail, bone->head); vec_roll_to_mat3(nor, roll, mat); - VECCOPY(up_axis, mat[2]); + copy_v3_v3(up_axis, mat[2]); } static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3]) { float nor[3], new_up_axis[3], x_axis[3], z_axis[3]; - VECCOPY(new_up_axis, old_up_axis); + copy_v3_v3(new_up_axis, old_up_axis); mul_qt_v3(qrot, new_up_axis); sub_v3_v3v3(nor, bone->tail, bone->head); @@ -236,7 +236,7 @@ static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4] mul_qt_v3(qroll, normal); - VECCOPY(new_up_axis, edge->up_axis); + copy_v3_v3(new_up_axis, edge->up_axis); mul_qt_v3(qrot, new_up_axis); normalize_v3(new_up_axis); @@ -252,7 +252,7 @@ float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]) { float new_up_axis[3]; - VECCOPY(new_up_axis, old_up_axis); + copy_v3_v3(new_up_axis, old_up_axis); mul_qt_v3(qrot, new_up_axis); return ED_rollBoneToVector(bone, new_up_axis, FALSE); @@ -367,7 +367,7 @@ static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3]) node = MEM_callocN(sizeof(RigNode), "rig node"); BLI_addtail(&rg->nodes, node); - VECCOPY(node->p, p); + copy_v3_v3(node->p, p); node->degree = 1; node->arcs = NULL; @@ -389,7 +389,7 @@ static RigNode *newRigNode(RigGraph *rg, float p[3]) node = MEM_callocN(sizeof(RigNode), "rig node"); BLI_addtail(&rg->nodes, node); - VECCOPY(node->p, p); + copy_v3_v3(node->p, p); node->degree = 0; node->arcs = NULL; @@ -412,12 +412,12 @@ static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge) if (edge->prev == NULL) { - VECCOPY(edge->head, arc->head->p); + copy_v3_v3(edge->head, arc->head->p); } else { RigEdge *last_edge = edge->prev; - VECCOPY(edge->head, last_edge->tail); + copy_v3_v3(edge->head, last_edge->tail); RIG_calculateEdgeAngles(last_edge, edge); } @@ -434,7 +434,7 @@ static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone) edge = MEM_callocN(sizeof(RigEdge), "rig edge"); - VECCOPY(edge->tail, tail); + copy_v3_v3(edge->tail, tail); edge->bone = bone; if (bone) @@ -489,10 +489,10 @@ static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ ctrl = newRigControl(rg); - VECCOPY(ctrl->head, src_ctrl->head); - VECCOPY(ctrl->tail, src_ctrl->tail); - VECCOPY(ctrl->up_axis, src_ctrl->up_axis); - VECCOPY(ctrl->offset, src_ctrl->offset); + copy_v3_v3(ctrl->head, src_ctrl->head); + copy_v3_v3(ctrl->tail, src_ctrl->tail); + copy_v3_v3(ctrl->up_axis, src_ctrl->up_axis); + copy_v3_v3(ctrl->offset, src_ctrl->offset); ctrl->tail_mode = src_ctrl->tail_mode; ctrl->flag = src_ctrl->flag; @@ -531,9 +531,9 @@ static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash * edge = MEM_callocN(sizeof(RigEdge), "rig edge"); - VECCOPY(edge->head, src_edge->head); - VECCOPY(edge->tail, src_edge->tail); - VECCOPY(edge->up_axis, src_edge->up_axis); + copy_v3_v3(edge->head, src_edge->head); + copy_v3_v3(edge->tail, src_edge->tail); + copy_v3_v3(edge->up_axis, src_edge->up_axis); edge->length = src_edge->length; edge->angle = src_edge->angle; @@ -690,8 +690,8 @@ static void RIG_addControlBone(RigGraph *rg, EditBone *bone) { RigControl *ctrl = newRigControl(rg); ctrl->bone = bone; - VECCOPY(ctrl->head, bone->head); - VECCOPY(ctrl->tail, bone->tail); + copy_v3_v3(ctrl->head, bone->head); + copy_v3_v3(ctrl->tail, bone->tail); getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis); ctrl->tail_mode = TL_NONE; @@ -765,7 +765,7 @@ static int RIG_parentControl(RigControl *ctrl, EditBone *link) ctrl->link = link; ctrl->flag = flag; - VECCOPY(ctrl->offset, offset); + copy_v3_v3(ctrl->offset, offset); return 1; } @@ -1146,7 +1146,7 @@ static void RIG_removeUneededOffsets(RigGraph *rg) BLI_remlink(&arc->edges, first_edge); MEM_freeN(first_edge); - VECCOPY(arc->head->p, next_edge->head); + copy_v3_v3(arc->head->p, next_edge->head); } } } @@ -1222,7 +1222,7 @@ static void RIG_removeUneededOffsets(RigGraph *rg) BLI_remlink(&arc->edges, first_edge); MEM_freeN(first_edge); - VECCOPY(arc->head->p, next_edge->head); + copy_v3_v3(arc->head->p, next_edge->head); /* remove null edge in other arcs too */ for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) @@ -1284,7 +1284,7 @@ static void RIG_removeUneededOffsets(RigGraph *rg) BLI_remlink(&arc->edges, last_edge); MEM_freeN(last_edge); - VECCOPY(arc->tail->p, previous_edge->tail); + copy_v3_v3(arc->tail->p, previous_edge->tail); previous_edge->angle = 0; } } @@ -1755,7 +1755,7 @@ static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize) sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head); sub_v3_v3v3(v2, tail_vec, ctrl->bone->head); - VECCOPY(ctrl->bone->tail, tail_vec); + copy_v3_v3(ctrl->bone->tail, tail_vec); rotation_between_vecs_to_quat(qtail, v1, v2); mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot); @@ -1791,7 +1791,7 @@ static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], f { float parent_offset[3], tail_offset[3]; - VECCOPY(parent_offset, ctrl->offset); + copy_v3_v3(parent_offset, ctrl->offset); mul_v3_fl(parent_offset, resize); mul_qt_v3(qrot, parent_offset); @@ -1799,7 +1799,7 @@ static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], f ctrl->flag |= RIG_CTRL_HEAD_DONE; - QUATCOPY(ctrl->qrot, qrot); + copy_qt_qt(ctrl->qrot, qrot); if (ctrl->tail_mode == TL_NONE) { @@ -1836,8 +1836,8 @@ static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec rotation_between_vecs_to_quat(qrot, v1, v2); - VECCOPY(bone->head, vec0); - VECCOPY(bone->tail, vec1); + copy_v3_v3(bone->head, vec0); + copy_v3_v3(bone->tail, vec1); if (!is_zero_v3(up_axis)) { diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index d228d4d3772..b97e843529a 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -624,7 +624,7 @@ static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *ite gluQuadricNormals(quad, GLU_SMOOTH); iter->head(iter); - VECCOPY(head, iter->p); + copy_v3_v3(head, iter->p); index = next_subdividion(toolsettings, iter, bone_start, end, head, tail); while (index != -1) @@ -640,7 +640,7 @@ static void drawSubdividedStrokeBy(ToolSettings *toolsettings, BArcIterator *ite glPopMatrix(); - VECCOPY(head, tail); + copy_v3_v3(head, tail); bone_start = index; // start next bone from current index index = next_subdividion(toolsettings, iter, bone_start, end, head, tail); @@ -748,7 +748,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, if ((bone->flag & BONE_CONNECTED) == 0) { - VECCOPY(vec, bone->head); + copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); project_short_noclip(ar, vec, pval); @@ -758,13 +758,13 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { *dist = pdist; pt = &boneSnap; - VECCOPY(pt->p, vec); + copy_v3_v3(pt->p, vec); pt->type = PT_EXACT; } } - VECCOPY(vec, bone->tail); + copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); project_short_noclip(ar, vec, pval); @@ -774,7 +774,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { *dist = pdist; pt = &boneSnap; - VECCOPY(pt->p, vec); + copy_v3_v3(pt->p, vec); pt->type = PT_EXACT; } } @@ -1024,7 +1024,7 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr if (last != NULL) { - VECCOPY(fp, last->p); + copy_v3_v3(fp, last->p); } initgrabz(ar->regiondata, fp[0], fp[1], fp[2]); @@ -1134,12 +1134,12 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S } else { - VECCOPY(vec, p1->p); + copy_v3_v3(vec, p1->p); } if (last_p == NULL) { - VECCOPY(p, vec); + copy_v3_v3(p, vec); size = new_size; dist = 0; break; @@ -1149,7 +1149,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S if (new_dist < dist) { - VECCOPY(p, vec); + copy_v3_v3(p, vec); dist = new_dist; size = new_size; } @@ -1161,7 +1161,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S pt->type = dd->type; pt->mode = PT_SNAP; pt->size = size / 2; - VECCOPY(pt->p, p); + copy_v3_v3(pt->p, p); point_added = 1; } @@ -1193,7 +1193,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S if (spt != NULL) { - VECCOPY(pt->p, spt->p); + copy_v3_v3(pt->p, spt->p); point_added = 1; } } @@ -1207,7 +1207,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S { pt->type = dd->type; pt->mode = PT_SNAP; - VECCOPY(pt->p, vec); + copy_v3_v3(pt->p, vec); point_added = 1; } @@ -1234,7 +1234,7 @@ static int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, int total; int i; - VECCOPY(final_p, pt.p); + copy_v3_v3(final_p, pt.p); sk_projectDrawPoint(C, pt.p, stk, dd); sk_appendStrokePoint(stk, &pt); @@ -1259,7 +1259,7 @@ static int sk_addStrokeSnapPoint(bContext *C, SK_Sketch *sketch, SK_Stroke *stk, sk_interpolateDepth(C, stk, i + 1, stk->nb_points - 2, length, distance); } - VECCOPY(stk->points[stk->nb_points - 1].p, final_p); + copy_v3_v3(stk->points[stk->nb_points - 1].p, final_p); point_added = 1; } @@ -1296,7 +1296,7 @@ static void sk_getStrokePoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, SK_S { point_added = sk_getStrokeSnapPoint(C, pt, sketch, stk, dd); LAST_SNAP_POINT_VALID = 1; - VECCOPY(LAST_SNAP_POINT, pt->p); + copy_v3_v3(LAST_SNAP_POINT, pt->p); } else { @@ -1536,8 +1536,8 @@ static void sk_convertStroke(bContext *C, SK_Stroke *stk) { bone = ED_armature_edit_bone_add(arm, "Bone"); - VECCOPY(bone->head, head->p); - VECCOPY(bone->tail, pt->p); + copy_v3_v3(bone->head, head->p); + copy_v3_v3(bone->tail, pt->p); mul_m4_v3(invmat, bone->head); mul_m4_v3(invmat, bone->tail); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index ff3b69c2bf6..12f03f7341c 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -658,7 +658,7 @@ static void gp_stroke_newfrombuffer (tGPsdata *p) found_depth= TRUE; } - VECCOPY2D(mval_prev, mval); + copy_v2_v2_int(mval_prev, mval); } if (found_depth == FALSE) { diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index dd75f506be8..e5092c82304 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1224,7 +1224,7 @@ void ui_get_but_vectorf(uiBut *but, float vec[3]) int a, tot; if(but->editvec) { - VECCOPY(vec, but->editvec); + copy_v3_v3(vec, but->editvec); } if(but->rnaprop) { @@ -1248,7 +1248,7 @@ void ui_get_but_vectorf(uiBut *but, float vec[3]) } else if(but->pointype == FLO) { float *fp= (float *)but->poin; - VECCOPY(vec, fp); + copy_v3_v3(vec, fp); } else { if (but->editvec==NULL) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index ed018830a0a..878d1bc36a4 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1510,7 +1510,7 @@ static void widget_state(uiWidgetType *wt, int state) wt->wcol= *(wt->wcol_theme); if(state & UI_SELECT) { - QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel) + copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); if(state & UI_BUT_ANIMATED_KEY) widget_state_blend(wt->wcol.inner, wcol_state->inner_key_sel, wcol_state->blend); @@ -1519,7 +1519,7 @@ static void widget_state(uiWidgetType *wt, int state) else if(state & UI_BUT_DRIVEN) widget_state_blend(wt->wcol.inner, wcol_state->inner_driven_sel, wcol_state->blend); - VECCOPY(wt->wcol.text, wt->wcol.text_sel); + copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel); if(state & UI_SELECT) SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); @@ -1604,7 +1604,7 @@ static void widget_state_option_menu(uiWidgetType *wt, int state) else { bTheme *btheme= U.themes.first; /* XXX */ - VECCOPY(wt->wcol.text, btheme->tui.wcol_menu_back.text); + copy_v3_v3_char(wt->wcol.text, btheme->tui.wcol_menu_back.text); } } @@ -1619,11 +1619,11 @@ static void widget_state_pulldown(uiWidgetType *wt, int state) { wt->wcol= *(wt->wcol_theme); - QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel); - VECCOPY(wt->wcol.outline, wt->wcol.inner); + copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); + copy_v3_v3_char(wt->wcol.outline, wt->wcol.inner); if(state & UI_ACTIVE) - VECCOPY(wt->wcol.text, wt->wcol.text_sel); + copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel); } /* special case, menu items */ @@ -1637,8 +1637,8 @@ static void widget_state_menu_item(uiWidgetType *wt, int state) wt->wcol.text[2]= 0.5f*(wt->wcol.text[2]+wt->wcol.text_sel[2]); } else if(state & UI_ACTIVE) { - QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel); - VECCOPY(wt->wcol.text, wt->wcol.text_sel); + copy_v4_v4_char(wt->wcol.inner, wt->wcol.inner_sel); + copy_v3_v3_char(wt->wcol.text, wt->wcol.text_sel); } } @@ -2197,7 +2197,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat SWAP(short, wcol->shadetop, wcol->shadedown); - QUATCOPY(wcol->inner, wcol->item); + copy_v4_v4_char(wcol->inner, wcol->item); if(wcol->shadetop>wcol->shadedown) wcol->shadetop+= 20; /* XXX violates themes... */ @@ -2369,9 +2369,9 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s if(!(state & UI_TEXTINPUT)) { /* slider part */ - VECCOPY(outline, wcol->outline); - VECCOPY(wcol->outline, wcol->item); - VECCOPY(wcol->inner, wcol->item); + copy_v3_v3_char(outline, wcol->outline); + copy_v3_v3_char(wcol->outline, wcol->item); + copy_v3_v3_char(wcol->inner, wcol->item); if(!(state & UI_SELECT)) SWAP(short, wcol->shadetop, wcol->shadedown); @@ -2397,7 +2397,7 @@ static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int s round_box_edges(&wtb1, roundboxalign & ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT), &rect1, offs); widgetbase_draw(&wtb1, wcol); - VECCOPY(wcol->outline, outline); + copy_v3_v3_char(wcol->outline, outline); if(!(state & UI_SELECT)) SWAP(short, wcol->shadetop, wcol->shadedown); @@ -2624,7 +2624,7 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( widget_init(&wtb); - VECCOPY(old_col, wcol->inner); + copy_v3_v3_char(old_col, wcol->inner); /* abuse but->hsv - if it's non-zero, use this color as the box's background */ if (but->col[3]) { @@ -2643,7 +2643,7 @@ static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED( /* XXX, this doesnt work right since the color applies to buttons outside the box too. */ glClearColor(wcol->inner[0]/255.0, wcol->inner[1]/255.0, wcol->inner[2]/255.0, 1.0); - VECCOPY(wcol->inner, old_col); + copy_v3_v3_char(wcol->inner, old_col); } static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 25c1e32f4ae..cac167ad84f 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -35,6 +35,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_curve_types.h" @@ -132,7 +133,7 @@ void load_editLatt(Object *obedit) bp= editlt->def; while(tot--) { - VECCOPY(fp, bp->vec); + copy_v3_v3(fp, bp->vec); fp+= 3; bp++; } diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 129d9df86a5..ad2280baba2 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -357,7 +357,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * key= cache[a]; kmax= key->steps; for(k=0; k<=kmax; k++,key++,cvert++,mvert++) { - VECCOPY(mvert->co,key->co); + copy_v3_v3(mvert->co,key->co); if(k) { medge->v1= cvert-1; medge->v2= cvert; @@ -376,7 +376,7 @@ int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene * key=cache[a]; kmax=key->steps; for(k=0; k<=kmax; k++,key++,cvert++,mvert++) { - VECCOPY(mvert->co,key->co); + copy_v3_v3(mvert->co,key->co); if(k) { medge->v1=cvert-1; medge->v2=cvert; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 3c9edb2fcfe..ce603ce80b6 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -105,12 +105,30 @@ #define IMAPAINT_CHAR_TO_FLOAT(c) ((c)/255.0f) -#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { (c)[0]=FTOCHAR((f)[0]); (c)[1]=FTOCHAR((f)[1]); (c)[2]=FTOCHAR((f)[2]); } -#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { (c)[0]=FTOCHAR((f)[0]); (c)[1]=FTOCHAR((f)[1]); (c)[2]=FTOCHAR((f)[2]); (c)[3]=FTOCHAR((f)[3]); } +#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \ + (c)[0]= FTOCHAR((f)[0]); \ + (c)[1]= FTOCHAR((f)[1]); \ + (c)[2]= FTOCHAR((f)[2]); \ +} +#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \ + (c)[0]= FTOCHAR((f)[0]); \ + (c)[1]= FTOCHAR((f)[1]); \ + (c)[2]= FTOCHAR((f)[2]); \ + (c)[3]= FTOCHAR((f)[3]); \ +} +#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \ + (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \ + (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \ + (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \ +} +#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \ + (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \ + (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \ + (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \ + (f)[3]= IMAPAINT_CHAR_TO_FLOAT((c)[3]); \ +} -#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { (f)[0]=IMAPAINT_CHAR_TO_FLOAT((c)[0]); (f)[1]=IMAPAINT_CHAR_TO_FLOAT((c)[1]); (f)[2]=IMAPAINT_CHAR_TO_FLOAT((c)[2]); } -#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { (f)[0]=IMAPAINT_CHAR_TO_FLOAT((c)[0]); (f)[1]=IMAPAINT_CHAR_TO_FLOAT((c)[1]); (f)[2]=IMAPAINT_CHAR_TO_FLOAT((c)[2]); (f)[3]=IMAPAINT_CHAR_TO_FLOAT((c)[3]); } -#define IMAPAINT_FLOAT_RGB_COPY(a, b) VECCOPY(a, b) +#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b) #define IMAPAINT_TILE_BITS 6 #define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS) diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 70c4ebd445a..177b72567e5 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -33,6 +33,7 @@ #include "BLF_api.h" +#include "BLI_math.h" #include "BLI_utildefines.h" @@ -131,7 +132,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str const char *line_stride= str + initial_offset; /* advance to the last line and draw it first */ int sel_orig[2]; - VECCOPY2D(sel_orig, cdc->sel); + copy_v2_v2_int(sel_orig, cdc->sel); /* invert and swap for wrapping */ cdc->sel[0] = str_len - sel_orig[1]; @@ -178,7 +179,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str return 0; } - VECCOPY2D(cdc->sel, sel_orig); + copy_v2_v2_int(cdc->sel, sel_orig); STEP_SEL(-(str_len + 1)); } else { /* simple, no wrap */ diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index a7bb1fb3ee6..c0046b089af 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -153,17 +153,17 @@ static short set_pchan_glColor (short colCode, int boneflag, short constflag) unsigned char cp[3]; if (boneflag & BONE_DRAW_ACTIVE) { - VECCOPY(cp, bcolor->active); + copy_v3_v3_char((char *)cp, bcolor->active); if(!(boneflag & BONE_SELECTED)) { cp_shade_color3ub(cp, -80); } } else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); + copy_v3_v3_char((char *)cp, bcolor->select); } else { /* a bit darker than solid */ - VECCOPY(cp, bcolor->solid); + copy_v3_v3_char((char *)cp, bcolor->solid); cp_shade_color3ub(cp, -50); } @@ -213,13 +213,13 @@ static short set_pchan_glColor (short colCode, int boneflag, short constflag) unsigned char cp[3]; if (boneflag & BONE_DRAW_ACTIVE) { - VECCOPY(cp, bcolor->active); + copy_v3_v3_char((char *)cp, bcolor->active); } else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); + copy_v3_v3_char((char *)cp, bcolor->select); } else { - VECCOPY(cp, bcolor->solid); + copy_v3_v3_char((char *)cp, bcolor->solid); } glColor3ubv(cp); @@ -239,15 +239,15 @@ static short set_pchan_glColor (short colCode, int boneflag, short constflag) unsigned char cp[3]; if (boneflag & BONE_DRAW_ACTIVE) { - VECCOPY(cp, bcolor->active); + copy_v3_v3_char((char *)cp, bcolor->active); cp_shade_color3ub(cp, 10); } else if (boneflag & BONE_SELECTED) { - VECCOPY(cp, bcolor->select); + copy_v3_v3_char((char *)cp, bcolor->select); cp_shade_color3ub(cp, -30); } else { - VECCOPY(cp, bcolor->solid); + copy_v3_v3_char((char *)cp, bcolor->solid); cp_shade_color3ub(cp, -30); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 9f98a6c6b48..6ebb7cf4a48 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4922,7 +4922,7 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int skip= nu->resolu/16; while (nr-->0) { /* accounts for empty bevel lists */ - float fac= bevp->radius * ts->normalsize; + const float fac= bevp->radius * ts->normalsize; float vec_a[3]; // Offset perpendicular to the curve float vec_b[3]; // Delta along the curve @@ -4938,9 +4938,9 @@ static void drawnurb(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, mul_qt_v3(bevp->quat, vec_b); add_v3_v3(vec_a, bevp->vec); add_v3_v3(vec_b, bevp->vec); - - VECSUBFAC(vec_a, vec_a, bevp->dir, fac); - VECSUBFAC(vec_b, vec_b, bevp->dir, fac); + + madd_v3_v3fl(vec_a, bevp->dir, -fac); + madd_v3_v3fl(vec_b, bevp->dir, -fac); glBegin(GL_LINE_STRIP); glVertex3fv(vec_a); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e7fbdaf1deb..b677a8fd7cf 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -3462,8 +3462,8 @@ int ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], cons data.margin= margin; data.depth= FLT_MAX; - VECCOPY2D(p1, mval_sta); - VECCOPY2D(p2, mval_end); + copy_v2_v2_int(p1, mval_sta); + copy_v2_v2_int(p2, mval_end); plot_line_v2v2i(p1, p2, depth_segment_cb, &data); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index e9db9fe1d7e..0cdb7a19995 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -314,7 +314,7 @@ static int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *even fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); - VECCOPY2D(fly->mval, event->mval) + copy_v2_v2_int(fly->mval, event->mval); fly->ndof = NULL; fly->time_lastdraw= fly->time_lastwheel= PIL_check_seconds_timer(); @@ -475,7 +475,7 @@ static void flyEvent(FlyInfo *fly, wmEvent *event) fly->redraw = 1; } else if (event->type == MOUSEMOVE) { - VECCOPY2D(fly->mval, event->mval); + copy_v2_v2_int(fly->mval, event->mval); } else if (event->type == NDOF_MOTION) { // do these automagically get delivered? yes. diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b5f0a4a071e..591bb99ae22 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -548,7 +548,7 @@ int transformEvent(TransInfo *t, wmEvent *event) if (t->modifiers & MOD_CONSTRAINT_SELECT) t->con.mode |= CON_SELECT; - VECCOPY2D(t->mval, event->mval); + copy_v2_v2_int(t->mval, event->mval); // t->redraw |= TREDRAW_SOFT; /* Use this for soft redraw. Might cause flicker in object mode */ t->redraw |= TREDRAW_HARD; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 2c69cc85214..0c3e045d5ce 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -941,7 +941,7 @@ int initTransInfo (bContext *C, TransInfo *t, wmOperator *op, wmEvent *event) if (event) { - VECCOPY2D(t->imval, event->mval); + copy_v2_v2_int(t->imval, event->mval); t->event_type = event->type; } else diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index cc3ffe086f1..3de68a6e312 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -409,7 +409,7 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) t->modifiers |= MOD_PRECISION; /* shift is modifier for higher precision transform * store the mouse position where the normal movement ended */ - VECCOPY2D(mi->precision_mval, event->mval); + copy_v2_v2_int(mi->precision_mval, event->mval); mi->precision = 1; } else diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index 9ca990c4193..9ee4a875e24 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -80,7 +80,7 @@ static void make_vertexcos__mapFunc(void *userData, int index, float *co, float if(!mappedData->flags[index]) { /* we need coord from prototype vertex, not it clones or images, suppose they stored in the beginning of vertex array stored in DM */ - VECCOPY(vec, co); + copy_v3_v3(vec, co); mappedData->flags[index]= 1; } } diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index a438d5c86e9..9344b4e680a 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -260,7 +260,7 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim if(!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay))) { lamp->dynenergy = lamp->energy; - VECCOPY(lamp->dyncol, lamp->col); + copy_v3_v3(lamp->dyncol, lamp->col); } else { lamp->dynenergy = 0.0f; @@ -306,14 +306,14 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[][4], float v lamp= nlink->data; if(material->dynproperty & DYN_LAMP_VEC) { - VECCOPY(lamp->dynvec, lamp->vec); + copy_v3_v3(lamp->dynvec, lamp->vec); normalize_v3(lamp->dynvec); negate_v3(lamp->dynvec); mul_mat3_m4_v3(viewmat, lamp->dynvec); } if(material->dynproperty & DYN_LAMP_CO) { - VECCOPY(lamp->dynco, lamp->co); + copy_v3_v3(lamp->dynco, lamp->co); mul_m4_v3(viewmat, lamp->dynco); } @@ -1472,8 +1472,8 @@ void GPU_lamp_update(GPULamp *lamp, int lay, int hide, float obmat[][4]) copy_m4_m4(mat, obmat); normalize_m4(mat); - VECCOPY(lamp->vec, mat[2]); - VECCOPY(lamp->co, mat[3]); + copy_v3_v3(lamp->vec, mat[2]); + copy_v3_v3(lamp->co, mat[3]); copy_m4_m4(lamp->obmat, mat); invert_m4_m4(lamp->imat, mat); } diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index cfaafe9bf5c..787766f0fa6 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -205,9 +205,9 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[][3]) // nr = t mul_m4_m4m4(pchan->pose_mat, ikmat, pchan->chan_mat); /* calculate head */ - VECCOPY(pchan->pose_head, pchan->pose_mat[3]); + copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]); /* calculate tail */ - VECCOPY(vec, pchan->pose_mat[1]); + copy_v3_v3(vec, pchan->pose_mat[1]); mul_v3_fl(vec, pchan->bone->length); add_v3_v3v3(pchan->pose_tail, pchan->pose_head, vec); @@ -340,7 +340,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) copy_m4_m4(rootmat, pchan->parent->pose_mat); else unit_m4(rootmat); - VECCOPY(rootmat[3], pchan->pose_head); + copy_v3_v3(rootmat[3], pchan->pose_head); mul_m4_m4m4(imat, rootmat, ob->obmat); invert_m4_m4(goalinv, imat); @@ -359,7 +359,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* and set and transform goal */ mul_m4_m4m4(goal, rootmat, goalinv); - VECCOPY(goalpos, goal[3]); + copy_v3_v3(goalpos, goal[3]); copy_m3_m4(goalrot, goal); /* same for pole vector target */ @@ -372,7 +372,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) } else { mul_m4_m4m4(goal, rootmat, goalinv); - VECCOPY(polepos, goal[3]); + copy_v3_v3(polepos, goal[3]); poleconstrain= 1; /* for pole targets, we blend the result of the ik solver @@ -398,7 +398,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree) /* end effector in world space */ copy_m4_m4(end_pose, pchan->pose_mat); - VECCOPY(end_pose[3], pchan->pose_tail); + copy_v3_v3(end_pose[3], pchan->pose_tail); mul_serie_m4(world_pose, goalinv, ob->obmat, end_pose, NULL, NULL, NULL, NULL, NULL); /* blend position */ diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index 400e720f138..2cb3a32ae3e 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -558,7 +558,7 @@ static bool target_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Fram pchan = pchan->parent; float chanmat[4][4]; copy_m4_m4(chanmat, pchan->pose_mat); - VECCOPY(chanmat[3], pchan->pose_tail); + copy_v3_v3(chanmat[3], pchan->pose_tail); mul_serie_m4(restmat, target->owner->obmat, chanmat, target->eeRest, NULL, NULL, NULL, NULL, NULL); } else { @@ -585,7 +585,7 @@ static bool base_callback(const iTaSC::Timestamp& timestamp, const iTaSC::Frame& pchan = pchan->parent; float chanmat[4][4]; copy_m4_m4(chanmat, pchan->pose_mat); - VECCOPY(chanmat[3], pchan->pose_tail); + copy_v3_v3(chanmat[3], pchan->pose_tail); // save the base as a frame too so that we can compute deformation // after simulation ikscene->baseFrame.setValue(&chanmat[0][0]); @@ -1662,12 +1662,12 @@ static void execute_scene(Scene* blscene, IK_Scene* ikscene, bItasc* ikparam, fl pchan = ikchan->pchan; // tail mat ikchan->frame.getValue(&pchan->pose_mat[0][0]); - VECCOPY(pchan->pose_tail, pchan->pose_mat[3]); + copy_v3_v3(pchan->pose_tail, pchan->pose_mat[3]); // shift to head - VECCOPY(yaxis, pchan->pose_mat[1]); + copy_v3_v3(yaxis, pchan->pose_mat[1]); mul_v3_fl(yaxis, length); sub_v3_v3v3(pchan->pose_mat[3], pchan->pose_mat[3], yaxis); - VECCOPY(pchan->pose_head, pchan->pose_mat[3]); + copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]); // add scale mul_v3_fl(pchan->pose_mat[0], scale); mul_v3_fl(pchan->pose_mat[1], scale); diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index e67ab012dc9..1ea1a4e3e7b 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -283,7 +283,7 @@ static void rna_EditBone_connected_check(EditBone *ebone) if(ebone->parent) { if(ebone->flag & BONE_CONNECTED) { /* Attach this bone to its parent */ - VECCOPY(ebone->head, ebone->parent->tail); + copy_v3_v3(ebone->head, ebone->parent->tail); if(ebone->flag & BONE_ROOTSEL) ebone->parent->flag |= BONE_TIPSEL; @@ -350,7 +350,7 @@ static void rna_EditBone_matrix_get(PointerRNA *ptr, float *values) sub_v3_v3v3(delta, ebone->tail, ebone->head); vec_roll_to_mat3(delta, ebone->roll, tmat); copy_m4_m3(mat, tmat); - VECCOPY(mat[3], ebone->head); + copy_v3_v3(mat[3], ebone->head); memcpy(values, mat, 16 * sizeof(float)); } @@ -363,12 +363,12 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po /* update our parent */ if(ebone->parent && ebone->flag & BONE_CONNECTED) - VECCOPY(ebone->parent->tail, ebone->head) + copy_v3_v3(ebone->parent->tail, ebone->head); /* update our children if necessary */ for(child = arm->edbo->first; child; child=child->next) if(child->parent == ebone && (child->flag & BONE_CONNECTED)) - VECCOPY(child->head, ebone->tail); + copy_v3_v3(child->head, ebone->tail); if(arm->flag & ARM_MIRROR_EDIT) { eboflip= ED_armature_bone_get_mirrored(arm->edbo, ebone); @@ -381,12 +381,12 @@ static void rna_Armature_editbone_transform_update(Main *bmain, Scene *scene, Po /* update our parent */ if(eboflip->parent && eboflip->flag & BONE_CONNECTED) - VECCOPY(eboflip->parent->tail, eboflip->head); + copy_v3_v3(eboflip->parent->tail, eboflip->head); /* update our children if necessary */ for(child = arm->edbo->first; child; child=child->next) if(child->parent == eboflip && (child->flag & BONE_CONNECTED)) - VECCOPY (child->head, eboflip->tail); + copy_v3_v3 (child->head, eboflip->tail); } } diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 5a544c46255..08f73ccbe0d 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -42,7 +42,6 @@ /* vector defines */ #define CROSS(dest, a, b) { dest[0]= a[1] * b[2] - a[2] * b[1]; dest[1]= a[2] * b[0] - a[0] * b[2]; dest[2]= a[0] * b[1] - a[1] * b[0]; } -#define VECMUL(dest, f) { dest[0]*= f; dest[1]*= f; dest[2]*= f; } struct HaloRen; struct ShadeInput; diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 2f20c328405..6ea62828601 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -704,7 +704,7 @@ int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexRe } /* rotate to envmap space, if object is set */ - VECCOPY(vec, texvec); + copy_v3_v3(vec, texvec); if(env->object) mul_m3_v3(env->obimat, vec); else mul_mat3_m4_v3(R.viewinv, vec); diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 1887f22198d..d1f7059416d 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -92,7 +92,7 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y) } else if(ibuf->channels==3) { float *fp= ibuf->rect_float + 3*ofs; - VECCOPY(col, fp); + copy_v3_v3(col, fp); col[3]= 1.0f; } else { diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index dfd10687a33..36709408496 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -84,7 +84,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3]) ir= ig= ib= 0.0; - VECCOPY(rco, har->co); + copy_v3_v3(rco, har->co); dco[0]=dco[1]=dco[2]= 1.0f/har->rad; vn= har->no; @@ -97,7 +97,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3]) /* lampdist cacluation */ if(lar->type==LA_SUN || lar->type==LA_HEMI) { - VECCOPY(lv, lar->vec); + copy_v3_v3(lv, lar->vec); lampdist= 1.0; } else { @@ -146,7 +146,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3]) memset(&shi, 0, sizeof(ShadeInput)); /* end warning! - Campbell */ - VECCOPY(shi.co, rco); + copy_v3_v3(shi.co, rco); shi.osatex= 0; do_lamp_tex(lar, lv, &shi, lacol, LA_TEXTURE); } @@ -158,7 +158,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3]) float x, lvrot[3]; /* rotate view to lampspace */ - VECCOPY(lvrot, lv); + copy_v3_v3(lvrot, lv); mul_m3_v3(lar->imat, lvrot); x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2])); @@ -610,7 +610,7 @@ void shadeSkyPixel(float collector[4], float fx, float fy, short thread) if((R.wrld.skytype & (WO_SKYBLEND+WO_SKYTEX))==0) { /* 1. solid color */ - VECCOPY(collector, &R.wrld.horr); + copy_v3_v3(collector, &R.wrld.horr); collector[3] = 0.0f; } diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 36ded5c10d2..c3a4ca9bf7d 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -153,7 +153,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa state.time = cfra; if(psys_get_particle_state(&sim, i, &state, 0)) { - VECCOPY(partco, state.co); + copy_v3_v3(partco, state.co); if (pd->psys_cache_space == TEX_PD_OBJECTSPACE) mul_m4_v3(ob->imat, partco); @@ -217,7 +217,7 @@ static void pointdensity_cache_object(Render *re, PointDensity *pd, Object *ob) for(i=0; i < pd->totpoints; i++, mvert++) { float co[3]; - VECCOPY(co, mvert->co); + copy_v3_v3(co, mvert->co); switch(pd->ob_cache_space) { case TEX_PD_OBJECTSPACE: @@ -423,7 +423,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) (pd->flag&TEX_PD_FALLOFF_CURVE ? pd->falloff_curve : NULL), pd->falloff_speed_scale*0.001f); noise_fac = pd->noise_fac * 0.5f; /* better default */ - VECCOPY(co, texvec); + copy_v3_v3(co, texvec); if (point_data_used(pd)) { /* does a BVH lookup to find accumulated density and additional point data * @@ -480,7 +480,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) if (pd->coba) { if (do_colorband(pd->coba, age, col)) { texres->talpha= 1; - VECCOPY(&texres->tr, col); + copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; } @@ -493,7 +493,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) if (pd->coba) { if (do_colorband(pd->coba, speed, col)) { texres->talpha= 1; - VECCOPY(&texres->tr, col); + copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; } @@ -503,7 +503,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) case TEX_PD_COLOR_PARTVEL: texres->talpha= 1; mul_v3_fl(vec, pd->speed_scale); - VECCOPY(&texres->tr, vec); + copy_v3_v3(&texres->tr, vec); texres->ta = texres->tin; break; case TEX_PD_COLOR_CONSTANT: diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 48134c46c61..456702e0827 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -768,18 +768,17 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl) continue; } - VECCOPY(tmp_rgb, rgbrect); + copy_v3_v3(tmp_rgb, rgbrect); if(rgbrect[3]!=1.0f) { /* de-premul */ - float div= 1.0f/rgbrect[3]; - VECMUL(tmp_rgb, div); + mul_v3_fl(tmp_rgb, 1.0f/rgbrect[3]); } shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect); if(rgbrect[3]!=1.0f) { /* premul */ - VECMUL(tmp_rgb, rgbrect[3]); + mul_v3_fl(tmp_rgb, rgbrect[3]); } if(done==0) { - VECCOPY(rgb, tmp_rgb); + copy_v3_v3(rgb, tmp_rgb); done = 1; } else{ @@ -793,7 +792,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl) /* if at least for one sun lamp aerial perspective was applied*/ if(done) { - VECCOPY(rgbrect, rgb); + copy_v3_v3(rgbrect, rgb); } } } @@ -1533,13 +1532,13 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe then clamp to avoid a too large contribution from a single pixel */ shi->osatex= 1; - VECCOPY(nor, shi->facenor); + copy_v3_v3(nor, shi->facenor); calc_view_vector(shi->facenor, sx, sy); normalize_v3(shi->facenor); shade_input_set_viewco(shi, x, y, sx, sy, z); orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco); - VECCOPY(shi->facenor, nor); + copy_v3_v3(shi->facenor, nor); shade_input_set_viewco(shi, x, y, sx, sy, z); *area= len_v3(shi->dxco)*len_v3(shi->dyco); *area= MIN2(*area, 2.0f*orthoarea); @@ -1572,8 +1571,8 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe shade_samples_do_AO(ssamp); shade_material_loop(shi, &shr); - VECCOPY(co, shi->co); - VECCOPY(color, shr.combined); + copy_v3_v3(co, shi->co); + copy_v3_v3(color, shr.combined); /* texture blending */ /* texfac= shi->mat->sss_texfac; */ /* UNUSED */ @@ -1711,7 +1710,7 @@ void zbufshade_sss_tile(RenderPart *pa) totpoint++; - VECADD(fcol, fcol, color); + add_v3_v3(fcol, color); fcol[3]= 1.0f; } @@ -1730,7 +1729,7 @@ void zbufshade_sss_tile(RenderPart *pa) shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz, co[totpoint], color[totpoint], &area[totpoint]); - VECADD(fcol, fcol, color[totpoint]); + add_v3_v3(fcol, color[totpoint]); fcol[3]= 1.0f; totpoint++; } @@ -1753,7 +1752,7 @@ void zbufshade_sss_tile(RenderPart *pa) /* to indicate this is a back sample */ area[totpoint]= -area[totpoint]; - VECADD(fcol, fcol, color[totpoint]); + add_v3_v3(fcol, color[totpoint]); fcol[3]= 1.0f; totpoint++; } @@ -2068,7 +2067,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua if(bs->type==RE_BAKE_NORMALS) { float nor[3]; - VECCOPY(nor, shi->vn); + copy_v3_v3(nor, shi->vn); if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA); else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { @@ -2076,16 +2075,16 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua /* bitangent */ if(tvn && ttang) { - VECCOPY(mat[0], ttang); + copy_v3_v3(mat[0], ttang); cross_v3_v3v3(mat[1], tvn, ttang); mul_v3_fl(mat[1], ttang[3]); - VECCOPY(mat[2], tvn); + copy_v3_v3(mat[2], tvn); } else { - VECCOPY(mat[0], shi->nmaptang); + copy_v3_v3(mat[0], shi->nmaptang); cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang); mul_v3_fl(mat[1], shi->nmaptang[3]); - VECCOPY(mat[2], shi->nmapnorm); + copy_v3_v3(mat[2], shi->nmapnorm); } invert_m3_m3(imat, mat); @@ -2115,7 +2114,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua shr.alpha = shi->alpha; } else if(bs->type==RE_BAKE_SHADOW) { - VECCOPY(shr.combined, shr.shad); + copy_v3_v3(shr.combined, shr.shad); shr.alpha = shi->alpha; } else if(bs->type==RE_BAKE_SPEC_COLOR) { @@ -2158,7 +2157,7 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua if(bs->rect_float) { float *col= bs->rect_float + 4*(bs->rectx*y + x); - VECCOPY(col, shr.combined); + copy_v3_v3(col, shr.combined); if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) { col[3]= shr.alpha; } else { @@ -2336,15 +2335,15 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(obi->flag & R_TRANSFORMED) mul_m4_v3(obi->mat, shi->co); - VECCOPY(shi->dxco, bs->dxco); - VECCOPY(shi->dyco, bs->dyco); + copy_v3_v3(shi->dxco, bs->dxco); + copy_v3_v3(shi->dyco, bs->dyco); quad= bs->quad; bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v); if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) { shade_input_set_shade_texco(shi); - VECCOPY(tvn, shi->nmapnorm); + copy_v3_v3(tvn, shi->nmapnorm); copy_v4_v4(ttang, shi->nmaptang); } @@ -2359,7 +2358,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) memset(&minisec, 0, sizeof(minisec)); minco[0]= minco[1]= minco[2]= 0.0f; - VECCOPY(bs->dir, shi->vn); + copy_v3_v3(bs->dir, shi->vn); for(sign=-1; sign<=1; sign+=2) { memset(&isec, 0, sizeof(isec)); @@ -2375,7 +2374,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) if(!hit || len_v3v3(shi->co, co) < len_v3v3(shi->co, minco)) { minisec= isec; mindist= dist; - VECCOPY(minco, co); + copy_v3_v3(minco, co); hit= 1; dir = sign; } @@ -2395,7 +2394,7 @@ static void do_bake_shade(void *handle, int x, int y, float u, float v) obi= (ObjectInstanceRen*)minisec.hit.ob; vlr= (VlakRen*)minisec.hit.face; quad= (minisec.isect == 2); - VECCOPY(shi->co, minco); + copy_v3_v3(shi->co, minco); u= -minisec.u; v= -minisec.v; diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 274fa4469e0..f3eb2234778 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -672,7 +672,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar) else ver++; if(clipflag[a]) { - VECCOPY(vec, ver->co); + copy_v3_v3(vec, ver->co); mul_m4_v3(obviewmat, vec); /* Z on visible side of lamp space */ if(vec[2] < 0.0f) { @@ -2063,7 +2063,7 @@ static int viewpixel_to_lampbuf(ShadBuf *shb, ObjectInstanceRen *obi, VlakRen *v float dface, fac, siz; RE_vlakren_get_normal(&R, obi, vlr, nor); - VECCOPY(v1, vlr->v1->co); + copy_v3_v3(v1, vlr->v1->co); if(obi->flag & R_TRANSFORMED) mul_m4_v3(obi->mat, v1); @@ -2463,7 +2463,7 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la samp->facenr= apn->p[a] & ~RE_QUAD_OFFS; samp->shadfac= &apn->shadfac[a]; - VECCOPY(samp->zco, zco); + copy_v3_v3(samp->zco, zco); bound_rectf((rctf *)&root.box, samp->zco); } } @@ -2479,7 +2479,7 @@ static void isb_make_buffer_transp(RenderPart *pa, APixstr *apixbuf, LampRen *la samp->facenr= apn->p[a] & ~RE_QUAD_OFFS; samp->shadfac= &apn->shadfac[a]; - VECCOPY(samp->zco, zco); + copy_v3_v3(samp->zco, zco); bound_rectf((rctf *)&root.box, samp->zco); } } diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index 55d3703d351..1852dfaebab 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -127,8 +127,8 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) if(shi->passflag & SCE_PASS_SHADOW) VECADDISFAC(shr->shad, shr_t.shad, fac); - VECMUL(shi->vn, -1.0f); - VECMUL(shi->facenor, -1.0f); + negate_v3(shi->vn); + negate_v3(shi->facenor); } /* depth >= 1 when ray-shading */ diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index ddcffcc303b..633c7ca1847 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -139,12 +139,9 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint) spoint->dtco[1]= data[0]*p[0][1] + data[1]*p[1][1] + data[2]*p[2][1] + data[3]*p[3][1]; spoint->dtco[2]= data[0]*p[0][2] + data[1]*p[1][2] + data[2]*p[2][2] + data[3]*p[3][2]; - copy_v3_v3(spoint->tan, spoint->dtco); - normalize_v3(spoint->tan); - - copy_v3_v3(spoint->nor, spoint->co); - VECMUL(spoint->nor, -1.0f); - normalize_v3(spoint->nor); + normalize_v3_v3(spoint->tan, spoint->dtco); + normalize_v3_v3(spoint->nor, spoint->co); + negate_v3(spoint->nor); spoint->width= strand_eval_width(ma, spoint->strandco); diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 11d7d9342f7..29eea081672 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -623,7 +623,7 @@ static void precache_init_parts(Render *re, RayObject *tree, ShadeInput *shi, Ob copy_v3_v3(pa->bbmin, bbmin); copy_v3_v3(pa->voxel, voxel); - VECCOPY(pa->res, res); /* int's */ + copy_v3_v3_int(pa->res, res); pa->minx = minx; pa->maxx = maxx; pa->miny = miny; pa->maxy = maxy; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index d624751f613..57ff5f4237a 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -241,7 +241,7 @@ static void init_frame_smoke(VoxelData *vd, float cfra) size_t i; float *heat; - VECCOPY(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, smd->domain->res); totRes= vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 @@ -262,7 +262,7 @@ static void init_frame_smoke(VoxelData *vd, float cfra) size_t i; float *xvel, *yvel, *zvel; - VECCOPY(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, smd->domain->res); totRes= vd_resol_size(vd); // scaling heat values from -2.0-2.0 to 0.0-1.0 @@ -286,7 +286,7 @@ static void init_frame_smoke(VoxelData *vd, float cfra) smoke_turbulence_get_res(smd->domain->wt, vd->resol); density = smoke_turbulence_get_density(smd->domain->wt); } else { - VECCOPY(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, smd->domain->res); density = smoke_get_density(smd->domain->fluid); } From bb8fe0bf4afeaa5ae91329b8d8147b94cc54034a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 04:36:37 +0000 Subject: [PATCH 121/147] minor edits - remove unneeded type check from convert grease pencil operator. - correct some error prints & use __func__. - make copy_libblock take an ID* argument rather than void*. --- source/blender/blenkernel/BKE_library.h | 2 +- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/armature.c | 2 +- source/blender/blenkernel/intern/brush.c | 2 +- source/blender/blenkernel/intern/camera.c | 2 +- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/key.c | 2 +- source/blender/blenkernel/intern/lamp.c | 4 ++-- source/blender/blenkernel/intern/lattice.c | 2 +- source/blender/blenkernel/intern/library.c | 12 +++++------- source/blender/blenkernel/intern/material.c | 4 ++-- source/blender/blenkernel/intern/mball.c | 2 +- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/blenkernel/intern/node.c | 2 +- source/blender/blenkernel/intern/object.c | 2 +- source/blender/blenkernel/intern/particle.c | 2 +- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/blenkernel/intern/speaker.c | 2 +- source/blender/blenkernel/intern/text.c | 2 +- source/blender/blenkernel/intern/texture.c | 4 ++-- source/blender/blenkernel/intern/world.c | 4 ++-- source/blender/editors/gpencil/gpencil_edit.c | 19 ++++++------------- .../windowmanager/intern/wm_operators.c | 19 +++++++++++-------- 23 files changed, 46 insertions(+), 52 deletions(-) diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 9130cac6cd6..308d7ff22c2 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -46,7 +46,7 @@ struct PointerRNA; struct PropertyRNA; void *alloc_libblock(struct ListBase *lb, short type, const char *name); -void *copy_libblock(void *rt); +void *copy_libblock(struct ID *id); void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action); void BKE_id_lib_local_paths(struct Main *bmain, struct ID *id); diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 944f7c6a0b6..5fb03b7bbd0 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -185,7 +185,7 @@ bAction *copy_action (bAction *src) if (src == NULL) return NULL; - dst= copy_libblock(src); + dst= copy_libblock(&src->id); /* duplicate the lists of groups and markers */ BLI_duplicatelist(&dst->groups, &src->groups); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index f19ed859064..50f305e4400 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -204,7 +204,7 @@ bArmature *copy_armature(bArmature *arm) Bone *oldBone, *newBone; Bone *newActBone= NULL; - newArm= copy_libblock (arm); + newArm= copy_libblock(&arm->id); BLI_duplicatelist(&newArm->bonebase, &arm->bonebase); /* Duplicate the childrens' lists*/ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index e78b89441c9..09021e71025 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -144,7 +144,7 @@ Brush *copy_brush(Brush *brush) { Brush *brushn; - brushn= copy_libblock(brush); + brushn= copy_libblock(&brush->id); if (brush->mtex.tex) id_us_plus((ID*)brush->mtex.tex); diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index eeec82c3beb..145eb9363e9 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -68,7 +68,7 @@ Camera *copy_camera(Camera *cam) { Camera *camn; - camn= copy_libblock(cam); + camn= copy_libblock(&cam->id); return camn; } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index adc08f5cd9f..160f5703a01 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -192,7 +192,7 @@ Curve *copy_curve(Curve *cu) Curve *cun; int a; - cun= copy_libblock(cu); + cun= copy_libblock(&cu->id); cun->nurb.first= cun->nurb.last= NULL; duplicateNurblist( &(cun->nurb), &(cu->nurb)); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index c389800b0d1..eb7d07a6f7d 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -154,7 +154,7 @@ Key *copy_key(Key *key) if(key==NULL) return NULL; - keyn= copy_libblock(key); + keyn= copy_libblock(&key->id); BLI_duplicatelist(&keyn->block, &key->block); diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c index 974aa660e9f..4edd032dc04 100644 --- a/source/blender/blenkernel/intern/lamp.c +++ b/source/blender/blenkernel/intern/lamp.c @@ -106,7 +106,7 @@ Lamp *copy_lamp(Lamp *la) Lamp *lan; int a; - lan= copy_libblock(la); + lan= copy_libblock(&la->id); for(a=0; amtex[a]) { @@ -132,7 +132,7 @@ Lamp *localize_lamp(Lamp *la) Lamp *lan; int a; - lan= copy_libblock(la); + lan= copy_libblock(&la->id); BLI_remlink(&G.main->lamp, lan); for(a=0; aid); ltn->def= MEM_dupallocN(lt->def); ltn->key= copy_key(ltn->key); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 0b01c3d6dd1..878b87759b7 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -717,14 +717,11 @@ void copy_libblock_data(ID *id, const ID *id_from, const short do_action) } /* used everywhere in blenkernel */ -void *copy_libblock(void *rt) +void *copy_libblock(ID *id) { - ID *idn, *id; + ID *idn; ListBase *lb; - char *cp, *cpn; size_t idn_len; - - id= rt; lb= which_libbase(G.main, GS(id->name)); idn= alloc_libblock(lb, GS(id->name), id->name+2); @@ -733,8 +730,9 @@ void *copy_libblock(void *rt) idn_len= MEM_allocN_len(idn); if((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */ - cp= (char *)id; - cpn= (char *)idn; + const char *cp= (const char *)id; + char *cpn= (char *)idn; + memcpy(cpn+sizeof(ID), cp+sizeof(ID), idn_len - sizeof(ID)); } diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 7be3514e0f2..48c6d6b2a19 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -215,7 +215,7 @@ Material *copy_material(Material *ma) Material *man; int a; - man= copy_libblock(ma); + man= copy_libblock(&ma->id); id_lib_extern((ID *)man->group); @@ -247,7 +247,7 @@ Material *localize_material(Material *ma) Material *man; int a; - man= copy_libblock(ma); + man= copy_libblock(&ma->id); BLI_remlink(&G.main->mat, man); /* no increment for texture ID users, in previewrender.c it prevents decrement */ diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index 327306b32ee..5c82acde99b 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -120,7 +120,7 @@ MetaBall *copy_mball(MetaBall *mb) MetaBall *mbn; int a; - mbn= copy_libblock(mb); + mbn= copy_libblock(&mb->id); BLI_duplicatelist(&mbn->elems, &mb->elems); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 4a8bc34cdf7..ec9d4873057 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -206,7 +206,7 @@ Mesh *copy_mesh(Mesh *me) MTFace *tface; int a, i; - men= copy_libblock(me); + men= copy_libblock(&me->id); men->mat= MEM_dupallocN(me->mat); for(a=0; atotcol; a++) { diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8f609291351..a9b2ffe7529 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -629,7 +629,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) for(newtree=G.main->nodetree.first; newtree; newtree= newtree->id.next) if(newtree==ntree) break; if(newtree) { - newtree= copy_libblock(ntree); + newtree= copy_libblock(&ntree->id); } else { newtree= MEM_dupallocN(ntree); copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index ae4e6ea81b8..1d654839969 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1084,7 +1084,7 @@ Object *copy_object(Object *ob) ModifierData *md; int a; - obn= copy_libblock(ob); + obn= copy_libblock(&ob->id); if(ob->totcol) { obn->mat= MEM_dupallocN(ob->mat); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 56e4c91ba5e..1064a5af160 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3569,7 +3569,7 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part) ParticleSettings *partn; int a; - partn= copy_libblock(part); + partn= copy_libblock(&part->id); partn->pd= MEM_dupallocN(part->pd); partn->pd2= MEM_dupallocN(part->pd2); partn->effector_weights= MEM_dupallocN(part->effector_weights); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 66d29b02263..14dfe015894 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -126,7 +126,7 @@ Scene *copy_scene(Scene *sce, int type) scen->r.layers= lb; } else { - scen= copy_libblock(sce); + scen= copy_libblock(&sce->id); BLI_duplicatelist(&(scen->base), &(sce->base)); clear_id_newpoins(); diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index 018c7a197ff..a14233e9179 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -69,7 +69,7 @@ Speaker *copy_speaker(Speaker *spk) { Speaker *spkn; - spkn= copy_libblock(spk); + spkn= copy_libblock(&spk->id); if(spkn->sound) spkn->sound->id.us++; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 955127a8000..e8be0bb2608 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -431,7 +431,7 @@ Text *copy_text(Text *ta) Text *tan; TextLine *line, *tmp; - tan= copy_libblock(ta); + tan= copy_libblock(&ta->id); /* file name can be NULL */ if(ta->name) { diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 3aa289d0ef8..377eeef117e 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -751,7 +751,7 @@ Tex *copy_texture(Tex *tex) { Tex *texn; - texn= copy_libblock(tex); + texn= copy_libblock(&tex->id); if(texn->type==TEX_IMAGE) id_us_plus((ID *)texn->ima); else texn->ima= NULL; @@ -781,7 +781,7 @@ Tex *localize_texture(Tex *tex) { Tex *texn; - texn= copy_libblock(tex); + texn= copy_libblock(&tex->id); BLI_remlink(&G.main->tex, texn); /* image texture: free_texture also doesn't decrease */ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index c7d2763774d..1d6972b9d61 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -118,7 +118,7 @@ World *copy_world(World *wrld) World *wrldn; int a; - wrldn= copy_libblock(wrld); + wrldn= copy_libblock(&wrld->id); for(a=0; amtex[a]) { @@ -142,7 +142,7 @@ World *localize_world(World *wrld) World *wrldn; int a; - wrldn= copy_libblock(wrld); + wrldn= copy_libblock(&wrld->id); BLI_remlink(&G.main->world, wrldn); for(a=0; aloc[0]= ob->loc[1]= ob->loc[2]= 0; - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0; + zero_v3(ob->loc); + zero_v3(ob->rot); cu= ob->data; cu->flag |= CU_3D; @@ -573,6 +573,9 @@ static void gp_layer_to_curve (bContext *C, bGPdata *gpd, bGPDlayer *gpl, short case GP_STROKECONVERT_CURVE: gp_stroke_to_bezier(C, gpl, gps, cu, subrect_ptr); break; + default: + BLI_assert(!"invalid mode"); + break; } } } @@ -602,17 +605,7 @@ static int gp_convert_layer_exec (bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* handle conversion modes */ - switch (mode) { - case GP_STROKECONVERT_PATH: - case GP_STROKECONVERT_CURVE: - gp_layer_to_curve(C, gpd, gpl, mode); - break; - - default: /* unsupoorted */ - BKE_report(op->reports, RPT_ERROR, "Unknown conversion option"); - return OPERATOR_CANCELLED; - } + gp_layer_to_curve(C, gpd, gpl, mode); /* notifiers */ WM_event_add_notifier(C, NC_OBJECT|NA_ADDED, NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 933066513e2..19e9a6bd483 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -270,7 +270,7 @@ static int wm_macro_modal(bContext *C, wmOperator *op, wmEvent *event) int retval= OPERATOR_FINISHED; if(opm==NULL) - printf("macro error, calling NULL modal()\n"); + printf("%s: macro error, calling NULL modal()\n", __func__); else { retval = opm->type->modal(C, opm, event); OPERATOR_RETVAL_CHECK(retval); @@ -341,7 +341,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam wmOperatorType *ot; if(WM_operatortype_find(idname, TRUE)) { - printf("Macro error: operator %s exists\n", idname); + printf("%s: macro error: operator %s exists\n", __func__, idname); return NULL; } @@ -658,10 +658,11 @@ int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) uiLayout *layout; if(prop==NULL) { - printf("WM_menu_invoke: %s has no enum property set\n", op->type->idname); + printf("%s: %s has no enum property set\n", __func__, op->type->idname); } else if (RNA_property_type(prop) != PROP_ENUM) { - printf("WM_menu_invoke: %s \"%s\" is not an enum property\n", op->type->idname, RNA_property_identifier(prop)); + printf("%s: %s \"%s\" is not an enum property\n", + __func__, op->type->idname, RNA_property_identifier(prop)); } else if (RNA_property_is_set(op->ptr, RNA_property_identifier(prop))) { const int retval= op->type->exec(C, op); @@ -686,10 +687,12 @@ static void operator_enum_search_cb(const struct bContext *C, void *arg_ot, cons PropertyRNA *prop= ot->prop; if(prop==NULL) { - printf("WM_enum_search_invoke: %s has no enum property set\n", ot->idname); + printf("%s: %s has no enum property set\n", + __func__, ot->idname); } else if (RNA_property_type(prop) != PROP_ENUM) { - printf("WM_enum_search_invoke: %s \"%s\" is not an enum property\n", ot->idname, RNA_property_identifier(prop)); + printf("%s: %s \"%s\" is not an enum property\n", + __func__, ot->idname, RNA_property_identifier(prop)); } else { PointerRNA ptr; @@ -725,7 +728,7 @@ static void operator_enum_call_cb(struct bContext *C, void *arg1, void *arg2) WM_operator_properties_free(&props_ptr); } else { - printf("operator_enum_call_cb: op->prop for '%s' is NULL\n", ot->idname); + printf("%s: op->prop for '%s' is NULL\n", __func__, ot->idname); } } } @@ -2619,7 +2622,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event) memcpy(gesture->customdata, old_lasso, 2*sizeof(short)*gesture->size); gesture->size = gesture->size + WM_LASSO_MIN_POINTS; MEM_freeN(old_lasso); - printf("realloc\n"); + // printf("realloc\n"); } { From 4b3cc63f73cfe519689bdbd8482e655b72423038 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 05:28:26 +0000 Subject: [PATCH 122/147] fix [#29183] Make duplicates real: parent informations of the group is not copied infact this is a feature request but we had reports about it before and its useful to have. 2 new options for OBJECT_OT_duplicates_make_real - parent to original duplicator - keep internal hierarchy --- source/blender/editors/object/object_add.c | 87 +++++++++++++++++++--- 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index a929144ed2e..8d4d29dbe50 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -48,6 +48,7 @@ #include "DNA_vfont_types.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_listbase.h" #include "BLI_utildefines.h" @@ -1008,23 +1009,21 @@ static void copy_object_set_idnew(bContext *C, int dupflag) /********************* Make Duplicates Real ************************/ -static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base) +static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, + const short use_base_parent, + const short use_hierarchy) { - Base *basen; - Object *ob; ListBase *lb; DupliObject *dob; - - if(!base && !(base = BASACT)) - return; - + if(!(base->object->transflag & OB_DUPLI)) return; lb= object_duplilist(scene, base->object); for(dob= lb->first; dob; dob= dob->next) { - ob= copy_object(dob->ob); + Base *basen; + Object *ob= copy_object(dob->ob); /* font duplis can have a totcol without material, we get them from parent * should be implemented better... */ @@ -1051,22 +1050,85 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base) object_apply_mat4(ob, ob->obmat, FALSE, FALSE); } + if (use_hierarchy) { + for(dob= lb->first; dob; dob= dob->next) { + /* original parents */ + Object *ob_src= dob->ob; + Object *ob_src_par= ob_src->parent; + + Object *ob_dst= (Object *)ob_src->id.newid; + + if (ob_src_par && ob_src_par->id.newid) { + /* the parent was also made real, parent newly real duplis */ + Object *ob_dst_par= (Object *)ob_src_par->id.newid; + + /* allow for all possible parent types */ + ob_dst->partype= ob_src->partype; + BLI_strncpy(ob_dst->parsubstr, ob_src->parsubstr, sizeof(ob_dst->parsubstr)); + ob_dst->par1= ob_src->par1; + ob_dst->par2= ob_src->par2; + ob_dst->par3= ob_src->par3; + + copy_m4_m4(ob_dst->parentinv, ob_src->parentinv); + + ob_dst->parent= ob_dst_par; + } + else if (use_base_parent) { + ob_dst->parent= base->object; + ob_dst->partype= PAROBJECT; + } + + if (ob_dst->parent) { + invert_m4_m4(ob_dst->parentinv, dob->mat); + + /* note, this may be the parent of other objects, but it should + * still work out ok */ + object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE); + + /* to set ob_dst->orig and incase theres any other discrepicies */ + DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); + } + } + } + else if (use_base_parent) { + /* since we are ignoring the internal hierarchy - parent all to the + * base object */ + for(dob= lb->first; dob; dob= dob->next) { + /* original parents */ + Object *ob_src= dob->ob; + Object *ob_dst= (Object *)ob_src->id.newid; + + ob_dst->parent= base->object; + ob_dst->partype= PAROBJECT; + + /* similer to the code above, see comments */ + invert_m4_m4(ob_dst->parentinv, dob->mat); + object_apply_mat4(ob_dst, dob->mat, FALSE, TRUE); + DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB); + + + } + } + copy_object_set_idnew(C, 0); free_object_duplilist(lb); - base->object->transflag &= ~OB_DUPLI; + base->object->transflag &= ~OB_DUPLI; } -static int object_duplicates_make_real_exec(bContext *C, wmOperator *UNUSED(op)) +static int object_duplicates_make_real_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); + + const short use_base_parent= RNA_boolean_get(op->ptr, "use_base_parent"); + const short use_hierarchy= RNA_boolean_get(op->ptr, "use_hierarchy"); clear_id_newpoins(); CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { - make_object_duplilist_real(C, scene, base); + make_object_duplilist_real(C, scene, base, use_base_parent, use_hierarchy); /* dependencies were changed */ WM_event_add_notifier(C, NC_OBJECT|ND_PARENT, base->object); @@ -1096,6 +1158,9 @@ void OBJECT_OT_duplicates_make_real(wmOperatorType *ot) /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "use_base_parent", 0, "Parent", "Parent newly created objects to the original duplicator"); + RNA_def_boolean(ot->srna, "use_hierarchy", 0, "Keep Hierarchy", "Maintain parent child relationships"); } /**************************** Convert **************************/ From 22723a313ec7d07d34b5a777cc42bf3b4c4bff95 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Nov 2011 07:16:30 +0000 Subject: [PATCH 123/147] Fix #29174: Vertex normals temporarily incorrect after deleting a face Looks like it was just missed recalc_editnoormals call in Delete Mesh operator. --- source/blender/editors/mesh/editmesh_tools.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 99af17c161e..1852d90eed0 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1387,6 +1387,8 @@ static void delete_mesh(EditMesh *em, wmOperator *op, int event) } } + recalc_editnormals(em); + EM_fgon_flags(em); // redo flags and indices for fgons } From e122dc0748f6a4d77b236e26beba93e2a9a36bf0 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 7 Nov 2011 09:33:49 +0000 Subject: [PATCH 124/147] Removing a wrong node_type_storage (checked and confirmed by lukas_t). --- source/blender/nodes/composite/nodes/node_composite_normalize.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/nodes/composite/nodes/node_composite_normalize.c b/source/blender/nodes/composite/nodes/node_composite_normalize.c index a6220fbd20d..d14f589f3f2 100644 --- a/source/blender/nodes/composite/nodes/node_composite_normalize.c +++ b/source/blender/nodes/composite/nodes/node_composite_normalize.c @@ -109,7 +109,6 @@ void register_node_type_cmp_normalize(ListBase *lb) node_type_socket_templates(&ntype, cmp_node_normalize_in, cmp_node_normalize_out); node_type_size(&ntype, 100, 60, 150); node_type_exec(&ntype, node_composit_exec_normalize); - node_type_storage(&ntype, "TexMapping", NULL, NULL); nodeRegisterType(lb, &ntype); } From 27d42c63d9b507b1771ed5a7923c389c719b877b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Nov 2011 12:55:18 +0000 Subject: [PATCH 125/147] Camera tracking integration =========================== Commiting camera tracking integration gsoc project into trunk. This commit includes: - Bundled version of libmv library (with some changes against official repo, re-sync with libmv repo a bit later) - New datatype ID called MovieClip which is optimized to work with movie clips (both of movie files and image sequences) and doing camera/motion tracking operations. - New editor called Clip Editor which is currently used for motion/tracking stuff only, but which can be easily extended to work with masks too. This editor supports: * Loading movie files/image sequences * Build proxies with different size for loaded movie clip, also supports building undistorted proxies to increase speed of playback in undistorted mode. * Manual lens distortion mode calibration using grid and grease pencil * Supervised 2D tracking using two different algorithms KLT and SAD. * Basic algorithm for feature detection * Camera motion solving. scene orientation - New constraints to "link" scene objects with solved motions from clip: * Follow Track (make object follow 2D motion of track with given name or parent object to reconstructed 3D position of track) * Camera Solver to make camera moving in the same way as reconstructed camera This commit NOT includes changes from tomato branch: - New nodes (they'll be commited as separated patch) - Automatic image offset guessing for image input node and image editor (need to do more tests and gather more feedback) - Code cleanup in libmv-capi. It's not so critical cleanup, just increasing readability and understanadability of code. Better to make this chaneg when Keir will finish his current patch. More details about this project can be found on this page: http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2011 Further development of small features would be done in trunk, bigger/experimental features would first be implemented in tomato branch. --- CMakeLists.txt | 3 + build_files/scons/tools/Blender.py | 4 + build_files/scons/tools/btools.py | 2 + extern/CMakeLists.txt | 4 + extern/SConscript | 3 + extern/libmv/CMakeLists.txt | 210 + extern/libmv/ChangeLog | 312 + extern/libmv/SConscript | 60 + extern/libmv/bundle.sh | 250 + extern/libmv/files.txt | 141 + extern/libmv/libmv-capi.cpp | 770 + extern/libmv/libmv-capi.h | 128 + extern/libmv/libmv/base/id_generator.h | 37 + extern/libmv/libmv/base/scoped_ptr.h | 60 + extern/libmv/libmv/base/vector.h | 172 + extern/libmv/libmv/base/vector_utils.h | 34 + extern/libmv/libmv/image/array_nd.cc | 108 + extern/libmv/libmv/image/array_nd.h | 473 + extern/libmv/libmv/image/convolve.cc | 305 + extern/libmv/libmv/image/convolve.h | 93 + extern/libmv/libmv/image/image.h | 158 + extern/libmv/libmv/image/sample.h | 103 + extern/libmv/libmv/image/tuple.h | 90 + extern/libmv/libmv/logging/logging.h | 31 + extern/libmv/libmv/multiview/conditioning.cc | 99 + extern/libmv/libmv/multiview/conditioning.h | 60 + .../libmv/multiview/euclidean_resection.cc | 661 + .../libmv/multiview/euclidean_resection.h | 124 + extern/libmv/libmv/multiview/fundamental.cc | 391 + extern/libmv/libmv/multiview/fundamental.h | 144 + .../libmv/multiview/nviewtriangulation.h | 80 + extern/libmv/libmv/multiview/projection.cc | 221 + extern/libmv/libmv/multiview/projection.h | 231 + extern/libmv/libmv/multiview/resection.h | 62 + extern/libmv/libmv/multiview/triangulation.cc | 49 + extern/libmv/libmv/multiview/triangulation.h | 38 + extern/libmv/libmv/numeric/dogleg.h | 261 + .../libmv/libmv/numeric/function_derivative.h | 107 + .../libmv/libmv/numeric/levenberg_marquardt.h | 183 + extern/libmv/libmv/numeric/numeric.cc | 136 + extern/libmv/libmv/numeric/numeric.h | 479 + extern/libmv/libmv/numeric/poly.cc | 23 + extern/libmv/libmv/numeric/poly.h | 123 + extern/libmv/libmv/simple_pipeline/bundle.cc | 184 + extern/libmv/libmv/simple_pipeline/bundle.h | 72 + .../simple_pipeline/camera_intrinsics.cc | 351 + .../libmv/simple_pipeline/camera_intrinsics.h | 152 + extern/libmv/libmv/simple_pipeline/detect.cc | 184 + extern/libmv/libmv/simple_pipeline/detect.h | 95 + .../initialize_reconstruction.cc | 218 + .../initialize_reconstruction.h | 74 + .../libmv/libmv/simple_pipeline/intersect.cc | 205 + .../libmv/libmv/simple_pipeline/intersect.h | 77 + .../libmv/libmv/simple_pipeline/pipeline.cc | 317 + extern/libmv/libmv/simple_pipeline/pipeline.h | 95 + .../libmv/simple_pipeline/reconstruction.cc | 191 + .../libmv/simple_pipeline/reconstruction.h | 217 + extern/libmv/libmv/simple_pipeline/resect.cc | 271 + extern/libmv/libmv/simple_pipeline/resect.h | 86 + extern/libmv/libmv/simple_pipeline/tracks.cc | 159 + extern/libmv/libmv/simple_pipeline/tracks.h | 119 + .../libmv/tracking/klt_region_tracker.cc | 132 + .../libmv/libmv/tracking/klt_region_tracker.h | 55 + .../libmv/tracking/pyramid_region_tracker.cc | 80 + .../libmv/tracking/pyramid_region_tracker.h | 46 + extern/libmv/libmv/tracking/region_tracker.h | 48 + .../libmv/tracking/retrack_region_tracker.cc | 47 + .../libmv/tracking/retrack_region_tracker.h | 48 + extern/libmv/libmv/tracking/sad.cc | 174 + extern/libmv/libmv/tracking/sad.h | 109 + .../libmv/tracking/trklt_region_tracker.cc | 135 + .../libmv/tracking/trklt_region_tracker.h | 65 + extern/libmv/mkfiles.sh | 4 + extern/libmv/patches/bundle_tweaks.patch | 122 + extern/libmv/patches/config_mac.patch | 13 + extern/libmv/patches/detect.patch | 181 + extern/libmv/patches/fast.patch | 24 + .../libmv/patches/function_derivative.patch | 21 + .../patches/high_distortion_crash_fix.patch | 21 + .../libmv/patches/levenberg_marquardt.patch | 71 + extern/libmv/patches/mingw.patch | 13 + extern/libmv/patches/msvc2010.patch | 12 + extern/libmv/patches/overscan.patch | 182 + extern/libmv/patches/scaled_distortion.patch | 261 + extern/libmv/patches/series | 13 + extern/libmv/patches/snrptinf_fix.patch | 15 + extern/libmv/patches/v3d_verbosity.patch | 12 + extern/libmv/third_party/fast/LICENSE | 30 + extern/libmv/third_party/fast/README | 31 + extern/libmv/third_party/fast/README.libmv | 9 + extern/libmv/third_party/fast/fast.c | 71 + extern/libmv/third_party/fast/fast.h | 39 + extern/libmv/third_party/fast/fast_10.c | 4666 ++++++ extern/libmv/third_party/fast/fast_11.c | 3910 +++++ extern/libmv/third_party/fast/fast_12.c | 3134 ++++ extern/libmv/third_party/fast/fast_9.c | 5910 +++++++ extern/libmv/third_party/fast/nonmax.c | 117 + extern/libmv/third_party/gflags/README.libmv | 14 + extern/libmv/third_party/gflags/config.h | 110 + extern/libmv/third_party/gflags/gflags.cc | 1971 +++ extern/libmv/third_party/gflags/gflags.h | 589 + .../third_party/gflags/gflags_completions.cc | 765 + .../third_party/gflags/gflags_completions.h | 121 + .../third_party/gflags/gflags_reporting.cc | 446 + extern/libmv/third_party/gflags/mutex.h | 349 + extern/libmv/third_party/glog/AUTHORS | 2 + extern/libmv/third_party/glog/COPYING | 65 + extern/libmv/third_party/glog/ChangeLog | 59 + extern/libmv/third_party/glog/NEWS | 0 extern/libmv/third_party/glog/README | 5 + extern/libmv/third_party/glog/README.libmv | 38 + .../glog/src/base/commandlineflags.h | 132 + .../third_party/glog/src/base/googleinit.h | 51 + .../libmv/third_party/glog/src/base/mutex.h | 325 + extern/libmv/third_party/glog/src/config.h | 11 + .../libmv/third_party/glog/src/config_linux.h | 164 + .../libmv/third_party/glog/src/config_mac.h | 159 + extern/libmv/third_party/glog/src/demangle.cc | 1231 ++ extern/libmv/third_party/glog/src/demangle.h | 84 + .../third_party/glog/src/glog/log_severity.h | 84 + .../libmv/third_party/glog/src/glog/logging.h | 1507 ++ .../third_party/glog/src/glog/raw_logging.h | 185 + .../third_party/glog/src/glog/vlog_is_on.h | 129 + extern/libmv/third_party/glog/src/logging.cc | 1783 ++ .../libmv/third_party/glog/src/raw_logging.cc | 172 + .../third_party/glog/src/signalhandler.cc | 348 + .../libmv/third_party/glog/src/stacktrace.h | 60 + .../glog/src/stacktrace_generic-inl.h | 59 + .../glog/src/stacktrace_libunwind-inl.h | 87 + .../glog/src/stacktrace_powerpc-inl.h | 130 + .../third_party/glog/src/stacktrace_x86-inl.h | 139 + .../glog/src/stacktrace_x86_64-inl.h | 105 + .../libmv/third_party/glog/src/symbolize.cc | 681 + extern/libmv/third_party/glog/src/symbolize.h | 116 + .../libmv/third_party/glog/src/utilities.cc | 335 + extern/libmv/third_party/glog/src/utilities.h | 222 + .../libmv/third_party/glog/src/vlog_is_on.cc | 249 + .../third_party/glog/src/windows/config.h | 136 + .../glog/src/windows/glog/log_severity.h | 88 + .../glog/src/windows/glog/logging.h | 1510 ++ .../glog/src/windows/glog/raw_logging.h | 189 + .../glog/src/windows/glog/vlog_is_on.h | 133 + .../third_party/glog/src/windows/port.cc | 64 + .../libmv/third_party/glog/src/windows/port.h | 149 + .../glog/src/windows/preprocess.sh | 118 + extern/libmv/third_party/ldl/CMakeLists.txt | 5 + extern/libmv/third_party/ldl/Doc/ChangeLog | 39 + extern/libmv/third_party/ldl/Doc/lesser.txt | 504 + extern/libmv/third_party/ldl/Include/ldl.h | 104 + extern/libmv/third_party/ldl/README.libmv | 10 + extern/libmv/third_party/ldl/README.txt | 136 + extern/libmv/third_party/ldl/Source/ldl.c | 507 + .../libmv/third_party/msinttypes/README.libmv | 5 + .../libmv/third_party/msinttypes/inttypes.h | 305 + extern/libmv/third_party/msinttypes/stdint.h | 247 + extern/libmv/third_party/ssba/COPYING.TXT | 165 + .../ssba/Geometry/v3d_cameramatrix.h | 204 + .../ssba/Geometry/v3d_distortion.h | 97 + .../ssba/Geometry/v3d_metricbundle.cpp | 365 + .../ssba/Geometry/v3d_metricbundle.h | 346 + .../libmv/third_party/ssba/Math/v3d_linear.h | 923 ++ .../third_party/ssba/Math/v3d_linear_utils.h | 391 + .../third_party/ssba/Math/v3d_mathutilities.h | 59 + .../ssba/Math/v3d_optimization.cpp | 955 ++ .../third_party/ssba/Math/v3d_optimization.h | 273 + extern/libmv/third_party/ssba/README.TXT | 92 + extern/libmv/third_party/ssba/README.libmv | 23 + release/datafiles/blender_icons.png | Bin 214916 -> 216116 bytes .../modules/bpy_extras/keyconfig_utils.py | 4 + .../presets/tracking_camera/Blender.py | 10 + .../presets/tracking_camera/Canon_1100D.py | 10 + .../presets/tracking_camera/Canon_1D.py | 10 + .../presets/tracking_camera/Canon_1DS.py | 10 + .../presets/tracking_camera/Canon_500D.py | 10 + .../presets/tracking_camera/Canon_550D.py | 10 + .../presets/tracking_camera/Canon_5D.py | 10 + .../presets/tracking_camera/Canon_600D.py | 10 + .../presets/tracking_camera/Canon_60D.py | 10 + .../presets/tracking_camera/Canon_7D.py | 10 + .../presets/tracking_camera/Nikon_D300S.py | 10 + .../presets/tracking_camera/Nikon_D3100.py | 10 + .../presets/tracking_camera/Nikon_D35.py | 10 + .../presets/tracking_camera/Nikon_D5000.py | 10 + .../presets/tracking_camera/Nikon_D5100.py | 10 + .../presets/tracking_camera/Nikon_D7000.py | 10 + .../presets/tracking_camera/Nikon_D90.py | 10 + .../presets/tracking_camera/Red_Epic.py | 10 + .../presets/tracking_camera/Red_One_2K.py | 10 + .../presets/tracking_camera/Red_One_3K.py | 10 + .../presets/tracking_camera/Red_One_4K.py | 10 + .../presets/tracking_track_color/default.py | 5 + .../presets/tracking_track_color/far_plane.py | 5 + .../tracking_track_color/near_plane.py | 5 + .../scripts/startup/bl_operators/__init__.py | 1 + release/scripts/startup/bl_operators/clip.py | 318 + .../scripts/startup/bl_operators/presets.py | 41 + release/scripts/startup/bl_ui/__init__.py | 1 + .../bl_ui/properties_object_constraint.py | 21 + .../scripts/startup/bl_ui/properties_scene.py | 10 + release/scripts/startup/bl_ui/space_clip.py | 885 + release/scripts/startup/bl_ui/space_time.py | 1 + release/scripts/startup/bl_ui/space_view3d.py | 46 +- source/blender/CMakeLists.txt | 2 + source/blender/blenkernel/BKE_context.h | 3 + source/blender/blenkernel/BKE_library.h | 2 +- source/blender/blenkernel/BKE_main.h | 1 + source/blender/blenkernel/BKE_movieclip.h | 70 + source/blender/blenkernel/BKE_object.h | 4 + source/blender/blenkernel/BKE_tracking.h | 145 + source/blender/blenkernel/CMakeLists.txt | 9 + source/blender/blenkernel/SConscript | 4 + source/blender/blenkernel/intern/constraint.c | 206 + source/blender/blenkernel/intern/context.c | 12 + source/blender/blenkernel/intern/depsgraph.c | 77 +- source/blender/blenkernel/intern/idcode.c | 1 + source/blender/blenkernel/intern/library.c | 11 + source/blender/blenkernel/intern/movieclip.c | 1033 ++ source/blender/blenkernel/intern/object.c | 84 +- source/blender/blenkernel/intern/tracking.c | 2168 +++ source/blender/blenlib/BLI_threads.h | 1 + source/blender/blenlib/intern/threads.c | 5 + .../blender/blenloader/intern/readblenentry.c | 6 + source/blender/blenloader/intern/readfile.c | 181 +- source/blender/blenloader/intern/readfile.h | 3 + source/blender/blenloader/intern/writefile.c | 37 + source/blender/editors/CMakeLists.txt | 1 + source/blender/editors/SConscript | 1 + .../editors/datafiles/blender_icons.png.c | 13473 ++++++++-------- source/blender/editors/gpencil/drawgpencil.c | 3 +- .../editors/gpencil/editaction_gpencil.c | 1 + source/blender/editors/gpencil/gpencil_edit.c | 14 + .../blender/editors/gpencil/gpencil_paint.c | 54 +- source/blender/editors/include/ED_clip.h | 64 + source/blender/editors/include/ED_space_api.h | 1 + source/blender/editors/include/ED_transform.h | 1 + source/blender/editors/include/ED_view3d.h | 2 + source/blender/editors/include/UI_icons.h | 6 +- source/blender/editors/include/UI_interface.h | 27 +- source/blender/editors/include/UI_resources.h | 13 +- .../editors/interface/interface_draw.c | 109 + .../editors/interface/interface_handlers.c | 98 +- .../editors/interface/interface_intern.h | 1 + .../editors/interface/interface_templates.c | 8 + .../editors/interface/interface_widgets.c | 4 + source/blender/editors/interface/resources.c | 75 +- .../editors/object/object_constraint.c | 20 + source/blender/editors/screen/area.c | 1 + source/blender/editors/screen/screen_edit.c | 3 + source/blender/editors/screen/screen_ops.c | 15 + source/blender/editors/space_api/spacetypes.c | 3 + .../blender/editors/space_clip/CMakeLists.txt | 56 + source/blender/editors/space_clip/SConscript | 9 + .../blender/editors/space_clip/clip_buttons.c | 436 + source/blender/editors/space_clip/clip_draw.c | 1325 ++ .../blender/editors/space_clip/clip_editor.c | 302 + .../editors/space_clip/clip_graph_draw.c | 255 + .../editors/space_clip/clip_graph_ops.c | 356 + .../blender/editors/space_clip/clip_intern.h | 144 + source/blender/editors/space_clip/clip_ops.c | 1004 ++ .../blender/editors/space_clip/clip_toolbar.c | 244 + .../blender/editors/space_clip/clip_utils.c | 219 + .../blender/editors/space_clip/space_clip.c | 949 ++ .../blender/editors/space_clip/tracking_ops.c | 2940 ++++ .../blender/editors/space_view3d/drawobject.c | 234 +- .../editors/space_view3d/space_view3d.c | 8 + .../editors/space_view3d/view3d_draw.c | 62 +- .../editors/space_view3d/view3d_edit.c | 32 +- .../editors/space_view3d/view3d_intern.h | 1 + .../editors/space_view3d/view3d_select.c | 45 +- .../editors/space_view3d/view3d_snap.c | 41 + source/blender/editors/transform/transform.c | 46 +- source/blender/editors/transform/transform.h | 4 + .../editors/transform/transform_conversions.c | 246 + .../editors/transform/transform_generics.c | 45 + .../blender/editors/transform/transform_ops.c | 5 + source/blender/editors/util/CMakeLists.txt | 1 + source/blender/makesdna/DNA_ID.h | 1 + .../blender/makesdna/DNA_constraint_types.h | 29 + source/blender/makesdna/DNA_movieclip_types.h | 126 + source/blender/makesdna/DNA_scene_types.h | 5 +- source/blender/makesdna/DNA_space_types.h | 60 +- source/blender/makesdna/DNA_tracking_types.h | 217 + source/blender/makesdna/DNA_userdef_types.h | 6 + source/blender/makesdna/DNA_view3d_types.h | 23 +- source/blender/makesdna/intern/makesdna.c | 4 + source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/intern/CMakeLists.txt | 2 + source/blender/makesrna/intern/makesrna.c | 2 + source/blender/makesrna/intern/rna_ID.c | 2 + .../blender/makesrna/intern/rna_constraint.c | 72 + source/blender/makesrna/intern/rna_internal.h | 3 + source/blender/makesrna/intern/rna_main.c | 7 + source/blender/makesrna/intern/rna_main_api.c | 54 + .../blender/makesrna/intern/rna_movieclip.c | 278 + source/blender/makesrna/intern/rna_scene.c | 25 +- source/blender/makesrna/intern/rna_screen.c | 5 + source/blender/makesrna/intern/rna_space.c | 293 + source/blender/makesrna/intern/rna_tracking.c | 772 + source/blender/makesrna/intern/rna_ui_api.c | 19 + source/blender/makesrna/intern/rna_userdef.c | 109 + source/blender/windowmanager/WM_types.h | 2 + .../windowmanager/intern/wm_operators.c | 2 + source/blenderplayer/CMakeLists.txt | 6 + .../bad_level_call_stubs/stubs.c | 5 + source/creator/CMakeLists.txt | 11 + source/creator/creator.c | 12 + 306 files changed, 75102 insertions(+), 6811 deletions(-) create mode 100644 extern/libmv/CMakeLists.txt create mode 100644 extern/libmv/ChangeLog create mode 100644 extern/libmv/SConscript create mode 100755 extern/libmv/bundle.sh create mode 100644 extern/libmv/files.txt create mode 100644 extern/libmv/libmv-capi.cpp create mode 100644 extern/libmv/libmv-capi.h create mode 100644 extern/libmv/libmv/base/id_generator.h create mode 100644 extern/libmv/libmv/base/scoped_ptr.h create mode 100644 extern/libmv/libmv/base/vector.h create mode 100644 extern/libmv/libmv/base/vector_utils.h create mode 100644 extern/libmv/libmv/image/array_nd.cc create mode 100644 extern/libmv/libmv/image/array_nd.h create mode 100644 extern/libmv/libmv/image/convolve.cc create mode 100644 extern/libmv/libmv/image/convolve.h create mode 100644 extern/libmv/libmv/image/image.h create mode 100644 extern/libmv/libmv/image/sample.h create mode 100644 extern/libmv/libmv/image/tuple.h create mode 100644 extern/libmv/libmv/logging/logging.h create mode 100644 extern/libmv/libmv/multiview/conditioning.cc create mode 100644 extern/libmv/libmv/multiview/conditioning.h create mode 100644 extern/libmv/libmv/multiview/euclidean_resection.cc create mode 100644 extern/libmv/libmv/multiview/euclidean_resection.h create mode 100644 extern/libmv/libmv/multiview/fundamental.cc create mode 100644 extern/libmv/libmv/multiview/fundamental.h create mode 100644 extern/libmv/libmv/multiview/nviewtriangulation.h create mode 100644 extern/libmv/libmv/multiview/projection.cc create mode 100644 extern/libmv/libmv/multiview/projection.h create mode 100644 extern/libmv/libmv/multiview/resection.h create mode 100644 extern/libmv/libmv/multiview/triangulation.cc create mode 100644 extern/libmv/libmv/multiview/triangulation.h create mode 100644 extern/libmv/libmv/numeric/dogleg.h create mode 100644 extern/libmv/libmv/numeric/function_derivative.h create mode 100644 extern/libmv/libmv/numeric/levenberg_marquardt.h create mode 100644 extern/libmv/libmv/numeric/numeric.cc create mode 100644 extern/libmv/libmv/numeric/numeric.h create mode 100644 extern/libmv/libmv/numeric/poly.cc create mode 100644 extern/libmv/libmv/numeric/poly.h create mode 100644 extern/libmv/libmv/simple_pipeline/bundle.cc create mode 100644 extern/libmv/libmv/simple_pipeline/bundle.h create mode 100644 extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc create mode 100644 extern/libmv/libmv/simple_pipeline/camera_intrinsics.h create mode 100644 extern/libmv/libmv/simple_pipeline/detect.cc create mode 100644 extern/libmv/libmv/simple_pipeline/detect.h create mode 100644 extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc create mode 100644 extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h create mode 100644 extern/libmv/libmv/simple_pipeline/intersect.cc create mode 100644 extern/libmv/libmv/simple_pipeline/intersect.h create mode 100644 extern/libmv/libmv/simple_pipeline/pipeline.cc create mode 100644 extern/libmv/libmv/simple_pipeline/pipeline.h create mode 100644 extern/libmv/libmv/simple_pipeline/reconstruction.cc create mode 100644 extern/libmv/libmv/simple_pipeline/reconstruction.h create mode 100644 extern/libmv/libmv/simple_pipeline/resect.cc create mode 100644 extern/libmv/libmv/simple_pipeline/resect.h create mode 100644 extern/libmv/libmv/simple_pipeline/tracks.cc create mode 100644 extern/libmv/libmv/simple_pipeline/tracks.h create mode 100644 extern/libmv/libmv/tracking/klt_region_tracker.cc create mode 100644 extern/libmv/libmv/tracking/klt_region_tracker.h create mode 100644 extern/libmv/libmv/tracking/pyramid_region_tracker.cc create mode 100644 extern/libmv/libmv/tracking/pyramid_region_tracker.h create mode 100644 extern/libmv/libmv/tracking/region_tracker.h create mode 100644 extern/libmv/libmv/tracking/retrack_region_tracker.cc create mode 100644 extern/libmv/libmv/tracking/retrack_region_tracker.h create mode 100644 extern/libmv/libmv/tracking/sad.cc create mode 100644 extern/libmv/libmv/tracking/sad.h create mode 100644 extern/libmv/libmv/tracking/trklt_region_tracker.cc create mode 100644 extern/libmv/libmv/tracking/trklt_region_tracker.h create mode 100755 extern/libmv/mkfiles.sh create mode 100644 extern/libmv/patches/bundle_tweaks.patch create mode 100644 extern/libmv/patches/config_mac.patch create mode 100644 extern/libmv/patches/detect.patch create mode 100644 extern/libmv/patches/fast.patch create mode 100644 extern/libmv/patches/function_derivative.patch create mode 100644 extern/libmv/patches/high_distortion_crash_fix.patch create mode 100644 extern/libmv/patches/levenberg_marquardt.patch create mode 100644 extern/libmv/patches/mingw.patch create mode 100644 extern/libmv/patches/msvc2010.patch create mode 100644 extern/libmv/patches/overscan.patch create mode 100644 extern/libmv/patches/scaled_distortion.patch create mode 100644 extern/libmv/patches/series create mode 100644 extern/libmv/patches/snrptinf_fix.patch create mode 100644 extern/libmv/patches/v3d_verbosity.patch create mode 100644 extern/libmv/third_party/fast/LICENSE create mode 100644 extern/libmv/third_party/fast/README create mode 100644 extern/libmv/third_party/fast/README.libmv create mode 100644 extern/libmv/third_party/fast/fast.c create mode 100644 extern/libmv/third_party/fast/fast.h create mode 100644 extern/libmv/third_party/fast/fast_10.c create mode 100644 extern/libmv/third_party/fast/fast_11.c create mode 100644 extern/libmv/third_party/fast/fast_12.c create mode 100644 extern/libmv/third_party/fast/fast_9.c create mode 100644 extern/libmv/third_party/fast/nonmax.c create mode 100644 extern/libmv/third_party/gflags/README.libmv create mode 100644 extern/libmv/third_party/gflags/config.h create mode 100644 extern/libmv/third_party/gflags/gflags.cc create mode 100644 extern/libmv/third_party/gflags/gflags.h create mode 100644 extern/libmv/third_party/gflags/gflags_completions.cc create mode 100644 extern/libmv/third_party/gflags/gflags_completions.h create mode 100644 extern/libmv/third_party/gflags/gflags_reporting.cc create mode 100644 extern/libmv/third_party/gflags/mutex.h create mode 100644 extern/libmv/third_party/glog/AUTHORS create mode 100644 extern/libmv/third_party/glog/COPYING create mode 100644 extern/libmv/third_party/glog/ChangeLog create mode 100644 extern/libmv/third_party/glog/NEWS create mode 100644 extern/libmv/third_party/glog/README create mode 100644 extern/libmv/third_party/glog/README.libmv create mode 100644 extern/libmv/third_party/glog/src/base/commandlineflags.h create mode 100644 extern/libmv/third_party/glog/src/base/googleinit.h create mode 100644 extern/libmv/third_party/glog/src/base/mutex.h create mode 100644 extern/libmv/third_party/glog/src/config.h create mode 100644 extern/libmv/third_party/glog/src/config_linux.h create mode 100644 extern/libmv/third_party/glog/src/config_mac.h create mode 100644 extern/libmv/third_party/glog/src/demangle.cc create mode 100644 extern/libmv/third_party/glog/src/demangle.h create mode 100644 extern/libmv/third_party/glog/src/glog/log_severity.h create mode 100644 extern/libmv/third_party/glog/src/glog/logging.h create mode 100644 extern/libmv/third_party/glog/src/glog/raw_logging.h create mode 100644 extern/libmv/third_party/glog/src/glog/vlog_is_on.h create mode 100644 extern/libmv/third_party/glog/src/logging.cc create mode 100644 extern/libmv/third_party/glog/src/raw_logging.cc create mode 100644 extern/libmv/third_party/glog/src/signalhandler.cc create mode 100644 extern/libmv/third_party/glog/src/stacktrace.h create mode 100644 extern/libmv/third_party/glog/src/stacktrace_generic-inl.h create mode 100644 extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h create mode 100644 extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h create mode 100644 extern/libmv/third_party/glog/src/stacktrace_x86-inl.h create mode 100644 extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h create mode 100644 extern/libmv/third_party/glog/src/symbolize.cc create mode 100644 extern/libmv/third_party/glog/src/symbolize.h create mode 100644 extern/libmv/third_party/glog/src/utilities.cc create mode 100644 extern/libmv/third_party/glog/src/utilities.h create mode 100644 extern/libmv/third_party/glog/src/vlog_is_on.cc create mode 100644 extern/libmv/third_party/glog/src/windows/config.h create mode 100644 extern/libmv/third_party/glog/src/windows/glog/log_severity.h create mode 100644 extern/libmv/third_party/glog/src/windows/glog/logging.h create mode 100644 extern/libmv/third_party/glog/src/windows/glog/raw_logging.h create mode 100644 extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h create mode 100644 extern/libmv/third_party/glog/src/windows/port.cc create mode 100644 extern/libmv/third_party/glog/src/windows/port.h create mode 100755 extern/libmv/third_party/glog/src/windows/preprocess.sh create mode 100644 extern/libmv/third_party/ldl/CMakeLists.txt create mode 100644 extern/libmv/third_party/ldl/Doc/ChangeLog create mode 100644 extern/libmv/third_party/ldl/Doc/lesser.txt create mode 100644 extern/libmv/third_party/ldl/Include/ldl.h create mode 100644 extern/libmv/third_party/ldl/README.libmv create mode 100644 extern/libmv/third_party/ldl/README.txt create mode 100644 extern/libmv/third_party/ldl/Source/ldl.c create mode 100644 extern/libmv/third_party/msinttypes/README.libmv create mode 100644 extern/libmv/third_party/msinttypes/inttypes.h create mode 100644 extern/libmv/third_party/msinttypes/stdint.h create mode 100644 extern/libmv/third_party/ssba/COPYING.TXT create mode 100644 extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h create mode 100644 extern/libmv/third_party/ssba/Geometry/v3d_distortion.h create mode 100644 extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp create mode 100644 extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h create mode 100644 extern/libmv/third_party/ssba/Math/v3d_linear.h create mode 100644 extern/libmv/third_party/ssba/Math/v3d_linear_utils.h create mode 100644 extern/libmv/third_party/ssba/Math/v3d_mathutilities.h create mode 100644 extern/libmv/third_party/ssba/Math/v3d_optimization.cpp create mode 100644 extern/libmv/third_party/ssba/Math/v3d_optimization.h create mode 100644 extern/libmv/third_party/ssba/README.TXT create mode 100755 extern/libmv/third_party/ssba/README.libmv create mode 100644 release/scripts/presets/tracking_camera/Blender.py create mode 100644 release/scripts/presets/tracking_camera/Canon_1100D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_1D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_1DS.py create mode 100644 release/scripts/presets/tracking_camera/Canon_500D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_550D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_5D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_600D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_60D.py create mode 100644 release/scripts/presets/tracking_camera/Canon_7D.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D300S.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D3100.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D35.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D5000.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D5100.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D7000.py create mode 100644 release/scripts/presets/tracking_camera/Nikon_D90.py create mode 100644 release/scripts/presets/tracking_camera/Red_Epic.py create mode 100644 release/scripts/presets/tracking_camera/Red_One_2K.py create mode 100644 release/scripts/presets/tracking_camera/Red_One_3K.py create mode 100644 release/scripts/presets/tracking_camera/Red_One_4K.py create mode 100644 release/scripts/presets/tracking_track_color/default.py create mode 100644 release/scripts/presets/tracking_track_color/far_plane.py create mode 100644 release/scripts/presets/tracking_track_color/near_plane.py create mode 100644 release/scripts/startup/bl_operators/clip.py create mode 100644 release/scripts/startup/bl_ui/space_clip.py create mode 100644 source/blender/blenkernel/BKE_movieclip.h create mode 100644 source/blender/blenkernel/BKE_tracking.h create mode 100644 source/blender/blenkernel/intern/movieclip.c create mode 100644 source/blender/blenkernel/intern/tracking.c create mode 100644 source/blender/editors/include/ED_clip.h create mode 100644 source/blender/editors/space_clip/CMakeLists.txt create mode 100644 source/blender/editors/space_clip/SConscript create mode 100644 source/blender/editors/space_clip/clip_buttons.c create mode 100644 source/blender/editors/space_clip/clip_draw.c create mode 100644 source/blender/editors/space_clip/clip_editor.c create mode 100644 source/blender/editors/space_clip/clip_graph_draw.c create mode 100644 source/blender/editors/space_clip/clip_graph_ops.c create mode 100644 source/blender/editors/space_clip/clip_intern.h create mode 100644 source/blender/editors/space_clip/clip_ops.c create mode 100644 source/blender/editors/space_clip/clip_toolbar.c create mode 100644 source/blender/editors/space_clip/clip_utils.c create mode 100644 source/blender/editors/space_clip/space_clip.c create mode 100644 source/blender/editors/space_clip/tracking_ops.c create mode 100644 source/blender/makesdna/DNA_movieclip_types.h create mode 100644 source/blender/makesdna/DNA_tracking_types.h create mode 100644 source/blender/makesrna/intern/rna_movieclip.c create mode 100644 source/blender/makesrna/intern/rna_tracking.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e06f39e718..6bc409fe0df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,6 +202,9 @@ option(WITH_JACK "Enable Jack Support (http://www.jackaudio.org)" OFF) option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON) option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON) +# Camera/motion tracking +option(WITH_LIBMV "Enable libmv structure from motion library" ON) + # Misc option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) option(WITH_RAYOPTIMIZATION "Enable use of SIMD (SSE) optimizations for the raytracer" ON) diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py index 44f9a4c8062..ba15f1c1c09 100644 --- a/build_files/scons/tools/Blender.py +++ b/build_files/scons/tools/Blender.py @@ -329,6 +329,10 @@ def creator(env): if env['WITH_BF_SDL']: defs.append('WITH_SDL') + if env['WITH_BF_LIBMV']: + incs.append('#/extern/libmv') + defs.append('WITH_LIBMV') + if env['WITH_BF_PYTHON']: incs.append('#/source/blender/python') defs.append('WITH_PYTHON') diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py index 68054fe485e..5c78dc646bb 100644 --- a/build_files/scons/tools/btools.py +++ b/build_files/scons/tools/btools.py @@ -515,6 +515,8 @@ def read_opts(env, cfg, args): (BoolVariable('WITH_BF_LZO', 'Enable fast LZO pointcache compression', True)), (BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)), + (BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)), + ('BF_X264_CONFIG', 'configuration flags for x264', ''), ('BF_XVIDCORE_CONFIG', 'configuration flags for xvidcore', ''), # (BoolVariable('WITH_BF_DOCS', 'Generate API documentation', False)), diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 321ebc11985..a5dd3b16860 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -63,3 +63,7 @@ endif() if(WITH_LZMA) add_subdirectory(lzma) endif() + +if(WITH_LIBMV) + add_subdirectory(libmv) +endif() diff --git a/extern/SConscript b/extern/SConscript index f363d75d068..031471a8a01 100644 --- a/extern/SConscript +++ b/extern/SConscript @@ -28,3 +28,6 @@ if env['WITH_BF_LZO']: if env['WITH_BF_LZMA']: SConscript(['lzma/SConscript']) + +if env['WITH_BF_LIBMV']: + SConscript(['libmv/SConscript']) diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt new file mode 100644 index 00000000000..41fc39c97ac --- /dev/null +++ b/extern/libmv/CMakeLists.txt @@ -0,0 +1,210 @@ +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + ../Eigen3 + ./third_party/ssba + ./third_party/ldl/Include + ../colamd/Include +) + +set(INC_SYS + ${PNG_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIRS} +) + +set(SRC + libmv-capi.cpp + libmv/numeric/numeric.cc + libmv/numeric/poly.cc + libmv/simple_pipeline/reconstruction.cc + libmv/simple_pipeline/resect.cc + libmv/simple_pipeline/intersect.cc + libmv/simple_pipeline/initialize_reconstruction.cc + libmv/simple_pipeline/camera_intrinsics.cc + libmv/simple_pipeline/pipeline.cc + libmv/simple_pipeline/detect.cc + libmv/simple_pipeline/tracks.cc + libmv/simple_pipeline/bundle.cc + libmv/image/convolve.cc + libmv/image/array_nd.cc + libmv/tracking/pyramid_region_tracker.cc + libmv/tracking/sad.cc + libmv/tracking/trklt_region_tracker.cc + libmv/tracking/klt_region_tracker.cc + libmv/tracking/retrack_region_tracker.cc + libmv/multiview/projection.cc + libmv/multiview/conditioning.cc + libmv/multiview/fundamental.cc + libmv/multiview/euclidean_resection.cc + libmv/multiview/triangulation.cc + + third_party/ssba/Geometry/v3d_metricbundle.cpp + third_party/ssba/Math/v3d_optimization.cpp + third_party/gflags/gflags.cc + third_party/gflags/gflags_reporting.cc + third_party/gflags/gflags_completions.cc + third_party/fast/fast_9.c + third_party/fast/fast_10.c + third_party/fast/fast_11.c + third_party/fast/fast_12.c + third_party/fast/fast.c + third_party/fast/nonmax.c + third_party/ldl/Source/ldl.c + + libmv-capi.h + libmv/logging/logging.h + libmv/numeric/dogleg.h + libmv/numeric/levenberg_marquardt.h + libmv/numeric/poly.h + libmv/numeric/function_derivative.h + libmv/numeric/numeric.h + libmv/simple_pipeline/resect.h + libmv/simple_pipeline/reconstruction.h + libmv/simple_pipeline/camera_intrinsics.h + libmv/simple_pipeline/tracks.h + libmv/simple_pipeline/detect.h + libmv/simple_pipeline/pipeline.h + libmv/simple_pipeline/intersect.h + libmv/simple_pipeline/bundle.h + libmv/simple_pipeline/initialize_reconstruction.h + libmv/image/convolve.h + libmv/image/tuple.h + libmv/image/array_nd.h + libmv/image/sample.h + libmv/image/image.h + libmv/tracking/region_tracker.h + libmv/tracking/retrack_region_tracker.h + libmv/tracking/sad.h + libmv/tracking/pyramid_region_tracker.h + libmv/tracking/trklt_region_tracker.h + libmv/tracking/klt_region_tracker.h + libmv/base/id_generator.h + libmv/base/vector.h + libmv/base/scoped_ptr.h + libmv/base/vector_utils.h + libmv/multiview/nviewtriangulation.h + libmv/multiview/resection.h + libmv/multiview/euclidean_resection.h + libmv/multiview/triangulation.h + libmv/multiview/projection.h + libmv/multiview/fundamental.h + libmv/multiview/conditioning.h + + third_party/ssba/Geometry/v3d_metricbundle.h + third_party/ssba/Geometry/v3d_cameramatrix.h + third_party/ssba/Geometry/v3d_distortion.h + third_party/ssba/Math/v3d_linear_utils.h + third_party/ssba/Math/v3d_optimization.h + third_party/ssba/Math/v3d_mathutilities.h + third_party/ssba/Math/v3d_linear.h + third_party/gflags/gflags_completions.h + third_party/gflags/mutex.h + third_party/gflags/config.h + third_party/gflags/gflags.h + third_party/fast/fast.h + third_party/ldl/Include/ldl.h + third_party/msinttypes/stdint.h + third_party/msinttypes/inttypes.h +) + +IF(WIN32) + list(APPEND SRC + third_party/glog/src/logging.cc + third_party/glog/src/raw_logging.cc + third_party/glog/src/utilities.cc + third_party/glog/src/vlog_is_on.cc + third_party/glog/src/windows/port.cc + + third_party/glog/src/utilities.h + third_party/glog/src/stacktrace_generic-inl.h + third_party/glog/src/stacktrace.h + third_party/glog/src/stacktrace_x86_64-inl.h + third_party/glog/src/base/googleinit.h + third_party/glog/src/base/mutex.h + third_party/glog/src/base/commandlineflags.h + third_party/glog/src/stacktrace_powerpc-inl.h + third_party/glog/src/stacktrace_x86-inl.h + third_party/glog/src/config.h + third_party/glog/src/stacktrace_libunwind-inl.h + third_party/glog/src/windows/glog/raw_logging.h + third_party/glog/src/windows/glog/vlog_is_on.h + third_party/glog/src/windows/glog/logging.h + third_party/glog/src/windows/glog/log_severity.h + third_party/glog/src/windows/port.h + third_party/glog/src/windows/config.h + ) + + list(APPEND INC + ./third_party/glog/src/windows + ./third_party/msinttypes + ) + + IF(MSVC) + set(MSVC_OFLAGS O1 O2 Ox) + foreach(FLAG ) + string(REPLACE "" "Od" CMAKE_CXX_FLAGS_RELEASE "") + string(REPLACE "" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "") + endforeach() + ENDIF(MSVC) +ELSE(WIN32) + list(APPEND SRC + third_party/glog/src/utilities.cc + third_party/glog/src/symbolize.cc + third_party/glog/src/vlog_is_on.cc + third_party/glog/src/signalhandler.cc + third_party/glog/src/logging.cc + third_party/glog/src/demangle.cc + third_party/glog/src/raw_logging.cc + + third_party/glog/src/utilities.h + third_party/glog/src/stacktrace_generic-inl.h + third_party/glog/src/config_mac.h + third_party/glog/src/stacktrace.h + third_party/glog/src/stacktrace_x86_64-inl.h + third_party/glog/src/symbolize.h + third_party/glog/src/base/googleinit.h + third_party/glog/src/base/mutex.h + third_party/glog/src/base/commandlineflags.h + third_party/glog/src/stacktrace_powerpc-inl.h + third_party/glog/src/stacktrace_x86-inl.h + third_party/glog/src/config.h + third_party/glog/src/demangle.h + third_party/glog/src/stacktrace_libunwind-inl.h + third_party/glog/src/glog/raw_logging.h + third_party/glog/src/glog/vlog_is_on.h + third_party/glog/src/glog/logging.h + third_party/glog/src/glog/log_severity.h + third_party/glog/src/config_linux.h + ) + + list(APPEND INC + ./third_party/glog/src + ) +ENDIF(WIN32) + +add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=) + +blender_add_lib(extern_libmv "${SRC}" "${INC}" "${INC_SYS}") diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog new file mode 100644 index 00000000000..7e10abfead6 --- /dev/null +++ b/extern/libmv/ChangeLog @@ -0,0 +1,312 @@ +commit 531c79bf95fddaaa70707d1abcd4fdafda16bbf0 +Author: Matthias Fauconneau +Date: Sat Aug 20 00:00:42 2011 +0200 + + Display warped pattern in marker preview. + +commit bb5c27e671b6f8eb56ddf490f0795d59bede591b +Author: Matthias Fauconneau +Date: Fri Aug 19 18:37:48 2011 +0200 + + Fix CMake build. + +commit 2ac7281ff6b9545b425dd84fb03bf9c5c98b4de2 +Author: Matthias Fauconneau +Date: Fri Aug 19 17:34:45 2011 +0200 + + Avoid symbol shadowing. + +commit 2a7c3de4acc60e0433b4952f69e30528dbafe0d2 +Author: Matthias Fauconneau +Date: Fri Aug 19 17:22:47 2011 +0200 + + Better dragging behavior when hitting borders. + +commit a14eb3953c9521b2e08ff9ddd45b33ff1f8aeafb +Author: Matthias Fauconneau +Date: Fri Aug 19 17:12:12 2011 +0200 + + Update marker preview to new affine tracking. + +commit 5299ea67043459eda147950e589c2d327a8fbced +Author: Matthias Fauconneau +Date: Fri Aug 19 16:05:54 2011 +0200 + + sqrt takes double precision. + +commit 9f9221ce151d788c49b48f6f293ab2e2f8813978 +Author: Matthias Fauconneau +Date: Fri Aug 19 16:04:37 2011 +0200 + + MSVC compatibility: heap allocate pattern, explicit float cast. + +commit 702658d2f8616964a6eeb3743fd85e97ac7ff09d +Author: Matthias Fauconneau +Date: Fri Aug 19 14:59:24 2011 +0200 + + Expose regularization parameters (areaPenalty and conditionPenalty) in API. + +commit 3e84ae5fbac10451d4935418f6281a90cedace11 +Author: Matthias Fauconneau +Date: Fri Aug 19 14:19:27 2011 +0200 + + Add LaplaceFilter. + Add regularization in affine SAD Tracker (keep constant area and good condition number). + UI: Better track display (+enable line antialiasing). + +commit 6d26d9a8ccc4ce009fbf253898fea8864dd5001a +Author: Matthias Fauconneau +Date: Fri Aug 19 10:25:26 2011 +0200 + + Add optimization for integer pixel search. + Allows more agressive settings for affine coordinate descent. + +commit 70ceae81c0ab561b07e640ecb9933f0a902b57cd +Author: Matthias Fauconneau +Date: Fri Aug 19 00:02:12 2011 +0200 + + Document coordinate descent method in affine SAD matcher. + Add heuristic to prevent high distortions. + +commit 75520f4bc4ccbb272a1b4149d3b8d05a90f7f896 +Author: Matthias Fauconneau +Date: Thu Aug 18 23:14:17 2011 +0200 + + Fix affine iteration. + +commit 4e8e0aa6018e3eb2fbebdad7f1cbd6c909d26e79 +Author: Matthias Fauconneau +Date: Thu Aug 18 23:03:26 2011 +0200 + + Handle rotations. + +commit 3ce41cf3c1b5c136a61d8f4c63ccae3cafbdb8da +Author: Matthias Fauconneau +Date: Thu Aug 18 22:24:47 2011 +0200 + + Slow brute-force affine diamond search implementation. + +commit 1c4acd03e030c1c50dc6fc36c419c72ea69a0713 +Author: Matthias Fauconneau +Date: Thu Aug 18 20:51:43 2011 +0200 + + Fix detect.cc. + +commit ec18cc5ea9ae2e641075a847e82d0aacb8415ad8 +Author: Matthias Fauconneau +Date: Thu Aug 18 17:45:37 2011 +0200 + + Compute and return Pearson product-moment correlation coefficient between reference and matched pattern. + +commit 21d4245c63a01bfc736192d55baf10983e7c9ec7 +Author: Matthias Fauconneau +Date: Thu Aug 18 16:18:44 2011 +0200 + + UI and API support for affine tracking. + +commit a4876d8c40dcde615b44009c38c49e9a1b1d4698 +Author: Matthias Fauconneau +Date: Wed Aug 17 20:26:01 2011 +0200 + + Hack to make sad.cc compile with MSVC on system without support for the SSE instruction set. + +commit 0de723dfce5bbe44dbd19be8cd6dd6e9b03b7924 +Author: Matthias Fauconneau +Date: Wed Aug 17 20:10:46 2011 +0200 + + Fix slow path (for computers without SSE2). + Heap allocate scores in detect.cc + +commit 65a9d496f81e8b37eae39a4063957b8be9a4e6f0 +Author: Matthias Fauconneau +Date: Wed Aug 17 19:25:17 2011 +0200 + + Fix compilation on OSX. + +commit d22720e618456329388d2c107422c3b371657cba +Author: Matthias Fauconneau +Date: Wed Aug 17 14:14:45 2011 +0200 + + Improve Detect and SAD Tracker API and documentation. + +commit 5d6cd4ad365b061901bad40695b51d568487a0cf +Author: Matthias Fauconneau +Date: Wed Aug 17 11:57:29 2011 +0200 + + MSVC support fixes. + +commit 50f0323173c6deebd6aaf9c126f0b51b2a79c3c1 +Author: Matthias Fauconneau +Date: Tue Aug 16 23:21:37 2011 +0200 + + Detector can detect features similar to a given pattern. + +commit 5734cc27bbf84c2b6edcfcc1ea736798e12d5820 +Author: Matthias Fauconneau +Date: Tue Aug 16 22:53:54 2011 +0200 + + Ensure SAD Tracker is C compatible. + Update Detect API documentation. + +commit 701c42842574064fea992f8822e3899cb9066108 +Author: Matthias Fauconneau +Date: Tue Aug 16 21:56:42 2011 +0200 + + Remove FAST detector. + Add Moravec detector. + This detector is more suited to tracking since it try to choose patterns which are unlikely to drift by computing SAD with neighbouring patches. + It could be improved to better avoid edges. + +commit 9bdf93e13fc880c78b6f34397da673388c16040e +Author: Matthias Fauconneau +Date: Tue Aug 16 21:55:08 2011 +0200 + + Fix Qt Tracker GL to work with AMD drivers. + +commit 81613ee0cc94b315f333c9632b18b95d426aad05 +Author: Matthias Fauconneau +Date: Tue Aug 16 21:54:12 2011 +0200 + + Make CameraIntrinsics (and thus Qt tracker) compilable without linking libmv. + +commit a1d9a8fa8b01ef7cf2a79b3b891633fc333fc9cf +Author: Matthias Fauconneau +Date: Tue Aug 16 21:24:51 2011 +0200 + + Fix SAD tracker. Pattern was transposed by affine pattern sampler. + +commit c3b794da2e7fd23f2fbdf90dbd71de0e6b3bc811 +Author: Matthias Fauconneau +Date: Tue Aug 16 21:19:02 2011 +0200 + + Fix SAD tracker. Pattern was transposed by affine pattern sampler. + +commit a9b61bf3356f27174cdd983f562f99c3a6a2cc35 +Author: Matthias Fauconneau +Date: Sun Aug 14 09:56:51 2011 +0200 + + Clarify CameraIntrinsics documentation. + Edit CameraInstrinsics test to fail. + +commit 10bdad9ad2cea2603896263cde5a5339169a9af0 +Author: Matthias Fauconneau +Date: Fri Aug 12 21:05:32 2011 +0200 + + Fix out of bound access in warp bilinear sampling. + +commit dd9a418db021a28af2c1198d5e5b9e68fe048a03 +Author: Matthias Fauconneau +Date: Fri Aug 12 19:14:36 2011 +0200 + + Fix compilation with -funsigned-char. + +commit bd1a268ede39b67f2ba4b360f6fc693419e7cd7f +Author: Matthias Fauconneau +Date: Fri Aug 12 18:39:27 2011 +0200 + + CameraIntrinsics fixes. + +commit ae513b39fb779632f96ceff7c1e014fb8e68702a +Author: Matthias Fauconneau +Date: Tue Aug 9 19:38:58 2011 +0200 + + Remove stray QDebug include. + +commit 1e58f55078ce6009a885be30ae0316aec6ed8239 +Author: Matthias Fauconneau +Date: Tue Aug 9 14:16:31 2011 +0200 + + Make API future-proof (for an eventual affine or planar tracker). + +commit c2af303e7bf0dddcb02937323ac5846b1801e6cc +Author: Matthias Fauconneau +Date: Tue Aug 9 11:13:29 2011 +0200 + + Remove reconstruction breaking debug code. + +commit 8792a633e5c5f1c1f12e164b9e8897ca0790ac59 +Author: Matthias Fauconneau +Date: Tue Aug 9 10:49:18 2011 +0200 + + Remove getchar()s. + +commit 63a9bdee0cbd1197e0315d01c27bfc2361bd5656 +Author: Matthias Fauconneau +Date: Tue Aug 9 10:35:07 2011 +0200 + + Adapt patch to new PipelineRoutines code generation strategy. + +commit 096ff1a4070f7212c50fb0a4b2feec7ca9d97158 +Author: Matthias Fauconneau +Date: Tue Aug 9 09:54:12 2011 +0200 + + Merge max_image and max_track fix from tomato. + +commit d8450cd3c37278a397482cd36b1e2419f154cfb9 +Author: Matthias Fauconneau +Date: Tue Aug 9 09:38:49 2011 +0200 + + Synchronize tree with Tomato: Merge patch for better resection, keep deprecated KLT tracker. + +commit e9b2dca920cf9575c15150a4988634b00e343a41 +Author: Matthias Fauconneau +Date: Mon Aug 8 17:07:08 2011 +0200 + + Fixes, Documentation. + +commit 4fc1c57a2d92442808ac4a3676e6d9a25a51e310 +Author: Matthias Fauconneau +Date: Sun Aug 7 14:35:08 2011 +0200 + + Improve tracker resilience by penalizing large motion vectors. + +commit cc8e7e8e08cd91f75c080a0091461ca9fe969664 +Author: Matthias Fauconneau +Date: Sun Aug 7 09:28:09 2011 +0200 + + Leverage SSE2 SAD instruction for 16x speed improvement in integer pixel search resulting in ~1ms per marker for 16x16 pattern on 128x128 region. + +commit f362ab4999a768370fca57552464b459eb9fbddc +Author: Matthias Fauconneau +Date: Sun Aug 7 09:06:04 2011 +0200 + + Improve SAD Tracker subpixel precision (avoid drift even when adapting at each frame). + +commit fce7a214c561b5f5f0e17115c31fb48814bde2db +Author: Matthias Fauconneau +Date: Sat Aug 6 21:57:06 2011 +0200 + + Track using simple Sum of Absolute Differences matching. + This method is simpler, more robust, faster and accurate. + +commit 620a7a35d9a2818bf6e9dbf5d11debda4be6bc26 +Author: Matthias Fauconneau +Date: Fri Jul 29 12:35:57 2011 +0200 + + Add Intersect unit test. + +commit a2bf58fa57be11215eb17ff7f7de58f97d480ec3 +Author: Matthias Fauconneau +Date: Thu Jul 28 11:08:06 2011 +0200 + + Remove tests depending on dead code. + Fix CameraIntrinsics test. + Add Intersect and Resect tests. + +commit 19bddee10b4879c8cd2238ccdf5b8f7620cf8384 +Author: Matthias Fauconneau +Date: Wed Jul 27 12:07:21 2011 +0200 + + Image Distortion: Fixes and more testing. + +commit 0454d97da328fb0eda8c6c50511ac31864a6d3d6 +Author: Matthias Fauconneau +Date: Wed Jul 27 10:32:37 2011 +0200 + + Test float image distortion. + +commit 8db01595a8721f766d85931a8d92b780461d8741 +Author: Matthias Fauconneau +Date: Wed Jul 27 10:27:07 2011 +0200 + + Image Distortion: Bilinear sampling, Optimization, Instantiate all variants (Distort/Undistort, float/ubyte, 1-4 channels). diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript new file mode 100644 index 00000000000..1ffc6233c1d --- /dev/null +++ b/extern/libmv/SConscript @@ -0,0 +1,60 @@ +#!/usr/bin/python +import sys +import os + +Import('env') + +defs = [] + +cflags_libmv = Split(env['CFLAGS']) +ccflags_libmv = Split(env['CCFLAGS']) +cxxflags_libmv = Split(env['CXXFLAGS']) + +defs.append('V3DLIB_ENABLE_SUITESPARSE') +defs.append('GOOGLE_GLOG_DLL_DECL=') + +src = env.Glob("*.cpp") +src += env.Glob('libmv/image/*.cc') +src += env.Glob('libmv/multiview/*.cc') +src += env.Glob('libmv/numeric/*.cc') +src += env.Glob('libmv/simple_pipeline/*.cc') +src += env.Glob('libmv/tracking/*.cc') +src += env.Glob('third_party/fast/*.c') +src += env.Glob('third_party/gflags/*.cc') +src += env.Glob('third_party/ldl/Source/*.c') +src += env.Glob('third_party/ssba/Geometry/*.cpp') +src += env.Glob('third_party/ssba/Math/*.cpp') + +incs = '. ../Eigen3' +incs += ' ' + env['BF_PNG_INC'] +incs += ' ' + env['BF_ZLIB_INC'] + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes' + + src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc'] + src += ['./third_party/glog/src/windows/port.cc'] + + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + cflags_libmv.append('/Od') + ccflags_libmv.append('/Od') + cxxflags_libmv.append('/Od') + + if not env['BF_DEBUG']: + defs.append('NDEBUG') + else: + if not env['BF_DEBUG']: + cflags_libmv = Split(env['REL_CFLAGS']) + ccflags_libmv = Split(env['REL_CCFLAGS']) + cxxflags_libmv = Split(env['REL_CXXFLAGS']) +else: + src += env.Glob("third_party/glog/src/*.cc") + incs += ' ./third_party/glog/src' + if not env['BF_DEBUG']: + cflags_libmv = Split(env['REL_CFLAGS']) + ccflags_libmv = Split(env['REL_CCFLAGS']) + cxxflags_libmv = Split(env['REL_CXXFLAGS']) + +incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include' + +env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv ) diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh new file mode 100755 index 00000000000..c8df8ae7341 --- /dev/null +++ b/extern/libmv/bundle.sh @@ -0,0 +1,250 @@ +#!/bin/sh + +#BRANCH="keir" +BRANCH="Matthias-Fauconneau" + +if [ -d ./.svn ]; then + echo "This script is supposed to work only when using git-svn" + exit 1 +fi + +repo="git://github.com/${BRANCH}/libmv.git" +tmp=`mktemp -d` + +git clone $repo $tmp/libmv + +#git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log --since="1 month ago" > ChangeLog +git --git-dir $tmp/libmv/.git --work-tree $tmp/libmv log -n 50 > ChangeLog + +for p in `cat ./patches/series`; do + echo "Applying patch $p..." + cat ./patches/$p | patch -d $tmp/libmv -p1 +done + +rm -rf libmv +rm -rf third_party + +cat "files.txt" | while f=`line`; do + mkdir -p `dirname $f` + cp $tmp/libmv/src/$f $f +done + +rm -rf $tmp + +chmod 664 ./third_party/glog/src/windows/*.cc ./third_party/glog/src/windows/*.h ./third_party/glog/src/windows/glog/*.h + +sources=`find ./libmv -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/'` +headers=`find ./libmv -type f -iname '*.h' | sed -r 's/^\.\//\t/'` + +third_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep -v glog | sed -r 's/^\.\//\t/'` +third_headers=`find ./third_party -type f -iname '*.h' | grep -v glog | sed -r 's/^\.\//\t/'` + +third_glog_sources=`find ./third_party -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'` +third_glog_headers=`find ./third_party -type f -iname '*.h' | grep glog | grep -v windows | sed -r 's/^\.\//\t\t/'` + +src_dir=`find ./libmv -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort | uniq` +src_third_dir=`find ./third_party -type f -iname '*.cc' -exec dirname {} \; -or -iname '*.cpp' -exec dirname {} \; -or -iname '*.c' -exec dirname {} \; | sed -r 's/^\.\//\t/' | sort | uniq` +src="" +win_src="" +for x in $src_dir $src_third_dir; do + t="" + + if test `echo "$x" | grep -c glog ` -eq 1; then + continue; + fi + + if stat $x/*.cpp > /dev/null 2>&1; then + t="src += env.Glob('`echo $x'/*.cpp'`')" + fi + + if stat $x/*.c > /dev/null 2>&1; then + if [ -z "$t" ]; then + t="src += env.Glob('`echo $x'/*.c'`')" + else + t="$t + env.Glob('`echo $x'/*.c'`')" + fi + fi + + if stat $x/*.cc > /dev/null 2>&1; then + if [ -z "$t" ]; then + t="src += env.Glob('`echo $x'/*.cc'`')" + else + t="$t + env.Glob('`echo $x'/*.cc'`')" + fi + fi + + if test `echo $x | grep -c windows ` -eq 0; then + if [ -z "$src" ]; then + src=$t + else + src=`echo "$src\n$t"` + fi + else + if [ -z "$win_src" ]; then + win_src=`echo " $t"` + else + win_src=`echo "$win_src\n $t"` + fi + fi +done + +cat > CMakeLists.txt << EOF +# \$Id\$ +# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# The Original Code is Copyright (C) 2011, Blender Foundation +# All rights reserved. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + . + ../Eigen3 + ./third_party/ssba + ./third_party/ldl/Include + ../colamd/Include +) + +set(INC_SYS + ${PNG_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIRS} +) + +set(SRC + libmv-capi.cpp +${sources} + +${third_sources} + + libmv-capi.h +${headers} + +${third_headers} +) + +IF(WIN32) + list(APPEND SRC + third_party/glog/src/logging.cc + third_party/glog/src/raw_logging.cc + third_party/glog/src/utilities.cc + third_party/glog/src/vlog_is_on.cc + third_party/glog/src/windows/port.cc + + third_party/glog/src/utilities.h + third_party/glog/src/stacktrace_generic-inl.h + third_party/glog/src/stacktrace.h + third_party/glog/src/stacktrace_x86_64-inl.h + third_party/glog/src/base/googleinit.h + third_party/glog/src/base/mutex.h + third_party/glog/src/base/commandlineflags.h + third_party/glog/src/stacktrace_powerpc-inl.h + third_party/glog/src/stacktrace_x86-inl.h + third_party/glog/src/config.h + third_party/glog/src/stacktrace_libunwind-inl.h + third_party/glog/src/windows/glog/raw_logging.h + third_party/glog/src/windows/glog/vlog_is_on.h + third_party/glog/src/windows/glog/logging.h + third_party/glog/src/windows/glog/log_severity.h + third_party/glog/src/windows/port.h + third_party/glog/src/windows/config.h + ) + + list(APPEND INC + ./third_party/glog/src/windows + ./third_party/msinttypes + ) + + IF(MSVC) + set(MSVC_OFLAGS O1 O2 Ox) + foreach(FLAG ${MSVC_OFLAGS}) + string(REPLACE "${FLAG}" "Od" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "${FLAG}" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}") + endforeach() + ENDIF(MSVC) +ELSE(WIN32) + list(APPEND SRC +${third_glog_sources} + +${third_glog_headers} + ) + + list(APPEND INC + ./third_party/glog/src + ) +ENDIF(WIN32) + +add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=) + +blender_add_lib(extern_libmv "\${SRC}" "\${INC}" "\${INC_SYS}") +EOF + +cat > SConscript << EOF +#!/usr/bin/python +import sys +import os + +Import('env') + +defs = [] + +cflags_libmv = Split(env['CFLAGS']) +ccflags_libmv = Split(env['CCFLAGS']) +cxxflags_libmv = Split(env['CXXFLAGS']) + +defs.append('V3DLIB_ENABLE_SUITESPARSE') +defs.append('GOOGLE_GLOG_DLL_DECL=') + +src = env.Glob("*.cpp") +$src + +incs = '. ../Eigen3' +incs += ' ' + env['BF_PNG_INC'] +incs += ' ' + env['BF_ZLIB_INC'] + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes' +${win_src} + src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc'] + src += ['./third_party/glog/src/windows/port.cc'] + + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + cflags_libmv.append('/Od') + ccflags_libmv.append('/Od') + cxxflags_libmv.append('/Od') + + if not env['BF_DEBUG']: + defs.append('NDEBUG') + else: + if not env['BF_DEBUG']: + cflags_libmv = Split(env['REL_CFLAGS']) + ccflags_libmv = Split(env['REL_CCFLAGS']) + cxxflags_libmv = Split(env['REL_CXXFLAGS']) +else: + src += env.Glob("third_party/glog/src/*.cc") + incs += ' ./third_party/glog/src' + if not env['BF_DEBUG']: + cflags_libmv = Split(env['REL_CFLAGS']) + ccflags_libmv = Split(env['REL_CCFLAGS']) + cxxflags_libmv = Split(env['REL_CXXFLAGS']) + +incs += ' ./third_party/ssba ./third_party/ldl/Include ../colamd/Include' + +env.BlenderLib ( libname = 'extern_libmv', sources=src, includes=Split(incs), defines=defs, libtype=['extern', 'player'], priority=[20,137], compileflags=cflags_libmv, cc_compileflags=ccflags_libmv, cxx_compileflags=cxxflags_libmv ) +EOF diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt new file mode 100644 index 00000000000..fe6be5d0b20 --- /dev/null +++ b/extern/libmv/files.txt @@ -0,0 +1,141 @@ +libmv/logging/logging.h +libmv/numeric/dogleg.h +libmv/numeric/levenberg_marquardt.h +libmv/numeric/poly.h +libmv/numeric/numeric.cc +libmv/numeric/function_derivative.h +libmv/numeric/poly.cc +libmv/numeric/tinyvector.cc +libmv/numeric/numeric.h +libmv/simple_pipeline/reconstruction.cc +libmv/simple_pipeline/resect.h +libmv/simple_pipeline/resect.cc +libmv/simple_pipeline/reconstruction.h +libmv/simple_pipeline/camera_intrinsics.h +libmv/simple_pipeline/intersect.cc +libmv/simple_pipeline/initialize_reconstruction.cc +libmv/simple_pipeline/camera_intrinsics.cc +libmv/simple_pipeline/pipeline.cc +libmv/simple_pipeline/tracks.h +libmv/simple_pipeline/detect.h +libmv/simple_pipeline/detect.cc +libmv/simple_pipeline/pipeline.h +libmv/simple_pipeline/tracks.cc +libmv/simple_pipeline/bundle.cc +libmv/simple_pipeline/intersect.h +libmv/simple_pipeline/bundle.h +libmv/simple_pipeline/initialize_reconstruction.h +libmv/image/convolve.h +libmv/image/tuple.h +libmv/image/array_nd.h +libmv/image/convolve.cc +libmv/image/array_nd.cc +libmv/image/sample.h +libmv/image/image.h +libmv/tracking/pyramid_region_tracker.cc +libmv/tracking/region_tracker.h +libmv/tracking/sad.cc +libmv/tracking/trklt_region_tracker.cc +libmv/tracking/klt_region_tracker.cc +libmv/tracking/retrack_region_tracker.h +libmv/tracking/sad.h +libmv/tracking/pyramid_region_tracker.h +libmv/tracking/trklt_region_tracker.h +libmv/tracking/retrack_region_tracker.cc +libmv/tracking/klt_region_tracker.h +libmv/base/id_generator.h +libmv/base/vector.h +libmv/base/scoped_ptr.h +libmv/base/vector_utils.h +libmv/multiview/projection.cc +libmv/multiview/conditioning.cc +libmv/multiview/nviewtriangulation.h +libmv/multiview/resection.h +libmv/multiview/fundamental.cc +libmv/multiview/euclidean_resection.cc +libmv/multiview/euclidean_resection.h +libmv/multiview/triangulation.h +libmv/multiview/projection.h +libmv/multiview/triangulation.cc +libmv/multiview/fundamental.h +libmv/multiview/conditioning.h +third_party/ssba/README.TXT +third_party/ssba/COPYING.TXT +third_party/ssba/Geometry/v3d_metricbundle.h +third_party/ssba/Geometry/v3d_metricbundle.cpp +third_party/ssba/Geometry/v3d_cameramatrix.h +third_party/ssba/Geometry/v3d_distortion.h +third_party/ssba/README.libmv +third_party/ssba/Math/v3d_linear_utils.h +third_party/ssba/Math/v3d_optimization.h +third_party/ssba/Math/v3d_mathutilities.h +third_party/ssba/Math/v3d_linear.h +third_party/ssba/Math/v3d_optimization.cpp +third_party/gflags/gflags_completions.h +third_party/gflags/mutex.h +third_party/gflags/gflags.cc +third_party/gflags/gflags_reporting.cc +third_party/gflags/README.libmv +third_party/gflags/config.h +third_party/gflags/gflags_completions.cc +third_party/gflags/gflags.h +third_party/fast/fast_9.c +third_party/fast/fast_10.c +third_party/fast/fast_11.c +third_party/fast/fast.h +third_party/fast/LICENSE +third_party/fast/fast_12.c +third_party/fast/fast.c +third_party/fast/README +third_party/fast/README.libmv +third_party/fast/nonmax.c +third_party/ldl/Include/ldl.h +third_party/ldl/CMakeLists.txt +third_party/ldl/README.libmv +third_party/ldl/Doc/ChangeLog +third_party/ldl/Doc/lesser.txt +third_party/ldl/README.txt +third_party/ldl/Source/ldl.c +third_party/glog/ChangeLog +third_party/glog/COPYING +third_party/glog/src/utilities.cc +third_party/glog/src/utilities.h +third_party/glog/src/symbolize.cc +third_party/glog/src/stacktrace_generic-inl.h +third_party/glog/src/config_mac.h +third_party/glog/src/vlog_is_on.cc +third_party/glog/src/signalhandler.cc +third_party/glog/src/stacktrace.h +third_party/glog/src/stacktrace_x86_64-inl.h +third_party/glog/src/symbolize.h +third_party/glog/src/base/googleinit.h +third_party/glog/src/base/mutex.h +third_party/glog/src/base/commandlineflags.h +third_party/glog/src/windows/preprocess.sh +third_party/glog/src/windows/port.h +third_party/glog/src/windows/config.h +third_party/glog/src/windows/glog/raw_logging.h +third_party/glog/src/windows/glog/vlog_is_on.h +third_party/glog/src/windows/glog/logging.h +third_party/glog/src/windows/glog/log_severity.h +third_party/glog/src/windows/port.cc +third_party/glog/src/logging.cc +third_party/glog/src/stacktrace_powerpc-inl.h +third_party/glog/src/stacktrace_x86-inl.h +third_party/glog/src/demangle.cc +third_party/glog/src/config.h +third_party/glog/src/demangle.h +third_party/glog/src/stacktrace_libunwind-inl.h +third_party/glog/src/glog/raw_logging.h +third_party/glog/src/glog/vlog_is_on.h +third_party/glog/src/glog/logging.h +third_party/glog/src/glog/log_severity.h +third_party/glog/src/raw_logging.cc +third_party/glog/src/config_linux.h +third_party/glog/NEWS +third_party/glog/README +third_party/glog/README.libmv +third_party/glog/AUTHORS +third_party/msinttypes/stdint.h +third_party/msinttypes/inttypes.h +third_party/msinttypes/README.libmv diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp new file mode 100644 index 00000000000..2e007bb47b2 --- /dev/null +++ b/extern/libmv/libmv-capi.cpp @@ -0,0 +1,770 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/* define this to generate PNG images with content of search areas + tracking between which failed */ +#undef DUMP_FAILURE + +#include "libmv-capi.h" + +#include "glog/logging.h" +#include "Math/v3d_optimization.h" + +#include "libmv/tracking/klt_region_tracker.h" +#include "libmv/tracking/trklt_region_tracker.h" +#include "libmv/tracking/pyramid_region_tracker.h" + +#include "libmv/tracking/sad.h" + +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/initialize_reconstruction.h" +#include "libmv/simple_pipeline/bundle.h" +#include "libmv/simple_pipeline/detect.h" +#include "libmv/simple_pipeline/pipeline.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" + +#include + +#ifdef DUMP_FAILURE +# include +#endif + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +#define DEFAULT_WINDOW_HALFSIZE 5 + +typedef struct libmv_RegionTracker { + libmv::TrkltRegionTracker *trklt_region_tracker; + libmv::RegionTracker *region_tracker; +} libmv_RegionTracker; + +typedef struct libmv_Reconstruction { + libmv::EuclideanReconstruction reconstruction; + + /* used for per-track average error calculation after reconstruction */ + libmv::Tracks tracks; + libmv::CameraIntrinsics intrinsics; + + double error; +} libmv_Reconstruction; + +typedef struct libmv_Features { + int count, margin; + libmv::Feature *features; +} libmv_Features; + +/* ************ Logging ************ */ + +void libmv_initLogging(const char *argv0) +{ + google::InitGoogleLogging(argv0); + google::SetCommandLineOption("logtostderr", "1"); + google::SetCommandLineOption("v", "0"); + google::SetCommandLineOption("stderrthreshold", "7"); + google::SetCommandLineOption("minloglevel", "7"); + V3D::optimizerVerbosenessLevel = 0; +} + +void libmv_startDebugLogging(void) +{ + google::SetCommandLineOption("logtostderr", "1"); + google::SetCommandLineOption("v", "0"); + google::SetCommandLineOption("stderrthreshold", "1"); + google::SetCommandLineOption("minloglevel", "0"); + V3D::optimizerVerbosenessLevel = 1; +} + +void libmv_setLoggingVerbosity(int verbosity) +{ + char val[10]; + snprintf(val, sizeof(val), "%d", verbosity); + + google::SetCommandLineOption("v", val); + V3D::optimizerVerbosenessLevel = verbosity; +} + +/* ************ RegionTracker ************ */ + +libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level) +{ + libmv::TrkltRegionTracker *trklt_region_tracker = new libmv::TrkltRegionTracker; + + trklt_region_tracker->half_window_size = DEFAULT_WINDOW_HALFSIZE; + trklt_region_tracker->max_iterations = max_iterations; + trklt_region_tracker->min_determinant = 1e-4; + + libmv::PyramidRegionTracker *region_tracker = + new libmv::PyramidRegionTracker(trklt_region_tracker, pyramid_level); + + libmv_RegionTracker *configured_region_tracker = new libmv_RegionTracker; + configured_region_tracker->trklt_region_tracker = trklt_region_tracker; + configured_region_tracker->region_tracker = region_tracker; + + return configured_region_tracker; +} + +static void floatBufToImage(const float *buf, int width, int height, libmv::FloatImage *image) +{ + int x, y, a = 0; + + image->resize(height, width); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + (*image)(y, x, 0) = buf[a++]; + } + } +} + +#ifdef DUMP_FAILURE +void savePNGImage(png_bytep *row_pointers, int width, int height, int depth, int color_type, char *file_name) +{ + png_infop info_ptr; + png_structp png_ptr; + FILE *fp = fopen(file_name, "wb"); + + if (!fp) + return; + + /* Initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + + if (setjmp(png_jmpbuf(png_ptr))) { + fclose(fp); + return; + } + + png_init_io(png_ptr, fp); + + /* write header */ + if (setjmp(png_jmpbuf(png_ptr))) { + fclose(fp); + return; + } + + png_set_IHDR(png_ptr, info_ptr, width, height, + depth, color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) { + fclose(fp); + return; + } + + png_write_image(png_ptr, row_pointers); + + /* end write */ + if (setjmp(png_jmpbuf(png_ptr))) { + fclose(fp); + return; + } + + png_write_end(png_ptr, NULL); + + fclose(fp); +} + +static void saveImage(char *prefix, libmv::FloatImage image, int x0, int y0) +{ + int x, y; + png_bytep *row_pointers; + + row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*image.Height()); + + for (y = 0; y < image.Height(); y++) { + row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*image.Width()); + + for (x = 0; x < image.Width(); x++) { + if (x0 == x && y0 == y) { + row_pointers[y][x*4+0]= 255; + row_pointers[y][x*4+1]= 0; + row_pointers[y][x*4+2]= 0; + row_pointers[y][x*4+3]= 255; + } + else { + float pixel = image(y, x, 0); + row_pointers[y][x*4+0]= pixel*255; + row_pointers[y][x*4+1]= pixel*255; + row_pointers[y][x*4+2]= pixel*255; + row_pointers[y][x*4+3]= 255; + } + } + } + + { + static int a= 0; + char buf[128]; + snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a); + savePNGImage(row_pointers, image.Width(), image.Height(), 8, PNG_COLOR_TYPE_RGBA, buf); + } + + for (y = 0; y < image.Height(); y++) { + free(row_pointers[y]); + } + free(row_pointers); +} + +static void saveBytesImage(char *prefix, unsigned char *data, int width, int height) +{ + int x, y; + png_bytep *row_pointers; + + row_pointers= (png_bytep*)malloc(sizeof(png_bytep)*height); + + for (y = 0; y < height; y++) { + row_pointers[y]= (png_bytep)malloc(sizeof(png_byte)*4*width); + + for (x = 0; x < width; x++) { + char pixel = data[width*y+x]; + row_pointers[y][x*4+0]= pixel; + row_pointers[y][x*4+1]= pixel; + row_pointers[y][x*4+2]= pixel; + row_pointers[y][x*4+3]= 255; + } + } + + { + static int a= 0; + char buf[128]; + snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a); + savePNGImage(row_pointers, width, height, 8, PNG_COLOR_TYPE_RGBA, buf); + } + + for (y = 0; y < height; y++) { + free(row_pointers[y]); + } + free(row_pointers); +} +#endif + +int libmv_regionTrackerTrack(libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2, + int width, int height, int half_window_size, + double x1, double y1, double *x2, double *y2) +{ + libmv::RegionTracker *region_tracker; + libmv::TrkltRegionTracker *trklt_region_tracker; + libmv::FloatImage old_patch, new_patch; + + trklt_region_tracker = libmv_tracker->trklt_region_tracker; + region_tracker = libmv_tracker->region_tracker; + + trklt_region_tracker->half_window_size = half_window_size; + + floatBufToImage(ima1, width, height, &old_patch); + floatBufToImage(ima2, width, height, &new_patch); + +#ifndef DUMP_FAILURE + return region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2); +#else + { + double sx2 = *x2, sy2 = *y2; + int result = region_tracker->Track(old_patch, new_patch, x1, y1, x2, y2); + + if (!result) { + saveImage("old_patch", old_patch, x1, y1); + saveImage("new_patch", new_patch, sx2, sy2); + } + + return result; + } +#endif +} + +void libmv_regionTrackerDestroy(libmv_RegionTracker *libmv_tracker) +{ + delete libmv_tracker->region_tracker; + delete libmv_tracker; +} + +/* ************ Tracks ************ */ + +void libmv_SADSamplePattern(unsigned char *image, int stride, + float warp[3][2], unsigned char *pattern) +{ + libmv::mat32 mat32; + + memcpy(mat32.data, warp, sizeof(float)*3*2); + + libmv::SamplePattern(image, stride, mat32, pattern, 16); +} + +float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image, int stride, + int width, int height, float warp[3][2]) +{ + float result; + libmv::mat32 mat32; + + memcpy(mat32.data, warp, sizeof(float)*3*2); + + result = libmv::Track(pattern, warped, 16, image, stride, width, height, &mat32, 16, 16); + + memcpy(warp, mat32.data, sizeof(float)*3*2); + + return result; +} + +/* ************ Tracks ************ */ + +libmv_Tracks *libmv_tracksNew(void) +{ + libmv::Tracks *libmv_tracks = new libmv::Tracks(); + + return (libmv_Tracks *)libmv_tracks; +} + +void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y) +{ + ((libmv::Tracks*)libmv_tracks)->Insert(image, track, x, y); +} + +void libmv_tracksDestroy(libmv_Tracks *libmv_tracks) +{ + delete (libmv::Tracks*)libmv_tracks; +} + +/* ************ Reconstruction solver ************ */ + +libmv_Reconstruction *libmv_solveReconstruction(libmv_Tracks *tracks, int keyframe1, int keyframe2, + double focal_length, double principal_x, double principal_y, double k1, double k2, double k3) +{ + /* Invert the camera intrinsics. */ + libmv::vector markers = ((libmv::Tracks*)tracks)->AllMarkers(); + libmv_Reconstruction *libmv_reconstruction = new libmv_Reconstruction(); + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics; + + intrinsics->SetFocalLength(focal_length, focal_length); + intrinsics->SetPrincipalPoint(principal_x, principal_y); + intrinsics->SetRadialDistortion(k1, k2, k3); + + if(focal_length) { + /* do a lens undistortion if focal length is non-zero only */ + for (int i = 0; i < markers.size(); ++i) { + intrinsics->InvertIntrinsics(markers[i].x, + markers[i].y, + &(markers[i].x), + &(markers[i].y)); + } + } + + libmv::Tracks normalized_tracks(markers); + + libmv::vector keyframe_markers = + normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2); + + libmv::EuclideanReconstructTwoFrames(keyframe_markers, reconstruction); + libmv::EuclideanBundle(normalized_tracks, reconstruction); + libmv::EuclideanCompleteReconstruction(normalized_tracks, reconstruction); + + libmv_reconstruction->tracks = *(libmv::Tracks *)tracks; + libmv_reconstruction->error = libmv::EuclideanReprojectionError(*(libmv::Tracks *)tracks, *reconstruction, *intrinsics); + + return (libmv_Reconstruction *)libmv_reconstruction; +} + +int libmv_reporojectionPointForTrack(libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]) +{ + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::EuclideanPoint *point = reconstruction->PointForTrack(track); + + if(point) { + pos[0] = point->X[0]; + pos[1] = point->X[2]; + pos[2] = point->X[1]; + + return 1; + } + + return 0; +} + +static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point, const libmv::EuclideanCamera &camera, + const libmv::CameraIntrinsics &intrinsics) { + libmv::Vec3 projected = camera.R * point.X + camera.t; + projected /= projected(2); + + libmv::Marker reprojected_marker; + intrinsics.ApplyIntrinsics(projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y); + + reprojected_marker.image = camera.image; + reprojected_marker.track = point.track; + + return reprojected_marker; +} + +double libmv_reporojectionErrorForTrack(libmv_Reconstruction *libmv_reconstruction, int track) +{ + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics; + libmv::vector markers = libmv_reconstruction->tracks.MarkersForTrack(track); + + int num_reprojected = 0; + double total_error = 0.0; + + for (int i = 0; i < markers.size(); ++i) { + const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image); + const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track); + + if (!camera || !point) { + continue; + } + + num_reprojected++; + + libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics); + double ex = reprojected_marker.x - markers[i].x; + double ey = reprojected_marker.y - markers[i].y; + + total_error += sqrt(ex*ex + ey*ey); + } + + return total_error / num_reprojected; +} + +double libmv_reporojectionErrorForImage(libmv_Reconstruction *libmv_reconstruction, int image) +{ + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::CameraIntrinsics *intrinsics = &libmv_reconstruction->intrinsics; + libmv::vector markers = libmv_reconstruction->tracks.MarkersInImage(image); + const libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image); + int num_reprojected = 0; + double total_error = 0.0; + + if (!camera) + return 0; + + for (int i = 0; i < markers.size(); ++i) { + const libmv::EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track); + + if (!point) { + continue; + } + + num_reprojected++; + + libmv::Marker reprojected_marker = ProjectMarker(*point, *camera, *intrinsics); + double ex = reprojected_marker.x - markers[i].x; + double ey = reprojected_marker.y - markers[i].y; + + total_error += sqrt(ex*ex + ey*ey); + } + + return total_error / num_reprojected; +} + +int libmv_reporojectionCameraForImage(libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4]) +{ + libmv::EuclideanReconstruction *reconstruction = &libmv_reconstruction->reconstruction; + libmv::EuclideanCamera *camera = reconstruction->CameraForImage(image); + + if(camera) { + for (int j = 0; j < 3; ++j) { + for (int k = 0; k < 3; ++k) { + int l = k; + + if (k == 1) l = 2; + else if (k == 2) l = 1; + + if (j == 2) mat[j][l] = -camera->R(j,k); + else mat[j][l] = camera->R(j,k); + } + mat[j][3]= 0.0; + } + + libmv::Vec3 optical_center = -camera->R.transpose() * camera->t; + + mat[3][0] = optical_center(0); + mat[3][1] = optical_center(2); + mat[3][2] = optical_center(1); + + mat[3][3]= 1.0; + + return 1; + } + + return 0; +} + +double libmv_reprojectionError(libmv_Reconstruction *libmv_reconstruction) +{ + return libmv_reconstruction->error; +} + +void libmv_destroyReconstruction(libmv_Reconstruction *libmv_reconstruction) +{ + delete libmv_reconstruction; +} + +/* ************ feature detector ************ */ + +struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride, + int margin, int min_trackness, int min_distance) +{ + libmv::Feature *features = NULL; + std::vector v; + libmv_Features *libmv_features = new libmv_Features(); + int i= 0, count; + + if(margin) { + data += margin*stride+margin; + width -= 2*margin; + height -= 2*margin; + } + + v = libmv::DetectFAST(data, width, height, stride, min_trackness, min_distance); + + count = v.size(); + + if(count) { + features= new libmv::Feature[count]; + + for(std::vector::iterator it = v.begin(); it != v.end(); it++) { + features[i++]= *it; + } + } + + libmv_features->features = features; + libmv_features->count = count; + libmv_features->margin = margin; + + return (libmv_Features *)libmv_features; +} + +struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride, + int margin, int count, int min_distance) +{ + libmv::Feature *features = NULL; + libmv_Features *libmv_features = new libmv_Features; + + if(count) { + if(margin) { + data += margin*stride+margin; + width -= 2*margin; + height -= 2*margin; + } + + features = new libmv::Feature[count]; + libmv::DetectMORAVEC(data, stride, width, height, features, &count, min_distance, NULL); + } + + libmv_features->count = count; + libmv_features->margin = margin; + libmv_features->features = features; + + return libmv_features; +} + +int libmv_countFeatures(struct libmv_Features *libmv_features) +{ + return libmv_features->count; +} + +void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size) +{ + libmv::Feature feature= libmv_features->features[number]; + + *x = feature.x + libmv_features->margin; + *y = feature.y + libmv_features->margin; + *score = feature.score; + *size = feature.size; +} + +void libmv_destroyFeatures(struct libmv_Features *libmv_features) +{ + if(libmv_features->features) + delete [] libmv_features->features; + + delete libmv_features; +} + +/* ************ camera intrinsics ************ */ + +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y, + double k1, double k2, double k3, int width, int height) +{ + libmv::CameraIntrinsics *intrinsics= new libmv::CameraIntrinsics(); + + intrinsics->SetFocalLength(focal_length, focal_length); + intrinsics->SetPrincipalPoint(principal_x, principal_y); + intrinsics->SetRadialDistortion(k1, k2, k3); + intrinsics->SetImageSize(width, height); + + return (struct libmv_CameraIntrinsics *) intrinsics; +} + +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics) +{ + libmv::CameraIntrinsics *orig_intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + libmv::CameraIntrinsics *new_intrinsics= new libmv::CameraIntrinsics(*orig_intrinsics); + + return (struct libmv_CameraIntrinsics *) new_intrinsics; +} + +void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + + delete intrinsics; +} + +void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length, + double principal_x, double principal_y, double k1, double k2, double k3, int width, int height) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + + if (intrinsics->focal_length() != focal_length) + intrinsics->SetFocalLength(focal_length, focal_length); + + if (intrinsics->principal_point_x() != principal_x || intrinsics->principal_point_y() != principal_y) + intrinsics->SetFocalLength(focal_length, focal_length); + + if (intrinsics->k1() != k1 || intrinsics->k2() != k2 || intrinsics->k3() != k3) + intrinsics->SetRadialDistortion(k1, k2, k3); + + if (intrinsics->image_width() != width || intrinsics->image_height() != height) + intrinsics->SetImageSize(width, height); +} + +void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + + intrinsics->Undistort(src, dst, width, height, overscan, channels); +} + +void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, + float *src, float *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + + intrinsics->Undistort(src, dst, width, height, overscan, channels); +} + +void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + intrinsics->Distort(src, dst, width, height, overscan, channels); +} + +void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, + float *src, float *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics *intrinsics = (libmv::CameraIntrinsics *) libmvIntrinsics; + + intrinsics->Distort(src, dst, width, height, overscan, channels); +} + +/* ************ distortion ************ */ + +void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + intrinsics.Undistort(src, dst, width, height, overscan, channels); +} + +void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + float *src, float *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + intrinsics.Undistort(src, dst, width, height, overscan, channels); +} + +void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + intrinsics.Distort(src, dst, width, height, overscan, channels); +} + +void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + float *src, float *dst, int width, int height, float overscan, int channels) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + intrinsics.Distort(src, dst, width, height, overscan, channels); +} + +/* ************ utils ************ */ + +void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + double x, double y, double *x1, double *y1) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + if(focal_length) { + /* do a lens undistortion if focal length is non-zero only */ + + intrinsics.ApplyIntrinsics(x, y, x1, y1); + } +} + +void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + double x, double y, double *x1, double *y1) +{ + libmv::CameraIntrinsics intrinsics; + + intrinsics.SetFocalLength(focal_length, focal_length); + intrinsics.SetPrincipalPoint(principal_x, principal_y); + intrinsics.SetRadialDistortion(k1, k2, k3); + + if(focal_length) { + /* do a lens distortion if focal length is non-zero only */ + + intrinsics.InvertIntrinsics(x, y, x1, y1); + } +} diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h new file mode 100644 index 00000000000..b71a66b73a6 --- /dev/null +++ b/extern/libmv/libmv-capi.h @@ -0,0 +1,128 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef LIBMV_C_API_H +#define LIBMV_C_API_H + +#ifdef __cplusplus +extern "C" { +#endif + +struct libmv_RegionTracker; +struct libmv_Tracks; +struct libmv_Reconstruction; +struct libmv_Features; +struct libmv_CameraIntrinsics; + +/* Logging */ +void libmv_initLogging(const char *argv0); +void libmv_startDebugLogging(void); +void libmv_setLoggingVerbosity(int verbosity); + +/* RegionTracker */ +struct libmv_RegionTracker *libmv_regionTrackerNew(int max_iterations, int pyramid_level); +int libmv_regionTrackerTrack(struct libmv_RegionTracker *libmv_tracker, const float *ima1, const float *ima2, + int width, int height, int half_window_size, + double x1, double y1, double *x2, double *y2); +void libmv_regionTrackerDestroy(struct libmv_RegionTracker *libmv_tracker); + +/* SAD Tracker */ +void libmv_SADSamplePattern(unsigned char *image, int stride, + float warp[3][2], unsigned char *pattern); +float libmv_SADTrackerTrack(unsigned char *pattern, unsigned char *warped, unsigned char *image, + int stride, int width, int height, float warp[3][2]); + +/* Tracks */ +struct libmv_Tracks *libmv_tracksNew(void); +void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y); +void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks); + +/* Reconstruction solver */ +struct libmv_Reconstruction *libmv_solveReconstruction(struct libmv_Tracks *tracks, int keyframe1, int keyframe2, + double focal_length, double principal_x, double principal_y, double k1, double k2, double k3); +int libmv_reporojectionPointForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]); +double libmv_reporojectionErrorForTrack(struct libmv_Reconstruction *libmv_reconstruction, int track); +double libmv_reporojectionErrorForImage(struct libmv_Reconstruction *libmv_reconstruction, int image); +int libmv_reporojectionCameraForImage(struct libmv_Reconstruction *libmv_reconstruction, int image, double mat[4][4]); +double libmv_reprojectionError(struct libmv_Reconstruction *libmv_reconstruction); +void libmv_destroyReconstruction(struct libmv_Reconstruction *libmv_reconstruction); + +/* feature detector */ +struct libmv_Features *libmv_detectFeaturesFAST(unsigned char *data, int width, int height, int stride, + int margin, int min_trackness, int min_distance); +struct libmv_Features *libmv_detectFeaturesMORAVEC(unsigned char *data, int width, int height, int stride, + int margin, int count, int min_distance); +int libmv_countFeatures(struct libmv_Features *libmv_features); +void libmv_getFeature(struct libmv_Features *libmv_features, int number, double *x, double *y, double *score, double *size); +void libmv_destroyFeatures(struct libmv_Features *libmv_features); + +/* camera intrinsics */ +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(double focal_length, double principal_x, double principal_y, + double k1, double k2, double k3, int width, int height); + +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics); + +struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmvIntrinsics); + +void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmvIntrinsics); + +void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmvIntrinsics, double focal_length, + double principal_x, double principal_y, double k1, double k2, double k3, int width, int height); + +void libmv_CameraIntrinsicsUndistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); + +void libmv_CameraIntrinsicsUndistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, + float *src, float *dst, int width, int height, float overscan, int channels); + +void libmv_CameraIntrinsicsDistortByte(struct libmv_CameraIntrinsics *libmvIntrinsics, + unsigned char *src, unsigned char *dst, int width, int height, float overscan, int channels); + +void libmv_CameraIntrinsicsDistortFloat(struct libmv_CameraIntrinsics *libmvIntrinsics, + float *src, float *dst, int width, int height, float overscan, int channels); + +/* dsitortion */ +void libmv_undistortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + unsigned char *src, unsigned char *dst, int width, int height, int channels); +void libmv_undistortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + float *src, float *dst, int width, int height, int channels); + +void libmv_distortByte(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + unsigned char *src, unsigned char *dst, int width, int height, int channels); +void libmv_distortFloat(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + float *src, float *dst, int width, int height, int channels); + +/* utils */ +void libmv_applyCameraIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + double x, double y, double *x1, double *y1); +void libmv_InvertIntrinsics(double focal_length, double principal_x, double principal_y, double k1, double k2, double k3, + double x, double y, double *x1, double *y1); + +#ifdef __cplusplus +} +#endif + +#endif // LIBMV_C_API_H diff --git a/extern/libmv/libmv/base/id_generator.h b/extern/libmv/libmv/base/id_generator.h new file mode 100644 index 00000000000..bf1eafd218e --- /dev/null +++ b/extern/libmv/libmv/base/id_generator.h @@ -0,0 +1,37 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_ID_GENERATOR_H +#define LIBMV_ID_GENERATOR_H + +namespace libmv { + +template +class IdGenerator { + public: + IdGenerator() : next_(0) {} + ID Generate() { return next_++; } + private: + ID next_; +}; + +} // namespace libmv + +#endif // LIBMV_ID_GENERATOR_H diff --git a/extern/libmv/libmv/base/scoped_ptr.h b/extern/libmv/libmv/base/scoped_ptr.h new file mode 100644 index 00000000000..f1e89eb5625 --- /dev/null +++ b/extern/libmv/libmv/base/scoped_ptr.h @@ -0,0 +1,60 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_BASE_SCOPED_PTR_H +#define LIBMV_BASE_SCOPED_PTR_H + +namespace libmv { + +/** + * A handle for a heap-allocated resource that should be freed when it goes out + * of scope. This looks similar to the one found in TR1. + */ +template +class scoped_ptr { + public: + scoped_ptr(T *resource) : resource_(resource) {} + ~scoped_ptr() { reset(0); } + + T *get() const { return resource_; } + T *operator->() const { return resource_; } + T &operator*() const { return *resource_; } + + void reset(T *new_resource) { + if (sizeof(T)) { + delete resource_; + } + resource_ = new_resource; + } + + T *release() { + T *released_resource = resource_; + resource_ = 0; + return released_resource; + } + + private: + // No copying allowed. + T *resource_; +}; + +} // namespace libmv + +#endif // LIBMV_BASE_SCOPED_PTR_H diff --git a/extern/libmv/libmv/base/vector.h b/extern/libmv/libmv/base/vector.h new file mode 100644 index 00000000000..9dc48676629 --- /dev/null +++ b/extern/libmv/libmv/base/vector.h @@ -0,0 +1,172 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Get an aligned vector implementation. Must be included before . The +// Eigen guys went through some trouble to make a portable override for the +// fixed size vector types. + +#ifndef LIBMV_BASE_VECTOR_H +#define LIBMV_BASE_VECTOR_H + +#include +#include + +#include + +namespace libmv { + +// A simple container class, which guarantees 16 byte alignment needed for most +// vectorization. Don't use this container for classes that cannot be copied +// via memcpy. +// FIXME: this class has some issues: +// - doesn't support iterators. +// - impede compatibility with code using STL. +// - the STL already provide support for custom allocators +// it could be replaced with a simple +// template class vector : std::vector {} declaration +// provided it doesn't break code relying on libmv::vector specific behavior +template > +class vector { + public: + ~vector() { clear(); } + + vector() { init(); } + vector(int size) { init(); resize(size); } + vector(int size, const T & val) { + init(); + resize(size); + std::fill(data_, data_+size_, val); } + + // Copy constructor and assignment. + vector(const vector &rhs) { + init(); + copy(rhs); + } + vector &operator=(const vector &rhs) { + if (&rhs != this) { + copy(rhs); + } + return *this; + } + + /// Swaps the contents of two vectors in constant time. + void swap(vector &other) { + std::swap(allocator_, other.allocator_); + std::swap(size_, other.size_); + std::swap(capacity_, other.capacity_); + std::swap(data_, other.data_); + } + + T *data() const { return data_; } + int size() const { return size_; } + int capacity() const { return capacity_; } + const T& back() const { return data_[size_ - 1]; } + T& back() { return data_[size_ - 1]; } + const T& front() const { return data_[0]; } + T& front() { return data_[0]; } + const T& operator[](int n) const { return data_[n]; } + T& operator[](int n) { return data_[n]; } + const T * begin() const { return data_; } + const T * end() const { return data_+size_; } + T * begin() { return data_; } + T * end() { return data_+size_; } + + void resize(size_t size) { + reserve(size); + if (size > size_) { + construct(size_, size); + } else if (size < size_) { + destruct(size, size_); + } + size_ = size; + } + + + + void push_back(const T &value) { + if (size_ == capacity_) { + reserve(size_ ? 2 * size_ : 1); + } + new (&data_[size_++]) T(value); + } + + void pop_back() { + resize(size_ - 1); + } + + void clear() { + destruct(0, size_); + deallocate(); + init(); + } + + void reserve(unsigned int size) { + if (size > size_) { + T *data = static_cast(allocate(size)); + memcpy(data, data_, sizeof(*data)*size_); + allocator_.deallocate(data_, capacity_); + data_ = data; + capacity_ = size; + } + } + + private: + void construct(int start, int end) { + for (int i = start; i < end; ++i) { + new (&data_[i]) T; + } + } + void destruct(int start, int end) { + for (int i = start; i < end; ++i) { + data_[i].~T(); + } + } + void init() { + size_ = 0; + data_ = 0; + capacity_ = 0; + } + + void *allocate(int size) { + return size ? allocator_.allocate(size) : 0; + } + + void deallocate() { + allocator_.deallocate(data_, size_); + data_ = 0; + } + + void copy(const vector &rhs) { + resize(rhs.size()); + for (int i = 0; i < rhs.size(); ++i) { + (*this)[i] = rhs[i]; + } + } + + Allocator allocator_; + size_t size_; + size_t capacity_; + T *data_; +}; + +} // namespace libmv + +#endif // LIBMV_BASE_VECTOR_H diff --git a/extern/libmv/libmv/base/vector_utils.h b/extern/libmv/libmv/base/vector_utils.h new file mode 100644 index 00000000000..7a0c3ba24f5 --- /dev/null +++ b/extern/libmv/libmv/base/vector_utils.h @@ -0,0 +1,34 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + + +#ifndef LIBMV_BASE_VECTOR_UTILS_H_ +#define LIBMV_BASE_VECTOR_UTILS_H_ + +/// Delete the contents of a container. +template +void DeleteElements(Array *array) { + for (int i = 0; i < array->size(); ++i) { + delete (*array)[i]; + } + array->clear(); +} + +#endif // LIBMV_BASE_VECTOR_UTILS_H_ diff --git a/extern/libmv/libmv/image/array_nd.cc b/extern/libmv/libmv/image/array_nd.cc new file mode 100644 index 00000000000..3a77e3e4881 --- /dev/null +++ b/extern/libmv/libmv/image/array_nd.cc @@ -0,0 +1,108 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/image/image.h" +#include +#include + +namespace libmv { + +void FloatArrayToScaledByteArray(const Array3Df &float_array, + Array3Du *byte_array, + bool automatic_range_detection + ) { + byte_array->ResizeLike(float_array); + float minval = HUGE_VAL; + float maxval = -HUGE_VAL; + if (automatic_range_detection) { + for (int i = 0; i < float_array.Height(); ++i) { + for (int j = 0; j < float_array.Width(); ++j) { + for (int k = 0; k < float_array.Depth(); ++k) { + minval = std::min(minval, float_array(i,j,k)); + maxval = std::max(maxval, float_array(i,j,k)); + } + } + } + } else { + minval = 0; + maxval = 1; + } + for (int i = 0; i < float_array.Height(); ++i) { + for (int j = 0; j < float_array.Width(); ++j) { + for (int k = 0; k < float_array.Depth(); ++k) { + float unscaled = (float_array(i,j,k) - minval) / (maxval - minval); + (*byte_array)(i,j,k) = (unsigned char)(255 * unscaled); + } + } + } +} + +void ByteArrayToScaledFloatArray(const Array3Du &byte_array, + Array3Df *float_array) { + float_array->ResizeLike(byte_array); + for (int i = 0; i < byte_array.Height(); ++i) { + for (int j = 0; j < byte_array.Width(); ++j) { + for (int k = 0; k < byte_array.Depth(); ++k) { + (*float_array)(i,j,k) = float(byte_array(i,j,k)) / 255.0f; + } + } + } +} + +void SplitChannels(const Array3Df &input, + Array3Df *channel0, + Array3Df *channel1, + Array3Df *channel2) { + assert(input.Depth() >= 3); + channel0->Resize(input.Height(), input.Width()); + channel1->Resize(input.Height(), input.Width()); + channel2->Resize(input.Height(), input.Width()); + for (int row = 0; row < input.Height(); ++row) { + for (int column = 0; column < input.Width(); ++column) { + (*channel0)(row, column) = input(row, column, 0); + (*channel1)(row, column) = input(row, column, 1); + (*channel2)(row, column) = input(row, column, 2); + } + } +} + +void PrintArray(const Array3Df &array) { + using namespace std; + + printf("[\n"); + for (int r = 0; r < array.Height(); ++r) { + printf("["); + for (int c = 0; c < array.Width(); ++c) { + if (array.Depth() == 1) { + printf("%11f, ", array(r, c)); + } else { + printf("["); + for (int k = 0; k < array.Depth(); ++k) { + printf("%11f, ", array(r, c, k)); + } + printf("],"); + } + } + printf("],\n"); + } + printf("]\n"); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/image/array_nd.h b/extern/libmv/libmv/image/array_nd.h new file mode 100644 index 00000000000..6d7570cda9b --- /dev/null +++ b/extern/libmv/libmv/image/array_nd.h @@ -0,0 +1,473 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_IMAGE_ARRAY_ND_H +#define LIBMV_IMAGE_ARRAY_ND_H + +#include +#include +#include + +#include "libmv/image/tuple.h" + +namespace libmv { + +class BaseArray {}; + +/// A multidimensional array class. +template +class ArrayND : public BaseArray { + public: + typedef T Scalar; + + /// Type for the multidimensional indices. + typedef Tuple Index; + + /// Create an empty array. + ArrayND() : data_(NULL), own_data(true) { Resize(Index(0)); } + + /// Create an array with the specified shape. + ArrayND(const Index &shape) : data_(NULL), own_data(true) { Resize(shape); } + + /// Create an array with the specified shape. + ArrayND(int *shape) : data_(NULL), own_data(true) { Resize(shape); } + + /// Copy constructor. + ArrayND(const ArrayND &b) : data_(NULL), own_data(true) { + ResizeLike(b); + std::memcpy(Data(), b.Data(), sizeof(T) * Size()); + } + + ArrayND(int s0) : data_(NULL), own_data(true) { Resize(s0); } + ArrayND(int s0, int s1) : data_(NULL), own_data(true) { Resize(s0, s1); } + ArrayND(int s0, int s1, int s2) : data_(NULL), own_data(true) { Resize(s0, s1, s2); } + + ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data(false) { Resize(s0, s1, s2); } + + /// Destructor deletes pixel data. + ~ArrayND() { + delete [] data_; + } + + /// Assignation copies pixel data. + ArrayND &operator=(const ArrayND &b) { + assert(this != &b); + ResizeLike(b); + std::memcpy(Data(), b.Data(), sizeof(T) * Size()); + return *this; + } + + const Index &Shapes() const { + return shape_; + } + + const Index &Strides() const { + return strides_; + } + + /// Create an array of shape s. + void Resize(const Index &new_shape) { + if (data_ != NULL && shape_ == new_shape) { + // Don't bother realloacting if the shapes match. + return; + } + shape_.Reset(new_shape); + strides_(N - 1) = 1; + for (int i = N - 1; i > 0; --i) { + strides_(i - 1) = strides_(i) * shape_(i); + } + if(own_data) { + delete [] data_; + data_ = NULL; + if (Size() > 0) { + data_ = new T[Size()]; + } + } + } + + template + void ResizeLike(const ArrayND &other) { + Resize(other.Shape()); + } + + /// Resizes the array to shape s. All data is lost. + void Resize(const int *new_shape_array) { + Resize(Index(new_shape_array)); + } + + /// Resize a 1D array to length s0. + void Resize(int s0) { + assert(N == 1); + int shape[] = {s0}; + Resize(shape); + } + + /// Resize a 2D array to shape (s0,s1). + void Resize(int s0, int s1) { + int shape[N] = {s0, s1}; + for (int i = 2; i < N; ++i) { + shape[i] = 1; + } + Resize(shape); + } + + // Match Eigen2's API. + void resize(int rows, int cols) { + Resize(rows, cols); + } + + /// Resize a 3D array to shape (s0,s1,s2). + void Resize(int s0, int s1, int s2) { + assert(N == 3); + int shape[] = {s0,s1,s2}; + Resize(shape); + } + + template + void CopyFrom(const ArrayND &other) { + ResizeLike(other); + T *data = Data(); + const D *other_data = other.Data(); + for (int i = 0; i < Size(); ++i) { + data[i] = T(other_data[i]); + } + } + + void Fill(T value) { + for (int i = 0; i < Size(); ++i) { + Data()[i] = value; + } + } + + // Match Eigen's API. + void fill(T value) { + for (int i = 0; i < Size(); ++i) { + Data()[i] = value; + } + } + + /// Return a tuple containing the length of each axis. + const Index &Shape() const { + return shape_; + } + + /// Return the length of an axis. + int Shape(int axis) const { + return shape_(axis); + } + + /// Return the distance between neighboring elements along axis. + int Stride(int axis) const { + return strides_(axis); + } + + /// Return the number of elements of the array. + int Size() const { + int size = 1; + for (int i = 0; i < N; ++i) + size *= Shape(i); + return size; + } + + /// Return the total amount of memory used by the array. + int MemorySizeInBytes() const { + return sizeof(*this) + Size() * sizeof(T); + } + + /// Pointer to the first element of the array. + T *Data() { return data_; } + + /// Constant pointer to the first element of the array. + const T *Data() const { return data_; } + + /// Distance between the first element and the element at position index. + int Offset(const Index &index) const { + int offset = 0; + for (int i = 0; i < N; ++i) + offset += index(i) * Stride(i); + return offset; + } + + /// 1D specialization. + int Offset(int i0) const { + assert(N == 1); + return i0 * Stride(0); + } + + /// 2D specialization. + int Offset(int i0, int i1) const { + assert(N == 2); + return i0 * Stride(0) + i1 * Stride(1); + } + + /// 3D specialization. + int Offset(int i0, int i1, int i2) const { + assert(N == 3); + return i0 * Stride(0) + i1 * Stride(1) + i2 * Stride(2); + } + + /// Return a reference to the element at position index. + T &operator()(const Index &index) { + // TODO(pau) Boundary checking in debug mode. + return *( Data() + Offset(index) ); + } + + /// 1D specialization. + T &operator()(int i0) { + return *( Data() + Offset(i0) ); + } + + /// 2D specialization. + T &operator()(int i0, int i1) { + assert(0 <= i0 && i0 < Shape(0)); + assert(0 <= i1 && i1 < Shape(1)); + return *( Data() + Offset(i0,i1) ); + } + + /// 3D specialization. + T &operator()(int i0, int i1, int i2) { + assert(0 <= i0 && i0 < Shape(0)); + assert(0 <= i1 && i1 < Shape(1)); + assert(0 <= i2 && i2 < Shape(2)); + return *( Data() + Offset(i0,i1,i2) ); + } + + /// Return a constant reference to the element at position index. + const T &operator()(const Index &index) const { + return *( Data() + Offset(index) ); + } + + /// 1D specialization. + const T &operator()(int i0) const { + return *( Data() + Offset(i0) ); + } + + /// 2D specialization. + const T &operator()(int i0, int i1) const { + assert(0 <= i0 && i0 < Shape(0)); + assert(0 <= i1 && i1 < Shape(1)); + return *( Data() + Offset(i0,i1) ); + } + + /// 3D specialization. + const T &operator()(int i0, int i1, int i2) const { + return *( Data() + Offset(i0,i1,i2) ); + } + + /// True if index is inside array. + bool Contains(const Index &index) const { + for (int i = 0; i < N; ++i) + if (index(i) < 0 || index(i) >= Shape(i)) + return false; + return true; + } + + /// 1D specialization. + bool Contains(int i0) const { + return 0 <= i0 && i0 < Shape(0); + } + + /// 2D specialization. + bool Contains(int i0, int i1) const { + return 0 <= i0 && i0 < Shape(0) + && 0 <= i1 && i1 < Shape(1); + } + + /// 3D specialization. + bool Contains(int i0, int i1, int i2) const { + return 0 <= i0 && i0 < Shape(0) + && 0 <= i1 && i1 < Shape(1) + && 0 <= i2 && i2 < Shape(2); + } + + bool operator==(const ArrayND &other) const { + if (shape_ != other.shape_) return false; + if (strides_ != other.strides_) return false; + for (int i = 0; i < Size(); ++i) { + if (this->Data()[i] != other.Data()[i]) + return false; + } + return true; + } + + bool operator!=(const ArrayND &other) const { + return !(*this == other); + } + + ArrayND operator*(const ArrayND &other) const { + assert(Shape() = other.Shape()); + ArrayND res; + res.ResizeLike(*this); + for (int i = 0; i < res.Size(); ++i) { + res.Data()[i] = Data()[i] * other.Data()[i]; + } + return res; + } + + protected: + /// The number of element in each dimension. + Index shape_; + + /// How to jump to neighbors in each dimension. + Index strides_; + + /// Pointer to the first element of the array. + T *data_; + + /// Flag if this Array either own or reference the data + bool own_data; +}; + +/// 3D array (row, column, channel). +template +class Array3D : public ArrayND { + typedef ArrayND Base; + public: + Array3D() + : Base() { + } + Array3D(int height, int width, int depth=1) + : Base(height, width, depth) { + } + Array3D(T* data, int height, int width, int depth=1) + : Base(data, height, width, depth) { + } + + void Resize(int height, int width, int depth=1) { + Base::Resize(height, width, depth); + } + + int Height() const { + return Base::Shape(0); + } + int Width() const { + return Base::Shape(1); + } + int Depth() const { + return Base::Shape(2); + } + + // Match Eigen2's API so that Array3D's and Mat*'s can work together via + // template magic. + int rows() const { return Height(); } + int cols() const { return Width(); } + int depth() const { return Depth(); } + + int Get_Step() const { return Width()*Depth(); } + + /// Enable accessing with 2 indices for grayscale images. + T &operator()(int i0, int i1, int i2 = 0) { + assert(0 <= i0 && i0 < Height()); + assert(0 <= i1 && i1 < Width()); + return Base::operator()(i0,i1,i2); + } + const T &operator()(int i0, int i1, int i2 = 0) const { + assert(0 <= i0 && i0 < Height()); + assert(0 <= i1 && i1 < Width()); + return Base::operator()(i0,i1,i2); + } +}; + +typedef Array3D Array3Du; +typedef Array3D Array3Dui; +typedef Array3D Array3Di; +typedef Array3D Array3Df; +typedef Array3D Array3Ds; + +void SplitChannels(const Array3Df &input, + Array3Df *channel0, + Array3Df *channel1, + Array3Df *channel2); + +void PrintArray(const Array3Df &array); + +/** Convert a float array into a byte array by scaling values by 255* (max-min). + * where max and min are automatically detected + * (if automatic_range_detection = true) + * \note and TODO this automatic detection only works when the image contains + * at least one pixel of both bounds. + **/ +void FloatArrayToScaledByteArray(const Array3Df &float_array, + Array3Du *byte_array, + bool automatic_range_detection = false); + +//! Convert a byte array into a float array by dividing values by 255. +void ByteArrayToScaledFloatArray(const Array3Du &byte_array, + Array3Df *float_array); + +template +void MultiplyElements( const AArrayType &a, + const BArrayType &b, + CArrayType *c ) { + // This function does an element-wise multiply between + // the two Arrays A and B, and stores the result in C. + // A and B must have the same dimensions. + assert( a.Shape() == b.Shape() ); + c->ResizeLike(a); + + // To perform the multiplcation, a "current" index into the N-dimensions of + // the A and B matrix specifies which elements are being multiplied. + typename CArrayType::Index index; + + // The index starts at the maximum value for each dimension + const typename CArrayType::Index& cShape = c->Shape(); + for ( int i = 0; i < CArrayType::Index::SIZE; ++i ) + index(i) = cShape(i) - 1; + + // After each multiplication, the highest-dimensional index is reduced. + // if this reduces it less than zero, it resets to its maximum value + // and decrements the index of the next lower dimension. + // This ripple-action continues until the entire new array has been + // calculated, indicated by dimension zero having a negative index. + while ( index(0) >= 0 ) { + (*c)(index) = a(index) * b(index); + + int dimension = CArrayType::Index::SIZE - 1; + index(dimension) = index(dimension) - 1; + while ( dimension > 0 && index(dimension) < 0 ) { + index(dimension) = cShape(dimension) - 1; + index(dimension - 1) = index(dimension - 1) - 1; + --dimension; + } + } +} + +template +void MultiplyElements(const ArrayND &a, + const ArrayND &b, + ArrayND *c) { + // Specialization for N==3 + c->ResizeLike(a); + assert(a.Shape(0) == b.Shape(0)); + assert(a.Shape(1) == b.Shape(1)); + assert(a.Shape(2) == b.Shape(2)); + for (int i = 0; i < a.Shape(0); ++i) { + for (int j = 0; j < a.Shape(1); ++j) { + for (int k = 0; k < a.Shape(2); ++k) { + (*c)(i, j, k) = TC(a(i, j, k) * b(i, j, k)); + } + } + } +} + + +} // namespace libmv + +#endif // LIBMV_IMAGE_ARRAY_ND_H diff --git a/extern/libmv/libmv/image/convolve.cc b/extern/libmv/libmv/image/convolve.cc new file mode 100644 index 00000000000..be73a1a3263 --- /dev/null +++ b/extern/libmv/libmv/image/convolve.cc @@ -0,0 +1,305 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/image/image.h" +#include "libmv/image/convolve.h" + +namespace libmv { + +// Compute a Gaussian kernel and derivative, such that you can take the +// derivative of an image by convolving with the kernel horizontally then the +// derivative vertically to get (eg) the y derivative. +void ComputeGaussianKernel(double sigma, Vec *kernel, Vec *derivative) { + assert(sigma >= 0.0); + + // 0.004 implies a 3 pixel kernel with 1 pixel sigma. + const float truncation_factor = 0.004f; + + // Calculate the kernel size based on sigma such that it is odd. + float precisehalfwidth = GaussianInversePositive(truncation_factor, sigma); + int width = lround(2*precisehalfwidth); + if (width % 2 == 0) { + width++; + } + // Calculate the gaussian kernel and its derivative. + kernel->resize(width); + derivative->resize(width); + kernel->setZero(); + derivative->setZero(); + int halfwidth = width / 2; + for (int i = -halfwidth; i <= halfwidth; ++i) { + (*kernel)(i + halfwidth) = Gaussian(i, sigma); + (*derivative)(i + halfwidth) = GaussianDerivative(i, sigma); + } + // Since images should not get brighter or darker, normalize. + NormalizeL1(kernel); + + // Normalize the derivative differently. See + // www.cs.duke.edu/courses/spring03/cps296.1/handouts/Image%20Processing.pdf + double factor = 0.; + for (int i = -halfwidth; i <= halfwidth; ++i) { + factor -= i*(*derivative)(i+halfwidth); + } + *derivative /= factor; +} + +template +void FastConvolve(const Vec &kernel, int width, int height, + const float* src, int src_stride, int src_line_stride, + float* dst, int dst_stride) { + double coefficients[2 * size + 1]; + for (int k = 0; k < 2 * size + 1; ++k) { + coefficients[k] = kernel(2 * size - k); + } + // Fast path: if the kernel has a certain size, use the constant sized loops. + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + double sum = 0; + for (int k = -size; k <= size; ++k) { + if (vertical) { + if (y + k >= 0 && y + k < height) { + sum += src[k * src_line_stride] * coefficients[k + size]; + } + } else { + if (x + k >= 0 && x + k < width) { + sum += src[k * src_stride] * coefficients[k + size]; + } + } + } + dst[0] = static_cast(sum); + src += src_stride; + dst += dst_stride; + } + } +} + +template +void Convolve(const Array3Df &in, + const Vec &kernel, + Array3Df *out_pointer, + int plane) { + int width = in.Width(); + int height = in.Height(); + Array3Df &out = *out_pointer; + if (plane == -1) { + out.ResizeLike(in); + plane = 0; + } + + assert(kernel.size() % 2 == 1); + assert(&in != out_pointer); + + int src_line_stride = in.Stride(0); + int src_stride = in.Stride(1); + int dst_stride = out.Stride(1); + const float* src = in.Data(); + float* dst = out.Data() + plane; + + // Use a dispatch table to make most convolutions used in practice use the + // fast path. + int half_width = kernel.size() / 2; + switch (half_width) { +#define static_convolution( size ) case size: \ + FastConvolve(kernel, width, height, src, src_stride, \ + src_line_stride, dst, dst_stride); break; + static_convolution(1) + static_convolution(2) + static_convolution(3) + static_convolution(4) + static_convolution(5) + static_convolution(6) + static_convolution(7) +#undef static_convolution + default: + int dynamic_size = kernel.size() / 2; + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + double sum = 0; + // Slow path: this loop cannot be unrolled. + for (int k = -dynamic_size; k <= dynamic_size; ++k) { + if(vertical) { + if (y + k >= 0 && y + k < height) { + sum += src[k * src_line_stride] * kernel(2 * dynamic_size - (k + dynamic_size)); + } + } else { + if (x + k >= 0 && x + k < width) { + sum += src[k * src_stride] * kernel(2 * dynamic_size - (k + dynamic_size)); + } + } + } + dst[0] = static_cast(sum); + src += src_stride; + dst += dst_stride; + } + } + } +} + +void ConvolveHorizontal(const Array3Df &in, + const Vec &kernel, + Array3Df *out_pointer, + int plane) { + Convolve(in, kernel, out_pointer, plane); +} + +void ConvolveVertical(const Array3Df &in, + const Vec &kernel, + Array3Df *out_pointer, + int plane) { + Convolve(in, kernel, out_pointer, plane); +} + +void ConvolveGaussian(const Array3Df &in, + double sigma, + Array3Df *out_pointer) { + Vec kernel, derivative; + ComputeGaussianKernel(sigma, &kernel, &derivative); + + Array3Df tmp; + ConvolveVertical(in, kernel, &tmp); + ConvolveHorizontal(tmp, kernel, out_pointer); +} + +void BlurredImageAndDerivatives(const Array3Df &in, + double sigma, + Array3Df *blurred_image, + Array3Df *gradient_x, + Array3Df *gradient_y) { + Vec kernel, derivative; + ComputeGaussianKernel(sigma, &kernel, &derivative); + Array3Df tmp; + + // Compute convolved image. + ConvolveVertical(in, kernel, &tmp); + ConvolveHorizontal(tmp, kernel, blurred_image); + + // Compute first derivative in x (reusing vertical convolution above). + ConvolveHorizontal(tmp, derivative, gradient_x); + + // Compute first derivative in y. + ConvolveHorizontal(in, kernel, &tmp); + ConvolveVertical(tmp, derivative, gradient_y); +} + +// Compute the gaussian blur of an image and the derivatives of the blurred +// image, and store the results in three channels. Since the blurred value and +// gradients are closer in memory, this leads to better performance if all +// three values are needed at the same time. +void BlurredImageAndDerivativesChannels(const Array3Df &in, + double sigma, + Array3Df *blurred_and_gradxy) { + assert(in.Depth() == 1); + + Vec kernel, derivative; + ComputeGaussianKernel(sigma, &kernel, &derivative); + + // Compute convolved image. + Array3Df tmp; + ConvolveVertical(in, kernel, &tmp); + blurred_and_gradxy->Resize(in.Height(), in.Width(), 3); + ConvolveHorizontal(tmp, kernel, blurred_and_gradxy, 0); + + // Compute first derivative in x. + ConvolveHorizontal(tmp, derivative, blurred_and_gradxy, 1); + + // Compute first derivative in y. + ConvolveHorizontal(in, kernel, &tmp); + ConvolveVertical(tmp, derivative, blurred_and_gradxy, 2); +} + +void BoxFilterHorizontal(const Array3Df &in, + int window_size, + Array3Df *out_pointer) { + Array3Df &out = *out_pointer; + out.ResizeLike(in); + int half_width = (window_size - 1) / 2; + + for (int k = 0; k < in.Depth(); ++k) { + for (int i=0; i + +#include "libmv/image/array_nd.h" + +namespace libmv { + +typedef Array3Du ByteImage; // For backwards compatibility. +typedef Array3Df FloatImage; + +// Type added only to manage special 2D array for feature detection +typedef Array3Di IntImage; +typedef Array3Ds ShortImage; + +// An image class that is a thin wrapper around Array3D's of various types. +// TODO(keir): Decide if we should add reference counting semantics... Maybe it +// is the best solution after all. +class Image { + public: + + // Create an image from an array. The image takes ownership of the array. + Image(Array3Du *array) : array_type_(BYTE), array_(array) {} + Image(Array3Df *array) : array_type_(FLOAT), array_(array) {} + + Image(const Image &img): array_type_(NONE), array_(NULL) { + *this = img; + } + + // Underlying data type. + enum DataType { + NONE, + BYTE, + FLOAT, + INT, + SHORT, + }; + + // Size in bytes that the image takes in memory. + int MemorySizeInBytes() { + int size; + switch (array_type_) + { + case BYTE: + size = reinterpret_cast(array_)->MemorySizeInBytes(); + break; + case FLOAT: + size = reinterpret_cast(array_)->MemorySizeInBytes(); + break; + case INT: + size = reinterpret_cast(array_)->MemorySizeInBytes(); + break; + case SHORT: + size = reinterpret_cast(array_)->MemorySizeInBytes(); + break; + default : + size = 0; + assert(0); + } + size += sizeof(*this); + return size; + } + + ~Image() { + switch (array_type_) + { + case BYTE: + delete reinterpret_cast(array_); + + break; + case FLOAT: + delete reinterpret_cast(array_); + + break; + case INT: + delete reinterpret_cast(array_); + + break; + case SHORT: + delete reinterpret_cast(array_); + + break; + default: + assert(0); + } + } + + Image& operator= (const Image& f) { + if (this != &f) { + array_type_ = f.array_type_; + switch (array_type_) + { + case BYTE: + delete reinterpret_cast(array_); + array_ = new Array3Du( *(Array3Du *)f.array_); + break; + case FLOAT: + delete reinterpret_cast(array_); + array_ = new Array3Df( *(Array3Df *)f.array_); + break; + case INT: + delete reinterpret_cast(array_); + array_ = new Array3Di( *(Array3Di *)f.array_); + break; + case SHORT: + delete reinterpret_cast(array_); + array_ = new Array3Ds( *(Array3Ds *)f.array_); + break; + default: + assert(0); + } + } + return *this; + } + + Array3Du *AsArray3Du() const { + if (array_type_ == BYTE) { + return reinterpret_cast(array_); + } + return NULL; + } + + Array3Df *AsArray3Df() const { + if (array_type_ == FLOAT) { + return reinterpret_cast(array_); + } + return NULL; + } + + private: + DataType array_type_; + BaseArray *array_; +}; + +} // namespace libmv + +#endif // LIBMV_IMAGE_IMAGE_IMAGE_H diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h new file mode 100644 index 00000000000..cd361231b58 --- /dev/null +++ b/extern/libmv/libmv/image/sample.h @@ -0,0 +1,103 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_IMAGE_SAMPLE_H_ +#define LIBMV_IMAGE_SAMPLE_H_ + +#include "libmv/image/image.h" + +namespace libmv { + +/// Nearest neighbor interpolation. +template +inline T SampleNearest(const Array3D &image, + float y, float x, int v = 0) { + const int i = int(round(y)); + const int j = int(round(x)); + return image(i, j, v); +} + +static inline void LinearInitAxis(float fx, int width, + int *x1, int *x2, + float *dx1, float *dx2) { + const int ix = int(fx); + if (ix < 0) { + *x1 = 0; + *x2 = 0; + *dx1 = 1; + *dx2 = 0; + } else if (ix > width-2) { + *x1 = width-1; + *x2 = width-1; + *dx1 = 1; + *dx2 = 0; + } else { + *x1 = ix; + *x2 = *x1 + 1; + *dx1 = *x2 - fx; + *dx2 = 1 - *dx1; + } +} + +/// Linear interpolation. +template +inline T SampleLinear(const Array3D &image, float y, float x, int v = 0) { + int x1, y1, x2, y2; + float dx1, dy1, dx2, dy2; + + LinearInitAxis(y, image.Height(), &y1, &y2, &dy1, &dy2); + LinearInitAxis(x, image.Width(), &x1, &x2, &dx1, &dx2); + + const T im11 = image(y1, x1, v); + const T im12 = image(y1, x2, v); + const T im21 = image(y2, x1, v); + const T im22 = image(y2, x2, v); + + return T(dy1 * ( dx1 * im11 + dx2 * im12 ) + + dy2 * ( dx1 * im21 + dx2 * im22 )); +} + +// Downsample all channels by 2. If the image has odd width or height, the last +// row or column is ignored. +// FIXME(MatthiasF): this implementation shouldn't be in an interface file +inline void DownsampleChannelsBy2(const Array3Df &in, Array3Df *out) { + int height = in.Height() / 2; + int width = in.Width() / 2; + int depth = in.Depth(); + + out->Resize(height, width, depth); + + // 2x2 box filter downsampling. + for (int r = 0; r < height; ++r) { + for (int c = 0; c < width; ++c) { + for (int k = 0; k < depth; ++k) { + (*out)(r, c, k) = (in(2 * r, 2 * c, k) + + in(2 * r + 1, 2 * c, k) + + in(2 * r, 2 * c + 1, k) + + in(2 * r + 1, 2 * c + 1, k)) / 4.0f; + } + } + } + +} + +} // namespace libmv + +#endif // LIBMV_IMAGE_SAMPLE_H_ diff --git a/extern/libmv/libmv/image/tuple.h b/extern/libmv/libmv/image/tuple.h new file mode 100644 index 00000000000..79acc9579d0 --- /dev/null +++ b/extern/libmv/libmv/image/tuple.h @@ -0,0 +1,90 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_IMAGE_TUPLE_H +#define LIBMV_IMAGE_TUPLE_H + +#include + +namespace libmv { + +// A vector of elements with fixed lenght and deep copy semantics. +template +class Tuple { + public: + enum { SIZE = N }; + Tuple() {} + Tuple(T initial_value) { Reset(initial_value); } + + template + Tuple(D *values) { Reset(values); } + + template + Tuple(const Tuple &b) { Reset(b); } + + template + Tuple& operator=(const Tuple& b) { + Reset(b); + return *this; + } + + template + void Reset(const Tuple& b) { Reset(b.Data()); } + + template + void Reset(D *values) { + for(int i=0;i &other) const { + for (int i = 0; i < N; ++i) { + if ((*this)(i) != other(i)) { + return false; + } + } + return true; + } + bool operator!=(const Tuple &other) const { + return !(*this == other); + } + + private: + T data_[N]; +}; + +} // namespace libmv + +#endif // LIBMV_IMAGE_TUPLE_H diff --git a/extern/libmv/libmv/logging/logging.h b/extern/libmv/libmv/logging/logging.h new file mode 100644 index 00000000000..af86c4baa42 --- /dev/null +++ b/extern/libmv/libmv/logging/logging.h @@ -0,0 +1,31 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_LOGGING_LOGGING_H +#define LIBMV_LOGGING_LOGGING_H + +#include "glog/logging.h" + +#define LG LOG(INFO) +#define V0 LOG(INFO) +#define V1 LOG(INFO) +#define V2 LOG(INFO) + +#endif // LIBMV_LOGGING_LOGGING_H diff --git a/extern/libmv/libmv/multiview/conditioning.cc b/extern/libmv/libmv/multiview/conditioning.cc new file mode 100644 index 00000000000..20e3a88e6cb --- /dev/null +++ b/extern/libmv/libmv/multiview/conditioning.cc @@ -0,0 +1,99 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/projection.h" + +namespace libmv { + +// HZ 4.4.4 pag.109: Point conditioning (non isotropic) +void PreconditionerFromPoints(const Mat &points, Mat3 *T) { + Vec mean, variance; + MeanAndVarianceAlongRows(points, &mean, &variance); + + double xfactor = sqrt(2.0 / variance(0)); + double yfactor = sqrt(2.0 / variance(1)); + + // If variance is equal to 0.0 set scaling factor to identity. + // -> Else it will provide nan value (because division by 0). + if (variance(0) < 1e-8) + xfactor = mean(0) = 1.0; + if (variance(1) < 1e-8) + yfactor = mean(1) = 1.0; + + *T << xfactor, 0, -xfactor * mean(0), + 0, yfactor, -yfactor * mean(1), + 0, 0, 1; +} +// HZ 4.4.4 pag.107: Point conditioning (isotropic) +void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T) { + Vec mean, variance; + MeanAndVarianceAlongRows(points, &mean, &variance); + + double var_norm = variance.norm(); + double factor = sqrt(2.0 / var_norm); + + // If variance is equal to 0.0 set scaling factor to identity. + // -> Else it will provide nan value (because division by 0). + if (var_norm < 1e-8) { + factor = 1.0; + mean.setOnes(); + } + + *T << factor, 0, -factor * mean(0), + 0, factor, -factor * mean(1), + 0, 0, 1; +} + +void ApplyTransformationToPoints(const Mat &points, + const Mat3 &T, + Mat *transformed_points) { + int n = points.cols(); + transformed_points->resize(2,n); + Mat3X p(3, n); + EuclideanToHomogeneous(points, &p); + p = T * p; + HomogeneousToEuclidean(p, transformed_points); +} + +void NormalizePoints(const Mat &points, + Mat *normalized_points, + Mat3 *T) { + PreconditionerFromPoints(points, T); + ApplyTransformationToPoints(points, *T, normalized_points); +} + +void NormalizeIsotropicPoints(const Mat &points, + Mat *normalized_points, + Mat3 *T) { + IsotropicPreconditionerFromPoints(points, T); + ApplyTransformationToPoints(points, *T, normalized_points); +} + +// Denormalize the results. See HZ page 109. +void UnnormalizerT::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) { + *H = T2.transpose() * (*H) * T1; +} + +void UnnormalizerI::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) { + *H = T2.inverse() * (*H) * T1; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/conditioning.h b/extern/libmv/libmv/multiview/conditioning.h new file mode 100644 index 00000000000..181d7485374 --- /dev/null +++ b/extern/libmv/libmv/multiview/conditioning.h @@ -0,0 +1,60 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_CONDITIONNING_H_ +#define LIBMV_MULTIVIEW_CONDITIONNING_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// Point conditioning (non isotropic) +void PreconditionerFromPoints(const Mat &points, Mat3 *T); +// Point conditioning (isotropic) +void IsotropicPreconditionerFromPoints(const Mat &points, Mat3 *T); + +void ApplyTransformationToPoints(const Mat &points, + const Mat3 &T, + Mat *transformed_points); + +void NormalizePoints(const Mat &points, + Mat *normalized_points, + Mat3 *T); + +void NormalizeIsotropicPoints(const Mat &points, + Mat *normalized_points, + Mat3 *T); + +/// Use inverse for unnormalize +struct UnnormalizerI { + // Denormalize the results. See HZ page 109. + static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H); +}; + +/// Use transpose for unnormalize +struct UnnormalizerT { + // Denormalize the results. See HZ page 109. + static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H); +}; + +} //namespace libmv + + +#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_ diff --git a/extern/libmv/libmv/multiview/euclidean_resection.cc b/extern/libmv/libmv/multiview/euclidean_resection.cc new file mode 100644 index 00000000000..6d918a1a8bc --- /dev/null +++ b/extern/libmv/libmv/multiview/euclidean_resection.cc @@ -0,0 +1,661 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include +#include + +#include +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/euclidean_resection.h" +#include "libmv/multiview/projection.h" + +namespace libmv { +namespace euclidean_resection { + +bool EuclideanResection(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t, + ResectionMethod method) { + switch (method) { + case RESECTION_ANSAR_DANIILIDIS: + EuclideanResectionAnsarDaniilidis(x_camera, X_world, R, t); + break; + case RESECTION_EPNP: + return EuclideanResectionEPnP(x_camera, X_world, R, t); + break; + default: + LOG(FATAL) << "Unknown resection method."; + } + return false; +} + +bool EuclideanResection(const Mat &x_image, + const Mat3X &X_world, + const Mat3 &K, + Mat3 *R, Vec3 *t, + ResectionMethod method) { + CHECK(x_image.rows() == 2 || x_image.rows() == 3) + << "Invalid size for x_image: " + << x_image.rows() << "x" << x_image.cols(); + + Mat2X x_camera; + if (x_image.rows() == 2) { + EuclideanToNormalizedCamera(x_image, K, &x_camera); + } else if (x_image.rows() == 3) { + HomogeneousToNormalizedCamera(x_image, K, &x_camera); + } + return EuclideanResection(x_camera, X_world, R, t, method); +} + +void AbsoluteOrientation(const Mat3X &X, + const Mat3X &Xp, + Mat3 *R, + Vec3 *t) { + int num_points = X.cols(); + Vec3 C = X.rowwise().sum() / num_points; // Centroid of X. + Vec3 Cp = Xp.rowwise().sum() / num_points; // Centroid of Xp. + + // Normalize the two point sets. + Mat3X Xn(3, num_points), Xpn(3, num_points); + for( int i = 0; i < num_points; ++i ){ + Xn.col(i) = X.col(i) - C; + Xpn.col(i) = Xp.col(i) - Cp; + } + + // Construct the N matrix (pg. 635). + double Sxx = Xn.row(0).dot(Xpn.row(0)); + double Syy = Xn.row(1).dot(Xpn.row(1)); + double Szz = Xn.row(2).dot(Xpn.row(2)); + double Sxy = Xn.row(0).dot(Xpn.row(1)); + double Syx = Xn.row(1).dot(Xpn.row(0)); + double Sxz = Xn.row(0).dot(Xpn.row(2)); + double Szx = Xn.row(2).dot(Xpn.row(0)); + double Syz = Xn.row(1).dot(Xpn.row(2)); + double Szy = Xn.row(2).dot(Xpn.row(1)); + + Mat4 N; + N << Sxx + Syy + Szz, Syz - Szy, Szx - Sxz, Sxy - Syx, + Syz - Szy, Sxx - Syy - Szz, Sxy + Syx, Szx + Sxz, + Szx - Sxz, Sxy + Syx, -Sxx + Syy - Szz, Syz + Szy, + Sxy - Syx, Szx + Sxz, Syz + Szy, -Sxx - Syy + Szz; + + // Find the unit quaternion q that maximizes qNq. It is the eigenvector + // corresponding to the lagest eigenvalue. + Vec4 q = N.jacobiSvd(Eigen::ComputeFullU).matrixU().col(0); + + // Retrieve the 3x3 rotation matrix. + Vec4 qq = q.array() * q.array(); + double q0q1 = q(0) * q(1); + double q0q2 = q(0) * q(2); + double q0q3 = q(0) * q(3); + double q1q2 = q(1) * q(2); + double q1q3 = q(1) * q(3); + double q2q3 = q(2) * q(3); + + (*R) << qq(0) + qq(1) - qq(2) - qq(3), + 2 * (q1q2 - q0q3), + 2 * (q1q3 + q0q2), + 2 * (q1q2+ q0q3), + qq(0) - qq(1) + qq(2) - qq(3), + 2 * (q2q3 - q0q1), + 2 * (q1q3 - q0q2), + 2 * (q2q3 + q0q1), + qq(0) - qq(1) - qq(2) + qq(3); + + // Fix the handedness of the R matrix. + if (R->determinant() < 0) { + R->row(2) = -R->row(2); + } + // Compute the final translation. + *t = Cp - *R * C; +} + +// Convert i and j indices of the original variables into their quadratic +// permutation single index. It follows that t_ij = t_ji. +static int IJToPointIndex(int i, int j, int num_points) { + // Always make sure that j is bigger than i. This handles t_ij = t_ji. + if (j < i) { + std::swap(i, j); + } + int idx; + int num_permutation_rows = num_points * (num_points - 1) / 2; + + // All t_ii's are located at the end of the t vector after all t_ij's. + if (j == i) { + idx = num_permutation_rows + i; + } else { + int offset = (num_points - i - 1) * (num_points - i) / 2; + idx = (num_permutation_rows - offset + j - i - 1); + } + return idx; +}; + +// Convert i and j indexes of the solution for lambda to their linear indexes. +static int IJToIndex(int i, int j, int num_lambda) { + if (j < i) { + std::swap(i, j); + } + int A = num_lambda * (num_lambda + 1) / 2; + int B = num_lambda - i; + int C = B * (B + 1) / 2; + int idx = A - C + j - i; + return idx; +}; + +static int Sign(double value) { + return (value < 0) ? -1 : 1; +}; + +// Organizes a square matrix into a single row constraint on the elements of +// Lambda to create the constraints in equation (5) in "Linear Pose Estimation +// from Points or Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. +// 5. +static Vec MatrixToConstraint(const Mat &A, + int num_k_columns, + int num_lambda) { + Vec C(num_k_columns); + C.setZero(); + int idx = 0; + for (int i = 0; i < num_lambda; ++i) { + for( int j = i; j < num_lambda; ++j) { + C(idx) = A(i, j); + if (i != j){ + C(idx) += A(j, i); + } + ++ idx; + } + } + return C; +} + +// Normalizes the columns of vectors. +static void NormalizeColumnVectors(Mat3X *vectors) { + int num_columns = vectors->cols(); + for (int i = 0; i < num_columns; ++i){ + vectors->col(i).normalize(); + } +} + +void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, + Vec3 *t) { + CHECK(x_camera.cols() == X_world.cols()); + CHECK(x_camera.cols() > 3); + + int num_points = x_camera.cols(); + + // Copy the normalized camera coords into 3 vectors and normalize them so + // that they are unit vectors from the camera center. + Mat3X x_camera_unit(3, num_points); + x_camera_unit.block(0, 0, 2, num_points) = x_camera; + x_camera_unit.row(2).setOnes(); + NormalizeColumnVectors(&x_camera_unit); + + int num_m_rows = num_points * (num_points - 1) / 2; + int num_tt_variables = num_points * (num_points + 1) / 2; + int num_m_columns = num_tt_variables + 1; + Mat M(num_m_columns, num_m_columns); + M.setZero(); + Matu ij_index(num_tt_variables, 2); + + // Create the constraint equations for the t_ij variables (7) and arrange + // them into the M matrix (8). Also store the initial (i, j) indices. + int row=0; + for (int i = 0; i < num_points; ++i) { + for (int j = i+1; j < num_points; ++j) { + M(row, row) = -2 * x_camera_unit.col(i).dot(x_camera_unit.col(j)); + M(row, num_m_rows + i) = x_camera_unit.col(i).dot(x_camera_unit.col(i)); + M(row, num_m_rows + j) = x_camera_unit.col(j).dot(x_camera_unit.col(j)); + Vec3 Xdiff = X_world.col(i) - X_world.col(j); + double center_to_point_distance = Xdiff.norm(); + M(row, num_m_columns - 1) = + - center_to_point_distance * center_to_point_distance; + ij_index(row, 0) = i; + ij_index(row, 1) = j; + ++row; + } + ij_index(i + num_m_rows, 0) = i; + ij_index(i + num_m_rows, 1) = i; + } + + int num_lambda = num_points + 1; // Dimension of the null space of M. + Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0, + num_m_rows, + num_m_columns, + num_lambda); + + // TODO(vess): The number of constraint equations in K (num_k_rows) must be + // (num_points + 1) * (num_points + 2)/2. This creates a performance issue + // for more than 4 points. It is fine for 4 points at the moment with 18 + // instead of 15 equations. + int num_k_rows = num_m_rows + num_points * + (num_points*(num_points-1)/2 - num_points+1); + int num_k_columns = num_lambda * (num_lambda + 1) / 2; + Mat K(num_k_rows, num_k_columns); + K.setZero(); + + // Construct the first part of the K matrix corresponding to (t_ii, t_jk) for + // i != j. + int counter_k_row = 0; + for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) { + for (int idx2 = 0; idx2 < num_m_rows; ++idx2) { + + unsigned int i = ij_index(idx1, 0); + unsigned int j = ij_index(idx2, 0); + unsigned int k = ij_index(idx2, 1); + + if( i != j && i != k ){ + int idx3 = IJToPointIndex(i, j, num_points); + int idx4 = IJToPointIndex(i, k, num_points); + + K.row(counter_k_row) = + MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)- + V.row(idx3).transpose() * V.row(idx4), + num_k_columns, + num_lambda); + ++counter_k_row; + } + } + } + + // Construct the second part of the K matrix corresponding to (t_ii,t_jk) for + // j==k. + for (int idx1 = num_m_rows; idx1 < num_tt_variables; ++idx1) { + for (int idx2 = idx1 + 1; idx2 < num_tt_variables; ++idx2) { + unsigned int i = ij_index(idx1, 0); + unsigned int j = ij_index(idx2, 0); + unsigned int k = ij_index(idx2, 1); + + int idx3 = IJToPointIndex(i, j, num_points); + int idx4 = IJToPointIndex(i, k, num_points); + + K.row(counter_k_row) = + MatrixToConstraint(V.row(idx1).transpose() * V.row(idx2)- + V.row(idx3).transpose() * V.row(idx4), + num_k_columns, + num_lambda); + ++counter_k_row; + } + } + Vec L_sq = K.jacobiSvd(Eigen::ComputeFullV).matrixV().col(num_k_columns - 1); + + // Pivot on the largest element for numerical stability. Afterwards recover + // the sign of the lambda solution. + double max_L_sq_value = fabs(L_sq(IJToIndex(0, 0, num_lambda))); + int max_L_sq_index = 1; + for (int i = 1; i < num_lambda; ++i) { + double abs_sq_value = fabs(L_sq(IJToIndex(i, i, num_lambda))); + if (max_L_sq_value < abs_sq_value) { + max_L_sq_value = abs_sq_value; + max_L_sq_index = i; + } + } + // Ensure positiveness of the largest value corresponding to lambda_ii. + L_sq = L_sq * Sign(L_sq(IJToIndex(max_L_sq_index, + max_L_sq_index, + num_lambda))); + + + Vec L(num_lambda); + L(max_L_sq_index) = sqrt(L_sq(IJToIndex(max_L_sq_index, + max_L_sq_index, + num_lambda))); + + for (int i = 0; i < num_lambda; ++i) { + if (i != max_L_sq_index) { + L(i) = L_sq(IJToIndex(max_L_sq_index, i, num_lambda)) / L(max_L_sq_index); + } + } + + // Correct the scale using the fact that the last constraint is equal to 1. + L = L / (V.row(num_m_columns - 1).dot(L)); + Vec X = V * L; + + // Recover the distances from the camera center to the 3D points Q. + Vec d(num_points); + d.setZero(); + for (int c_point = num_m_rows; c_point < num_tt_variables; ++c_point) { + d(c_point - num_m_rows) = sqrt(X(c_point)); + } + + // Create the 3D points in the camera system. + Mat X_cam(3, num_points); + for (int c_point = 0; c_point < num_points; ++c_point ) { + X_cam.col(c_point) = d(c_point) * x_camera_unit.col(c_point); + } + // Recover the camera translation and rotation. + AbsoluteOrientation(X_world, X_cam, R, t); +} + +// Selects 4 virtual control points using mean and PCA. +void SelectControlPoints(const Mat3X &X_world, + Mat *X_centered, + Mat34 *X_control_points) { + size_t num_points = X_world.cols(); + + // The first virtual control point, C0, is the centroid. + Vec mean, variance; + MeanAndVarianceAlongRows(X_world, &mean, &variance); + X_control_points->col(0) = mean; + + // Computes PCA + X_centered->resize (3, num_points); + for (size_t c = 0; c < num_points; c++) { + X_centered->col(c) = X_world.col (c) - mean; + } + Mat3 X_centered_sq = (*X_centered) * X_centered->transpose(); + Eigen::JacobiSVD X_centered_sq_svd(X_centered_sq, Eigen::ComputeFullU); + Vec3 w = X_centered_sq_svd.singularValues(); + Mat3 u = X_centered_sq_svd.matrixU(); + for (size_t c = 0; c < 3; c++) { + double k = sqrt (w (c) / num_points); + X_control_points->col (c + 1) = mean + k * u.col (c); + } +} + +// Computes the barycentric coordinates for all real points +void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, + const Mat34 &X_control_points, + Mat4X *alphas) { + size_t num_points = X_world_centered.cols(); + Mat3 C2 ; + for (size_t c = 1; c < 4; c++) { + C2.col(c-1) = X_control_points.col(c) - X_control_points.col(0); + } + + Mat3 C2inv = C2.inverse(); + Mat3X a = C2inv * X_world_centered; + + alphas->resize(4, num_points); + alphas->setZero(); + alphas->block(1, 0, 3, num_points) = a; + for (size_t c = 0; c < num_points; c++) { + (*alphas)(0, c) = 1.0 - alphas->col(c).sum(); + } +} + +// Estimates the coordinates of all real points in the camera coordinate frame +void ComputePointsCoordinatesInCameraFrame( + const Mat4X &alphas, + const Vec4 &betas, + const Eigen::Matrix &U, + Mat3X *X_camera) { + size_t num_points = alphas.cols(); + + // Estimates the control points in the camera reference frame. + Mat34 C2b; C2b.setZero(); + for (size_t cu = 0; cu < 4; cu++) { + for (size_t c = 0; c < 4; c++) { + C2b.col(c) += betas(cu) * U.block(11 - cu, c * 3, 1, 3).transpose(); + } + } + + // Estimates the 3D points in the camera reference frame + X_camera->resize(3, num_points); + for (size_t c = 0; c < num_points; c++) { + X_camera->col(c) = C2b * alphas.col(c); + } + + // Check the sign of the z coordinate of the points (should be positive) + uint num_z_neg = 0; + for (size_t i = 0; i < X_camera->cols(); ++i) { + if ((*X_camera)(2,i) < 0) { + num_z_neg++; + } + } + + // If more than 50% of z are negative, we change the signs + if (num_z_neg > 0.5 * X_camera->cols()) { + C2b = -C2b; + *X_camera = -(*X_camera); + } +} + +bool EuclideanResectionEPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t) { + CHECK(x_camera.cols() == X_world.cols()); + CHECK(x_camera.cols() > 3); + size_t num_points = X_world.cols(); + + // Select the control points. + Mat34 X_control_points; + Mat X_centered; + SelectControlPoints(X_world, &X_centered, &X_control_points); + + // Compute the barycentric coordinates. + Mat4X alphas(4, num_points); + ComputeBarycentricCoordinates(X_centered, X_control_points, &alphas); + + // Estimates the M matrix with the barycentric coordinates + Mat M(2 * num_points, 12); + Eigen::Matrix sub_M; + for (size_t c = 0; c < num_points; c++) { + double a0 = alphas(0, c); + double a1 = alphas(1, c); + double a2 = alphas(2, c); + double a3 = alphas(3, c); + double ui = x_camera(0, c); + double vi = x_camera(1, c); + M.block(2*c, 0, 2, 12) << a0, 0, + a0*(-ui), a1, 0, + a1*(-ui), a2, 0, + a2*(-ui), a3, 0, + a3*(-ui), 0, + a0, a0*(-vi), 0, + a1, a1*(-vi), 0, + a2, a2*(-vi), 0, + a3, a3*(-vi); + } + + // TODO(julien): Avoid the transpose by rewriting the u2.block() calls. + Eigen::JacobiSVD MtMsvd(M.transpose()*M, Eigen::ComputeFullU); + Eigen::Matrix u2 = MtMsvd.matrixU().transpose(); + + // Estimate the L matrix. + Eigen::Matrix dv1; + Eigen::Matrix dv2; + Eigen::Matrix dv3; + Eigen::Matrix dv4; + + dv1.row(0) = u2.block(11, 0, 1, 3) - u2.block(11, 3, 1, 3); + dv1.row(1) = u2.block(11, 0, 1, 3) - u2.block(11, 6, 1, 3); + dv1.row(2) = u2.block(11, 0, 1, 3) - u2.block(11, 9, 1, 3); + dv1.row(3) = u2.block(11, 3, 1, 3) - u2.block(11, 6, 1, 3); + dv1.row(4) = u2.block(11, 3, 1, 3) - u2.block(11, 9, 1, 3); + dv1.row(5) = u2.block(11, 6, 1, 3) - u2.block(11, 9, 1, 3); + dv2.row(0) = u2.block(10, 0, 1, 3) - u2.block(10, 3, 1, 3); + dv2.row(1) = u2.block(10, 0, 1, 3) - u2.block(10, 6, 1, 3); + dv2.row(2) = u2.block(10, 0, 1, 3) - u2.block(10, 9, 1, 3); + dv2.row(3) = u2.block(10, 3, 1, 3) - u2.block(10, 6, 1, 3); + dv2.row(4) = u2.block(10, 3, 1, 3) - u2.block(10, 9, 1, 3); + dv2.row(5) = u2.block(10, 6, 1, 3) - u2.block(10, 9, 1, 3); + dv3.row(0) = u2.block( 9, 0, 1, 3) - u2.block( 9, 3, 1, 3); + dv3.row(1) = u2.block( 9, 0, 1, 3) - u2.block( 9, 6, 1, 3); + dv3.row(2) = u2.block( 9, 0, 1, 3) - u2.block( 9, 9, 1, 3); + dv3.row(3) = u2.block( 9, 3, 1, 3) - u2.block( 9, 6, 1, 3); + dv3.row(4) = u2.block( 9, 3, 1, 3) - u2.block( 9, 9, 1, 3); + dv3.row(5) = u2.block( 9, 6, 1, 3) - u2.block( 9, 9, 1, 3); + dv4.row(0) = u2.block( 8, 0, 1, 3) - u2.block( 8, 3, 1, 3); + dv4.row(1) = u2.block( 8, 0, 1, 3) - u2.block( 8, 6, 1, 3); + dv4.row(2) = u2.block( 8, 0, 1, 3) - u2.block( 8, 9, 1, 3); + dv4.row(3) = u2.block( 8, 3, 1, 3) - u2.block( 8, 6, 1, 3); + dv4.row(4) = u2.block( 8, 3, 1, 3) - u2.block( 8, 9, 1, 3); + dv4.row(5) = u2.block( 8, 6, 1, 3) - u2.block( 8, 9, 1, 3); + + Eigen::Matrix L; + for (size_t r = 0; r < 6; r++) { + L.row(r) << dv1.row(r).dot(dv1.row(r)), + 2.0 * dv1.row(r).dot(dv2.row(r)), + dv2.row(r).dot(dv2.row(r)), + 2.0 * dv1.row(r).dot(dv3.row(r)), + 2.0 * dv2.row(r).dot(dv3.row(r)), + dv3.row(r).dot(dv3.row(r)), + 2.0 * dv1.row(r).dot(dv4.row(r)), + 2.0 * dv2.row(r).dot(dv4.row(r)), + 2.0 * dv3.row(r).dot(dv4.row(r)), + dv4.row(r).dot(dv4.row(r)); + } + Vec6 rho; + rho << (X_control_points.col(0) - X_control_points.col(1)).squaredNorm(), + (X_control_points.col(0) - X_control_points.col(2)).squaredNorm(), + (X_control_points.col(0) - X_control_points.col(3)).squaredNorm(), + (X_control_points.col(1) - X_control_points.col(2)).squaredNorm(), + (X_control_points.col(1) - X_control_points.col(3)).squaredNorm(), + (X_control_points.col(2) - X_control_points.col(3)).squaredNorm(); + + // There are three possible solutions based on the three approximations of L + // (betas). Below, each one is solved for then the best one is chosen. + Mat3X X_camera; + Mat3 K; K.setIdentity(); + vector Rs(3); + vector ts(3); + Vec rmse(3); + + // TODO(julien): Document where the "1e-3" magical constant comes from below. + + // Find the first possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_1 = [b00 b01 b02 b03] + Vec4 betas = Vec4::Zero(); + Eigen::Matrix l_6x4; + for (size_t r = 0; r < 6; r++) { + l_6x4.row(r) << L(r, 0), L(r, 1), L(r, 3), L(r, 6); + } + Eigen::JacobiSVD svd_of_l4(l_6x4, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec4 b4 = svd_of_l4.solve(rho); + if ((l_6x4 * b4).isApprox(rho, 1e-3)) { + if (b4(0) < 0) { + b4 = -b4; + } + b4(0) = std::sqrt(b4(0)); + betas << b4(0), b4(1) / b4(0), b4(2) / b4(0), b4(3) / b4(0); + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[0], &ts[0]); + rmse(0) = RootMeanSquareError(x_camera, X_world, K, Rs[0], ts[0]); + } else { + LOG(ERROR) << "First approximation of beta not good enough."; + ts[0].setZero(); + rmse(0) = std::numeric_limits::max(); + } + + // Find the second possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_2 = [b00 b01 b11] + betas.setZero(); + Eigen::Matrix l_6x3; + l_6x3 = L.block(0, 0, 6, 3); + Eigen::JacobiSVD svdOfL3(l_6x3, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 b3 = svdOfL3.solve(rho); + VLOG(2) << " rho = " << rho; + VLOG(2) << " l_6x3 * b3 = " << l_6x3 * b3; + if ((l_6x3 * b3).isApprox(rho, 1e-3)) { + if (b3(0) < 0) { + betas(0) = std::sqrt(-b3(0)); + betas(1) = (b3(2) < 0) ? std::sqrt(-b3(2)) : 0; + } else { + betas(0) = std::sqrt(b3(0)); + betas(1) = (b3(2) > 0) ? std::sqrt(b3(2)) : 0; + } + if (b3(1) < 0) { + betas(0) = -betas(0); + } + betas(2) = 0; + betas(3) = 0; + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[1], &ts[1]); + rmse(1) = RootMeanSquareError(x_camera, X_world, K, Rs[1], ts[1]); + } else { + LOG(ERROR) << "Second approximation of beta not good enough."; + ts[1].setZero(); + rmse(1) = std::numeric_limits::max(); + } + + // Find the third possible solution for R, t corresponding to: + // Betas = [b00 b01 b11 b02 b12 b22 b03 b13 b23 b33] + // Betas_approx_3 = [b00 b01 b11 b02 b12] + betas.setZero(); + Eigen::Matrix l_6x5; + l_6x5 = L.block(0, 0, 6, 5); + Eigen::JacobiSVD svdOfL5(l_6x5, + Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec5 b5 = svdOfL5.solve(rho); + if ((l_6x5 * b5).isApprox(rho, 1e-3)) { + if (b5(0) < 0) { + betas(0) = std::sqrt(-b5(0)); + if (b5(2) < 0) { + betas(1) = std::sqrt(-b5(2)); + } else { + b5(2) = 0; + } + } else { + betas(0) = std::sqrt(b5(0)); + if (b5(2) > 0) { + betas(1) = std::sqrt(b5(2)); + } else { + b5(2) = 0; + } + } + if (b5(1) < 0) { + betas(0) = -betas(0); + } + betas(2) = b5(3) / betas(0); + betas(3) = 0; + ComputePointsCoordinatesInCameraFrame(alphas, betas, u2, &X_camera); + AbsoluteOrientation(X_world, X_camera, &Rs[2], &ts[2]); + rmse(2) = RootMeanSquareError(x_camera, X_world, K, Rs[2], ts[2]); + } else { + LOG(ERROR) << "Third approximation of beta not good enough."; + ts[2].setZero(); + rmse(2) = std::numeric_limits::max(); + } + + // Finally, with all three solutions, select the (R, t) with the best RMSE. + VLOG(2) << "RMSE for solution 0: " << rmse(0); + VLOG(2) << "RMSE for solution 1: " << rmse(0); + VLOG(2) << "RMSE for solution 2: " << rmse(0); + size_t n = 0; + if (rmse(1) < rmse(0)) { + n = 1; + } + if (rmse(2) < rmse(n)) { + n = 2; + } + if (rmse(n) == std::numeric_limits::max()) { + LOG(ERROR) << "All three possibilities failed. Reporting failure."; + return false; + } + + VLOG(1) << "RMSE for best solution #" << n << ": " << rmse(n); + *R = Rs[n]; + *t = ts[n]; + + // TODO(julien): Improve the solutions with non-linear refinement. + return true; +} + +} // namespace resection +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/euclidean_resection.h b/extern/libmv/libmv/multiview/euclidean_resection.h new file mode 100644 index 00000000000..08fa3d90bd3 --- /dev/null +++ b/extern/libmv/libmv/multiview/euclidean_resection.h @@ -0,0 +1,124 @@ +// Copyright (c) 2010 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ +#define LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ + +#include "libmv/numeric/numeric.h" +#include "libmv/multiview/projection.h" + +namespace libmv { +namespace euclidean_resection { + +enum ResectionMethod { + RESECTION_ANSAR_DANIILIDIS, + RESECTION_EPNP, +}; + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera + * from 4 or more 3D points and their normalized images. + * + * \param x_camera Image points in normalized camera coordinates e.g. x_camera + * = inv(K) * x_image. + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * \param method The resection method to use. + */ +bool EuclideanResection(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t, + ResectionMethod method = RESECTION_EPNP); + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera + * from 4 or more 3D points and their images. + * + * \param x_image Image points in non-normalized image coordinates. The + * coordates are laid out one per row. The matrix can be Nx2 + * or Nx3 for euclidean or homogenous 2D coordinates. + * \param X_world 3D points in the world coordinate system + * \param K Intrinsic parameters camera matrix + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * \param method Resection method + */ +bool EuclideanResection(const Mat &x_image, + const Mat3X &X_world, + const Mat3 &K, + Mat3 *R, Vec3 *t, + ResectionMethod method = RESECTION_EPNP); + +/** + * The absolute orientation algorithm recovers the transformation between a set + * of 3D points, X and Xp such that: + * + * Xp = R*X + t + * + * The recovery of the absolute orientation is implemented after this article: + * Horn, Hilden, "Closed-form solution of absolute orientation using + * orthonormal matrices" + */ +void AbsoluteOrientation(const Mat3X &X, + const Mat3X &Xp, + Mat3 *R, + Vec3 *t); + +/** + * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or + * more 3D points and their images. + * + * \param x_camera Image points in normalized camera coordinates, e.g. + * x_camera=inv(K)*x_image + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * + * This is the algorithm described in: "Linear Pose Estimation from Points or + * Lines", by Ansar, A. and Daniilidis, PAMI 2003. vol. 25, no. 5. + */ +void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t); +/** + * Computes the extrinsic parameters, R and t for a calibrated camera from 4 or + * more 3D points and their images. + * + * \param x_camera Image points in normalized camera coordinates, + * e.g. x_camera = inv(K) * x_image + * \param X_world 3D points in the world coordinate system + * \param R Solution for the camera rotation matrix + * \param t Solution for the camera translation vector + * + * This is the algorithm described in: + * "{EP$n$P: An Accurate $O(n)$ Solution to the P$n$P Problem", by V. Lepetit + * and F. Moreno-Noguer and P. Fua, IJCV 2009. vol. 81, no. 2 + * \note: the non-linear optimization is not implemented here. + */ +bool EuclideanResectionEPnP(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t); + +} // namespace euclidean_resection +} // namespace libmv + + +#endif /* LIBMV_MULTIVIEW_EUCLIDEAN_RESECTION_H_ */ diff --git a/extern/libmv/libmv/multiview/fundamental.cc b/extern/libmv/libmv/multiview/fundamental.cc new file mode 100644 index 00000000000..7a6b4a08439 --- /dev/null +++ b/extern/libmv/libmv/multiview/fundamental.cc @@ -0,0 +1,391 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/poly.h" +#include "libmv/multiview/conditioning.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/triangulation.h" +#include "libmv/multiview/fundamental.h" + +namespace libmv { + +void EliminateRow(const Mat34 &P, int row, Mat *X) { + X->resize(2, 4); + + int first_row = (row + 1) % 3; + int second_row = (row + 2) % 3; + + for (int i = 0; i < 4; ++i) { + (*X)(0, i) = P(first_row, i); + (*X)(1, i) = P(second_row, i); + } +} + +void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2) { + *P1 << Mat3::Identity(), Vec3::Zero(); + Vec3 e2; + Mat3 Ft = F.transpose(); + Nullspace(&Ft, &e2); + *P2 << CrossProductMatrix(e2) * F, e2; +} + +// Addapted from vgg_F_from_P. +void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F) { + Mat X[3]; + Mat Y[3]; + Mat XY; + + for (int i = 0; i < 3; ++i) { + EliminateRow(P1, i, X + i); + EliminateRow(P2, i, Y + i); + } + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + VerticalStack(X[j], Y[i], &XY); + (*F)(i, j) = XY.determinant(); + } + } +} + +// HZ 11.1 pag.279 (x1 = x, x2 = x') +// http://www.cs.unc.edu/~marc/tutorial/node54.html +double EightPointSolver(const Mat &x1, const Mat &x2, Mat3 *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 8); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + int n = x1.cols(); + Mat A(n, 9); + for (int i = 0; i < n; ++i) { + A(i, 0) = x2(0, i) * x1(0, i); + A(i, 1) = x2(0, i) * x1(1, i); + A(i, 2) = x2(0, i); + A(i, 3) = x2(1, i) * x1(0, i); + A(i, 4) = x2(1, i) * x1(1, i); + A(i, 5) = x2(1, i); + A(i, 6) = x1(0, i); + A(i, 7) = x1(1, i); + A(i, 8) = 1; + } + + Vec9 f; + double smaller_singular_value = Nullspace(&A, &f); + *F = Map(f.data()); + return smaller_singular_value; +} + +// HZ 11.1.1 pag.280 +void EnforceFundamentalRank2Constraint(Mat3 *F) { + Eigen::JacobiSVD USV(*F, Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 d = USV.singularValues(); + d(2) = 0.0; + *F = USV.matrixU() * d.asDiagonal() * USV.matrixV().transpose(); +} + +// HZ 11.2 pag.281 (x1 = x, x2 = x') +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 8); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + PreconditionerFromPoints(x1, &T1); + PreconditionerFromPoints(x2, &T2); + Mat x1_normalized, x2_normalized; + ApplyTransformationToPoints(x1, T1, &x1_normalized); + ApplyTransformationToPoints(x2, T2, &x2_normalized); + + // Estimate the fundamental matrix. + double smaller_singular_value = + EightPointSolver(x1_normalized, x2_normalized, F); + EnforceFundamentalRank2Constraint(F); + + // Denormalize the fundamental matrix. + *F = T2.transpose() * (*F) * T1; + + return smaller_singular_value; +} + +// Seven-point algorithm. +// http://www.cs.unc.edu/~marc/tutorial/node55.html +double FundamentalFrom7CorrespondencesLinear(const Mat &x1, + const Mat &x2, + std::vector *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_EQ(x1.cols(), 7); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x2.cols(), x2.cols()); + + // Build a 9 x n matrix from point matches, where each row is equivalent to + // the equation x'T*F*x = 0 for a single correspondence pair (x', x). The + // domain of the matrix is a 9 element vector corresponding to F. The + // nullspace should be rank two; the two dimensions correspond to the set of + // F matrices satisfying the epipolar geometry. + Matrix A; + for (int ii = 0; ii < 7; ++ii) { + A(ii, 0) = x1(0, ii) * x2(0, ii); // 0 represents x coords, + A(ii, 1) = x1(1, ii) * x2(0, ii); // 1 represents y coords. + A(ii, 2) = x2(0, ii); + A(ii, 3) = x1(0, ii) * x2(1, ii); + A(ii, 4) = x1(1, ii) * x2(1, ii); + A(ii, 5) = x2(1, ii); + A(ii, 6) = x1(0, ii); + A(ii, 7) = x1(1, ii); + A(ii, 8) = 1.0; + } + + // Find the two F matrices in the nullspace of A. + Vec9 f1, f2; + double s = Nullspace2(&A, &f1, &f2); + Mat3 F1 = Map(f1.data()); + Mat3 F2 = Map(f2.data()); + + // Then, use the condition det(F) = 0 to determine F. In other words, solve + // det(F1 + a*F2) = 0 for a. + double a = F1(0, 0), j = F2(0, 0), + b = F1(0, 1), k = F2(0, 1), + c = F1(0, 2), l = F2(0, 2), + d = F1(1, 0), m = F2(1, 0), + e = F1(1, 1), n = F2(1, 1), + f = F1(1, 2), o = F2(1, 2), + g = F1(2, 0), p = F2(2, 0), + h = F1(2, 1), q = F2(2, 1), + i = F1(2, 2), r = F2(2, 2); + + // Run fundamental_7point_coeffs.py to get the below coefficients. + // The coefficients are in ascending powers of alpha, i.e. P[N]*x^N. + double P[4] = { + a*e*i + b*f*g + c*d*h - a*f*h - b*d*i - c*e*g, + a*e*r + a*i*n + b*f*p + b*g*o + c*d*q + c*h*m + d*h*l + e*i*j + f*g*k - + a*f*q - a*h*o - b*d*r - b*i*m - c*e*p - c*g*n - d*i*k - e*g*l - f*h*j, + a*n*r + b*o*p + c*m*q + d*l*q + e*j*r + f*k*p + g*k*o + h*l*m + i*j*n - + a*o*q - b*m*r - c*n*p - d*k*r - e*l*p - f*j*q - g*l*n - h*j*o - i*k*m, + j*n*r + k*o*p + l*m*q - j*o*q - k*m*r - l*n*p, + }; + + // Solve for the roots of P[3]*x^3 + P[2]*x^2 + P[1]*x + P[0] = 0. + double roots[3]; + int num_roots = SolveCubicPolynomial(P, roots); + + // Build the fundamental matrix for each solution. + for (int kk = 0; kk < num_roots; ++kk) { + F->push_back(F1 + roots[kk] * F2); + } + return s; +} + +double FundamentalFromCorrespondences7Point(const Mat &x1, + const Mat &x2, + std::vector *F) { + DCHECK_EQ(x1.rows(), 2); + DCHECK_GE(x1.cols(), 7); + DCHECK_EQ(x1.rows(), x2.rows()); + DCHECK_EQ(x1.cols(), x2.cols()); + + // Normalize the data. + Mat3 T1, T2; + PreconditionerFromPoints(x1, &T1); + PreconditionerFromPoints(x2, &T2); + Mat x1_normalized, x2_normalized; + ApplyTransformationToPoints(x1, T1, &x1_normalized); + ApplyTransformationToPoints(x2, T2, &x2_normalized); + + // Estimate the fundamental matrix. + double smaller_singular_value = + FundamentalFrom7CorrespondencesLinear(x1_normalized, x2_normalized, &(*F)); + + for (int k = 0; k < F->size(); ++k) { + Mat3 & Fmat = (*F)[k]; + // Denormalize the fundamental matrix. + Fmat = T2.transpose() * Fmat * T1; + } + return smaller_singular_value; +} + +void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized) { + *F_normalized = F / FrobeniusNorm(F); + if ((*F_normalized)(2, 2) < 0) { + *F_normalized *= -1; + } +} + +double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + double y_F_x = y.dot(F_x); + + return Square(y_F_x) / ( F_x.head<2>().squaredNorm() + + Ft_y.head<2>().squaredNorm()); +} + +double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2) { + Vec3 x(x1(0), x1(1), 1.0); + Vec3 y(x2(0), x2(1), 1.0); + + Vec3 F_x = F * x; + Vec3 Ft_y = F.transpose() * y; + double y_F_x = y.dot(F_x); + + return Square(y_F_x) * ( 1 / F_x.head<2>().squaredNorm() + + 1 / Ft_y.head<2>().squaredNorm()); +} + +// HZ 9.6 pag 257 (formula 9.12) +void EssentialFromFundamental(const Mat3 &F, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *E) { + *E = K2.transpose() * F * K1; +} + +// HZ 9.6 pag 257 (formula 9.12) +// Or http://ai.stanford.edu/~birch/projective/node20.html +void FundamentalFromEssential(const Mat3 &E, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *F) { + *F = K2.inverse().transpose() * E * K1.inverse(); +} + +void RelativeCameraMotion(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *R, + Vec3 *t) { + *R = R2 * R1.transpose(); + *t = t2 - (*R) * t1; +} + +// HZ 9.6 pag 257 +void EssentialFromRt(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *E) { + Mat3 R; + Vec3 t; + RelativeCameraMotion(R1, t1, R2, t2, &R, &t); + Mat3 Tx = CrossProductMatrix(t); + *E = Tx * R; +} + +// HZ 9.6 pag 259 (Result 9.19) +void MotionFromEssential(const Mat3 &E, + std::vector *Rs, + std::vector *ts) { + Eigen::JacobiSVD USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV); + Mat3 U = USV.matrixU(); + Vec3 d = USV.singularValues(); + Mat3 Vt = USV.matrixV().transpose(); + + // Last column of U is undetermined since d = (a a 0). + if (U.determinant() < 0) { + U.col(2) *= -1; + } + // Last row of Vt is undetermined since d = (a a 0). + if (Vt.determinant() < 0) { + Vt.row(2) *= -1; + } + + Mat3 W; + W << 0, -1, 0, + 1, 0, 0, + 0, 0, 1; + + Mat3 U_W_Vt = U * W * Vt; + Mat3 U_Wt_Vt = U * W.transpose() * Vt; + + Rs->resize(4); + (*Rs)[0] = U_W_Vt; + (*Rs)[1] = U_W_Vt; + (*Rs)[2] = U_Wt_Vt; + (*Rs)[3] = U_Wt_Vt; + + ts->resize(4); + (*ts)[0] = U.col(2); + (*ts)[1] = -U.col(2); + (*ts)[2] = U.col(2); + (*ts)[3] = -U.col(2); +} + +int MotionFromEssentialChooseSolution(const std::vector &Rs, + const std::vector &ts, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2) { + DCHECK_EQ(4, Rs.size()); + DCHECK_EQ(4, ts.size()); + + Mat34 P1, P2; + Mat3 R1; + Vec3 t1; + R1.setIdentity(); + t1.setZero(); + P_From_KRt(K1, R1, t1, &P1); + for (int i = 0; i < 4; ++i) { + const Mat3 &R2 = Rs[i]; + const Vec3 &t2 = ts[i]; + P_From_KRt(K2, R2, t2, &P2); + Vec3 X; + TriangulateDLT(P1, x1, P2, x2, &X); + double d1 = Depth(R1, t1, X); + double d2 = Depth(R2, t2, X); + // Test if point is front to the two cameras. + if (d1 > 0 && d2 > 0) { + return i; + } + } + return -1; +} + +bool MotionFromEssentialAndCorrespondence(const Mat3 &E, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2, + Mat3 *R, + Vec3 *t) { + std::vector Rs; + std::vector ts; + MotionFromEssential(E, &Rs, &ts); + int solution = MotionFromEssentialChooseSolution(Rs, ts, K1, x1, K2, x2); + if (solution >= 0) { + *R = Rs[solution]; + *t = ts[solution]; + return true; + } else { + return false; + } +} + +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/fundamental.h b/extern/libmv/libmv/multiview/fundamental.h new file mode 100644 index 00000000000..3f4a3b7b211 --- /dev/null +++ b/extern/libmv/libmv/multiview/fundamental.h @@ -0,0 +1,144 @@ +// Copyright (c) 2007, 2008, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_FUNDAMENTAL_H_ +#define LIBMV_MULTIVIEW_FUNDAMENTAL_H_ + +#include + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void ProjectionsFromFundamental(const Mat3 &F, Mat34 *P1, Mat34 *P2); +void FundamentalFromProjections(const Mat34 &P1, const Mat34 &P2, Mat3 *F); + +/** + * The normalized 8-point fundamental matrix solver. + */ +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F); + +/** + * 7 points (minimal case, points coordinates must be normalized before): + */ +double FundamentalFrom7CorrespondencesLinear(const Mat &x1, + const Mat &x2, + std::vector *F); + +/** + * 7 points (points coordinates must be in image space): + */ +double FundamentalFromCorrespondences7Point(const Mat &x1, + const Mat &x2, + std::vector *F); + +/** + * 8 points (points coordinates must be in image space): + */ +double NormalizedEightPointSolver(const Mat &x1, + const Mat &x2, + Mat3 *F); + +/** + * Fundamental matrix utility function: + */ +void EnforceFundamentalRank2Constraint(Mat3 *F); + +void NormalizeFundamental(const Mat3 &F, Mat3 *F_normalized); + +/** + * Approximate squared reprojection errror. + * + * See page 287 of HZ equation 11.9. This avoids triangulating the point, + * relying only on the entries in F. + */ +double SampsonDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2); + +/** + * Calculates the sum of the distances from the points to the epipolar lines. + * + * See page 288 of HZ equation 11.10. + */ +double SymmetricEpipolarDistance(const Mat &F, const Vec2 &x1, const Vec2 &x2); + +/** + * Compute the relative camera motion between two cameras. + * + * Given the motion parameters of two cameras, computes the motion parameters + * of the second one assuming the first one to be at the origin. + * If T1 and T2 are the camera motions, the computed relative motion is + * T = T2 T1^{-1} + */ +void RelativeCameraMotion(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *R, + Vec3 *t); + +void EssentialFromFundamental(const Mat3 &F, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *E); + +void FundamentalFromEssential(const Mat3 &E, + const Mat3 &K1, + const Mat3 &K2, + Mat3 *F); + +void EssentialFromRt(const Mat3 &R1, + const Vec3 &t1, + const Mat3 &R2, + const Vec3 &t2, + Mat3 *E); + +void MotionFromEssential(const Mat3 &E, + std::vector *Rs, + std::vector *ts); + +/** + * Choose one of the four possible motion solutions from an essential matrix. + * + * Decides the right solution by checking that the triangulation of a match + * x1--x2 lies in front of the cameras. See HZ 9.6 pag 259 (9.6.3 Geometrical + * interpretation of the 4 solutions) + * + * \return index of the right solution or -1 if no solution. + */ +int MotionFromEssentialChooseSolution(const std::vector &Rs, + const std::vector &ts, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2); + +bool MotionFromEssentialAndCorrespondence(const Mat3 &E, + const Mat3 &K1, + const Vec2 &x1, + const Mat3 &K2, + const Vec2 &x2, + Mat3 *R, + Vec3 *t); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_FUNDAMENTAL_H_ diff --git a/extern/libmv/libmv/multiview/nviewtriangulation.h b/extern/libmv/libmv/multiview/nviewtriangulation.h new file mode 100644 index 00000000000..b4f521f185d --- /dev/null +++ b/extern/libmv/libmv/multiview/nviewtriangulation.h @@ -0,0 +1,80 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Compute a 3D position of a point from several images of it. In particular, +// compute the projective point X in R^4 such that x = PX. +// +// Algorithm is the standard DLT; for derivation see appendix of Keir's thesis. + +#ifndef LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H +#define LIBMV_MULTIVIEW_NVIEWTRIANGULATION_H + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The +// output, X, is a homogeneous four vectors. +template +void NViewTriangulate(const Matrix &x, + const vector > &Ps, + Matrix *X) { + int nviews = x.cols(); + assert(nviews == Ps.size()); + + Matrix design(3*nviews, 4 + nviews); + design.setConstant(0.0); + for (int i = 0; i < nviews; i++) { + design.template block<3, 4>(3*i, 0) = -Ps[i]; + design(3*i + 0, 4 + i) = x(0, i); + design(3*i + 1, 4 + i) = x(1, i); + design(3*i + 2, 4 + i) = 1.0; + } + Matrix X_and_alphas; + Nullspace(&design, &X_and_alphas); + X->resize(4); + *X = X_and_alphas.head(4); +} + +// x's are 2D coordinates (x,y,1) in each image; Ps are projective cameras. The +// output, X, is a homogeneous four vectors. +// This method uses the algebraic distance approximation. +// Note that this method works better when the 2D points are normalized +// with an isotopic normalization. +template +void NViewTriangulateAlgebraic(const Matrix &x, + const vector > &Ps, + Matrix *X) { + int nviews = x.cols(); + assert(nviews == Ps.size()); + + Matrix design(2*nviews, 4); + for (int i = 0; i < nviews; i++) { + design.template block<2, 4>(2*i, 0) = SkewMatMinimal(x.col(i)) * Ps[i]; + } + X->resize(4); + Nullspace(&design, X); +} + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_H diff --git a/extern/libmv/libmv/multiview/projection.cc b/extern/libmv/libmv/multiview/projection.cc new file mode 100644 index 00000000000..a7d1a058e9c --- /dev/null +++ b/extern/libmv/libmv/multiview/projection.cc @@ -0,0 +1,221 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P) { + P->block<3, 3>(0, 0) = R; + P->col(3) = t; + (*P) = K * (*P); +} + +void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { + // Decompose using the RQ decomposition HZ A4.1.1 pag.579. + Mat3 K = P.block(0, 0, 3, 3); + + Mat3 Q; + Q.setIdentity(); + + // Set K(2,1) to zero. + if (K(2, 1) != 0) { + double c = -K(2,2); + double s = K(2,1); + double l = sqrt(c * c + s * s); + c /= l; s /= l; + Mat3 Qx; + Qx << 1, 0, 0, + 0, c, -s, + 0, s, c; + K = K * Qx; + Q = Qx.transpose() * Q; + } + // Set K(2,0) to zero. + if (K(2, 0) != 0) { + double c = K(2, 2); + double s = K(2, 0); + double l = sqrt(c * c + s * s); + c /= l; s /= l; + Mat3 Qy; + Qy << c, 0, s, + 0, 1, 0, + -s, 0, c; + K = K * Qy; + Q = Qy.transpose() * Q; + } + // Set K(1,0) to zero. + if (K(1, 0) != 0) { + double c = -K(1, 1); + double s = K(1, 0); + double l = sqrt(c * c + s * s); + c /= l; s /= l; + Mat3 Qz; + Qz << c,-s, 0, + s, c, 0, + 0, 0, 1; + K = K * Qz; + Q = Qz.transpose() * Q; + } + + Mat3 R = Q; + + // Ensure that the diagonal is positive. + // TODO(pau) Change this to ensure that: + // - K(0,0) > 0 + // - K(2,2) = 1 + // - det(R) = 1 + if (K(2,2) < 0) { + K = -K; + R = -R; + } + if (K(1,1) < 0) { + Mat3 S; + S << 1, 0, 0, + 0,-1, 0, + 0, 0, 1; + K = K * S; + R = S * R; + } + if (K(0,0) < 0) { + Mat3 S; + S << -1, 0, 0, + 0, 1, 0, + 0, 0, 1; + K = K * S; + R = S * R; + } + + // Compute translation. + Vec p(3); + p << P(0,3), P(1,3), P(2,3); + // TODO(pau) This sould be done by a SolveLinearSystem(A, b, &x) call. + // TODO(keir) use the eigen LU solver syntax... + Vec3 t = K.inverse() * p; + + // scale K so that K(2,2) = 1 + K = K / K(2,2); + + *Kp = K; + *Rp = R; + *tp = t; +} + +void ProjectionShiftPrincipalPoint(const Mat34 &P, + const Vec2 &principal_point, + const Vec2 &principal_point_new, + Mat34 *P_new) { + Mat3 T; + T << 1, 0, principal_point_new(0) - principal_point(0), + 0, 1, principal_point_new(1) - principal_point(1), + 0, 0, 1; + *P_new = T * P; +} + +void ProjectionChangeAspectRatio(const Mat34 &P, + const Vec2 &principal_point, + double aspect_ratio, + double aspect_ratio_new, + Mat34 *P_new) { + Mat3 T; + T << 1, 0, 0, + 0, aspect_ratio_new / aspect_ratio, 0, + 0, 0, 1; + Mat34 P_temp; + + ProjectionShiftPrincipalPoint(P, principal_point, Vec2(0,0), &P_temp); + P_temp = T * P_temp; + ProjectionShiftPrincipalPoint(P_temp, Vec2(0,0), principal_point, P_new); +} + +void HomogeneousToEuclidean(const Mat &H, Mat *X) { + int d = H.rows() - 1; + int n = H.cols(); + X->resize(d, n); + for (size_t i = 0; i < n; ++i) { + double h = H(d, i); + for (int j = 0; j < d; ++j) { + (*X)(j, i) = H(j, i) / h; + } + } +} + +void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e) { + e->resize(2, h.cols()); + e->row(0) = h.row(0).array() / h.row(2).array(); + e->row(1) = h.row(1).array() / h.row(2).array(); +} +void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e) { + e->resize(3, h.cols()); + e->row(0) = h.row(0).array() / h.row(3).array(); + e->row(1) = h.row(1).array() / h.row(3).array(); + e->row(2) = h.row(2).array() / h.row(3).array(); +} + +void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X) { + double w = H(2); + *X << H(0) / w, H(1) / w; +} + +void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X) { + double w = H(3); + *X << H(0) / w, H(1) / w, H(2) / w; +} + +void EuclideanToHomogeneous(const Mat &X, Mat *H) { + int d = X.rows(); + int n = X.cols(); + H->resize(d + 1, n); + H->block(0, 0, d, n) = X; + H->row(d).setOnes(); +} + +void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H) { + *H << X(0), X(1), 1; +} + +void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H) { + *H << X(0), X(1), X(2), 1; +} + +// TODO(julien) Call conditioning.h/ApplyTransformationToPoints ? +void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n) { + Mat3X x_image_h; + EuclideanToHomogeneous(x, &x_image_h); + Mat3X x_camera_h = K.inverse() * x_image_h; + HomogeneousToEuclidean(x_camera_h, n); +} + +void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n) { + Mat3X x_camera_h = K.inverse() * x; + HomogeneousToEuclidean(x_camera_h, n); +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X) { + return (R*X)(2) + t(2); +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X) { + Vec3 Xe = X.head<3>() / X(3); + return Depth(R, t, Xe); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/projection.h b/extern/libmv/libmv/multiview/projection.h new file mode 100644 index 00000000000..bc353b64c08 --- /dev/null +++ b/extern/libmv/libmv/multiview/projection.h @@ -0,0 +1,231 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_PROJECTION_H_ +#define LIBMV_MULTIVIEW_PROJECTION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void P_From_KRt(const Mat3 &K, const Mat3 &R, const Vec3 &t, Mat34 *P); +void KRt_From_P(const Mat34 &P, Mat3 *K, Mat3 *R, Vec3 *t); + +// Applies a change of basis to the image coordinates of the projection matrix +// so that the principal point becomes principal_point_new. +void ProjectionShiftPrincipalPoint(const Mat34 &P, + const Vec2 &principal_point, + const Vec2 &principal_point_new, + Mat34 *P_new); + +// Applies a change of basis to the image coordinates of the projection matrix +// so that the aspect ratio becomes aspect_ratio_new. This is done by +// stretching the y axis. The aspect ratio is defined as the quotient between +// the focal length of the y and the x axis. +void ProjectionChangeAspectRatio(const Mat34 &P, + const Vec2 &principal_point, + double aspect_ratio, + double aspect_ratio_new, + Mat34 *P_new); + +void HomogeneousToEuclidean(const Mat &H, Mat *X); +void HomogeneousToEuclidean(const Mat3X &h, Mat2X *e); +void HomogeneousToEuclidean(const Mat4X &h, Mat3X *e); +void HomogeneousToEuclidean(const Vec3 &H, Vec2 *X); +void HomogeneousToEuclidean(const Vec4 &H, Vec3 *X); +inline Vec2 HomogeneousToEuclidean(const Vec3 &h) { + return h.head<2>() / h(2); +} +inline Vec3 HomogeneousToEuclidean(const Vec4 &h) { + return h.head<3>() / h(3); +} +inline Mat2X HomogeneousToEuclidean(const Mat3X &h) { + Mat2X e(2, h.cols()); + e.row(0) = h.row(0).array() / h.row(2).array(); + e.row(1) = h.row(1).array() / h.row(2).array(); + return e; +} + +void EuclideanToHomogeneous(const Mat &X, Mat *H); +inline Mat3X EuclideanToHomogeneous(const Mat2X &x) { + Mat3X h(3, x.cols()); + h.block(0, 0, 2, x.cols()) = x; + h.row(2).setOnes(); + return h; +} +inline void EuclideanToHomogeneous(const Mat2X &x, Mat3X *h) { + h->resize(3, x.cols()); + h->block(0, 0, 2, x.cols()) = x; + h->row(2).setOnes(); +} +inline Mat4X EuclideanToHomogeneous(const Mat3X &x) { + Mat4X h(4, x.cols()); + h.block(0, 0, 3, x.cols()) = x; + h.row(3).setOnes(); + return h; +} +inline void EuclideanToHomogeneous(const Mat3X &x, Mat4X *h) { + h->resize(4, x.cols()); + h->block(0, 0, 3, x.cols()) = x; + h->row(3).setOnes(); +} +void EuclideanToHomogeneous(const Vec2 &X, Vec3 *H); +void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H); +inline Vec3 EuclideanToHomogeneous(const Vec2 &x) { + return Vec3(x(0), x(1), 1); +} +inline Vec4 EuclideanToHomogeneous(const Vec3 &x) { + return Vec4(x(0), x(1), x(2), 1); +} +// Conversion from image coordinates to normalized camera coordinates +void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n); +void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n); + +inline Vec2 Project(const Mat34 &P, const Vec3 &X) { + Vec4 HX; + HX << X, 1.0; + Vec3 hx = P * HX; + return hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Vec4 &X, Vec3 *x) { + *x = P * X; +} + +inline void Project(const Mat34 &P, const Vec4 &X, Vec2 *x) { + Vec3 hx = P * X; + *x = hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Vec3 &X, Vec3 *x) { + Vec4 HX; + HX << X, 1.0; + Project(P, HX, x); +} + +inline void Project(const Mat34 &P, const Vec3 &X, Vec2 *x) { + Vec3 hx; + Project(P, X, x); + *x = hx.head<2>() / hx(2); +} + +inline void Project(const Mat34 &P, const Mat4X &X, Mat2X *x) { + x->resize(2, X.cols()); + for (int c = 0; c < X.cols(); ++c) { + Vec3 hx = P * X.col(c); + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline Mat2X Project(const Mat34 &P, const Mat4X &X) { + Mat2X x; + Project(P, X, &x); + return x; +} + +inline void Project(const Mat34 &P, const Mat3X &X, Mat2X *x) { + x->resize(2, X.cols()); + for (int c = 0; c < X.cols(); ++c) { + Vec4 HX; + HX << X.col(c), 1.0; + Vec3 hx = P * HX; + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline void Project(const Mat34 &P, const Mat3X &X, const Vecu &ids, Mat2X *x) { + x->resize(2, ids.size()); + Vec4 HX; + Vec3 hx; + for (int c = 0; c < ids.size(); ++c) { + HX << X.col(ids[c]), 1.0; + hx = P * HX; + x->col(c) = hx.head<2>() / hx(2); + } +} + +inline Mat2X Project(const Mat34 &P, const Mat3X &X) { + Mat2X x(2, X.cols()); + Project(P, X, &x); + return x; +} + +inline Mat2X Project(const Mat34 &P, const Mat3X &X, const Vecu &ids) { + Mat2X x(2, ids.size()); + Project(P, X, ids, &x); + return x; +} + +double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X); +double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X); + +/** +* Returns true if the homogenious 3D point X is in front of +* the camera P. +*/ +inline bool isInFrontOfCamera(const Mat34 &P, const Vec4 &X){ + double condition_1 = P.row(2).dot(X) * X[3]; + double condition_2 = X[2] * X[3]; + if( condition_1 > 0 && condition_2 > 0 ) + return true; + else + return false; +} + +inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X){ + Vec4 X_homo; + X_homo.segment<3>(0) = X; + X_homo(3) = 1; + return isInFrontOfCamera( P, X_homo); +} + +/** +* Transforms a 2D point from pixel image coordinates to a 2D point in +* normalized image coordinates. +*/ +inline Vec2 ImageToNormImageCoordinates(Mat3 &Kinverse, Vec2 &x){ + Vec3 x_h = Kinverse*EuclideanToHomogeneous(x); + return HomogeneousToEuclidean( x_h ); +} + +/// Estimates the root mean square error (2D) +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat4X &X_world, + const Mat34 &P) { + size_t num_points = x_image.cols(); + Mat2X dx = Project(P, X_world) - x_image; + return dx.norm() / num_points; +} + +/// Estimates the root mean square error (2D) +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat3X &X_world, + const Mat3 &K, + const Mat3 &R, + const Vec3 &t) { + Mat34 P; + P_From_KRt(K, R, t, &P); + size_t num_points = x_image.cols(); + Mat2X dx = Project(P, X_world) - x_image; + return dx.norm() / num_points; +} +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_PROJECTION_H_ diff --git a/extern/libmv/libmv/multiview/resection.h b/extern/libmv/libmv/multiview/resection.h new file mode 100644 index 00000000000..e4623899147 --- /dev/null +++ b/extern/libmv/libmv/multiview/resection.h @@ -0,0 +1,62 @@ +// Copyright (c) 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Compute the projection matrix from a set of 3D points X and their +// projections x = PX in 2D. This is useful if a point cloud is reconstructed. +// +// Algorithm is the standard DLT as described in Hartley & Zisserman, page 179. + +#ifndef LIBMV_MULTIVIEW_RESECTION_H +#define LIBMV_MULTIVIEW_RESECTION_H + +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { +namespace resection { + +// x's are 2D image coordinates, (x,y,1), and X's are homogeneous four vectors. +template +void Resection(const Matrix &x, + const Matrix &X, + Matrix *P) { + int N = x.cols(); + assert(X.cols() == N); + + Matrix design(2*N, 12); + design.setZero(); + for (int i = 0; i < N; i++) { + T xi = x(0, i); + T yi = x(1, i); + // See equation (7.2) on page 179 of H&Z. + design.template block<1,4>(2*i, 4) = -X.col(i).transpose(); + design.template block<1,4>(2*i, 8) = yi*X.col(i).transpose(); + design.template block<1,4>(2*i + 1, 0) = X.col(i).transpose(); + design.template block<1,4>(2*i + 1, 8) = -xi*X.col(i).transpose(); + } + Matrix p; + Nullspace(&design, &p); + reshape(p, 3, 4, P); +} + +} // namespace resection +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_RESECTION_H diff --git a/extern/libmv/libmv/multiview/triangulation.cc b/extern/libmv/libmv/multiview/triangulation.cc new file mode 100644 index 00000000000..b9d38cef936 --- /dev/null +++ b/extern/libmv/libmv/multiview/triangulation.cc @@ -0,0 +1,49 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/numeric/numeric.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/triangulation.h" + +namespace libmv { + +// HZ 12.2 pag.312 +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec4 *X_homogeneous) { + Mat4 design; + for (int i = 0; i < 4; ++i) { + design(0,i) = x1(0) * P1(2,i) - P1(0,i); + design(1,i) = x1(1) * P1(2,i) - P1(1,i); + design(2,i) = x2(0) * P2(2,i) - P2(0,i); + design(3,i) = x2(1) * P2(2,i) - P2(1,i); + } + Nullspace(&design, X_homogeneous); +} + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec3 *X_euclidean) { + Vec4 X_homogeneous; + TriangulateDLT(P1, x1, P2, x2, &X_homogeneous); + HomogeneousToEuclidean(X_homogeneous, X_euclidean); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/triangulation.h b/extern/libmv/libmv/multiview/triangulation.h new file mode 100644 index 00000000000..c35774d9e1b --- /dev/null +++ b/extern/libmv/libmv/multiview/triangulation.h @@ -0,0 +1,38 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_MULTIVIEW_TRIANGULATION_H_ +#define LIBMV_MULTIVIEW_TRIANGULATION_H_ + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec4 *X_homogeneous); + +void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, + const Mat34 &P2, const Vec2 &x2, + Vec3 *X_euclidean); + +} // namespace libmv + +#endif // LIBMV_MULTIVIEW_TRIANGULATION_H_ diff --git a/extern/libmv/libmv/numeric/dogleg.h b/extern/libmv/libmv/numeric/dogleg.h new file mode 100644 index 00000000000..f05882c1191 --- /dev/null +++ b/extern/libmv/libmv/numeric/dogleg.h @@ -0,0 +1,261 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// A simple implementation of Powell's dogleg nonlinear minimization. +// +// [1] K. Madsen, H. Nielsen, O. Tingleoff. Methods for Non-linear Least +// Squares Problems. +// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf +// +// TODO(keir): Cite the Lourakis' dogleg paper. + +#ifndef LIBMV_NUMERIC_DOGLEG_H +#define LIBMV_NUMERIC_DOGLEG_H + +#include +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/function_derivative.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +template, + typename Solver = Eigen::PartialPivLU< + Matrix > > +class Dogleg { + public: + typedef typename Function::XMatrixType::RealScalar Scalar; + typedef typename Function::FMatrixType FVec; + typedef typename Function::XMatrixType Parameters; + typedef Matrix JMatrixType; + typedef Matrix AMatrixType; + + enum Status { + RUNNING, + GRADIENT_TOO_SMALL, // eps > max(J'*f(x)) + RELATIVE_STEP_SIZE_TOO_SMALL, // eps > ||dx|| / ||x|| + TRUST_REGION_TOO_SMALL, // eps > radius / ||x|| + ERROR_TOO_SMALL, // eps > ||f(x)|| + HIT_MAX_ITERATIONS, + }; + + enum Step { + DOGLEG, + GAUSS_NEWTON, + STEEPEST_DESCENT, + }; + + Dogleg(const Function &f) + : f_(f), df_(f) {} + + struct SolverParameters { + SolverParameters() + : gradient_threshold(1e-16), + relative_step_threshold(1e-16), + error_threshold(1e-16), + initial_trust_radius(1e0), + max_iterations(500) {} + Scalar gradient_threshold; // eps > max(J'*f(x)) + Scalar relative_step_threshold; // eps > ||dx|| / ||x|| + Scalar error_threshold; // eps > ||f(x)|| + Scalar initial_trust_radius; // Initial u for solving normal equations. + int max_iterations; // Maximum number of solver iterations. + }; + + struct Results { + Scalar error_magnitude; // ||f(x)|| + Scalar gradient_magnitude; // ||J'f(x)|| + int iterations; + Status status; + }; + + Status Update(const Parameters &x, const SolverParameters ¶ms, + JMatrixType *J, AMatrixType *A, FVec *error, Parameters *g) { + *J = df_(x); + // TODO(keir): In the case of m = n, avoid computing A and just do J^-1 directly. + *A = (*J).transpose() * (*J); + *error = f_(x); + *g = (*J).transpose() * *error; + if (g->array().abs().maxCoeff() < params.gradient_threshold) { + return GRADIENT_TOO_SMALL; + } else if (error->array().abs().maxCoeff() < params.error_threshold) { + return ERROR_TOO_SMALL; + } + return RUNNING; + } + + Step SolveDoglegDirection(const Parameters &dx_sd, + const Parameters &dx_gn, + Scalar radius, + Scalar alpha, + Parameters *dx_dl, + Scalar *beta) { + Parameters a, b_minus_a; + // Solve for Dogleg step dx_dl. + if (dx_gn.norm() < radius) { + *dx_dl = dx_gn; + return GAUSS_NEWTON; + + } else if (alpha * dx_sd.norm() > radius) { + *dx_dl = (radius / dx_sd.norm()) * dx_sd; + return STEEPEST_DESCENT; + + } else { + Parameters a = alpha * dx_sd; + const Parameters &b = dx_gn; + b_minus_a = a - b; + Scalar Mbma2 = b_minus_a.squaredNorm(); + Scalar Ma2 = a.squaredNorm(); + Scalar c = a.dot(b_minus_a); + Scalar radius2 = radius*radius; + if (c <= 0) { + *beta = (-c + sqrt(c*c + Mbma2*(radius2 - Ma2)))/(Mbma2); + } else { + *beta = (radius2 - Ma2) / + (c + sqrt(c*c + Mbma2*(radius2 - Ma2))); + } + *dx_dl = alpha * dx_sd + (*beta) * (dx_gn - alpha*dx_sd); + return DOGLEG; + } + } + + Results minimize(Parameters *x_and_min) { + SolverParameters params; + return minimize(params, x_and_min); + } + + Results minimize(const SolverParameters ¶ms, Parameters *x_and_min) { + Parameters &x = *x_and_min; + JMatrixType J; + AMatrixType A; + FVec error; + Parameters g; + + Results results; + results.status = Update(x, params, &J, &A, &error, &g); + + Scalar radius = params.initial_trust_radius; + bool x_updated = true; + + Parameters x_new; + Parameters dx_sd; // Steepest descent step. + Parameters dx_dl; // Dogleg step. + Parameters dx_gn; // Gauss-Newton step. + printf("iteration ||f(x)|| max(g) radius\n"); + int i = 0; + for (; results.status == RUNNING && i < params.max_iterations; ++i) { + printf("%9d %12g %12g %12g", + i, f_(x).norm(), g.array().abs().maxCoeff(), radius); + + //LG << "iteration: " << i; + //LG << "||f(x)||: " << f_(x).norm(); + //LG << "max(g): " << g.cwise().abs().maxCoeff(); + //LG << "radius: " << radius; + // Eqn 3.19 from [1] + Scalar alpha = g.squaredNorm() / (J*g).squaredNorm(); + + // Solve for steepest descent direction dx_sd. + dx_sd = -g; + + // Solve for Gauss-Newton direction dx_gn. + if (x_updated) { + // TODO(keir): See Appendix B of [1] for discussion of when A is + // singular and there are many solutions. Solving that involves the SVD + // and is slower, but should still work. + Solver solver(A); + dx_gn = solver.solve(-g); + if (!(A * dx_gn).isApprox(-g)) { + LOG(ERROR) << "Failed to solve normal eqns. TODO: Solve via SVD."; + return results; + } + x_updated = false; + } + + // Solve for dogleg direction dx_dl. + Scalar beta = 0; + Step step = SolveDoglegDirection(dx_sd, dx_gn, radius, alpha, + &dx_dl, &beta); + + Scalar e3 = params.relative_step_threshold; + if (dx_dl.norm() < e3*(x.norm() + e3)) { + results.status = RELATIVE_STEP_SIZE_TOO_SMALL; + break; + } + + x_new = x + dx_dl; + Scalar actual = f_(x).squaredNorm() - f_(x_new).squaredNorm(); + Scalar predicted = 0; + if (step == GAUSS_NEWTON) { + predicted = f_(x).squaredNorm(); + } else if (step == STEEPEST_DESCENT) { + predicted = radius * (2*alpha*g.norm() - radius) / 2 / alpha; + } else if (step == DOGLEG) { + predicted = 0.5 * alpha * (1-beta)*(1-beta)*g.squaredNorm() + + beta*(2-beta)*f_(x).squaredNorm(); + } + Scalar rho = actual / predicted; + + if (step == GAUSS_NEWTON) printf(" GAUSS"); + if (step == STEEPEST_DESCENT) printf(" STEE"); + if (step == DOGLEG) printf(" DOGL"); + + printf(" %12g %12g %12g\n", rho, actual, predicted); + + if (rho > 0) { + // Accept update because the linear model is a good fit. + x = x_new; + results.status = Update(x, params, &J, &A, &error, &g); + x_updated = true; + } + if (rho > 0.75) { + radius = std::max(radius, 3*dx_dl.norm()); + } else if (rho < 0.25) { + radius /= 2; + if (radius < e3 * (x.norm() + e3)) { + results.status = TRUST_REGION_TOO_SMALL; + } + } + } + if (results.status == RUNNING) { + results.status = HIT_MAX_ITERATIONS; + } + results.error_magnitude = error.norm(); + results.gradient_magnitude = g.norm(); + results.iterations = i; + return results; + } + + private: + const Function &f_; + Jacobian df_; +}; + +} // namespace mv + +#endif // LIBMV_NUMERIC_DOGLEG_H diff --git a/extern/libmv/libmv/numeric/function_derivative.h b/extern/libmv/libmv/numeric/function_derivative.h new file mode 100644 index 00000000000..d7bc437b2e0 --- /dev/null +++ b/extern/libmv/libmv/numeric/function_derivative.h @@ -0,0 +1,107 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_NUMERIC_DERIVATIVE_H +#define LIBMV_NUMERIC_DERIVATIVE_H + +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +// Numeric derivative of a function. +// TODO(keir): Consider adding a quadratic approximation. + +enum NumericJacobianMode { + CENTRAL, + FORWARD, +}; + +template +class NumericJacobian { + public: + typedef typename Function::XMatrixType Parameters; + typedef typename Function::XMatrixType::RealScalar XScalar; + typedef typename Function::FMatrixType FMatrixType; + typedef Matrix + JMatrixType; + + NumericJacobian(const Function &f) : f_(f) {} + + // TODO(keir): Perhaps passing the jacobian back by value is not a good idea. + JMatrixType operator()(const Parameters &x) { + // Empirically determined constant. + Parameters eps = x.array().abs() * XScalar(1e-5); + // To handle cases where a paremeter is exactly zero, instead use the mean + // eps for the other dimensions. + XScalar mean_eps = eps.sum() / eps.rows(); + if (mean_eps == XScalar(0)) { + // TODO(keir): Do something better here. + mean_eps = 1e-8; // ~sqrt(machine precision). + } + // TODO(keir): Elimininate this needless function evaluation for the + // central difference case. + FMatrixType fx = f_(x); + const int rows = fx.rows(); + const int cols = x.rows(); + JMatrixType jacobian(rows, cols); + Parameters x_plus_delta = x; + for (int c = 0; c < cols; ++c) { + if (eps(c) == XScalar(0)) { + eps(c) = mean_eps; + } + x_plus_delta(c) = x(c) + eps(c); + jacobian.col(c) = f_(x_plus_delta); + + XScalar one_over_h = 1 / eps(c); + if (mode == CENTRAL) { + x_plus_delta(c) = x(c) - eps(c); + jacobian.col(c) -= f_(x_plus_delta); + one_over_h /= 2; + } else { + jacobian.col(c) -= fx; + } + x_plus_delta(c) = x(c); + jacobian.col(c) = jacobian.col(c) * one_over_h; + } + return jacobian; + } + private: + const Function &f_; +}; + +template +bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) { + Jacobian j_analytic(f); + NumericJacobian j_numeric(f); + + typename NumericJacobian::JMatrixType J_numeric = j_numeric(x); + typename NumericJacobian::JMatrixType J_analytic = j_analytic(x); + LG << J_numeric - J_analytic; + return true; +} + +} // namespace libmv + +#endif // LIBMV_NUMERIC_DERIVATIVE_H diff --git a/extern/libmv/libmv/numeric/levenberg_marquardt.h b/extern/libmv/libmv/numeric/levenberg_marquardt.h new file mode 100644 index 00000000000..4473b72f156 --- /dev/null +++ b/extern/libmv/libmv/numeric/levenberg_marquardt.h @@ -0,0 +1,183 @@ +// Copyright (c) 2007, 2008, 2009 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// A simple implementation of levenberg marquardt. +// +// [1] K. Madsen, H. Nielsen, O. Tingleoff. Methods for Non-linear Least +// Squares Problems. +// http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/3215/pdf/imm3215.pdf +// +// TODO(keir): Cite the Lourakis' dogleg paper. + +#ifndef LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H +#define LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H + +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/function_derivative.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +template, + typename Solver = Eigen::PartialPivLU< + Matrix > > +class LevenbergMarquardt { + public: + typedef typename Function::XMatrixType::RealScalar Scalar; + typedef typename Function::FMatrixType FVec; + typedef typename Function::XMatrixType Parameters; + typedef Matrix JMatrixType; + typedef Matrix AMatrixType; + + // TODO(keir): Some of these knobs can be derived from each other and + // removed, instead of requiring the user to set them. + enum Status { + RUNNING, + GRADIENT_TOO_SMALL, // eps > max(J'*f(x)) + RELATIVE_STEP_SIZE_TOO_SMALL, // eps > ||dx|| / ||x|| + ERROR_TOO_SMALL, // eps > ||f(x)|| + HIT_MAX_ITERATIONS, + }; + + LevenbergMarquardt(const Function &f) + : f_(f), df_(f) {} + + struct SolverParameters { + SolverParameters() + : gradient_threshold(1e-16), + relative_step_threshold(1e-16), + error_threshold(1e-16), + initial_scale_factor(1e-3), + max_iterations(100) {} + Scalar gradient_threshold; // eps > max(J'*f(x)) + Scalar relative_step_threshold; // eps > ||dx|| / ||x|| + Scalar error_threshold; // eps > ||f(x)|| + Scalar initial_scale_factor; // Initial u for solving normal equations. + int max_iterations; // Maximum number of solver iterations. + }; + + struct Results { + Scalar error_magnitude; // ||f(x)|| + Scalar gradient_magnitude; // ||J'f(x)|| + int iterations; + Status status; + }; + + Status Update(const Parameters &x, const SolverParameters ¶ms, + JMatrixType *J, AMatrixType *A, FVec *error, Parameters *g) { + *J = df_(x); + *A = (*J).transpose() * (*J); + *error = -f_(x); + *g = (*J).transpose() * *error; + if (g->array().abs().maxCoeff() < params.gradient_threshold) { + return GRADIENT_TOO_SMALL; + } else if (error->norm() < params.error_threshold) { + return ERROR_TOO_SMALL; + } + return RUNNING; + } + + Results minimize(Parameters *x_and_min) { + SolverParameters params; + minimize(params, x_and_min); + } + + Results minimize(const SolverParameters ¶ms, Parameters *x_and_min) { + Parameters &x = *x_and_min; + JMatrixType J; + AMatrixType A; + FVec error; + Parameters g; + + Results results; + results.status = Update(x, params, &J, &A, &error, &g); + + Scalar u = Scalar(params.initial_scale_factor*A.diagonal().maxCoeff()); + Scalar v = 2; + + Parameters dx, x_new; + int i; + for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) { + VLOG(1) << "iteration: " << i; + VLOG(1) << "||f(x)||: " << f_(x).norm(); + VLOG(1) << "max(g): " << g.array().abs().maxCoeff(); + VLOG(1) << "u: " << u; + VLOG(1) << "v: " << v; + + AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols()); + Solver solver(A_augmented); + dx = solver.solve(g); + bool solved = (A_augmented * dx).isApprox(g); + if (!solved) { + LOG(ERROR) << "Failed to solve"; + } + if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) { + results.status = RELATIVE_STEP_SIZE_TOO_SMALL; + break; + } + if (solved) { + x_new = x + dx; + // Rho is the ratio of the actual reduction in error to the reduction + // in error that would be obtained if the problem was linear. + // See [1] for details. + Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) + / dx.dot(u*dx + g)); + if (rho > 0) { + // Accept the Gauss-Newton step because the linear model fits well. + x = x_new; + results.status = Update(x, params, &J, &A, &error, &g); + Scalar tmp = Scalar(2*rho-1); + u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); + v = 2; + continue; + } + } + // Reject the update because either the normal equations failed to solve + // or the local linear model was not good (rho < 0). Instead, increase u + // to move closer to gradient descent. + u *= v; + v *= 2; + } + if (results.status == RUNNING) { + results.status = HIT_MAX_ITERATIONS; + } + results.error_magnitude = error.norm(); + results.gradient_magnitude = g.norm(); + results.iterations = i; + return results; + } + + private: + const Function &f_; + Jacobian df_; +}; + +} // namespace mv + +#endif // LIBMV_NUMERIC_LEVENBERG_MARQUARDT_H diff --git a/extern/libmv/libmv/numeric/numeric.cc b/extern/libmv/libmv/numeric/numeric.cc new file mode 100644 index 00000000000..0ca3a64e4f4 --- /dev/null +++ b/extern/libmv/libmv/numeric/numeric.cc @@ -0,0 +1,136 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + + +#include "libmv/numeric/numeric.h" + +namespace libmv { + +Mat3 RotationAroundX(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << 1, 0, 0, + 0, c, -s, + 0, s, c; + return R; +} + +Mat3 RotationAroundY(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << c, 0, s, + 0, 1, 0, + -s, 0, c; + return R; +} + +Mat3 RotationAroundZ(double angle) { + double c, s; + sincos(angle, &s, &c); + Mat3 R; + R << c, -s, 0, + s, c, 0, + 0, 0, 1; + return R; +} + + +Mat3 RotationRodrigues(const Vec3 &axis) { + double theta = axis.norm(); + Vec3 w = axis / theta; + Mat3 W = CrossProductMatrix(w); + + return Mat3::Identity() + sin(theta) * W + (1 - cos(theta)) * W * W; +} + + +Mat3 LookAt(Vec3 center) { + Vec3 zc = center.normalized(); + Vec3 xc = Vec3::UnitY().cross(zc).normalized(); + Vec3 yc = zc.cross(xc); + Mat3 R; + R.row(0) = xc; + R.row(1) = yc; + R.row(2) = zc; + return R; +} + +Mat3 CrossProductMatrix(const Vec3 &x) { + Mat3 X; + X << 0, -x(2), x(1), + x(2), 0, -x(0), + -x(1), x(0), 0; + return X; +} + +void MeanAndVarianceAlongRows(const Mat &A, + Vec *mean_pointer, + Vec *variance_pointer) { + Vec &mean = *mean_pointer; + Vec &variance = *variance_pointer; + int n = A.rows(); + int m = A.cols(); + mean.resize(n); + variance.resize(n); + + for (int i = 0; i < n; ++i) { + mean(i) = 0; + variance(i) = 0; + for (int j = 0; j < m; ++j) { + double x = A(i, j); + mean(i) += x; + variance(i) += x * x; + } + } + + mean /= m; + for (int i = 0; i < n; ++i) { + variance(i) = variance(i) / m - Square(mean(i)); + } +} + +void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked) { + assert(left.rows() == left.rows()); + int n = left.rows(); + int m1 = left.cols(); + int m2 = right.cols(); + + stacked->resize(n, m1 + m2); + stacked->block(0, 0, n, m1) = left; + stacked->block(0, m1, n, m2) = right; +} + +void MatrixColumn(const Mat &A, int i, Vec2 *v) { + assert(A.rows() == 2); + *v << A(0,i), A(1,i); +} +void MatrixColumn(const Mat &A, int i, Vec3 *v) { + assert(A.rows() == 3); + *v << A(0,i), A(1,i), A(2,i); +} +void MatrixColumn(const Mat &A, int i, Vec4 *v) { + assert(A.rows() == 4); + *v << A(0,i), A(1,i), A(2,i), A(3,i); +} + +} // namespace libmv + diff --git a/extern/libmv/libmv/numeric/numeric.h b/extern/libmv/libmv/numeric/numeric.h new file mode 100644 index 00000000000..21e0f067446 --- /dev/null +++ b/extern/libmv/libmv/numeric/numeric.h @@ -0,0 +1,479 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Matrix and vector classes, based on Eigen2. +// +// Avoid using Eigen2 classes directly; instead typedef them here. + +#ifndef LIBMV_NUMERIC_NUMERIC_H +#define LIBMV_NUMERIC_NUMERIC_H + +#include +#include +#include +#include +#include +#include +#include + +#if _WIN32 || __APPLE__ + void static sincos (double x, double *sinx, double *cosx) { + *sinx = sin(x); + *cosx = cos(x); + } +#endif //_WIN32 || __APPLE__ + +#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) + inline long lround(double d) { + return (long)(d>0 ? d+0.5 : ceil(d-0.5)); + } + inline int round(double d) { + return (d>0) ? int(d+0.5) : int(d-0.5); + } + typedef unsigned int uint; +#endif //_WIN32 + +namespace libmv { + +typedef Eigen::MatrixXd Mat; +typedef Eigen::VectorXd Vec; + +typedef Eigen::MatrixXf Matf; +typedef Eigen::VectorXf Vecf; + +typedef Eigen::Matrix Matu; +typedef Eigen::Matrix Vecu; +typedef Eigen::Matrix Vec2u; + +typedef Eigen::Matrix Mat2; +typedef Eigen::Matrix Mat23; +typedef Eigen::Matrix Mat3; +typedef Eigen::Matrix Mat34; +typedef Eigen::Matrix Mat35; +typedef Eigen::Matrix Mat41; +typedef Eigen::Matrix Mat43; +typedef Eigen::Matrix Mat4; +typedef Eigen::Matrix Mat46; +typedef Eigen::Matrix Mat2f; +typedef Eigen::Matrix Mat23f; +typedef Eigen::Matrix Mat3f; +typedef Eigen::Matrix Mat34f; +typedef Eigen::Matrix Mat35f; +typedef Eigen::Matrix Mat43f; +typedef Eigen::Matrix Mat4f; +typedef Eigen::Matrix Mat46f; + +typedef Eigen::Matrix RMat3; +typedef Eigen::Matrix RMat4; + +typedef Eigen::Matrix Mat2X; +typedef Eigen::Matrix Mat3X; +typedef Eigen::Matrix Mat4X; +typedef Eigen::Matrix MatX2; +typedef Eigen::Matrix MatX3; +typedef Eigen::Matrix MatX4; +typedef Eigen::Matrix MatX5; +typedef Eigen::Matrix MatX6; +typedef Eigen::Matrix MatX7; +typedef Eigen::Matrix MatX8; +typedef Eigen::Matrix MatX9; +typedef Eigen::Matrix MatX15; +typedef Eigen::Matrix MatX16; + +typedef Eigen::Vector2d Vec2; +typedef Eigen::Vector3d Vec3; +typedef Eigen::Vector4d Vec4; +typedef Eigen::Matrix Vec5; +typedef Eigen::Matrix Vec6; +typedef Eigen::Matrix Vec7; +typedef Eigen::Matrix Vec8; +typedef Eigen::Matrix Vec9; +typedef Eigen::Matrix Vec10; +typedef Eigen::Matrix Vec11; +typedef Eigen::Matrix Vec12; +typedef Eigen::Matrix Vec13; +typedef Eigen::Matrix Vec14; +typedef Eigen::Matrix Vec15; +typedef Eigen::Matrix Vec16; +typedef Eigen::Matrix Vec17; +typedef Eigen::Matrix Vec18; +typedef Eigen::Matrix Vec19; +typedef Eigen::Matrix Vec20; + +typedef Eigen::Vector2f Vec2f; +typedef Eigen::Vector3f Vec3f; +typedef Eigen::Vector4f Vec4f; + +typedef Eigen::VectorXi VecXi; + +typedef Eigen::Vector2i Vec2i; +typedef Eigen::Vector3i Vec3i; +typedef Eigen::Vector4i Vec4i; + +typedef Eigen::Matrix RMatf; + +typedef Eigen::NumTraits EigenDouble; + +using Eigen::Map; +using Eigen::Dynamic; +using Eigen::Matrix; + +// Find U, s, and VT such that +// +// A = U * diag(s) * VT +// +template +inline void SVD(TMat *A, Vec *s, Mat *U, Mat *VT) { + assert(0); +} + +// Solve the linear system Ax = 0 via SVD. Store the solution in x, such that +// ||x|| = 1.0. Return the singluar value corresponding to the solution. +// Destroys A and resizes x if necessary. +// TODO(maclean): Take the SVD of the transpose instead of this zero padding. +template +double Nullspace(TMat *A, TVec *nullspace) { + Eigen::JacobiSVD svd(*A, Eigen::ComputeFullV); + (*nullspace) = svd.matrixV().col(A->cols()-1); + if (A->rows() >= A->cols()) + return svd.singularValues()(A->cols()-1); + else + return 0.0; +} + +// Solve the linear system Ax = 0 via SVD. Finds two solutions, x1 and x2, such +// that x1 is the best solution and x2 is the next best solution (in the L2 +// norm sense). Store the solution in x1 and x2, such that ||x|| = 1.0. Return +// the singluar value corresponding to the solution x1. Destroys A and resizes +// x if necessary. +template +double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2) { + Eigen::JacobiSVD svd(*A, Eigen::ComputeFullV); + *x1 = svd.matrixV().col(A->cols() - 1); + *x2 = svd.matrixV().col(A->cols() - 2); + if (A->rows() >= A->cols()) + return svd.singularValues()(A->cols()-1); + else + return 0.0; +} + +// In place transpose for square matrices. +template +inline void TransposeInPlace(TA *A) { + *A = A->transpose().eval(); +} + +template +inline double NormL1(const TVec &x) { + return x.array().abs().sum(); +} + +template +inline double NormL2(const TVec &x) { + return x.norm(); +} + +template +inline double NormLInfinity(const TVec &x) { + return x.array().abs().maxCoeff(); +} + +template +inline double DistanceL1(const TVec &x, const TVec &y) { + return (x - y).array().abs().sum(); +} + +template +inline double DistanceL2(const TVec &x, const TVec &y) { + return (x - y).norm(); +} +template +inline double DistanceLInfinity(const TVec &x, const TVec &y) { + return (x - y).array().abs().maxCoeff(); +} + +// Normalize a vector with the L1 norm, and return the norm before it was +// normalized. +template +inline double NormalizeL1(TVec *x) { + double norm = NormL1(*x); + *x /= norm; + return norm; +} + +// Normalize a vector with the L2 norm, and return the norm before it was +// normalized. +template +inline double NormalizeL2(TVec *x) { + double norm = NormL2(*x); + *x /= norm; + return norm; +} + +// Normalize a vector with the L^Infinity norm, and return the norm before it +// was normalized. +template +inline double NormalizeLInfinity(TVec *x) { + double norm = NormLInfinity(*x); + *x /= norm; + return norm; +} + +// Return the square of a number. +template +inline T Square(T x) { + return x * x; +} + +Mat3 RotationAroundX(double angle); +Mat3 RotationAroundY(double angle); +Mat3 RotationAroundZ(double angle); + +// Returns the rotation matrix of a rotation of angle |axis| around axis. +// This is computed using the Rodrigues formula, see: +// http://mathworld.wolfram.com/RodriguesRotationFormula.html +Mat3 RotationRodrigues(const Vec3 &axis); + +// Make a rotation matrix such that center becomes the direction of the +// positive z-axis, and y is oriented close to up. +Mat3 LookAt(Vec3 center); + +// Return a diagonal matrix from a vector containg the diagonal values. +template +inline Mat Diag(const TVec &x) { + return x.asDiagonal(); +} + +template +inline double FrobeniusNorm(const TMat &A) { + return sqrt(A.array().abs2().sum()); +} + +template +inline double FrobeniusDistance(const TMat &A, const TMat &B) { + return FrobeniusNorm(A - B); +} + +inline Vec3 CrossProduct(const Vec3 &x, const Vec3 &y) { + return x.cross(y); +} + +Mat3 CrossProductMatrix(const Vec3 &x); + +void MeanAndVarianceAlongRows(const Mat &A, + Vec *mean_pointer, + Vec *variance_pointer); + +#if _WIN32 + // TODO(bomboze): un-#if this for both platforms once tested under Windows + /* This solution was extensively discussed here http://forum.kde.org/viewtopic.php?f=74&t=61940 */ + #define SUM_OR_DYNAMIC(x,y) (x==Eigen::Dynamic||y==Eigen::Dynamic)?Eigen::Dynamic:(x+y) + + template + struct hstack_return { + typedef typename Derived1::Scalar Scalar; + enum { + RowsAtCompileTime = Derived1::RowsAtCompileTime, + ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, Derived2::ColsAtCompileTime), + Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, + MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime, + MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, Derived2::MaxColsAtCompileTime) + }; + typedef Eigen::Matrix type; + }; + + template + typename hstack_return::type + HStack (const Eigen::MatrixBase& lhs, const Eigen::MatrixBase& rhs) { + typename hstack_return::type res; + res.resize(lhs.rows(), lhs.cols()+rhs.cols()); + res << lhs, rhs; + return res; + }; + + + template + struct vstack_return { + typedef typename Derived1::Scalar Scalar; + enum { + RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, Derived2::RowsAtCompileTime), + ColsAtCompileTime = Derived1::ColsAtCompileTime, + Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, + MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, Derived2::MaxRowsAtCompileTime), + MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime + }; + typedef Eigen::Matrix type; + }; + + template + typename vstack_return::type + VStack (const Eigen::MatrixBase& lhs, const Eigen::MatrixBase& rhs) { + typename vstack_return::type res; + res.resize(lhs.rows()+rhs.rows(), lhs.cols()); + res << lhs, rhs; + return res; + }; + + +#else //_WIN32 + + // Since it is not possible to typedef privately here, use a macro. + // Always take dynamic columns if either side is dynamic. + #define COLS \ + ((ColsLeft == Eigen::Dynamic || ColsRight == Eigen::Dynamic) \ + ? Eigen::Dynamic : (ColsLeft + ColsRight)) + + // Same as above, except that prefer fixed size if either is fixed. + #define ROWS \ + ((RowsLeft == Eigen::Dynamic && RowsRight == Eigen::Dynamic) \ + ? Eigen::Dynamic \ + : ((RowsLeft == Eigen::Dynamic) \ + ? RowsRight \ + : RowsLeft \ + ) \ + ) + + // TODO(keir): Add a static assert if both rows are at compiletime. + template + Eigen::Matrix + HStack(const Eigen::Matrix &left, + const Eigen::Matrix &right) { + assert(left.rows() == right.rows()); + int n = left.rows(); + int m1 = left.cols(); + int m2 = right.cols(); + + Eigen::Matrix stacked(n, m1 + m2); + stacked.block(0, 0, n, m1) = left; + stacked.block(0, m1, n, m2) = right; + return stacked; + } + + // Reuse the above macros by swapping the order of Rows and Cols. Nasty, but + // the duplication is worse. + // TODO(keir): Add a static assert if both rows are at compiletime. + // TODO(keir): Mail eigen list about making this work for general expressions + // rather than only matrix types. + template + Eigen::Matrix + VStack(const Eigen::Matrix &top, + const Eigen::Matrix &bottom) { + assert(top.cols() == bottom.cols()); + int n1 = top.rows(); + int n2 = bottom.rows(); + int m = top.cols(); + + Eigen::Matrix stacked(n1 + n2, m); + stacked.block(0, 0, n1, m) = top; + stacked.block(n1, 0, n2, m) = bottom; + return stacked; + } + #undef COLS + #undef ROWS +#endif //_WIN32 + + + +void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked); + +template +void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked) { + assert(top.cols() == bottom.cols()); + int n1 = top.rows(); + int n2 = bottom.rows(); + int m = top.cols(); + + stacked->resize(n1 + n2, m); + stacked->block(0, 0, n1, m) = top; + stacked->block(n1, 0, n2, m) = bottom; +} + +void MatrixColumn(const Mat &A, int i, Vec2 *v); +void MatrixColumn(const Mat &A, int i, Vec3 *v); +void MatrixColumn(const Mat &A, int i, Vec4 *v); + +template +TMat ExtractColumns(const TMat &A, const TCols &columns) { + TMat compressed(A.rows(), columns.size()); + for (int i = 0; i < columns.size(); ++i) { + compressed.col(i) = A.col(columns[i]); + } + return compressed; +} + +template +void reshape(const TMat &a, int rows, int cols, TDest *b) { + assert(a.rows()*a.cols() == rows*cols); + b->resize(rows, cols); + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + (*b)(i, j) = a[cols*i + j]; + } + } +} + +inline bool isnan(double i) { +#ifdef WIN32 + return _isnan(i) > 0; +#else + return std::isnan(i); +#endif +} + +/// Ceil function that has the same behaviour for positive +/// and negative values +template +FloatType ceil0(const FloatType& value) { + FloatType result = std::ceil( std::fabs( value ) ); + return (value < 0.0) ? -result : result; +} + +/// Returns the skew anti-symmetric matrix of a vector +inline Mat3 SkewMat(const Vec3 &x) { + Mat3 skew; + skew << 0 , -x(2), x(1), + x(2), 0 , -x(0), + -x(1), x(0), 0; + return skew; +} +/// Returns the skew anti-symmetric matrix of a vector with only +/// the first two (independent) lines +inline Mat23 SkewMatMinimal(const Vec2 &x) { + Mat23 skew; + skew << 0,-1, x(1), + 1, 0, -x(0); + return skew; +} +} // namespace libmv + +#endif // LIBMV_NUMERIC_NUMERIC_H diff --git a/extern/libmv/libmv/numeric/poly.cc b/extern/libmv/libmv/numeric/poly.cc new file mode 100644 index 00000000000..d96e3c104c7 --- /dev/null +++ b/extern/libmv/libmv/numeric/poly.cc @@ -0,0 +1,23 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// +// Routines for solving polynomials. + +// TODO(keir): Add a solver for degree > 3 polynomials. diff --git a/extern/libmv/libmv/numeric/poly.h b/extern/libmv/libmv/numeric/poly.h new file mode 100644 index 00000000000..cb1d65b32c4 --- /dev/null +++ b/extern/libmv/libmv/numeric/poly.h @@ -0,0 +1,123 @@ +// Copyright (c) 2007, 2008 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_NUMERIC_POLY_H_ +#define LIBMV_NUMERIC_POLY_H_ + +#include +#include + +namespace libmv { + +// Solve the cubic polynomial +// +// x^3 + a*x^2 + b*x + c = 0 +// +// The number of roots (from zero to three) is returned. If the number of roots +// is less than three, then higher numbered x's are not changed. For example, +// if there are 2 roots, only x0 and x1 are set. +// +// The GSL cubic solver was used as a reference for this routine. +template +int SolveCubicPolynomial(Real a, Real b, Real c, + Real *x0, Real *x1, Real *x2) { + Real q = a * a - 3 * b; + Real r = 2 * a * a * a - 9 * a * b + 27 * c; + + Real Q = q / 9; + Real R = r / 54; + + Real Q3 = Q * Q * Q; + Real R2 = R * R; + + Real CR2 = 729 * r * r; + Real CQ3 = 2916 * q * q * q; + + if (R == 0 && Q == 0) { + // Tripple root in one place. + *x0 = *x1 = *x2 = -a / 3 ; + return 3; + + } else if (CR2 == CQ3) { + // This test is actually R2 == Q3, written in a form suitable for exact + // computation with integers. + // + // Due to finite precision some double roots may be missed, and considered + // to be a pair of complex roots z = x +/- epsilon i close to the real + // axis. + Real sqrtQ = sqrt (Q); + if (R > 0) { + *x0 = -2 * sqrtQ - a / 3; + *x1 = sqrtQ - a / 3; + *x2 = sqrtQ - a / 3; + } else { + *x0 = -sqrtQ - a / 3; + *x1 = -sqrtQ - a / 3; + *x2 = 2 * sqrtQ - a / 3; + } + return 3; + + } else if (CR2 < CQ3) { + // This case is equivalent to R2 < Q3. + Real sqrtQ = sqrt (Q); + Real sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; + Real theta = acos (R / sqrtQ3); + Real norm = -2 * sqrtQ; + *x0 = norm * cos (theta / 3) - a / 3; + *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3; + *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3; + + // Put the roots in ascending order. + if (*x0 > *x1) { + std::swap(*x0, *x1); + } + if (*x1 > *x2) { + std::swap(*x1, *x2); + if (*x0 > *x1) { + std::swap(*x0, *x1); + } + } + return 3; + } + Real sgnR = (R >= 0 ? 1 : -1); + Real A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0); + Real B = Q / A ; + *x0 = A + B - a / 3; + return 1; +} + +// The coefficients are in ascending powers, i.e. coeffs[N]*x^N. +template +int SolveCubicPolynomial(const Real *coeffs, Real *solutions) { + if (coeffs[0] == 0.0) { + // TODO(keir): This is a quadratic not a cubic. Implement a quadratic + // solver! + return 0; + } + Real a = coeffs[2] / coeffs[3]; + Real b = coeffs[1] / coeffs[3]; + Real c = coeffs[0] / coeffs[3]; + return SolveCubicPolynomial(a, b, c, + solutions + 0, + solutions + 1, + solutions + 2); +} +} // namespace libmv +#endif // LIBMV_NUMERIC_POLY_H_ diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc new file mode 100644 index 00000000000..cb8822dcf44 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/bundle.cc @@ -0,0 +1,184 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#define V3DLIB_ENABLE_SUITESPARSE 1 + +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/fundamental.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" +#include "third_party/ssba/Geometry/v3d_cameramatrix.h" +#include "third_party/ssba/Geometry/v3d_metricbundle.h" +#include "third_party/ssba/Math/v3d_linear.h" +#include "third_party/ssba/Math/v3d_linear_utils.h" + +namespace libmv { + +void EuclideanBundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction) { + vector markers = tracks.AllMarkers(); + + // "index" in this context is the index that V3D's optimizer will see. The + // V3D index must be dense in that the cameras are numbered 0...n-1, which is + // not the case for the "image" numbering that arises from the tracks + // structure. The complicated mapping is necessary to convert between the two + // representations. + std::map camera_to_index; + std::map point_to_index; + vector index_to_camera; + vector index_to_point; + int num_cameras = 0; + int num_points = 0; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + EuclideanCamera *camera = reconstruction->CameraForImage(marker.image); + EuclideanPoint *point = reconstruction->PointForTrack(marker.track); + if (camera && point) { + if (camera_to_index.find(camera) == camera_to_index.end()) { + camera_to_index[camera] = num_cameras; + index_to_camera.push_back(camera); + num_cameras++; + } + if (point_to_index.find(point) == point_to_index.end()) { + point_to_index[point] = num_points; + index_to_point.push_back(point); + num_points++; + } + } + } + + // Make a V3D identity matrix, needed in a few places for K, since this + // assumes a calibrated setup. + V3D::Matrix3x3d identity3x3; + identity3x3[0][0] = 1.0; + identity3x3[0][1] = 0.0; + identity3x3[0][2] = 0.0; + identity3x3[1][0] = 0.0; + identity3x3[1][1] = 1.0; + identity3x3[1][2] = 0.0; + identity3x3[2][0] = 0.0; + identity3x3[2][1] = 0.0; + identity3x3[2][2] = 1.0; + + // Convert libmv's cameras to V3D's cameras. + std::vector v3d_cameras(index_to_camera.size()); + for (int k = 0; k < index_to_camera.size(); ++k) { + V3D::Matrix3x3d R; + V3D::Vector3d t; + + // Libmv's rotation matrix type. + const Mat3 &R_libmv = index_to_camera[k]->R; + const Vec3 &t_libmv = index_to_camera[k]->t; + + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + R[i][j] = R_libmv(i, j); + } + t[i] = t_libmv(i); + } + v3d_cameras[k].setIntrinsic(identity3x3); + v3d_cameras[k].setRotation(R); + v3d_cameras[k].setTranslation(t); + } + LG << "Number of cameras: " << index_to_camera.size(); + + // Convert libmv's points to V3D's points. + std::vector v3d_points(index_to_point.size()); + for (int i = 0; i < index_to_point.size(); i++) { + v3d_points[i][0] = index_to_point[i]->X(0); + v3d_points[i][1] = index_to_point[i]->X(1); + v3d_points[i][2] = index_to_point[i]->X(2); + } + LG << "Number of points: " << index_to_point.size(); + + // Convert libmv's measurements to v3d measurements. + int num_residuals = 0; + std::vector v3d_measurements; + std::vector v3d_camera_for_measurement; + std::vector v3d_point_for_measurement; + for (int i = 0; i < markers.size(); ++i) { + EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image); + EuclideanPoint *point = reconstruction->PointForTrack(markers[i].track); + if (!camera || !point) { + continue; + } + V3D::Vector2d v3d_point; + v3d_point[0] = markers[i].x; + v3d_point[1] = markers[i].y; + v3d_measurements.push_back(v3d_point); + v3d_camera_for_measurement.push_back(camera_to_index[camera]); + v3d_point_for_measurement.push_back(point_to_index[point]); + num_residuals++; + } + LG << "Number of residuals: " << num_residuals; + + // This is calibrated reconstruction, so use zero distortion. + V3D::StdDistortionFunction v3d_distortion; + v3d_distortion.k1 = 0; + v3d_distortion.k2 = 0; + v3d_distortion.p1 = 0; + v3d_distortion.p2 = 0; + + // Finally, run the bundle adjustment. + double const inlierThreshold = 500000.0; + V3D::CommonInternalsMetricBundleOptimizer opt(V3D::FULL_BUNDLE_METRIC, + inlierThreshold, + identity3x3, + v3d_distortion, + v3d_cameras, + v3d_points, + v3d_measurements, + v3d_camera_for_measurement, + v3d_point_for_measurement); + opt.maxIterations = 50; + opt.minimize(); + LG << "Bundle status: " << opt.status; + + // Convert V3D's cameras back to libmv's cameras. + for (int k = 0; k < num_cameras; k++) { + V3D::Matrix3x4d const Rt = v3d_cameras[k].getOrientation(); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 3; ++j) { + index_to_camera[k]->R(i, j) = Rt[i][j]; + } + index_to_camera[k]->t(i) = Rt[i][3]; + } + } + + // Convert V3D's points back to libmv's points. + for (int k = 0; k < num_points; k++) { + for (int i = 0; i < 3; ++i) { + index_to_point[k]->X(i) = v3d_points[k][i]; + } + } +} + +void ProjectiveBundle(const Tracks & /*tracks*/, + ProjectiveReconstruction * /*reconstruction*/) { + // TODO(keir): Implement this! This can't work until we have a better bundler + // than SSBA, since SSBA has no support for projective bundling. +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/bundle.h b/extern/libmv/libmv/simple_pipeline/bundle.h new file mode 100644 index 00000000000..c7fb2a79607 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/bundle.h @@ -0,0 +1,72 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_BUNDLE_H +#define LIBMV_SIMPLE_PIPELINE_BUNDLE_H + +namespace libmv { + +class EuclideanReconstruction; +class ProjectiveReconstruction; +class Tracks; + +/*! + Refine camera poses and 3D coordinates using bundle adjustment. + + This routine adjusts all cameras and points in \a *reconstruction. This + assumes a full observation for reconstructed tracks; this implies that if + there is a reconstructed 3D point (a bundle) for a track, then all markers + for that track will be included in the minimization. \a tracks should + contain markers used in the initial reconstruction. + + The cameras and bundles (3D points) are refined in-place. + + \note This assumes an outlier-free set of markers. + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + + \sa EuclideanResect, EuclideanIntersect, EuclideanReconstructTwoFrames +*/ +void EuclideanBundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction); + +/*! + Refine camera poses and 3D coordinates using bundle adjustment. + + This routine adjusts all cameras and points in \a *reconstruction. This + assumes a full observation for reconstructed tracks; this implies that if + there is a reconstructed 3D point (a bundle) for a track, then all markers + for that track will be included in the minimization. \a tracks should + contain markers used in the initial reconstruction. + + The cameras and bundles (homogeneous 3D points) are refined in-place. + + \note This assumes an outlier-free set of markers. + \note This assumes that radial distortion is already corrected for, but + does not assume that that other intrinsics are. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveReconstructTwoFrames +*/ +void ProjectiveBundle(const Tracks &tracks, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_BUNDLE_H diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc new file mode 100644 index 00000000000..366129dd3d2 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc @@ -0,0 +1,351 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/camera_intrinsics.h" +#include "libmv/numeric/levenberg_marquardt.h" + +namespace libmv { + +struct Offset { + signed char ix, iy; + unsigned char fx,fy; +}; + +struct Grid { + struct Offset *offset; + int width, height; + double overscan; +}; + +static struct Grid *copyGrid(struct Grid *from) +{ + struct Grid *to = NULL; + + if (from) { + to = new Grid; + + to->width = from->width; + to->height = from->height; + to->overscan = from->overscan; + + to->offset = new Offset[to->width*to->height]; + memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height); + } + + return to; +} + +CameraIntrinsics::CameraIntrinsics() + : K_(Mat3::Identity()), + image_width_(0), + image_height_(0), + k1_(0), + k2_(0), + k3_(0), + p1_(0), + p2_(0), + distort_(0), + undistort_(0) {} + +CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from) + : K_(from.K_), + image_width_(from.image_width_), + image_height_(from.image_height_), + k1_(from.k1_), + k2_(from.k2_), + k3_(from.k3_), + p1_(from.p1_), + p2_(from.p2_) +{ + distort_ = copyGrid(from.distort_); + undistort_ = copyGrid(from.undistort_); +} + +CameraIntrinsics::~CameraIntrinsics() { + FreeLookupGrid(); +} + +/// Set the entire calibration matrix at once. +void CameraIntrinsics::SetK(const Mat3 new_k) { + K_ = new_k; + FreeLookupGrid(); +} + +/// Set both x and y focal length in pixels. +void CameraIntrinsics::SetFocalLength(double focal_x, double focal_y) { + K_(0, 0) = focal_x; + K_(1, 1) = focal_y; + FreeLookupGrid(); +} + +void CameraIntrinsics::SetPrincipalPoint(double cx, double cy) { + K_(0, 2) = cx; + K_(1, 2) = cy; + FreeLookupGrid(); +} + +void CameraIntrinsics::SetImageSize(int width, int height) { + image_width_ = width; + image_height_ = height; + FreeLookupGrid(); +} + +void CameraIntrinsics::SetRadialDistortion(double k1, double k2, double k3) { + k1_ = k1; + k2_ = k2; + k3_ = k3; + FreeLookupGrid(); +} + +void CameraIntrinsics::SetTangentialDistortion(double p1, double p2) { + p1_ = p1; + p2_ = p2; + FreeLookupGrid(); +} + +void CameraIntrinsics::ApplyIntrinsics(double normalized_x, + double normalized_y, + double *image_x, + double *image_y) const { + double x = normalized_x; + double y = normalized_y; + + // Apply distortion to the normalized points to get (xd, yd). + double r2 = x*x + y*y; + double r4 = r2 * r2; + double r6 = r4 * r2; + double r_coeff = (1 + k1_*r2 + k2_*r4 + k3_*r6); + double xd = x * r_coeff + 2*p1_*x*y + p2_*(r2 + 2*x*x); + double yd = y * r_coeff + 2*p2_*x*y + p1_*(r2 + 2*y*y); + + // Apply focal length and principal point to get the final image coordinates. + *image_x = focal_length_x() * xd + principal_point_x(); + *image_y = focal_length_y() * yd + principal_point_y(); +} + +struct InvertIntrinsicsCostFunction { + public: + typedef Vec2 FMatrixType; + typedef Vec2 XMatrixType; + + InvertIntrinsicsCostFunction(const CameraIntrinsics &intrinsics, + double image_x, double image_y) + : intrinsics(intrinsics), x(image_x), y(image_y) {} + + Vec2 operator()(const Vec2 &u) const { + double xx, yy; + intrinsics.ApplyIntrinsics(u(0), u(1), &xx, &yy); + Vec2 fx; + fx << (xx - x), (yy - y); + return fx; + } + const CameraIntrinsics &intrinsics; + double x, y; +}; + +void CameraIntrinsics::InvertIntrinsics(double image_x, + double image_y, + double *normalized_x, + double *normalized_y) const { + // Compute the initial guess. For a camera with no distortion, this will also + // be the final answer; the LM iteration will terminate immediately. + Vec2 normalized; + normalized(0) = (image_x - principal_point_x()) / focal_length_x(); + normalized(1) = (image_y - principal_point_y()) / focal_length_y(); + + typedef LevenbergMarquardt Solver; + + InvertIntrinsicsCostFunction intrinsics_cost(*this, image_x, image_y); + Solver::SolverParameters params; + Solver solver(intrinsics_cost); + + /*Solver::Results results =*/ solver.minimize(params, &normalized); + + // TODO(keir): Better error handling. + + *normalized_x = normalized(0); + *normalized_y = normalized(1); +} + +// TODO(MatthiasF): downsample lookup +template +void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, double overscan) { + double w = (double)width / (1 + overscan); + double h = (double)height / (1 + overscan); + double aspx = (double)w / image_width_; + double aspy = (double)h / image_height_; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy; + double warp_x, warp_y; + WarpFunction(this,src_x,src_y,&warp_x,&warp_y); + warp_x = warp_x*aspx + 0.5 * overscan * w; + warp_y = warp_y*aspy + 0.5 * overscan * h; + int ix = int(warp_x), iy = int(warp_y); + int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256); + if(fx == 256) { fx=0; ix++; } + if(fy == 256) { fy=0; iy++; } + // Use nearest border pixel + if( ix < 0 ) { ix = 0, fx = 0; } + if( iy < 0 ) { iy = 0, fy = 0; } + if( ix >= width-2 ) ix = width-2; + if( iy >= height-2 ) iy = height-2; + if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) { + Offset offset = { ix-x, iy-y, fx, fy }; + grid->offset[y*width+x] = offset; + } else { + Offset offset = { 0, 0, 0, 0 }; + grid->offset[y*width+x] = offset; + } + } + } +} + +// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup +template +static void Warp(const Grid* grid, const T* src, T* dst, + int width, int height) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + Offset offset = grid->offset[y*width+x]; + const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N]; + for (int i = 0; i < N; i++) { + dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy) + +(s[width*N+i] * (256-offset.fx) + s[width*N+N+i] * offset.fx) * offset.fy) / (256*256); + } + } + } +} + +void CameraIntrinsics::FreeLookupGrid() { + if(distort_) { + delete distort_->offset; + delete distort_; + distort_ = NULL; + } + + if(undistort_) { + delete undistort_->offset; + delete undistort_; + undistort_ = NULL; + } +} + +// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method. +struct ApplyIntrinsicsFunction { + ApplyIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y, + double *warp_x, double *warp_y) { + intrinsics->ApplyIntrinsics( + (x-intrinsics->principal_point_x())/intrinsics->focal_length_x(), + (y-intrinsics->principal_point_y())/intrinsics->focal_length_y(), + warp_x, warp_y); + } +}; +struct InvertIntrinsicsFunction { + InvertIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y, + double *warp_x, double *warp_y) { + intrinsics->InvertIntrinsics(x,y,warp_x,warp_y); + *warp_x = *warp_x*intrinsics->focal_length_x()+intrinsics->principal_point_x(); + *warp_y = *warp_y*intrinsics->focal_length_y()+intrinsics->principal_point_y(); + } +}; + +void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double overscan) +{ + if(distort_) { + if(distort_->width != width || distort_->height != height || distort_->overscan != overscan) { + delete [] distort_->offset; + distort_->offset = NULL; + } + } else { + distort_ = new Grid; + distort_->offset = NULL; + } + + if(!distort_->offset) { + distort_->offset = new Offset[width*height]; + ComputeLookupGrid(distort_,width,height,overscan); + } + + distort_->width = width; + distort_->height = height; + distort_->overscan = overscan; +} + +void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double overscan) +{ + if(undistort_) { + if(undistort_->width != width || undistort_->height != height || undistort_->overscan != overscan) { + delete [] undistort_->offset; + undistort_->offset = NULL; + } + } else { + undistort_ = new Grid; + undistort_->offset = NULL; + } + + if(!undistort_->offset) { + undistort_->offset = new Offset[width*height]; + ComputeLookupGrid(undistort_,width,height,overscan); + } + + undistort_->width = width; + undistort_->height = height; + undistort_->overscan = overscan; +} + +void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) { + CheckDistortLookupGrid(width, height, overscan); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); + else if(channels==4) Warp(distort_,src,dst,width,height); + //else assert("channels must be between 1 and 4"); +} + +void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { + CheckDistortLookupGrid(width, height, overscan); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); + else if(channels==4) Warp(distort_,src,dst,width,height); + //else assert("channels must be between 1 and 4"); +} + +void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) { + CheckUndistortLookupGrid(width, height, overscan); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); + else if(channels==4) Warp(undistort_,src,dst,width,height); + //else assert("channels must be between 1 and 4"); +} + +void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { + CheckUndistortLookupGrid(width, height, overscan); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); + else if(channels==4) Warp(undistort_,src,dst,width,height); + //else assert("channels must be between 1 and 4"); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h new file mode 100644 index 00000000000..f4bf903c36c --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h @@ -0,0 +1,152 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ +#define LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ + +#include +typedef Eigen::Matrix Mat3; + +namespace libmv { + +struct Grid; + +class CameraIntrinsics { + public: + CameraIntrinsics(); + CameraIntrinsics(const CameraIntrinsics &from); + ~CameraIntrinsics(); + + const Mat3 &K() const { return K_; } + // FIXME(MatthiasF): these should be CamelCase methods + double focal_length() const { return K_(0, 0); } + double focal_length_x() const { return K_(0, 0); } + double focal_length_y() const { return K_(1, 1); } + double principal_point_x() const { return K_(0, 2); } + double principal_point_y() const { return K_(1, 2); } + int image_width() const { return image_width_; } + int image_height() const { return image_height_; } + double k1() const { return k1_; } + double k2() const { return k2_; } + double k3() const { return k3_; } + double p1() const { return p1_; } + double p2() const { return p2_; } + + /// Set the entire calibration matrix at once. + void SetK(const Mat3 new_k); + + /// Set both x and y focal length in pixels. + void SetFocalLength(double focal_x, double focal_y); + + void SetPrincipalPoint(double cx, double cy); + + void SetImageSize(int width, int height); + + void SetRadialDistortion(double k1, double k2, double k3 = 0); + + void SetTangentialDistortion(double p1, double p2); + + /*! + Apply camera intrinsics to the normalized point to get image coordinates. + + This applies the lens distortion to a point which is in normalized + camera coordinates (i.e. the principal point is at (0, 0)) to get image + coordinates in pixels. + */ + void ApplyIntrinsics(double normalized_x, double normalized_y, + double *image_x, double *image_y) const; + + /*! + Invert camera intrinsics on the image point to get normalized coordinates. + + This reverses the effect of lens distortion on a point which is in image + coordinates to get normalized camera coordinates. + */ + void InvertIntrinsics(double image_x, double image_y, + double *normalized_x, double *normalized_y) const; + + /*! + Distort an image using the current camera instrinsics + + The distorted image is computed in \a dst using samples from \a src. + both buffers should be \a width x \a height x \a channels sized. + + \note This is the reference implementation using floating point images. + */ + void Distort(const float* src, float* dst, + int width, int height, double overscan, int channels); + /*! + Distort an image using the current camera instrinsics + + The distorted image is computed in \a dst using samples from \a src. + both buffers should be \a width x \a height x \a channels sized. + + \note This version is much faster. + */ + void Distort(const unsigned char* src, unsigned char* dst, + int width, int height, double overscan, int channels); + /*! + Undistort an image using the current camera instrinsics + + The undistorted image is computed in \a dst using samples from \a src. + both buffers should be \a width x \a height x \a channels sized. + + \note This is the reference implementation using floating point images. + */ + void Undistort(const float* src, float* dst, + int width, int height, double overscan, int channels); + /*! + Undistort an image using the current camera instrinsics + + The undistorted image is computed in \a dst using samples from \a src. + both buffers should be \a width x \a height x \a channels sized. + + \note This version is much faster. + */ + void Undistort(const unsigned char* src, unsigned char* dst, + int width, int height, double overscan, int channels); + + private: + template void ComputeLookupGrid(struct Grid* grid, int width, int height, double overscan); + void CheckUndistortLookupGrid(int width, int height, double overscan); + void CheckDistortLookupGrid(int width, int height, double overscan); + void FreeLookupGrid(); + + // The traditional intrinsics matrix from x = K[R|t]X. + Mat3 K_; + + // This is the size of the image. This is necessary to, for example, handle + // the case of processing a scaled image. + int image_width_; + int image_height_; + + // OpenCV's distortion model with third order polynomial radial distortion + // terms and second order tangential distortion. The distortion is applied to + // the normalized coordinates before the focal length, which makes them + // independent of image size. + double k1_, k2_, k3_, p1_, p2_; + + struct Grid *distort_; + struct Grid *undistort_; +}; + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_CAMERA_INTRINSICS_H_ diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc new file mode 100644 index 00000000000..8ac42ab0aba --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/detect.cc @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (c) 2011 libmv authors. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to +** deal in the Software without restriction, including without limitation the +** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +** sell copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +** IN THE SOFTWARE. +** +****************************************************************************/ + +#include "libmv/simple_pipeline/detect.h" +#include +#include +#include + +#ifdef __SSE2__ +#include +#endif + +namespace libmv { + +typedef unsigned int uint; + +int featurecmp(const void *a_v, const void *b_v) +{ + Feature *a = (Feature*)a_v; + Feature *b = (Feature*)b_v; + + return b->score - a->score; +} + +std::vector DetectFAST(const unsigned char* data, int width, int height, int stride, + int min_trackness, int min_distance) { + std::vector features; + // TODO(MatthiasF): Support targetting a feature count (binary search trackness) + int num_features; + xy* all = fast9_detect(data, width, height, + stride, min_trackness, &num_features); + if(num_features == 0) { + free(all); + return features; + } + int* scores = fast9_score(data, stride, all, num_features, min_trackness); + // TODO: merge with close feature suppression + xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features); + free(all); + // Remove too close features + // TODO(MatthiasF): A resolution independent parameter would be better than distance + // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing) + // FIXME(MatthiasF): this method will not necessarily give all maximum markers + if(num_features) { + Feature *all_features = new Feature[num_features]; + + for(int i = 0; i < num_features; ++i) { + Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 }; + all_features[i] = a; + } + + qsort((void *)all_features, num_features, sizeof(Feature), featurecmp); + + features.reserve(num_features); + + int prev_score = all_features[0].score; + for(int i = 0; i < num_features; ++i) { + bool ok = true; + Feature a = all_features[i]; + if(a.score>prev_score) + abort(); + prev_score = a.score; + + // compare each feature against filtered set + for(int j = 0; j < features.size(); j++) { + Feature& b = features[j]; + if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) { + // already a nearby feature + ok = false; + break; + } + } + + if(ok) { + // add the new feature + features.push_back(a); + } + } + + delete [] all_features; + } + free(scores); + free(nonmax); + return features; +} + +#ifdef __SSE2__ +static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { + __m128i a = _mm_setzero_si128(); + for(int i = 0; i < 16; i++) { + a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(imageA+i*strideA)), + _mm_loadu_si128((__m128i*)(imageB+i*strideB)))); + } + return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4); +} +#else +static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { + uint sad=0; + for(int i = 0; i < 16; i++) { + for(int j = 0; j < 16; j++) { + sad += abs((int)imageA[i*strideA+j] - imageB[i*strideB+j]); + } + } + return sad; +} +#endif + +void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) { + unsigned short histogram[256]; + memset(histogram,0,sizeof(histogram)); + ubyte* scores = new ubyte[width*height]; + memset(scores,0,width*height); + const int r = 1; //radius for self similarity comparison + for(int y=distance; y255) score=255; // clip + ubyte* c = &scores[y*width+x]; + for(int i=-distance; i<0; i++) { + for(int j=-distance; j= score) goto nonmax; + c[i*width+j]=0, histogram[s]--; + } + } + for(int i=0, j=-distance; j<0; j++) { + int s = c[i*width+j]; + if(s == 0) continue; + if(s >= score) goto nonmax; + c[i*width+j]=0, histogram[s]--; + } + c[0] = score, histogram[score]++; + nonmax:; + } + } + int min=255, total=0; + for(; min>0; min--) { + int h = histogram[min]; + if(total+h > *count) break; + total += h; + } + int i=0; + for(int y=16; ymin) detected[i++] = f; + } + } + *count = i; + delete[] scores; +} + +} diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h new file mode 100644 index 00000000000..bbe7aed784c --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/detect.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (c) 2011 libmv authors. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to +** deal in the Software without restriction, including without limitation the +** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +** sell copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +** IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_ +#define LIBMV_SIMPLE_PIPELINE_DETECT_H_ + +#include + +namespace libmv { + +typedef unsigned char ubyte; + +/*! + A Feature is the 2D location of a detected feature in an image. + + \a x, \a y is the position of the feature in pixels from the top left corner. + \a score is an estimate of how well the feature will be tracked. + \a size can be used as an initial pattern size to track the feature. + + \sa Detect +*/ +struct Feature { + /// Position in pixels (from top-left corner) + /// \note libmv might eventually support subpixel precision. + float x, y; + /// Trackness of the feature + float score; + /// Size of the feature in pixels + float size; +}; + +/*! + Detect features in an image. + + You need to input a single channel 8-bit image using pointer to image \a data, + \a width, \a height and \a stride (i.e bytes per line). + + You can tweak the count of detected features using \a min_trackness, which is + the minimum score to add a feature, and \a min_distance which is the minimal + distance accepted between two featuress. + + \note You can binary search over \a min_trackness to get a given feature count. + + \note a way to get an uniform distribution of a given feature count is: + \a min_distance = \a width * \a height / desired_feature_count ^ 2 + + \return All detected feartures matching given parameters +*/ +std::vector DetectFAST(const unsigned char* data, int width, int height, + int stride, int min_trackness = 128, + int min_distance = 120); + +/*! + Detect features in an image. + + \a image is a single channel 8-bit image of size \a width x \a height + + \a detected is an array with space to hold \a *count features. + \a *count is the maximum count to detect on input and the actual + detected count on output. + + \a distance is the minimal distance between detected features. + + if \a pattern is null all good features will be found. + if \a pattern is not null only features similar to \a pattern will be found. + + \note \a You can crop the image (to avoid detecting markers near the borders) without copying: + image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY; +*/ +void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/); + +} + +#endif diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc new file mode 100644 index 00000000000..0597f09f728 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc @@ -0,0 +1,218 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/fundamental.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { +namespace { + +void CoordinatesForMarkersInImage(const vector &markers, + int image, + Mat *coordinates) { + vector coords; + for (int i = 0; i < markers.size(); ++i) { + const Marker &marker = markers[i]; + if (markers[i].image == image) { + coords.push_back(Vec2(marker.x, marker.y)); + } + } + coordinates->resize(2, coords.size()); + for (int i = 0; i < coords.size(); i++) { + coordinates->col(i) = coords[i]; + } +} + +void GetImagesInMarkers(const vector &markers, + int *image1, int *image2) { + if (markers.size() < 2) { + return; + } + *image1 = markers[0].image; + for (int i = 1; i < markers.size(); ++i) { + if (markers[i].image != *image1) { + *image2 = markers[i].image; + return; + } + } + *image2 = -1; + LOG(FATAL) << "Only one image in the markers."; +} + +} // namespace + +bool EuclideanReconstructTwoFrames(const vector &markers, + EuclideanReconstruction *reconstruction) { + if (markers.size() < 16) { + return false; + } + + int image1, image2; + GetImagesInMarkers(markers, &image1, &image2); + + Mat x1, x2; + CoordinatesForMarkersInImage(markers, image1, &x1); + CoordinatesForMarkersInImage(markers, image2, &x2); + + Mat3 F; + NormalizedEightPointSolver(x1, x2, &F); + + // The F matrix should be an E matrix, but squash it just to be sure. + Eigen::JacobiSVD svd(F, Eigen::ComputeFullU | Eigen::ComputeFullV); + + // See Hartley & Zisserman page 294, result 11.1, which shows how to get the + // closest essential matrix to a matrix that is "almost" an essential matrix. + double a = svd.singularValues()(0); + double b = svd.singularValues()(1); + double s = (a + b) / 2.0; + LG << "Initial reconstruction's rotation is non-euclidean by " + << (((a - b) / std::max(a, b)) * 100) << "%; singular values:" + << svd.singularValues().transpose(); + + Vec3 diag; + diag << s, s, 0; + Mat3 E = svd.matrixU() * diag.asDiagonal() * svd.matrixV().transpose(); + + // Recover motion between the two images. Since this function assumes a + // calibrated camera, use the identity for K. + Mat3 R; + Vec3 t; + Mat3 K = Mat3::Identity(); + if (!MotionFromEssentialAndCorrespondence(E, + K, x1.col(0), + K, x2.col(0), + &R, &t)) { + return false; + } + + // Image 1 gets the reference frame, image 2 gets the relative motion. + reconstruction->InsertCamera(image1, Mat3::Identity(), Vec3::Zero()); + reconstruction->InsertCamera(image2, R, t); + + LG << "From two frame reconstruction got:\nR:\n" << R + << "\nt:" << t.transpose(); + return true; +} + +namespace { + +Mat3 DecodeF(const Vec9 &encoded_F) { + // Decode F and force it to be rank 2. + Map full_rank_F(encoded_F.data(), 3, 3); + Eigen::JacobiSVD svd(full_rank_F, Eigen::ComputeFullU | Eigen::ComputeFullV); + Vec3 diagonal = svd.singularValues(); + diagonal(2) = 0; + Mat3 F = svd.matrixU() * diagonal.asDiagonal() * svd.matrixV().transpose(); + return F; +} + +// This is the stupidest way to refine F known to mankind, since it requires +// doing a full SVD of F at each iteration. This uses sampson error. +struct FundamentalSampsonCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec9 XMatrixType; + + // Assumes markers are ordered by track. + FundamentalSampsonCostFunction(const vector &markers) + : markers(markers) {} + + Vec operator()(const Vec9 &encoded_F) const { + // Decode F and force it to be rank 2. + Mat3 F = DecodeF(encoded_F); + + Vec residuals(markers.size() / 2); + residuals.setZero(); + for (int i = 0; i < markers.size() / 2; ++i) { + const Marker &marker1 = markers[2*i + 0]; + const Marker &marker2 = markers[2*i + 1]; + CHECK_EQ(marker1.track, marker2.track); + Vec2 x1(marker1.x, marker1.y); + Vec2 x2(marker2.x, marker2.y); + + residuals[i] = SampsonDistance(F, x1, x2); + } + return residuals; + } + const vector &markers; +}; + +} // namespace + +bool ProjectiveReconstructTwoFrames(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 16) { + return false; + } + + int image1, image2; + GetImagesInMarkers(markers, &image1, &image2); + + Mat x1, x2; + CoordinatesForMarkersInImage(markers, image1, &x1); + CoordinatesForMarkersInImage(markers, image2, &x2); + + Mat3 F; + NormalizedEightPointSolver(x1, x2, &F); + + // XXX Verify sampson distance. +#if 0 + // Refine the resulting projection fundamental matrix using Sampson's + // approximation of geometric error. This avoids having to do a full bundle + // at the cost of some accuracy. + // + // TODO(keir): After switching to a better bundling library, use a proper + // full bundle adjust here instead of this lame bundle adjustment. + typedef LevenbergMarquardt Solver; + + FundamentalSampsonCostFunction fundamental_cost(markers); + + // Pack the initial P matrix into a size-12 vector.. + Vec9 encoded_F = Map(F.data(), 3, 3); + + Solver solver(fundamental_cost); + + Solver::SolverParameters params; + Solver::Results results = solver.minimize(params, &encoded_F); + // TODO(keir): Check results to ensure clean termination. + + // Recover F from the minimization. + F = DecodeF(encoded_F); +#endif + + // Image 1 gets P = [I|0], image 2 gets arbitrary P. + Mat34 P1 = Mat34::Zero(); + P1.block<3, 3>(0, 0) = Mat3::Identity(); + Mat34 P2; + ProjectionsFromFundamental(F, &P1, &P2); + + reconstruction->InsertCamera(image1, P1); + reconstruction->InsertCamera(image2, P2); + + LG << "From two frame reconstruction got P2:\n" << P2; + return true; +} +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h new file mode 100644 index 00000000000..f512c9a3439 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h @@ -0,0 +1,74 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H +#define LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H + +#include "libmv/base/vector.h" + +namespace libmv { + +struct Marker; +class EuclideanReconstruction; +class ProjectiveReconstruction; + +/*! + Initialize the \link EuclideanReconstruction reconstruction \endlink using + two frames. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in both frames. The pose estimation of the camera for + these frames will be inserted into \a *reconstruction. + + \note The two frames need to have both enough parallax and enough common tracks + for accurate reconstruction. At least 8 tracks are suggested. + \note The origin of the coordinate system is defined to be the camera of + the first keyframe. + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \sa EuclideanResect, EuclideanIntersect, EuclideanBundle +*/ +bool EuclideanReconstructTwoFrames(const vector &markers, + EuclideanReconstruction *reconstruction); + +/*! + Initialize the \link ProjectiveReconstruction reconstruction \endlink using + two frames. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in both frames. An estimate of the projection matrices for + the two frames will get added to the reconstruction. + + \note The two frames need to have both enough parallax and enough common tracks + for accurate reconstruction. At least 8 tracks are suggested. + \note The origin of the coordinate system is defined to be the camera of + the first keyframe. + \note This assumes the markers are already corrected for radial distortion. + \note This assumes an outlier-free set of markers. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle +*/ +bool ProjectiveReconstructTwoFrames(const vector &markers, + ProjectiveReconstruction *reconstruction); +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_INITIALIZE_RECONSTRUCTION_H diff --git a/extern/libmv/libmv/simple_pipeline/intersect.cc b/extern/libmv/libmv/simple_pipeline/intersect.cc new file mode 100644 index 00000000000..b1518e04651 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/intersect.cc @@ -0,0 +1,205 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/projection.h" +#include "libmv/multiview/triangulation.h" +#include "libmv/multiview/nviewtriangulation.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { + +namespace { + +struct EuclideanIntersectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec3 XMatrixType; + + EuclideanIntersectCostFunction(const vector &markers, + const EuclideanReconstruction &reconstruction) + : markers(markers), + reconstruction(reconstruction) {} + + Vec operator()(const Vec3 &X) const { + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const EuclideanCamera &camera = + *reconstruction.CameraForImage(markers[i].image); + Vec3 projected = camera.R * X + camera.t; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + const vector &markers; + const EuclideanReconstruction &reconstruction; +}; + +} // namespace + +bool EuclideanIntersect(const vector &markers, + EuclideanReconstruction *reconstruction) { + if (markers.size() < 2) { + return false; + } + + // Compute projective camera matrices for the cameras the intersection is + // going to use. + Mat3 K = Mat3::Identity(); + vector cameras; + Mat34 P; + for (int i = 0; i < markers.size(); ++i) { + EuclideanCamera *camera = reconstruction->CameraForImage(markers[i].image); + P_From_KRt(K, camera->R, camera->t, &P); + cameras.push_back(P); + } + + // Stack the 2D coordinates together as required by NViewTriangulate. + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + + Vec4 Xp; + LG << "Intersecting with " << markers.size() << " markers."; + NViewTriangulateAlgebraic(points, cameras, &Xp); + + // Get euclidean version of the homogeneous point. + Xp /= Xp(3); + Vec3 X = Xp.head<3>(); + + typedef LevenbergMarquardt Solver; + + EuclideanIntersectCostFunction triangulate_cost(markers, *reconstruction); + Solver::SolverParameters params; + Solver solver(triangulate_cost); + + Solver::Results results = solver.minimize(params, &X); + + // Try projecting the point; make sure it's in front of everyone. + for (int i = 0; i < cameras.size(); ++i) { + const EuclideanCamera &camera = + *reconstruction->CameraForImage(markers[i].image); + Vec3 x = camera.R * X + camera.t; + if (x(2) < 0) { + LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image + << ": " << x.transpose(); + } + } + + Vec3 point = X.head<3>(); + reconstruction->InsertPoint(markers[0].track, point); + + // TODO(keir): Add proper error checking. + return true; +} + +namespace { + +struct ProjectiveIntersectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec4 XMatrixType; + + ProjectiveIntersectCostFunction( + const vector &markers, + const ProjectiveReconstruction &reconstruction) + : markers(markers), reconstruction(reconstruction) {} + + Vec operator()(const Vec4 &X) const { + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const ProjectiveCamera &camera = + *reconstruction.CameraForImage(markers[i].image); + Vec3 projected = camera.P * X; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + const vector &markers; + const ProjectiveReconstruction &reconstruction; +}; + +} // namespace + +bool ProjectiveIntersect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 2) { + return false; + } + + // Get the cameras to use for the intersection. + vector cameras; + for (int i = 0; i < markers.size(); ++i) { + ProjectiveCamera *camera = reconstruction->CameraForImage(markers[i].image); + cameras.push_back(camera->P); + } + + // Stack the 2D coordinates together as required by NViewTriangulate. + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + + Vec4 X; + LG << "Intersecting with " << markers.size() << " markers."; + NViewTriangulateAlgebraic(points, cameras, &X); + X /= X(3); + + typedef LevenbergMarquardt Solver; + + ProjectiveIntersectCostFunction triangulate_cost(markers, *reconstruction); + Solver::SolverParameters params; + Solver solver(triangulate_cost); + + Solver::Results results = solver.minimize(params, &X); + (void) results; // TODO(keir): Ensure results are good. + + // Try projecting the point; make sure it's in front of everyone. + for (int i = 0; i < cameras.size(); ++i) { + const ProjectiveCamera &camera = + *reconstruction->CameraForImage(markers[i].image); + Vec3 x = camera.P * X; + if (x(2) < 0) { + LOG(ERROR) << "POINT BEHIND CAMERA " << markers[i].image + << ": " << x.transpose(); + } + } + + reconstruction->InsertPoint(markers[0].track, X); + + // TODO(keir): Add proper error checking. + return true; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/intersect.h b/extern/libmv/libmv/simple_pipeline/intersect.h new file mode 100644 index 00000000000..edbf4a0335b --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/intersect.h @@ -0,0 +1,77 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_INTERSECT_H +#define LIBMV_SIMPLE_PIPELINE_INTERSECT_H + +#include "libmv/base/vector.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate the 3D coordinates of a track by intersecting rays from images. + + This takes a set of markers, where each marker is for the same track but + different images, and reconstructs the 3D position of that track. Each of + the frames for which there is a marker for that track must have a + corresponding reconstructed camera in \a *reconstruction. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in all frames. + \a reconstruction should contain the cameras for all frames. + The new \l Point points \endlink will be inserted in \a reconstruction. + + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \sa EuclideanResect +*/ +bool EuclideanIntersect(const vector &markers, + EuclideanReconstruction *reconstruction); + +/*! + Estimate the homogeneous coordinates of a track by intersecting rays. + + This takes a set of markers, where each marker is for the same track but + different images, and reconstructs the homogeneous 3D position of that + track. Each of the frames for which there is a marker for that track must + have a corresponding reconstructed camera in \a *reconstruction. + + \a markers should contain all \l Marker markers \endlink belonging to + tracks visible in all frames. + \a reconstruction should contain the cameras for all frames. + The new \l Point points \endlink will be inserted in \a reconstruction. + + \note This assumes that radial distortion is already corrected for, but + does not assume that e.g. focal length and principal point are + accounted for. + \note This assumes an outlier-free set of markers. + + \sa Resect +*/ +bool ProjectiveIntersect(const vector &markers, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_INTERSECT_H diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.cc b/extern/libmv/libmv/simple_pipeline/pipeline.cc new file mode 100644 index 00000000000..818c24cb5e7 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/pipeline.cc @@ -0,0 +1,317 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/logging/logging.h" +#include "libmv/simple_pipeline/bundle.h" +#include "libmv/simple_pipeline/intersect.h" +#include "libmv/simple_pipeline/resect.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/camera_intrinsics.h" + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +namespace libmv { +namespace { + +// These are "strategy" classes which make it possible to use the same code for +// both projective and euclidean reconstruction. +// FIXME(MatthiasF): OOP would achieve the same goal while avoiding +// template bloat and making interface changes much easier. +struct EuclideanPipelineRoutines { + typedef EuclideanReconstruction Reconstruction; + typedef EuclideanCamera Camera; + typedef EuclideanPoint Point; + + static void Bundle(const Tracks &tracks, + EuclideanReconstruction *reconstruction) { + EuclideanBundle(tracks, reconstruction); + } + + static bool Resect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass) { + return EuclideanResect(markers, reconstruction, final_pass); + } + + static bool Intersect(const vector &markers, + EuclideanReconstruction *reconstruction) { + return EuclideanIntersect(markers, reconstruction); + } + + static Marker ProjectMarker(const EuclideanPoint &point, + const EuclideanCamera &camera, + const CameraIntrinsics &intrinsics) { + Vec3 projected = camera.R * point.X + camera.t; + projected /= projected(2); + + Marker reprojected_marker; + intrinsics.ApplyIntrinsics(projected(0), + projected(1), + &reprojected_marker.x, + &reprojected_marker.y); + + reprojected_marker.image = camera.image; + reprojected_marker.track = point.track; + return reprojected_marker; + } +}; + +struct ProjectivePipelineRoutines { + typedef ProjectiveReconstruction Reconstruction; + typedef ProjectiveCamera Camera; + typedef ProjectivePoint Point; + + static void Bundle(const Tracks &tracks, + ProjectiveReconstruction *reconstruction) { + ProjectiveBundle(tracks, reconstruction); + } + + static bool Resect(const vector &markers, + ProjectiveReconstruction *reconstruction, bool final_pass) { + return ProjectiveResect(markers, reconstruction); + } + + static bool Intersect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + return ProjectiveIntersect(markers, reconstruction); + } + + static Marker ProjectMarker(const ProjectivePoint &point, + const ProjectiveCamera &camera, + const CameraIntrinsics &intrinsics) { + Vec3 projected = camera.P * point.X; + projected /= projected(2); + + Marker reprojected_marker; + intrinsics.ApplyIntrinsics(projected(0), + projected(1), + &reprojected_marker.x, + &reprojected_marker.y); + + reprojected_marker.image = camera.image; + reprojected_marker.track = point.track; + return reprojected_marker; + } +}; + +} // namespace + +template +void InternalCompleteReconstruction( + const Tracks &tracks, + typename PipelineRoutines::Reconstruction *reconstruction) { + int max_track = tracks.MaxTrack(); + int max_image = tracks.MaxImage(); + int num_resects = -1; + int num_intersects = -1; + LG << "Max track: " << max_track; + LG << "Max image: " << max_image; + LG << "Number of markers: " << tracks.NumMarkers(); + while (num_resects != 0 || num_intersects != 0) { + // Do all possible intersections. + num_intersects = 0; + for (int track = 0; track <= max_track; ++track) { + if (reconstruction->PointForTrack(track)) { + LG << "Skipping point: " << track; + continue; + } + vector all_markers = tracks.MarkersForTrack(track); + LG << "Got " << all_markers.size() << " markers for track " << track; + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->CameraForImage(all_markers[i].image)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + LG << "Got " << reconstructed_markers.size() + << " reconstructed markers for track " << track; + if (reconstructed_markers.size() >= 2) { + PipelineRoutines::Intersect(reconstructed_markers, reconstruction); + num_intersects++; + LG << "Ran Intersect() for track " << track; + } + } + if (num_intersects) { + PipelineRoutines::Bundle(tracks, reconstruction); + LG << "Ran Bundle() after intersections."; + } + LG << "Did " << num_intersects << " intersects."; + + // Do all possible resections. + num_resects = 0; + for (int image = 0; image <= max_image; ++image) { + if (reconstruction->CameraForImage(image)) { + LG << "Skipping frame: " << image; + continue; + } + vector all_markers = tracks.MarkersInImage(image); + LG << "Got " << all_markers.size() << " markers for image " << image; + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->PointForTrack(all_markers[i].track)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + LG << "Got " << reconstructed_markers.size() + << " reconstructed markers for image " << image; + if (reconstructed_markers.size() >= 5) { + if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, false)) { + num_resects++; + LG << "Ran Resect() for image " << image; + } else { + LG << "Failed Resect() for image " << image; + } + } + } + if (num_resects) { + PipelineRoutines::Bundle(tracks, reconstruction); + } + LG << "Did " << num_resects << " resects."; + } + + // One last pass... + num_resects = 0; + for (int image = 0; image <= max_image; ++image) { + if (reconstruction->CameraForImage(image)) { + LG << "Skipping frame: " << image; + continue; + } + vector all_markers = tracks.MarkersInImage(image); + + vector reconstructed_markers; + for (int i = 0; i < all_markers.size(); ++i) { + if (reconstruction->PointForTrack(all_markers[i].track)) { + reconstructed_markers.push_back(all_markers[i]); + } + } + if (reconstructed_markers.size() >= 5) { + if (PipelineRoutines::Resect(reconstructed_markers, reconstruction, true)) { + num_resects++; + LG << "Ran Resect() for image " << image; + } else { + LG << "Failed Resect() for image " << image; + } + } + } + if (num_resects) { + PipelineRoutines::Bundle(tracks, reconstruction); + } +} + +template +double InternalReprojectionError(const Tracks &image_tracks, + const typename PipelineRoutines::Reconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + int num_skipped = 0; + int num_reprojected = 0; + double total_error = 0.0; + vector markers = image_tracks.AllMarkers(); + for (int i = 0; i < markers.size(); ++i) { + const typename PipelineRoutines::Camera *camera = + reconstruction.CameraForImage(markers[i].image); + const typename PipelineRoutines::Point *point = + reconstruction.PointForTrack(markers[i].track); + if (!camera || !point) { + num_skipped++; + continue; + } + num_reprojected++; + + Marker reprojected_marker = + PipelineRoutines::ProjectMarker(*point, *camera, intrinsics); + double ex = reprojected_marker.x - markers[i].x; + double ey = reprojected_marker.y - markers[i].y; + + const int N = 100; + char line[N]; + snprintf(line, N, + "image %-3d track %-3d " + "x %7.1f y %7.1f " + "rx %7.1f ry %7.1f " + "ex %7.1f ey %7.1f" + " e %7.1f", + markers[i].image, + markers[i].track, + markers[i].x, + markers[i].y, + reprojected_marker.x, + reprojected_marker.y, + ex, + ey, + sqrt(ex*ex + ey*ey)); + //LG << line; + total_error += sqrt(ex*ex + ey*ey); + } + LG << "Skipped " << num_skipped << " markers."; + LG << "Reprojected " << num_reprojected << " markers."; + LG << "Total error: " << total_error; + LG << "Average error: " << (total_error / num_reprojected) << " [pixels]."; + return total_error / num_reprojected; +} + +double EuclideanReprojectionError(const Tracks &image_tracks, + const EuclideanReconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + return InternalReprojectionError(image_tracks, + reconstruction, + intrinsics); +} + +double ProjectiveReprojectionError( + const Tracks &image_tracks, + const ProjectiveReconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { + return InternalReprojectionError(image_tracks, + reconstruction, + intrinsics); +} + +void EuclideanCompleteReconstruction(const Tracks &tracks, + EuclideanReconstruction *reconstruction) { + InternalCompleteReconstruction(tracks, + reconstruction); +} + +void ProjectiveCompleteReconstruction(const Tracks &tracks, + ProjectiveReconstruction *reconstruction) { + InternalCompleteReconstruction(tracks, + reconstruction); +} + +void InvertIntrinsicsForTracks(const Tracks &raw_tracks, + const CameraIntrinsics &camera_intrinsics, + Tracks *calibrated_tracks) { + vector markers = raw_tracks.AllMarkers(); + for (int i = 0; i < markers.size(); ++i) { + camera_intrinsics.InvertIntrinsics(markers[i].x, + markers[i].y, + &(markers[i].x), + &(markers[i].y)); + } + *calibrated_tracks = Tracks(markers); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.h b/extern/libmv/libmv/simple_pipeline/pipeline.h new file mode 100644 index 00000000000..b7dfcb7993a --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/pipeline.h @@ -0,0 +1,95 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ +#define LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ + +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate camera poses and scene 3D coordinates for all frames and tracks. + + This method should be used once there is an initial reconstruction in + place, for example by reconstructing from two frames that have a sufficient + baseline and number of tracks in common. This function iteratively + triangulates points that are visible by cameras that have their pose + estimated, then resections (i.e. estimates the pose) of cameras that are + not estimated yet that can see triangulated points. This process is + repeated until all points and cameras are estimated. Periodically, bundle + adjustment is run to ensure a quality reconstruction. + + \a tracks should contain markers used in the reconstruction. + \a reconstruction should contain at least some 3D points or some estimated + cameras. The minimum number of cameras is two (with no 3D points) and the + minimum number of 3D points (with no estimated cameras) is 5. + + \sa EuclideanResect, EuclideanIntersect, EuclideanBundle +*/ +void EuclideanCompleteReconstruction(const Tracks &tracks, + EuclideanReconstruction *reconstruction); + +/*! + Estimate camera matrices and homogeneous 3D coordinates for all frames and + tracks. + + This method should be used once there is an initial reconstruction in + place, for example by reconstructing from two frames that have a sufficient + baseline and number of tracks in common. This function iteratively + triangulates points that are visible by cameras that have their pose + estimated, then resections (i.e. estimates the pose) of cameras that are + not estimated yet that can see triangulated points. This process is + repeated until all points and cameras are estimated. Periodically, bundle + adjustment is run to ensure a quality reconstruction. + + \a tracks should contain markers used in the reconstruction. + \a reconstruction should contain at least some 3D points or some estimated + cameras. The minimum number of cameras is two (with no 3D points) and the + minimum number of 3D points (with no estimated cameras) is 5. + + \sa ProjectiveResect, ProjectiveIntersect, ProjectiveBundle +*/ +void ProjectiveCompleteReconstruction(const Tracks &tracks, + ProjectiveReconstruction *reconstruction); + + +class CameraIntrinsics; + +// TODO(keir): Decide if we want these in the public API, and if so, what the +// appropriate include file is. + +double EuclideanReprojectionError(const Tracks &image_tracks, + const EuclideanReconstruction &reconstruction, + const CameraIntrinsics &intrinsics); + +double ProjectiveReprojectionError( + const Tracks &image_tracks, + const ProjectiveReconstruction &reconstruction, + const CameraIntrinsics &intrinsics); + +void InvertIntrinsicsForTracks(const Tracks &raw_tracks, + const CameraIntrinsics &camera_intrinsics, + Tracks *calibrated_tracks); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_PIPELINE_H_ diff --git a/extern/libmv/libmv/simple_pipeline/reconstruction.cc b/extern/libmv/libmv/simple_pipeline/reconstruction.cc new file mode 100644 index 00000000000..65e5dd27d5d --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/reconstruction.cc @@ -0,0 +1,191 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/numeric/numeric.h" +#include "libmv/logging/logging.h" + +namespace libmv { + +EuclideanReconstruction::EuclideanReconstruction() {} +EuclideanReconstruction::EuclideanReconstruction( + const EuclideanReconstruction &other) { + cameras_ = other.cameras_; + points_ = other.points_; +} + +EuclideanReconstruction &EuclideanReconstruction::operator=( + const EuclideanReconstruction &other) { + if (&other != this) { + cameras_ = other.cameras_; + points_ = other.points_; + } + return *this; +} + +void EuclideanReconstruction::InsertCamera(int image, + const Mat3 &R, + const Vec3 &t) { + LG << "InsertCamera " << image << ":\nR:\n"<< R << "\nt:\n" << t; + if (image >= cameras_.size()) { + cameras_.resize(image + 1); + } + cameras_[image].image = image; + cameras_[image].R = R; + cameras_[image].t = t; +} + +void EuclideanReconstruction::InsertPoint(int track, const Vec3 &X) { + LG << "InsertPoint " << track << ":\n" << X; + if (track >= points_.size()) { + points_.resize(track + 1); + } + points_[track].track = track; + points_[track].X = X; +} + +EuclideanCamera *EuclideanReconstruction::CameraForImage(int image) { + return const_cast( + static_cast( + this)->CameraForImage(image)); +} + +const EuclideanCamera *EuclideanReconstruction::CameraForImage( + int image) const { + if (image < 0 || image >= cameras_.size()) { + return NULL; + } + const EuclideanCamera *camera = &cameras_[image]; + if (camera->image == -1) { + return NULL; + } + return camera; +} + +vector EuclideanReconstruction::AllCameras() const { + vector cameras; + for (int i = 0; i < cameras_.size(); ++i) { + if (cameras_[i].image != -1) { + cameras.push_back(cameras_[i]); + } + } + return cameras; +} + +EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) { + return const_cast( + static_cast(this)->PointForTrack(track)); +} + +const EuclideanPoint *EuclideanReconstruction::PointForTrack(int track) const { + if (track < 0 || track >= points_.size()) { + return NULL; + } + const EuclideanPoint *point = &points_[track]; + if (point->track == -1) { + return NULL; + } + return point; +} + +vector EuclideanReconstruction::AllPoints() const { + vector points; + for (int i = 0; i < points_.size(); ++i) { + if (points_[i].track != -1) { + points.push_back(points_[i]); + } + } + return points; +} + +void ProjectiveReconstruction::InsertCamera(int image, + const Mat34 &P) { + LG << "InsertCamera " << image << ":\nP:\n"<< P; + if (image >= cameras_.size()) { + cameras_.resize(image + 1); + } + cameras_[image].image = image; + cameras_[image].P = P; +} + +void ProjectiveReconstruction::InsertPoint(int track, const Vec4 &X) { + LG << "InsertPoint " << track << ":\n" << X; + if (track >= points_.size()) { + points_.resize(track + 1); + } + points_[track].track = track; + points_[track].X = X; +} + +ProjectiveCamera *ProjectiveReconstruction::CameraForImage(int image) { + return const_cast( + static_cast( + this)->CameraForImage(image)); +} + +const ProjectiveCamera *ProjectiveReconstruction::CameraForImage( + int image) const { + if (image < 0 || image >= cameras_.size()) { + return NULL; + } + const ProjectiveCamera *camera = &cameras_[image]; + if (camera->image == -1) { + return NULL; + } + return camera; +} + +vector ProjectiveReconstruction::AllCameras() const { + vector cameras; + for (int i = 0; i < cameras_.size(); ++i) { + if (cameras_[i].image != -1) { + cameras.push_back(cameras_[i]); + } + } + return cameras; +} + +ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) { + return const_cast( + static_cast(this)->PointForTrack(track)); +} + +const ProjectivePoint *ProjectiveReconstruction::PointForTrack(int track) const { + if (track < 0 || track >= points_.size()) { + return NULL; + } + const ProjectivePoint *point = &points_[track]; + if (point->track == -1) { + return NULL; + } + return point; +} + +vector ProjectiveReconstruction::AllPoints() const { + vector points; + for (int i = 0; i < points_.size(); ++i) { + if (points_[i].track != -1) { + points.push_back(points_[i]); + } + } + return points; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/reconstruction.h b/extern/libmv/libmv/simple_pipeline/reconstruction.h new file mode 100644 index 00000000000..947a0636476 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/reconstruction.h @@ -0,0 +1,217 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ +#define LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ + +#include "libmv/base/vector.h" +#include "libmv/numeric/numeric.h" + +namespace libmv { + +/*! + A EuclideanCamera is the location and rotation of the camera viewing \a image. + + \a image identify which image from \l Tracks this camera represents. + \a R is a 3x3 matrix representing the rotation of the camera. + \a t is a translation vector representing its positions. + + \sa Reconstruction +*/ +struct EuclideanCamera { + EuclideanCamera() : image(-1) {} + EuclideanCamera(const EuclideanCamera &c) : image(c.image), R(c.R), t(c.t) {} + + int image; + Mat3 R; + Vec3 t; +}; + +/*! + A Point is the 3D location of a track. + + \a track identify which track from \l Tracks this point corresponds to. + \a X represents the 3D position of the track. + + \sa Reconstruction +*/ +struct EuclideanPoint { + EuclideanPoint() : track(-1) {} + EuclideanPoint(const EuclideanPoint &p) : track(p.track), X(p.X) {} + int track; + Vec3 X; +}; + +/*! + The EuclideanReconstruction class stores \link EuclideanCamera cameras + \endlink and \link EuclideanPoint points \endlink. + + The EuclideanReconstruction container is intended as the store of 3D + reconstruction data to be used with the MultiView API. + + The container has lookups to query a \a EuclideanCamera from an \a image or + a \a EuclideanPoint from a \a track. + + \sa Camera, Point +*/ +class EuclideanReconstruction { + public: + // Default constructor starts with no cameras. + EuclideanReconstruction(); + + /// Copy constructor. + EuclideanReconstruction(const EuclideanReconstruction &other); + + EuclideanReconstruction &operator=(const EuclideanReconstruction &other); + + /*! + Insert a camera into the set. If there is already a camera for the given + \a image, the existing camera is replaced. If there is no camera for the + given \a image, a new one is added. + + \a image is the key used to retrieve the cameras with the other methods + in this class. + + \note You should use the same \a image identifier as in \l Tracks. + */ + void InsertCamera(int image, const Mat3 &R, const Vec3 &t); + + /*! + Insert a point into the reconstruction. If there is already a point for + the given \a track, the existing point is replaced. If there is no point + for the given \a track, a new one is added. + + \a track is the key used to retrieve the points with the + other methods in this class. + + \note You should use the same \a track identifier as in \l Tracks. + */ + void InsertPoint(int track, const Vec3 &X); + + /// Returns a pointer to the camera corresponding to \a image. + EuclideanCamera *CameraForImage(int image); + const EuclideanCamera *CameraForImage(int image) const; + + /// Returns all cameras. + vector AllCameras() const; + + /// Returns a pointer to the point corresponding to \a track. + EuclideanPoint *PointForTrack(int track); + const EuclideanPoint *PointForTrack(int track) const; + + /// Returns all points. + vector AllPoints() const; + + private: + vector cameras_; + vector points_; +}; + +/*! + A ProjectiveCamera is the projection matrix for the camera of \a image. + + \a image identify which image from \l Tracks this camera represents. + \a P is the 3x4 projection matrix. + + \sa ProjectiveReconstruction +*/ +struct ProjectiveCamera { + ProjectiveCamera() : image(-1) {} + ProjectiveCamera(const ProjectiveCamera &c) : image(c.image), P(c.P) {} + + int image; + Mat34 P; +}; + +/*! + A Point is the 3D location of a track. + + \a track identifies which track from \l Tracks this point corresponds to. + \a X is the homogeneous 3D position of the track. + + \sa Reconstruction +*/ +struct ProjectivePoint { + ProjectivePoint() : track(-1) {} + ProjectivePoint(const ProjectivePoint &p) : track(p.track), X(p.X) {} + int track; + Vec4 X; +}; + +/*! + The ProjectiveReconstruction class stores \link ProjectiveCamera cameras + \endlink and \link ProjectivePoint points \endlink. + + The ProjectiveReconstruction container is intended as the store of 3D + reconstruction data to be used with the MultiView API. + + The container has lookups to query a \a ProjectiveCamera from an \a image or + a \a ProjectivePoint from a \a track. + + \sa Camera, Point +*/ +class ProjectiveReconstruction { + public: + /*! + Insert a camera into the set. If there is already a camera for the given + \a image, the existing camera is replaced. If there is no camera for the + given \a image, a new one is added. + + \a image is the key used to retrieve the cameras with the other methods + in this class. + + \note You should use the same \a image identifier as in \l Tracks. + */ + void InsertCamera(int image, const Mat34 &P); + + /*! + Insert a point into the reconstruction. If there is already a point for + the given \a track, the existing point is replaced. If there is no point + for the given \a track, a new one is added. + + \a track is the key used to retrieve the points with the + other methods in this class. + + \note You should use the same \a track identifier as in \l Tracks. + */ + void InsertPoint(int track, const Vec4 &X); + + /// Returns a pointer to the camera corresponding to \a image. + ProjectiveCamera *CameraForImage(int image); + const ProjectiveCamera *CameraForImage(int image) const; + + /// Returns all cameras. + vector AllCameras() const; + + /// Returns a pointer to the point corresponding to \a track. + ProjectivePoint *PointForTrack(int track); + const ProjectivePoint *PointForTrack(int track) const; + + /// Returns all points. + vector AllPoints() const; + + private: + vector cameras_; + vector points_; +}; + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_RECONSTRUCTION_H_ diff --git a/extern/libmv/libmv/simple_pipeline/resect.cc b/extern/libmv/libmv/simple_pipeline/resect.cc new file mode 100644 index 00000000000..6e71c3c7206 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/resect.cc @@ -0,0 +1,271 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/base/vector.h" +#include "libmv/logging/logging.h" +#include "libmv/multiview/euclidean_resection.h" +#include "libmv/multiview/resection.h" +#include "libmv/multiview/projection.h" +#include "libmv/numeric/numeric.h" +#include "libmv/numeric/levenberg_marquardt.h" +#include "libmv/simple_pipeline/reconstruction.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { +namespace { + +Mat2X PointMatrixFromMarkers(const vector &markers) { + Mat2X points(2, markers.size()); + for (int i = 0; i < markers.size(); ++i) { + points(0, i) = markers[i].x; + points(1, i) = markers[i].y; + } + return points; +} + +Mat3 RotationFromEulerVector(Vec3 euler_vector) { + double theta = euler_vector.norm(); + if (theta == 0.0) { + return Mat3::Identity(); + } + Vec3 w = euler_vector / theta; + Mat3 w_hat = CrossProductMatrix(w); + return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta)); +} + +// Uses an incremental rotation: +// +// x = R' * R * X + t; +// +// to avoid issues with the rotation representation. R' is derived from a +// euler vector encoding the rotation in 3 parameters; the direction is the +// axis to rotate around and the magnitude is the amount of the rotation. +struct EuclideanResectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec6 XMatrixType; + + EuclideanResectCostFunction(const vector &markers, + const EuclideanReconstruction &reconstruction, + const Mat3 initial_R) + : markers(markers), + reconstruction(reconstruction), + initial_R(initial_R) {} + + // dRt has dR (delta R) encoded as a euler vector in the first 3 parameters, + // followed by t in the next 3 parameters. + Vec operator()(const Vec6 &dRt) const { + // Unpack R, t from dRt. + Mat3 R = RotationFromEulerVector(dRt.head<3>()) * initial_R; + Vec3 t = dRt.tail<3>(); + + // Compute the reprojection error for each coordinate. + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const EuclideanPoint &point = + *reconstruction.PointForTrack(markers[i].track); + Vec3 projected = R * point.X + t; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + + const vector &markers; + const EuclideanReconstruction &reconstruction; + const Mat3 &initial_R; +}; + +} // namespace + +bool EuclideanResect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass) { + if (markers.size() < 5) { + return false; + } + Mat2X points_2d = PointMatrixFromMarkers(markers); + Mat3X points_3d(3, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d.col(i) = reconstruction->PointForTrack(markers[i].track)->X; + } + LG << "Points for resect:\n" << points_2d; + + Mat3 R; + Vec3 t; + if (0 || !euclidean_resection::EuclideanResection(points_2d, points_3d, &R, &t)) { + // printf("Resection for image %d failed\n", markers[0].image); + LG << "Resection for image " << markers[0].image << " failed;" + << " trying fallback projective resection."; + if (!final_pass) return false; + // Euclidean resection failed. Fall back to projective resection, which is + // less reliable but better conditioned when there are many points. + Mat34 P; + Mat4X points_3d_homogeneous(4, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d_homogeneous.col(i).head<3>() = points_3d.col(i); + points_3d_homogeneous(3, i) = 1.0; + } + resection::Resection(points_2d, points_3d_homogeneous, &P); + if ((P * points_3d_homogeneous.col(0))(2) < 0) { + LG << "Point behind camera; switch sign."; + P = -P; + } + + Mat3 ignored; + KRt_From_P(P, &ignored, &R, &t); + + // The R matrix should be a rotation, but don't rely on it. + Eigen::JacobiSVD svd(R, Eigen::ComputeFullU | Eigen::ComputeFullV); + + LG << "Resection rotation is: " << svd.singularValues().transpose(); + LG << "Determinant is: " << R.determinant(); + + // Correct to make R a rotation. + R = svd.matrixU() * svd.matrixV().transpose(); + + Vec3 xx = R * points_3d.col(0) + t; + if (xx(2) < 0.0) { + LG << "Final point is still behind camera..."; + } + // XXX Need to check if error is horrible and fail here too in that case. + } + + // Refine the result. + typedef LevenbergMarquardt Solver; + + // Give the cost our initial guess for R. + EuclideanResectCostFunction resect_cost(markers, *reconstruction, R); + + // Encode the initial parameters: start with zero delta rotation, and the + // guess for t obtained from resection. + Vec6 dRt = Vec6::Zero(); + dRt.tail<3>() = t; + + Solver solver(resect_cost); + + Solver::SolverParameters params; + Solver::Results results = solver.minimize(params, &dRt); + LG << "LM found incremental rotation: " << dRt.head<3>().transpose(); + // TODO(keir): Check results to ensure clean termination. + + // Unpack the rotation and translation. + R = RotationFromEulerVector(dRt.head<3>()) * R; + t = dRt.tail<3>(); + + LG << "Resection for image " << markers[0].image << " got:\n" + << "R:\n" << R << "\nt:\n" << t; + reconstruction->InsertCamera(markers[0].image, R, t); + return true; +} + +namespace { + +// Directly parameterize the projection matrix, P, which is a 12 parameter +// homogeneous entry. In theory P should be parameterized with only 11 +// parametetrs, but in practice it works fine to let the extra degree of +// freedom drift. +struct ProjectiveResectCostFunction { + public: + typedef Vec FMatrixType; + typedef Vec12 XMatrixType; + + ProjectiveResectCostFunction(const vector &markers, + const ProjectiveReconstruction &reconstruction) + : markers(markers), + reconstruction(reconstruction) {} + + Vec operator()(const Vec12 &vector_P) const { + // Unpack P from vector_P. + Map P(vector_P.data(), 3, 4); + + // Compute the reprojection error for each coordinate. + Vec residuals(2 * markers.size()); + residuals.setZero(); + for (int i = 0; i < markers.size(); ++i) { + const ProjectivePoint &point = + *reconstruction.PointForTrack(markers[i].track); + Vec3 projected = P * point.X; + projected /= projected(2); + residuals[2*i + 0] = projected(0) - markers[i].x; + residuals[2*i + 1] = projected(1) - markers[i].y; + } + return residuals; + } + + const vector &markers; + const ProjectiveReconstruction &reconstruction; +}; + +} // namespace + +bool ProjectiveResect(const vector &markers, + ProjectiveReconstruction *reconstruction) { + if (markers.size() < 5) { + return false; + } + + // Stack the homogeneous 3D points as the columns of a matrix. + Mat2X points_2d = PointMatrixFromMarkers(markers); + Mat4X points_3d_homogeneous(4, markers.size()); + for (int i = 0; i < markers.size(); i++) { + points_3d_homogeneous.col(i) = + reconstruction->PointForTrack(markers[i].track)->X; + } + LG << "Points for resect:\n" << points_2d; + + // Resection the point. + Mat34 P; + resection::Resection(points_2d, points_3d_homogeneous, &P); + + // Flip the sign of P if necessary to keep the point in front of the camera. + if ((P * points_3d_homogeneous.col(0))(2) < 0) { + LG << "Point behind camera; switch sign."; + P = -P; + } + + // TODO(keir): Check if error is horrible and fail in that case. + + // Refine the resulting projection matrix using geometric error. + typedef LevenbergMarquardt Solver; + + ProjectiveResectCostFunction resect_cost(markers, *reconstruction); + + // Pack the initial P matrix into a size-12 vector.. + Vec12 vector_P = Map(P.data()); + + Solver solver(resect_cost); + + Solver::SolverParameters params; + Solver::Results results = solver.minimize(params, &vector_P); + // TODO(keir): Check results to ensure clean termination. + + // Unpack the projection matrix. + P = Map(vector_P.data(), 3, 4); + + LG << "Resection for image " << markers[0].image << " got:\n" + << "P:\n" << P; + reconstruction->InsertCamera(markers[0].image, P); + return true; +} +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/resect.h b/extern/libmv/libmv/simple_pipeline/resect.h new file mode 100644 index 00000000000..f8b5b9f68ee --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/resect.h @@ -0,0 +1,86 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_RESECT_H +#define LIBMV_SIMPLE_PIPELINE_RESECT_H + +#include "libmv/base/vector.h" +#include "libmv/simple_pipeline/tracks.h" +#include "libmv/simple_pipeline/reconstruction.h" + +namespace libmv { + +/*! + Estimate the Euclidean pose of a camera from 2D to 3D correspondences. + + This takes a set of markers visible in one frame (which is the one to + resection), such that the markers are also reconstructed in 3D in the + reconstruction object, and solves for the pose and orientation of the + camera for that frame. + + \a markers should contain \l Marker markers \endlink belonging to tracks + visible in the one frame to be resectioned. Each of the tracks associated + with the markers must have a corresponding reconstructed 3D position in the + \a *reconstruction object. + + \a *reconstruction should contain the 3D points associated with the tracks + for the markers present in \a markers. + + \note This assumes a calibrated reconstruction, e.g. the markers are + already corrected for camera intrinsics and radial distortion. + \note This assumes an outlier-free set of markers. + + \return True if the resection was successful, false otherwise. + + \sa EuclideanIntersect, EuclideanReconstructTwoFrames +*/ +bool EuclideanResect(const vector &markers, + EuclideanReconstruction *reconstruction, bool final_pass); + +/*! + Estimate the projective pose of a camera from 2D to 3D correspondences. + + This takes a set of markers visible in one frame (which is the one to + resection), such that the markers are also reconstructed in a projective + frame in the reconstruction object, and solves for the projective matrix of + the camera for that frame. + + \a markers should contain \l Marker markers \endlink belonging to tracks + visible in the one frame to be resectioned. Each of the tracks associated + with the markers must have a corresponding reconstructed homogeneous 3D + position in the \a *reconstruction object. + + \a *reconstruction should contain the homogeneous 3D points associated with + the tracks for the markers present in \a markers. + + \note This assumes radial distortion has already been corrected, but + otherwise works for uncalibrated sequences. + \note This assumes an outlier-free set of markers. + + \return True if the resection was successful, false otherwise. + + \sa ProjectiveIntersect, ProjectiveReconstructTwoFrames +*/ +bool ProjectiveResect(const vector &markers, + ProjectiveReconstruction *reconstruction); + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_RESECT_H diff --git a/extern/libmv/libmv/simple_pipeline/tracks.cc b/extern/libmv/libmv/simple_pipeline/tracks.cc new file mode 100644 index 00000000000..3fb8ddbe513 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/tracks.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include +#include +#include + +#include "libmv/numeric/numeric.h" +#include "libmv/simple_pipeline/tracks.h" + +namespace libmv { + +Tracks::Tracks(const Tracks &other) { + markers_ = other.markers_; +} + +Tracks::Tracks(const vector &markers) : markers_(markers) {} + +void Tracks::Insert(int image, int track, double x, double y) { + // TODO(keir): Wow, this is quadratic for repeated insertions. Fix this by + // adding a smarter data structure like a set<>. + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image == image && + markers_[i].track == track) { + markers_[i].x = x; + markers_[i].y = y; + return; + } + } + Marker marker = { image, track, x, y }; + markers_.push_back(marker); +} + +vector Tracks::AllMarkers() const { + return markers_; +} + +vector Tracks::MarkersInImage(int image) const { + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if (image == markers_[i].image) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +vector Tracks::MarkersForTrack(int track) const { + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if (track == markers_[i].track) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +vector Tracks::MarkersForTracksInBothImages(int image1, int image2) const { + std::vector image1_tracks; + std::vector image2_tracks; + + for (int i = 0; i < markers_.size(); ++i) { + int image = markers_[i].image; + if (image == image1) { + image1_tracks.push_back(markers_[i].track); + } else if (image == image2) { + image2_tracks.push_back(markers_[i].track); + } + } + + std::sort(image1_tracks.begin(), image1_tracks.end()); + std::sort(image2_tracks.begin(), image2_tracks.end()); + + std::vector intersection; + std::set_intersection(image1_tracks.begin(), image1_tracks.end(), + image2_tracks.begin(), image2_tracks.end(), + std::back_inserter(intersection)); + + vector markers; + for (int i = 0; i < markers_.size(); ++i) { + if ((markers_[i].image == image1 || markers_[i].image == image2) && + std::binary_search(intersection.begin(),intersection.end(), + markers_[i].track)) { + markers.push_back(markers_[i]); + } + } + return markers; +} + +Marker Tracks::MarkerInImageForTrack(int image, int track) const { + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image == image && markers_[i].track == track) { + return markers_[i]; + } + } + Marker null = { -1, -1, -1, -1 }; + return null; +} + +void Tracks::RemoveMarkersForTrack(int track) { + int size = 0; + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].track != track) { + markers_[size++] = markers_[i]; + } + } + markers_.resize(size); +} + +void Tracks::RemoveMarker(int image, int track) { + int size = 0; + for (int i = 0; i < markers_.size(); ++i) { + if (markers_[i].image != image || markers_[i].track != track) { + markers_[size++] = markers_[i]; + } + } + markers_.resize(size); +} + +int Tracks::MaxImage() const { + // TODO(MatthiasF): maintain a max_image_ member (updated on Insert) + int max_image = 0; + for (int i = 0; i < markers_.size(); ++i) { + max_image = std::max(markers_[i].image, max_image); + } + return max_image; +} + +int Tracks::MaxTrack() const { + // TODO(MatthiasF): maintain a max_track_ member (updated on Insert) + int max_track = 0; + for (int i = 0; i < markers_.size(); ++i) { + max_track = std::max(markers_[i].track, max_track); + } + return max_track; +} + +int Tracks::NumMarkers() const { + return markers_.size(); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/tracks.h b/extern/libmv/libmv/simple_pipeline/tracks.h new file mode 100644 index 00000000000..739c3c4f243 --- /dev/null +++ b/extern/libmv/libmv/simple_pipeline/tracks.h @@ -0,0 +1,119 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_SIMPLE_PIPELINE_TRACKS_H_ +#define LIBMV_SIMPLE_PIPELINE_TRACKS_H_ + +#include "libmv/base/vector.h" + +namespace libmv { + +/*! + A Marker is the 2D location of a tracked point in an image. + + \a x, \a y is the position of the marker in pixels from the top left corner + in the image identified by \a image. All markers for to the same target + form a track identified by a common \a track number. + + \note Markers are typically aggregated with the help of the \l Tracks class. + + \sa Tracks +*/ +struct Marker { + int image; + int track; + double x, y; +}; + +/*! + The Tracks class stores \link Marker reconstruction markers \endlink. + + The Tracks container is intended as the store of correspondences between + images, which must get created before any 3D reconstruction can take place. + + The container has several fast lookups for queries typically needed for + structure from motion algorithms, such as \l MarkersForTracksInBothImages(). + + \sa Marker +*/ +class Tracks { + public: + Tracks() {} + + // Copy constructor for a tracks object. + Tracks(const Tracks &other); + + /// Construct a new tracks object using the given markers to start. + Tracks(const vector &markers); + + /*! + Inserts a marker into the set. If there is already a marker for the given + \a image and \a track, the existing marker is replaced. If there is no + marker for the given \a image and \a track, a new one is added. + + \a image and \a track are the keys used to retrieve the markers with the + other methods in this class. + + \note To get an identifier for a new track, use \l MaxTrack() + 1. + */ + void Insert(int image, int track, double x, double y); + + /// Returns all the markers. + vector AllMarkers() const; + + /// Returns all the markers belonging to a track. + vector MarkersForTrack(int track) const; + + /// Returns all the markers visible in \a image. + vector MarkersInImage(int image) const; + + /*! + Returns the markers in \a image1 and \a image2 which have a common track. + + This is not the same as the union of the markers in \a image1 and \a + image2; each marker is for a track that appears in both images. + */ + vector MarkersForTracksInBothImages(int image1, int image2) const; + + /// Returns the marker in \a image belonging to \a track. + Marker MarkerInImageForTrack(int image, int track) const; + + /// Removes all the markers belonging to \a track. + void RemoveMarkersForTrack(int track); + + /// Removes the marker in \a image belonging to \a track. + void RemoveMarker(int image, int track); + + /// Returns the maximum image identifier used. + int MaxImage() const; + + /// Returns the maximum track identifier used. + int MaxTrack() const; + + /// Returns the number of markers. + int NumMarkers() const; + + private: + vector markers_; +}; + +} // namespace libmv + +#endif // LIBMV_SIMPLE_PIPELINE_MARKERS_H_ diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.cc b/extern/libmv/libmv/tracking/klt_region_tracker.cc new file mode 100644 index 00000000000..299077be155 --- /dev/null +++ b/extern/libmv/libmv/tracking/klt_region_tracker.cc @@ -0,0 +1,132 @@ +// Copyright (c) 2007, 2008, 2009, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/logging/logging.h" +#include "libmv/tracking/klt_region_tracker.h" +#include "libmv/image/image.h" +#include "libmv/image/convolve.h" +#include "libmv/image/sample.h" + +namespace libmv { + +// Compute the gradient matrix noted by Z and the error vector e. See Good +// Features to Track. +// +// TODO(keir): The calls to SampleLinear() do boundary checking that should +// instead happen outside the loop. Since this is the innermost loop, the extra +// bounds checking hurts performance. +static void ComputeTrackingEquation(const Array3Df &image_and_gradient1, + const Array3Df &image_and_gradient2, + double x1, double y1, + double x2, double y2, + int half_width, + float *gxx, + float *gxy, + float *gyy, + float *ex, + float *ey) { + *gxx = *gxy = *gyy = 0; + *ex = *ey = 0; + for (int r = -half_width; r <= half_width; ++r) { + for (int c = -half_width; c <= half_width; ++c) { + float xx1 = x1 + c; + float yy1 = y1 + r; + float xx2 = x2 + c; + float yy2 = y2 + r; + float I = SampleLinear(image_and_gradient1, yy1, xx1, 0); + float J = SampleLinear(image_and_gradient2, yy2, xx2, 0); + float gx = SampleLinear(image_and_gradient2, yy2, xx2, 1); + float gy = SampleLinear(image_and_gradient2, yy2, xx2, 2); + *gxx += gx * gx; + *gxy += gx * gy; + *gyy += gy * gy; + *ex += (I - J) * gx; + *ey += (I - J) * gy; + } + } +} + +// Solve the tracking equation +// +// [gxx gxy] [dx] = [ex] +// [gxy gyy] [dy] = [ey] +// +// for dx and dy. Borrowed from Stan Birchfield's KLT implementation. +static bool SolveTrackingEquation(float gxx, float gxy, float gyy, + float ex, float ey, + float min_determinant, + float *dx, float *dy) { + float det = gxx * gyy - gxy * gxy; + if (det < min_determinant) { + *dx = 0; + *dy = 0; + return false; + } + *dx = (gyy * ex - gxy * ey) / det; + *dy = (gxx * ey - gxy * ex) / det; + return true; +} + +bool KltRegionTracker::Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const { + Array3Df image_and_gradient1; + Array3Df image_and_gradient2; + BlurredImageAndDerivativesChannels(image1, sigma, &image_and_gradient1); + BlurredImageAndDerivativesChannels(image2, sigma, &image_and_gradient2); + + int i; + float dx = 0, dy = 0; + for (i = 0; i < max_iterations; ++i) { + // Compute gradient matrix and error vector. + float gxx, gxy, gyy, ex, ey; + ComputeTrackingEquation(image_and_gradient1, + image_and_gradient2, + x1, y1, + *x2, *y2, + half_window_size, + &gxx, &gxy, &gyy, &ex, &ey); + + // Solve the linear system for the best update to x2 and y2. + if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant, + &dx, &dy)) { + // The determinant, which indicates the trackiness of the point, is too + // small, so fail out. + LG << "Determinant too small; failing tracking."; + return false; + } + + // Update the position with the solved displacement. + *x2 += dx; + *y2 += dy; + + // If the update is small, then we probably found the target. + if (dx * dx + dy * dy < min_update_squared_distance) { + LG << "Successful track in " << i << " iterations."; + return true; + } + } + // Getting here means we hit max iterations, so tracking failed. + LG << "Too many iterations."; + return false; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.h b/extern/libmv/libmv/tracking/klt_region_tracker.h new file mode 100644 index 00000000000..2b2d8a9a49d --- /dev/null +++ b/extern/libmv/libmv/tracking/klt_region_tracker.h @@ -0,0 +1,55 @@ +// Copyright (c) 2007, 2008, 2009, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_ +#define LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_ + +#include "libmv/image/image.h" +#include "libmv/tracking/region_tracker.h" + +namespace libmv { + +struct KltRegionTracker : public RegionTracker { + KltRegionTracker() + : half_window_size(4), + max_iterations(16), + min_determinant(1e-6), + min_update_squared_distance(1e-6), + sigma(0.9) {} + + virtual ~KltRegionTracker() {} + + // Tracker interface. + virtual bool Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const; + + // No point in creating getters or setters. + int half_window_size; + int max_iterations; + double min_determinant; + double min_update_squared_distance; + double sigma; +}; + +} // namespace libmv + +#endif // LIBMV_REGION_TRACKING_KLT_REGION_TRACKER_H_ diff --git a/extern/libmv/libmv/tracking/pyramid_region_tracker.cc b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc new file mode 100644 index 00000000000..58f42b26d7c --- /dev/null +++ b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc @@ -0,0 +1,80 @@ +// Copyright (c) 2007, 2008, 2009, 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include + +#include "libmv/image/convolve.h" +#include "libmv/image/image.h" +#include "libmv/image/sample.h" +#include "libmv/logging/logging.h" +#include "libmv/tracking/pyramid_region_tracker.h" + +namespace libmv { + +static void MakePyramid(const FloatImage &image, int num_levels, + std::vector *pyramid) { + pyramid->resize(num_levels); + (*pyramid)[0] = image; + for (int i = 1; i < num_levels; ++i) { + DownsampleChannelsBy2((*pyramid)[i - 1], &(*pyramid)[i]); + } +} + +bool PyramidRegionTracker::Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const { + // Shrink the guessed x and y location to match the coarsest level + 1 (which + // when gets corrected in the loop). + *x2 /= pow(2., num_levels_); + *y2 /= pow(2., num_levels_); + + // Create all the levels of the pyramid, since tracking has to happen from + // the coarsest to finest levels, which means holding on to all levels of the + // pyraid at once. + std::vector pyramid1(num_levels_); + std::vector pyramid2(num_levels_); + MakePyramid(image1, num_levels_, &pyramid1); + MakePyramid(image2, num_levels_, &pyramid2); + + for (int i = num_levels_ - 1; i >= 0; --i) { + // Position in the first image at pyramid level i. + double xx = x1 / pow(2., i); + double yy = y1 / pow(2., i); + + // Guess the new tracked position is where the last level tracked to. + *x2 *= 2; + *y2 *= 2; + + // Track the point on this level with the base tracker. + bool succeeded = tracker_->Track(pyramid1[i], pyramid2[i], xx, yy, x2, y2); + + if (i == 0 && !succeeded) { + // Only fail on the highest-resolution level, because a failure on a + // coarse level does not mean failure at a lower level (consider + // out-of-bounds conditions). + LG << "Finest level of pyramid tracking failed; failing."; + return false; + } + } + return true; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/pyramid_region_tracker.h b/extern/libmv/libmv/tracking/pyramid_region_tracker.h new file mode 100644 index 00000000000..1f9675469f4 --- /dev/null +++ b/extern/libmv/libmv/tracking/pyramid_region_tracker.h @@ -0,0 +1,46 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_ +#define LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_ + +#include "libmv/image/image.h" +#include "libmv/base/scoped_ptr.h" +#include "libmv/tracking/region_tracker.h" + +namespace libmv { + +class PyramidRegionTracker : public RegionTracker { + public: + PyramidRegionTracker(RegionTracker *tracker, int num_levels) + : tracker_(tracker), num_levels_(num_levels) {} + + virtual bool Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const; + private: + scoped_ptr tracker_; + int num_levels_; +}; + +} // namespace libmv + +#endif // LIBMV_CORRESPONDENCE_PYRAMID_TRACKER_H_ diff --git a/extern/libmv/libmv/tracking/region_tracker.h b/extern/libmv/libmv/tracking/region_tracker.h new file mode 100644 index 00000000000..4f7574df1a3 --- /dev/null +++ b/extern/libmv/libmv/tracking/region_tracker.h @@ -0,0 +1,48 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_TRACKING_TRACKER_H_ +#define LIBMV_TRACKING_TRACKER_H_ + +#include "libmv/image/image.h" + +namespace libmv { + +class RegionTracker { + public: + RegionTracker() {} + virtual ~RegionTracker() {} + + /*! + Track a point from \a image1 to \a image2. + + \a x2, \a y2 should start out as a best guess for the position in \a + image2. If no guess is available, (\a x1, \a y1) is a good start. Returns + true on success, false otherwise + */ + virtual bool Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const = 0; +}; + +} // namespace libmv + +#endif // LIBMV_CORRESPONDENCE_TRACKER_H_ diff --git a/extern/libmv/libmv/tracking/retrack_region_tracker.cc b/extern/libmv/libmv/tracking/retrack_region_tracker.cc new file mode 100644 index 00000000000..b3230b1b173 --- /dev/null +++ b/extern/libmv/libmv/tracking/retrack_region_tracker.cc @@ -0,0 +1,47 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include +#include + +#include "libmv/tracking/retrack_region_tracker.h" + +namespace libmv { + +bool RetrackRegionTracker::Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const { + // Track forward, getting x2 and y2. + if (!tracker_->Track(image1, image2, x1, y1, x2, y2)) { + return false; + } + // Now track x2 and y2 backward, to get xx1 and yy1 which, if the track is + // good, should match x1 and y1 (but may not if the track is bad). + double xx1 = *x2, yy1 = *x2; + if (!tracker_->Track(image2, image1, *x2, *y2, &xx1, &yy1)) { + return false; + } + double dx = xx1 - x1; + double dy = yy1 - y1; + return sqrt(dx * dx + dy * dy) < tolerance_; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/retrack_region_tracker.h b/extern/libmv/libmv/tracking/retrack_region_tracker.h new file mode 100644 index 00000000000..ab05f320834 --- /dev/null +++ b/extern/libmv/libmv/tracking/retrack_region_tracker.h @@ -0,0 +1,48 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_ +#define LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_ + +#include "libmv/image/image.h" +#include "libmv/base/scoped_ptr.h" +#include "libmv/tracking/region_tracker.h" + +namespace libmv { + +// A region tracker that tries tracking backwards and forwards, rejecting a +// track that doesn't track backwards to the starting point. +class RetrackRegionTracker : public RegionTracker { + public: + RetrackRegionTracker(RegionTracker *tracker, double tolerance) + : tracker_(tracker), tolerance_(tolerance) {} + + virtual bool Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const; + private: + scoped_ptr tracker_; + double tolerance_; +}; + +} // namespace libmv + +#endif // LIBMV_TRACKING_RETRACK_REGION_TRACKER_H_ diff --git a/extern/libmv/libmv/tracking/sad.cc b/extern/libmv/libmv/tracking/sad.cc new file mode 100644 index 00000000000..9b446bb4c35 --- /dev/null +++ b/extern/libmv/libmv/tracking/sad.cc @@ -0,0 +1,174 @@ +/**************************************************************************** +** +** Copyright (c) 2011 libmv authors. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to +** deal in the Software without restriction, including without limitation the +** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +** sell copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +** IN THE SOFTWARE. +** +****************************************************************************/ + +#include "libmv/tracking/sad.h" +#include +#include + +namespace libmv { + +void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength) { + for(int y=1; y 255) d=255; + dst[y*width+x] = d; + } +} + +struct vec2 { + float x,y; + inline vec2(float x, float y):x(x),y(y){} +}; +inline vec2 operator*(mat32 m, vec2 v) { + return vec2(v.x*m(0,0)+v.y*m(0,1)+m(0,2),v.x*m(1,0)+v.y*m(1,1)+m(1,2)); +} + +//! fixed point bilinear sample with precision k +template inline int sample(const ubyte* image,int stride, int x, int y, int u, int v) { + const ubyte* s = &image[y*stride+x]; + return ((s[ 0] * (k-u) + s[ 1] * u) * (k-v) + + (s[stride] * (k-u) + s[stride+1] * u) * ( v) ) / (k*k); +} + +#ifdef __SSE__ +#include +int lround(float x) { return _mm_cvtss_si32(_mm_set_ss(x)); } +#elif defined(_MSC_VER) +int lround(float x) { return x+0.5; } +#endif + +//TODO(MatthiasF): SSE optimization +void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size) { + const int k = 256; + for (int i = 0; i < size; i++) for (int j = 0; j < size; j++) { + vec2 p = warp*vec2(j-size/2,i-size/2); + int fx = lround(p.x*k), fy = lround(p.y*k); + int ix = fx/k, iy = fy/k; + int u = fx%k, v = fy%k; + pattern[i*size+j] = sample(image,stride,ix,iy,u,v); + } +} + +#ifdef __SSE2__ +#include +static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) { + __m128i a = _mm_setzero_si128(); + for(int i = 0; i < size; i++) { + for(int j = 0; j < size/16; j++) { + a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(pattern+i*size+j*16)), + _mm_loadu_si128((__m128i*)(image+i*stride+j*16)))); + } + } + return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4); +} +#else +static uint SAD(const ubyte* pattern, const ubyte* image, int stride, int size) { + uint sad=0; + for(int i = 0; i < size; i++) { + for(int j = 0; j < size; j++) { + sad += abs((int)pattern[i*size+j] - image[i*stride+j]); + } + } + return sad; +} +#endif + +float sq(float x) { return x*x; } +float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int w, int h, mat32* warp, float areaPenalty, float conditionPenalty) { + mat32 m=*warp; + uint min=-1; + + // exhaustive search integer pixel translation + int ix = m(0,2), iy = m(1,2); + for(int y = size/2; y < h-size/2; y++) { + for(int x = size/2; x < w-size/2; x++) { + m(0,2) = x, m(1,2) = y; + uint sad = SAD(warped,&image[(y-size/2)*stride+(x-size/2)],stride,size); + // TODO: using chroma could help disambiguate some cases + if(sad < min) { + min = sad; + ix = x, iy = y; + } + } + } + m(0,2) = ix, m(1,2) = iy; + min=-1; //reset score since direct warped search match too well (but the wrong pattern). + + // 6D coordinate descent to find affine transform + ubyte* match = new ubyte[size*size]; + float step = 0.5; + for(int p = 0; p < 8; p++) { //foreach precision level + for(int i = 0; i < 2; i++) { // iterate twice per precision level + //TODO: other sweep pattern might converge better + for(int d=0; d < 6; d++) { // iterate dimension sequentially (cyclic descent) + for(float e = -step; e <= step; e+=step) { //solve subproblem (evaluate only along one coordinate) + mat32 t = m; + t.data[d] += e; + //TODO: better performance would also allow a more exhaustive search + SamplePattern(image,stride,t,match,size); + uint sad = SAD(reference,match,size,size); + // regularization: keep constant area and good condition + float area = t(0,0)*t(1,1)-t(0,1)*t(1,0); + float x = sq(t(0,0))+sq(t(0,1)), y = sq(t(1,0))+sq(t(1,1)); + float condition = x>y ? x/y : y/x; + sad += size*size*( areaPenalty*sq(area-1) + conditionPenalty*sq(condition-1) ); + if(sad < min) { + min = sad; + m = t; + } + } + } + } + step /= 2; + } + *warp = m; + + // Compute Pearson product-moment correlation coefficient + uint sX=0,sY=0,sXX=0,sYY=0,sXY=0; + SamplePattern(image,stride,m,match,size); + SAD(reference,match,size,size); + for(int i = 0; i < size; i++) { + for(int j = 0; j < size; j++) { + int x = reference[i*size+j]; + int y = match[i*size+j]; + sX += x; + sY += y; + sXX += x*x; + sYY += y*y; + sXY += x*y; + } + } + delete[] match; + const int N = size*size; + sX /= N, sY /= N, sXX /= N, sYY /= N, sXY /= N; + return (sXY-sX*sY)/sqrt(double((sXX-sX*sX)*(sYY-sY*sY))); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/sad.h b/extern/libmv/libmv/tracking/sad.h new file mode 100644 index 00000000000..9fe323b74c4 --- /dev/null +++ b/extern/libmv/libmv/tracking/sad.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (c) 2011 libmv authors. +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to +** deal in the Software without restriction, including without limitation the +** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +** sell copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +** IN THE SOFTWARE. +** +****************************************************************************/ + +#ifndef LIBMV_TRACKING_SAD_H_ +#define LIBMV_TRACKING_SAD_H_ + +#ifdef __cplusplus +namespace libmv { +#endif + +typedef unsigned char ubyte; +typedef unsigned int uint; + +/*! + Convolve \a src into \a dst with the discrete laplacian operator. + + \a src and \a dst should be \a width x \a height images. + \a strength is an interpolation coefficient (0-256) between original image and the laplacian. + + \note Make sure the search region is filtered with the same strength as the pattern. +*/ +void LaplaceFilter(ubyte* src, ubyte* dst, int width, int height, int strength); + +/// Affine transformation matrix in column major order. +struct mat32 { + float data[3*2]; +#ifdef __cplusplus + inline mat32(int d=1) { for(int i=0;i<3*2;i++) data[i]=0; if(d!=0) for(int i=0;i<2;i++) m(i,i)=d; } + inline float m(int i, int j) const { return data[j*2+i]; } + inline float& m(int i, int j) { return data[j*2+i]; } + inline float operator()(int i, int j) const { return m(i,j); } + inline float& operator()(int i, int j) { return m(i,j); } + inline operator bool() const { for (int i=0; i<3*2; i++) if(data[i]!=0) return true; return false; } +#endif +}; + +/*! + Sample \a pattern from \a image. + + \a warp is the transformation to apply to \a image when sampling the \a pattern. +*/ +void SamplePattern(ubyte* image, int stride, mat32 warp, ubyte* pattern, int size); + +/*! + Track \a pattern in \a image. + + This template matcher computes the + \link http://en.wikipedia.org/wiki/Sum_of_absolute_differences Sum of Absolute Differences (SAD) \endlink + for each integer pixel position in the search region and then iteratively + refine subpixel position using a square search. + A similar method is used for motion estimation in video encoders. + + \a reference is the pattern to track. + \a warped is a warped version of reference for fast unsampled integer search. + Best is to directly extract an already warped pattern from previous frame. + The \a size of the patterns should be aligned to 16. + \a image is a reference to the region to search. + \a stride is size of \a image lines. + + On input, \a warp is the predicted affine transformation (e.g from previous frame) + On return, \a warp is the affine transformation which best match the reference \a pattern + + \a areaPenalty and conditionPenalty control the regularization and need to be tweaked depending on the motion. + Setting them to 0 will allow any transformation (including unrealistic distortions and scaling). + Good values are between 0-32. 16 can be used as a realistic default. + areaPenalty control scaling (decrease to allow pull/zoom, increase to allow only 2D rotation). + a large conditionPenalty avoid a large ratio between the largest and smallest axices. + It need to be decreased for non-2D rotation (when pattern appears to scale along an axis). + + \return Pearson product-moment correlation coefficient between reference and matched pattern. + This measure of the linear dependence between the patterns + ranges from −1 (negative correlation) to 1 (positive correlation). + A value of 0 implies that there is no linear correlation between the variables. + + \note To track affine features: + - Sample reference pattern using estimated (e.g previous frame) warp. + - + \note \a stride allow you to reference your search region instead of copying. + \note For a 16x speedup, compile this tracker with SSE2 support. +*/ +float Track(ubyte* reference, ubyte* warped, int size, ubyte* image, int stride, int width, int height, mat32* warp, + float areaPenalty, float conditionPenalty); + +#ifdef __cplusplus +} // namespace libmv +#endif + +#endif // LIBMV_TRACKING_SAD_H_ diff --git a/extern/libmv/libmv/tracking/trklt_region_tracker.cc b/extern/libmv/libmv/tracking/trklt_region_tracker.cc new file mode 100644 index 00000000000..94319fcb7d3 --- /dev/null +++ b/extern/libmv/libmv/tracking/trklt_region_tracker.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#include "libmv/tracking/trklt_region_tracker.h" + +#include "libmv/logging/logging.h" +#include "libmv/numeric/numeric.h" +#include "libmv/image/image.h" +#include "libmv/image/convolve.h" +#include "libmv/image/sample.h" + +namespace libmv { + +// Computes U and e from the Ud = e equation (number 14) from the paper. +static void ComputeTrackingEquation(const Array3Df &image_and_gradient1, + const Array3Df &image_and_gradient2, + double x1, double y1, + double x2, double y2, + int half_width, + double lambda, + Mat2f *U, + Vec2f *e) { + Mat2f A, B, C, D; + A = B = C = D = Mat2f::Zero(); + + Vec2f R, S, V, W; + R = S = V = W = Vec2f::Zero(); + + for (int r = -half_width; r <= half_width; ++r) { + for (int c = -half_width; c <= half_width; ++c) { + float xx1 = x1 + c; + float yy1 = y1 + r; + float xx2 = x2 + c; + float yy2 = y2 + r; + + float I = SampleLinear(image_and_gradient1, yy1, xx1, 0); + float J = SampleLinear(image_and_gradient2, yy2, xx2, 0); + + Vec2f gI, gJ; + gI << SampleLinear(image_and_gradient1, yy1, xx1, 1), + SampleLinear(image_and_gradient1, yy1, xx1, 2); + gJ << SampleLinear(image_and_gradient2, yy2, xx2, 1), + SampleLinear(image_and_gradient2, yy2, xx2, 2); + + // Equation 15 from the paper. + A += gI * gI.transpose(); + B += gI * gJ.transpose(); + C += gJ * gJ.transpose(); + R += I * gI; + S += J * gI; + V += I * gJ; + W += J * gJ; + } + } + + // In the paper they show a D matrix, but it is just B transpose, so use that + // instead of explicitly computing D. + Mat2f Di = B.transpose().inverse(); + + // Equation 14 from the paper. + *U = A*Di*C + lambda*Di*C - 0.5*B; + *e = (A + lambda*Mat2f::Identity())*Di*(V - W) + 0.5*(S - R); +} + +bool TrkltRegionTracker::Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const { + Array3Df image_and_gradient1; + Array3Df image_and_gradient2; + BlurredImageAndDerivativesChannels(image1, sigma, &image_and_gradient1); + BlurredImageAndDerivativesChannels(image2, sigma, &image_and_gradient2); + + int i; + Vec2f d = Vec2f::Zero(); + for (i = 0; i < max_iterations; ++i) { + // Compute gradient matrix and error vector. + Mat2f U; + Vec2f e; + ComputeTrackingEquation(image_and_gradient1, + image_and_gradient2, + x1, y1, + *x2, *y2, + half_window_size, + lambda, + &U, &e); + + // Solve the linear system for the best update to x2 and y2. + d = U.lu().solve(e); + + // Update the position with the solved displacement. + *x2 += d[0]; + *y2 += d[1]; + + // Check for the quality of the solution, but not until having already + // updated the position with our best estimate. The reason to do the update + // anyway is that the user already knows the position is bad, so we may as + // well try our best. + float determinant = U.determinant(); + if (fabs(determinant) < min_determinant) { + // The determinant, which indicates the trackiness of the point, is too + // small, so fail out. + LG << "Determinant " << determinant << " is too small; failing tracking."; + return false; + } + + // If the update is small, then we probably found the target. + if (d.squaredNorm() < min_update_squared_distance) { + LG << "Successful track in " << i << " iterations."; + return true; + } + } + // Getting here means we hit max iterations, so tracking failed. + LG << "Too many iterations; max is set to " << max_iterations << "."; + return false; +} + +} // namespace libmv diff --git a/extern/libmv/libmv/tracking/trklt_region_tracker.h b/extern/libmv/libmv/tracking/trklt_region_tracker.h new file mode 100644 index 00000000000..5046e0f069d --- /dev/null +++ b/extern/libmv/libmv/tracking/trklt_region_tracker.h @@ -0,0 +1,65 @@ +// Copyright (c) 2011 libmv authors. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. + +#ifndef LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_ +#define LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_ + +#include "libmv/image/image.h" +#include "libmv/tracking/region_tracker.h" + +namespace libmv { + +// An improved KLT algorithm that enforces that the tracking is time-reversible +// [1]. This is not the same as the "symmetric" KLT that is sometimes used. +// Anecdotally, this tracks much more consistently than vanilla KLT. +// +// [1] H. Wu, R. Chellappa, and A. Sankaranarayanan and S. Kevin Zhou. Robust +// visual tracking using the time-reversibility constraint. International +// Conference on Computer Vision (ICCV), Rio de Janeiro, October 2007. +// +struct TrkltRegionTracker : public RegionTracker { + TrkltRegionTracker() + : half_window_size(4), + max_iterations(100), + min_determinant(1e-6), + min_update_squared_distance(1e-6), + sigma(0.9), + lambda(0.05) {} + + virtual ~TrkltRegionTracker() {} + + // Tracker interface. + virtual bool Track(const FloatImage &image1, + const FloatImage &image2, + double x1, double y1, + double *x2, double *y2) const; + + // No point in creating getters or setters. + int half_window_size; + int max_iterations; + double min_determinant; + double min_update_squared_distance; + double sigma; + double lambda; +}; + +} // namespace libmv + +#endif // LIBMV_REGION_TRACKING_TRKLT_REGION_TRACKER_H_ diff --git a/extern/libmv/mkfiles.sh b/extern/libmv/mkfiles.sh new file mode 100755 index 00000000000..6618f2849ea --- /dev/null +++ b/extern/libmv/mkfiles.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +find ./libmv/ -type f | sed -r 's/^\.\///' > files.txt +find ./third_party/ -type f | sed -r 's/^\.\///' >> files.txt diff --git a/extern/libmv/patches/bundle_tweaks.patch b/extern/libmv/patches/bundle_tweaks.patch new file mode 100644 index 00000000000..f7b06b0a2dd --- /dev/null +++ b/extern/libmv/patches/bundle_tweaks.patch @@ -0,0 +1,122 @@ +diff --git a/src/libmv/logging/logging.h b/src/libmv/logging/logging.h +index 067da52..af86c4b 100644 +--- a/src/libmv/logging/logging.h ++++ b/src/libmv/logging/logging.h +@@ -21,7 +21,7 @@ + #ifndef LIBMV_LOGGING_LOGGING_H + #define LIBMV_LOGGING_LOGGING_H + +-#include "third_party/glog/src/glog/logging.h" ++#include "glog/logging.h" + + #define LG LOG(INFO) + #define V0 LOG(INFO) +diff --git a/src/third_party/glog/src/glog/logging.h b/src/third_party/glog/src/glog/logging.h +index 57615ef..a58d478 100644 +--- a/src/third_party/glog/src/glog/logging.h ++++ b/src/third_party/glog/src/glog/logging.h +@@ -33,6 +33,7 @@ + // Pretty much everybody needs to #include this file so that they can + // log various happenings. + // ++ + #ifndef _LOGGING_H_ + #define _LOGGING_H_ + +diff --git a/src/third_party/glog/src/logging.cc b/src/third_party/glog/src/logging.cc +index 868898f..1bb3867 100644 +--- a/src/third_party/glog/src/logging.cc ++++ b/src/third_party/glog/src/logging.cc +@@ -58,8 +58,8 @@ + #include // for errno + #include + #include "base/commandlineflags.h" // to get the program name +-#include "glog/logging.h" +-#include "glog/raw_logging.h" ++#include ++#include + #include "base/googleinit.h" + + #ifdef HAVE_STACKTRACE +@@ -1232,7 +1232,9 @@ void LogMessage::RecordCrashReason( + } + + static void logging_fail() { +-#if defined(_DEBUG) && defined(_MSC_VER) ++// #if defined(_DEBUG) && defined(_MSC_VER) ++// doesn't work for my laptop (sergey) ++#if 0 + // When debugging on windows, avoid the obnoxious dialog and make + // it possible to continue past a LOG(FATAL) in the debugger + _asm int 3 +diff --git a/src/third_party/glog/src/raw_logging.cc b/src/third_party/glog/src/raw_logging.cc +index 50c6a71..b179a1e 100644 +--- a/src/third_party/glog/src/raw_logging.cc ++++ b/src/third_party/glog/src/raw_logging.cc +@@ -42,8 +42,8 @@ + #include // for open() + #include + #include "config.h" +-#include "glog/logging.h" // To pick up flag settings etc. +-#include "glog/raw_logging.h" ++#include // To pick up flag settings etc. ++#include + #include "base/commandlineflags.h" + + #ifdef HAVE_STACKTRACE +diff --git a/src/third_party/glog/src/utilities.h b/src/third_party/glog/src/utilities.h +index ee54f94..2d4e99e 100644 +--- a/src/third_party/glog/src/utilities.h ++++ b/src/third_party/glog/src/utilities.h +@@ -79,7 +79,7 @@ + #endif + + #include "config.h" +-#include "glog/logging.h" ++#include + + // There are three different ways we can try to get the stack trace: + // +diff --git a/src/third_party/glog/src/vlog_is_on.cc b/src/third_party/glog/src/vlog_is_on.cc +index ee0e412..ed88514 100644 +--- a/src/third_party/glog/src/vlog_is_on.cc ++++ b/src/third_party/glog/src/vlog_is_on.cc +@@ -40,8 +40,8 @@ + #include + #include + #include "base/commandlineflags.h" +-#include "glog/logging.h" +-#include "glog/raw_logging.h" ++#include ++#include + #include "base/googleinit.h" + + // glog doesn't have annotation +diff --git a/src/third_party/glog/src/windows/config.h b/src/third_party/glog/src/windows/config.h +index 114762e..682a1b9 100755 +--- a/src/third_party/glog/src/windows/config.h ++++ b/src/third_party/glog/src/windows/config.h +@@ -19,7 +19,7 @@ + #undef HAVE_LIBUNWIND_H + + /* define if you have google gflags library */ +-#undef HAVE_LIB_GFLAGS ++#define HAVE_LIB_GFLAGS 1 + + /* define if you have libunwind */ + #undef HAVE_LIB_UNWIND +diff --git a/src/third_party/glog/src/windows/glog/logging.h b/src/third_party/glog/src/windows/glog/logging.h +index 7a6df74..de51586 100755 +--- a/src/third_party/glog/src/windows/glog/logging.h ++++ b/src/third_party/glog/src/windows/glog/logging.h +@@ -82,8 +82,8 @@ + #include // a third place for uint16_t or u_int16_t + #endif + +-#if 0 +-#include ++#if 1 ++#include "third_party/gflags/gflags.h" + #endif + + namespace google { diff --git a/extern/libmv/patches/config_mac.patch b/extern/libmv/patches/config_mac.patch new file mode 100644 index 00000000000..5a880155bfa --- /dev/null +++ b/extern/libmv/patches/config_mac.patch @@ -0,0 +1,13 @@ +diff --git a/src/third_party/glog/src/config_mac.h b/src/third_party/glog/src/config_mac.h +index a45575b..5f953d1 100644 +--- a/src/third_party/glog/src/config_mac.h ++++ b/src/third_party/glog/src/config_mac.h +@@ -131,7 +131,7 @@ + #define PACKAGE_VERSION "0.3.1" + + /* How to access the PC from a struct ucontext */ +-#define PC_FROM_UCONTEXT uc_mcontext->__ss.__rip ++#undef PC_FROM_UCONTEXT + + /* Define to necessary symbol if this constant uses a non-standard name on + your system. */ diff --git a/extern/libmv/patches/detect.patch b/extern/libmv/patches/detect.patch new file mode 100644 index 00000000000..36fea8427db --- /dev/null +++ b/extern/libmv/patches/detect.patch @@ -0,0 +1,181 @@ +diff --git a/src/libmv/simple_pipeline/detect.cc b/src/libmv/simple_pipeline/detect.cc +index 6fc0cdd..8ac42ab 100644 +--- a/src/libmv/simple_pipeline/detect.cc ++++ b/src/libmv/simple_pipeline/detect.cc +@@ -23,15 +23,89 @@ + ****************************************************************************/ + + #include "libmv/simple_pipeline/detect.h" ++#include + #include +-#include ++#include ++ ++#ifdef __SSE2__ ++#include ++#endif + + namespace libmv { + + typedef unsigned int uint; + ++int featurecmp(const void *a_v, const void *b_v) ++{ ++ Feature *a = (Feature*)a_v; ++ Feature *b = (Feature*)b_v; ++ ++ return b->score - a->score; ++} ++ ++std::vector DetectFAST(const unsigned char* data, int width, int height, int stride, ++ int min_trackness, int min_distance) { ++ std::vector features; ++ // TODO(MatthiasF): Support targetting a feature count (binary search trackness) ++ int num_features; ++ xy* all = fast9_detect(data, width, height, ++ stride, min_trackness, &num_features); ++ if(num_features == 0) { ++ free(all); ++ return features; ++ } ++ int* scores = fast9_score(data, stride, all, num_features, min_trackness); ++ // TODO: merge with close feature suppression ++ xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features); ++ free(all); ++ // Remove too close features ++ // TODO(MatthiasF): A resolution independent parameter would be better than distance ++ // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing) ++ // FIXME(MatthiasF): this method will not necessarily give all maximum markers ++ if(num_features) { ++ Feature *all_features = new Feature[num_features]; ++ ++ for(int i = 0; i < num_features; ++i) { ++ Feature a = { nonmax[i].x, nonmax[i].y, scores[i], 0 }; ++ all_features[i] = a; ++ } ++ ++ qsort((void *)all_features, num_features, sizeof(Feature), featurecmp); ++ ++ features.reserve(num_features); ++ ++ int prev_score = all_features[0].score; ++ for(int i = 0; i < num_features; ++i) { ++ bool ok = true; ++ Feature a = all_features[i]; ++ if(a.score>prev_score) ++ abort(); ++ prev_score = a.score; ++ ++ // compare each feature against filtered set ++ for(int j = 0; j < features.size(); j++) { ++ Feature& b = features[j]; ++ if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) { ++ // already a nearby feature ++ ok = false; ++ break; ++ } ++ } ++ ++ if(ok) { ++ // add the new feature ++ features.push_back(a); ++ } ++ } ++ ++ delete [] all_features; ++ } ++ free(scores); ++ free(nonmax); ++ return features; ++} ++ + #ifdef __SSE2__ +-#include + static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { + __m128i a = _mm_setzero_si128(); + for(int i = 0; i < 16; i++) { +@@ -52,7 +126,7 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid + } + #endif + +-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) { ++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) { + unsigned short histogram[256]; + memset(histogram,0,sizeof(histogram)); + ubyte* scores = new ubyte[width*height]; +diff --git a/src/libmv/simple_pipeline/detect.h b/src/libmv/simple_pipeline/detect.h +index 23b239b..bbe7aed 100644 +--- a/src/libmv/simple_pipeline/detect.h ++++ b/src/libmv/simple_pipeline/detect.h +@@ -25,27 +25,52 @@ + #ifndef LIBMV_SIMPLE_PIPELINE_DETECT_H_ + #define LIBMV_SIMPLE_PIPELINE_DETECT_H_ + +-#ifdef __cplusplus ++#include ++ + namespace libmv { +-#endif + + typedef unsigned char ubyte; + + /*! +- \a Feature is the 2D location of a detected feature in an image. ++ A Feature is the 2D location of a detected feature in an image. + +- \a x, \a y is the position of the center in pixels (from image top-left). +- \a score is an estimate of how well the pattern will be tracked. +- \a size can be used as an initial size to track the pattern. ++ \a x, \a y is the position of the feature in pixels from the top left corner. ++ \a score is an estimate of how well the feature will be tracked. ++ \a size can be used as an initial pattern size to track the feature. + + \sa Detect + */ + struct Feature { ++ /// Position in pixels (from top-left corner) ++ /// \note libmv might eventually support subpixel precision. + float x, y; ++ /// Trackness of the feature + float score; ++ /// Size of the feature in pixels + float size; + }; +- //radius for non maximal suppression ++ ++/*! ++ Detect features in an image. ++ ++ You need to input a single channel 8-bit image using pointer to image \a data, ++ \a width, \a height and \a stride (i.e bytes per line). ++ ++ You can tweak the count of detected features using \a min_trackness, which is ++ the minimum score to add a feature, and \a min_distance which is the minimal ++ distance accepted between two featuress. ++ ++ \note You can binary search over \a min_trackness to get a given feature count. ++ ++ \note a way to get an uniform distribution of a given feature count is: ++ \a min_distance = \a width * \a height / desired_feature_count ^ 2 ++ ++ \return All detected feartures matching given parameters ++*/ ++std::vector DetectFAST(const unsigned char* data, int width, int height, ++ int stride, int min_trackness = 128, ++ int min_distance = 120); ++ + /*! + Detect features in an image. + +@@ -63,10 +88,8 @@ struct Feature { + \note \a You can crop the image (to avoid detecting markers near the borders) without copying: + image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY; + */ +-void Detect(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/); ++void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/); + +-#ifdef __cplusplus + } +-#endif + + #endif diff --git a/extern/libmv/patches/fast.patch b/extern/libmv/patches/fast.patch new file mode 100644 index 00000000000..8e0aeb7e721 --- /dev/null +++ b/extern/libmv/patches/fast.patch @@ -0,0 +1,24 @@ +diff --git a/src/third_party/fast/fast.h b/src/third_party/fast/fast.h +index 2b3825a..06fa90e 100644 +--- a/src/third_party/fast/fast.h ++++ b/src/third_party/fast/fast.h +@@ -1,6 +1,10 @@ + #ifndef FAST_H + #define FAST_H + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + typedef struct { int x, y; } xy; + typedef unsigned char byte; + +@@ -28,4 +32,8 @@ xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b + xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax); + + ++#ifdef __cplusplus ++} ++#endif ++ + #endif diff --git a/extern/libmv/patches/function_derivative.patch b/extern/libmv/patches/function_derivative.patch new file mode 100644 index 00000000000..be7ccfc911a --- /dev/null +++ b/extern/libmv/patches/function_derivative.patch @@ -0,0 +1,21 @@ +diff --git a/src/libmv/numeric/function_derivative.h b/src/libmv/numeric/function_derivative.h +index 0075d23..d7bc437 100644 +--- a/src/libmv/numeric/function_derivative.h ++++ b/src/libmv/numeric/function_derivative.h +@@ -24,6 +24,7 @@ + #include + + #include "libmv/numeric/numeric.h" ++#include "libmv/logging/logging.h" + + namespace libmv { + +@@ -97,7 +98,7 @@ bool CheckJacobian(const Function &f, const typename Function::XMatrixType &x) { + + typename NumericJacobian::JMatrixType J_numeric = j_numeric(x); + typename NumericJacobian::JMatrixType J_analytic = j_analytic(x); +- //LG << J_numeric - J_analytic; ++ LG << J_numeric - J_analytic; + return true; + } + diff --git a/extern/libmv/patches/high_distortion_crash_fix.patch b/extern/libmv/patches/high_distortion_crash_fix.patch new file mode 100644 index 00000000000..54ab66fa27c --- /dev/null +++ b/extern/libmv/patches/high_distortion_crash_fix.patch @@ -0,0 +1,21 @@ +diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc +index 4e88e1f..f9888ff 100644 +--- a/src/libmv/simple_pipeline/camera_intrinsics.cc ++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc +@@ -160,9 +160,13 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) { + if( iy < 0 ) { iy = 0, fy = 0; } + if( ix >= width-2 ) ix = width-2; + if( iy >= height-2 ) iy = height-2; +- //assert( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ); +- Offset offset = { ix-x, iy-y, fx, fy }; +- grid[y*width+x] = offset; ++ if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) { ++ Offset offset = { ix-x, iy-y, fx, fy }; ++ grid[y*width+x] = offset; ++ } else { ++ Offset offset = { 0, 0, 0, 0 }; ++ grid[y*width+x] = offset; ++ } + } + } + } diff --git a/extern/libmv/patches/levenberg_marquardt.patch b/extern/libmv/patches/levenberg_marquardt.patch new file mode 100644 index 00000000000..49ef82d73d2 --- /dev/null +++ b/extern/libmv/patches/levenberg_marquardt.patch @@ -0,0 +1,71 @@ +diff --git a/src/libmv/numeric/levenberg_marquardt.h b/src/libmv/numeric/levenberg_marquardt.h +index 6a54f66..4473b72 100644 +--- a/src/libmv/numeric/levenberg_marquardt.h ++++ b/src/libmv/numeric/levenberg_marquardt.h +@@ -33,6 +33,7 @@ + + #include "libmv/numeric/numeric.h" + #include "libmv/numeric/function_derivative.h" ++#include "libmv/logging/logging.h" + + namespace libmv { + +@@ -123,26 +124,40 @@ class LevenbergMarquardt { + Parameters dx, x_new; + int i; + for (i = 0; results.status == RUNNING && i < params.max_iterations; ++i) { +- if (dx.norm() <= params.relative_step_threshold * x.norm()) { ++ VLOG(1) << "iteration: " << i; ++ VLOG(1) << "||f(x)||: " << f_(x).norm(); ++ VLOG(1) << "max(g): " << g.array().abs().maxCoeff(); ++ VLOG(1) << "u: " << u; ++ VLOG(1) << "v: " << v; ++ ++ AMatrixType A_augmented = A + u*AMatrixType::Identity(J.cols(), J.cols()); ++ Solver solver(A_augmented); ++ dx = solver.solve(g); ++ bool solved = (A_augmented * dx).isApprox(g); ++ if (!solved) { ++ LOG(ERROR) << "Failed to solve"; ++ } ++ if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) { + results.status = RELATIVE_STEP_SIZE_TOO_SMALL; + break; +- } +- x_new = x + dx; +- // Rho is the ratio of the actual reduction in error to the reduction +- // in error that would be obtained if the problem was linear. +- // See [1] for details. +- Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) +- / dx.dot(u*dx + g)); +- if (rho > 0) { +- // Accept the Gauss-Newton step because the linear model fits well. +- x = x_new; +- results.status = Update(x, params, &J, &A, &error, &g); +- Scalar tmp = Scalar(2*rho-1); +- u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); +- v = 2; +- continue; +- } +- ++ } ++ if (solved) { ++ x_new = x + dx; ++ // Rho is the ratio of the actual reduction in error to the reduction ++ // in error that would be obtained if the problem was linear. ++ // See [1] for details. ++ Scalar rho((error.squaredNorm() - f_(x_new).squaredNorm()) ++ / dx.dot(u*dx + g)); ++ if (rho > 0) { ++ // Accept the Gauss-Newton step because the linear model fits well. ++ x = x_new; ++ results.status = Update(x, params, &J, &A, &error, &g); ++ Scalar tmp = Scalar(2*rho-1); ++ u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); ++ v = 2; ++ continue; ++ } ++ } + // Reject the update because either the normal equations failed to solve + // or the local linear model was not good (rho < 0). Instead, increase u + // to move closer to gradient descent. diff --git a/extern/libmv/patches/mingw.patch b/extern/libmv/patches/mingw.patch new file mode 100644 index 00000000000..0b08a483bea --- /dev/null +++ b/extern/libmv/patches/mingw.patch @@ -0,0 +1,13 @@ +diff --git a/src/libmv/numeric/numeric.h b/src/libmv/numeric/numeric.h +index f39d126..21e0f06 100644 +--- a/src/libmv/numeric/numeric.h ++++ b/src/libmv/numeric/numeric.h +@@ -40,7 +40,7 @@ + } + #endif //_WIN32 || __APPLE__ + +-#if _WIN32 ++#if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) + inline long lround(double d) { + return (long)(d>0 ? d+0.5 : ceil(d-0.5)); + } diff --git a/extern/libmv/patches/msvc2010.patch b/extern/libmv/patches/msvc2010.patch new file mode 100644 index 00000000000..c090b070628 --- /dev/null +++ b/extern/libmv/patches/msvc2010.patch @@ -0,0 +1,12 @@ +diff --git a/src/libmv/simple_pipeline/tracks.cc b/src/libmv/simple_pipeline/tracks.cc +index 0e2a1b6..3fb8ddb 100644 +--- a/src/libmv/simple_pipeline/tracks.cc ++++ b/src/libmv/simple_pipeline/tracks.cc +@@ -20,6 +20,7 @@ + + #include + #include ++#include + + #include "libmv/numeric/numeric.h" + #include "libmv/simple_pipeline/tracks.h" diff --git a/extern/libmv/patches/overscan.patch b/extern/libmv/patches/overscan.patch new file mode 100644 index 00000000000..c68f36804ec --- /dev/null +++ b/extern/libmv/patches/overscan.patch @@ -0,0 +1,182 @@ +diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc +index 110a16d..366129d 100644 +--- a/src/libmv/simple_pipeline/camera_intrinsics.cc ++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc +@@ -31,6 +31,7 @@ struct Offset { + struct Grid { + struct Offset *offset; + int width, height; ++ double overscan; + }; + + static struct Grid *copyGrid(struct Grid *from) +@@ -42,6 +43,7 @@ static struct Grid *copyGrid(struct Grid *from) + + to->width = from->width; + to->height = from->height; ++ to->overscan = from->overscan; + + to->offset = new Offset[to->width*to->height]; + memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height); +@@ -184,17 +186,19 @@ void CameraIntrinsics::InvertIntrinsics(double image_x, + + // TODO(MatthiasF): downsample lookup + template +-void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) { +- double aspx = (double)width / image_width_; +- double aspy = (double)height / image_height_; ++void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, double overscan) { ++ double w = (double)width / (1 + overscan); ++ double h = (double)height / (1 + overscan); ++ double aspx = (double)w / image_width_; ++ double aspy = (double)h / image_height_; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { +- double src_x = x / aspx, src_y = y / aspy; ++ double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy; + double warp_x, warp_y; + WarpFunction(this,src_x,src_y,&warp_x,&warp_y); +- warp_x = warp_x*aspx; +- warp_y = warp_y*aspy; ++ warp_x = warp_x*aspx + 0.5 * overscan * w; ++ warp_y = warp_y*aspy + 0.5 * overscan * h; + int ix = int(warp_x), iy = int(warp_y); + int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256); + if(fx == 256) { fx=0; ix++; } +@@ -264,10 +268,10 @@ struct InvertIntrinsicsFunction { + } + }; + +-void CameraIntrinsics::CheckDistortLookupGrid(int width, int height) ++void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double overscan) + { + if(distort_) { +- if(distort_->width != width || distort_->height != height) { ++ if(distort_->width != width || distort_->height != height || distort_->overscan != overscan) { + delete [] distort_->offset; + distort_->offset = NULL; + } +@@ -278,17 +282,18 @@ void CameraIntrinsics::CheckDistortLookupGrid(int width, int height) + + if(!distort_->offset) { + distort_->offset = new Offset[width*height]; +- ComputeLookupGrid(distort_,width,height); ++ ComputeLookupGrid(distort_,width,height,overscan); + } + + distort_->width = width; + distort_->height = height; ++ distort_->overscan = overscan; + } + +-void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height) ++void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double overscan) + { + if(undistort_) { +- if(undistort_->width != width || undistort_->height != height) { ++ if(undistort_->width != width || undistort_->height != height || undistort_->overscan != overscan) { + delete [] undistort_->offset; + undistort_->offset = NULL; + } +@@ -299,15 +304,16 @@ void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height) + + if(!undistort_->offset) { + undistort_->offset = new Offset[width*height]; +- ComputeLookupGrid(undistort_,width,height); ++ ComputeLookupGrid(undistort_,width,height,overscan); + } + + undistort_->width = width; + undistort_->height = height; ++ undistort_->overscan = overscan; + } + +-void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) { +- CheckDistortLookupGrid(width, height); ++void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) { ++ CheckDistortLookupGrid(width, height, overscan); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); +@@ -315,8 +321,8 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig + //else assert("channels must be between 1 and 4"); + } + +-void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) { +- CheckDistortLookupGrid(width, height); ++void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { ++ CheckDistortLookupGrid(width, height, overscan); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); +@@ -324,8 +330,8 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int + //else assert("channels must be between 1 and 4"); + } + +-void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) { +- CheckUndistortLookupGrid(width, height); ++void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) { ++ CheckUndistortLookupGrid(width, height, overscan); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); +@@ -333,8 +339,8 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he + //else assert("channels must be between 1 and 4"); + } + +-void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) { +- CheckUndistortLookupGrid(width, height); ++void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { ++ CheckUndistortLookupGrid(width, height, overscan); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); +diff --git a/src/libmv/simple_pipeline/camera_intrinsics.h b/src/libmv/simple_pipeline/camera_intrinsics.h +index f525571..f4bf903 100644 +--- a/src/libmv/simple_pipeline/camera_intrinsics.h ++++ b/src/libmv/simple_pipeline/camera_intrinsics.h +@@ -91,7 +91,7 @@ class CameraIntrinsics { + \note This is the reference implementation using floating point images. + */ + void Distort(const float* src, float* dst, +- int width, int height, int channels); ++ int width, int height, double overscan, int channels); + /*! + Distort an image using the current camera instrinsics + +@@ -101,7 +101,7 @@ class CameraIntrinsics { + \note This version is much faster. + */ + void Distort(const unsigned char* src, unsigned char* dst, +- int width, int height, int channels); ++ int width, int height, double overscan, int channels); + /*! + Undistort an image using the current camera instrinsics + +@@ -111,7 +111,7 @@ class CameraIntrinsics { + \note This is the reference implementation using floating point images. + */ + void Undistort(const float* src, float* dst, +- int width, int height, int channels); ++ int width, int height, double overscan, int channels); + /*! + Undistort an image using the current camera instrinsics + +@@ -121,12 +121,12 @@ class CameraIntrinsics { + \note This version is much faster. + */ + void Undistort(const unsigned char* src, unsigned char* dst, +- int width, int height, int channels); ++ int width, int height, double overscan, int channels); + + private: +- template void ComputeLookupGrid(struct Grid* grid, int width, int height); +- void CheckUndistortLookupGrid(int width, int height); +- void CheckDistortLookupGrid(int width, int height); ++ template void ComputeLookupGrid(struct Grid* grid, int width, int height, double overscan); ++ void CheckUndistortLookupGrid(int width, int height, double overscan); ++ void CheckDistortLookupGrid(int width, int height, double overscan); + void FreeLookupGrid(); + + // The traditional intrinsics matrix from x = K[R|t]X. diff --git a/extern/libmv/patches/scaled_distortion.patch b/extern/libmv/patches/scaled_distortion.patch new file mode 100644 index 00000000000..2da832931d1 --- /dev/null +++ b/extern/libmv/patches/scaled_distortion.patch @@ -0,0 +1,261 @@ +diff --git a/src/libmv/simple_pipeline/camera_intrinsics.cc b/src/libmv/simple_pipeline/camera_intrinsics.cc +index f9888ff..110a16d 100644 +--- a/src/libmv/simple_pipeline/camera_intrinsics.cc ++++ b/src/libmv/simple_pipeline/camera_intrinsics.cc +@@ -23,7 +23,32 @@ + + namespace libmv { + +-struct Offset { signed char ix,iy; unsigned char fx,fy; }; ++struct Offset { ++ signed char ix, iy; ++ unsigned char fx,fy; ++}; ++ ++struct Grid { ++ struct Offset *offset; ++ int width, height; ++}; ++ ++static struct Grid *copyGrid(struct Grid *from) ++{ ++ struct Grid *to = NULL; ++ ++ if (from) { ++ to = new Grid; ++ ++ to->width = from->width; ++ to->height = from->height; ++ ++ to->offset = new Offset[to->width*to->height]; ++ memcpy(to->offset, from->offset, sizeof(struct Offset)*to->width*to->height); ++ } ++ ++ return to; ++} + + CameraIntrinsics::CameraIntrinsics() + : K_(Mat3::Identity()), +@@ -37,9 +62,22 @@ CameraIntrinsics::CameraIntrinsics() + distort_(0), + undistort_(0) {} + ++CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from) ++ : K_(from.K_), ++ image_width_(from.image_width_), ++ image_height_(from.image_height_), ++ k1_(from.k1_), ++ k2_(from.k2_), ++ k3_(from.k3_), ++ p1_(from.p1_), ++ p2_(from.p2_) ++{ ++ distort_ = copyGrid(from.distort_); ++ undistort_ = copyGrid(from.undistort_); ++} ++ + CameraIntrinsics::~CameraIntrinsics() { +- if(distort_) delete[] distort_; +- if(undistort_) delete[] undistort_; ++ FreeLookupGrid(); + } + + /// Set the entire calibration matrix at once. +@@ -146,11 +184,17 @@ void CameraIntrinsics::InvertIntrinsics(double image_x, + + // TODO(MatthiasF): downsample lookup + template +-void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) { ++void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height) { ++ double aspx = (double)width / image_width_; ++ double aspy = (double)height / image_height_; ++ + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { ++ double src_x = x / aspx, src_y = y / aspy; + double warp_x, warp_y; +- WarpFunction(this,x,y,&warp_x,&warp_y); ++ WarpFunction(this,src_x,src_y,&warp_x,&warp_y); ++ warp_x = warp_x*aspx; ++ warp_y = warp_y*aspy; + int ix = int(warp_x), iy = int(warp_y); + int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256); + if(fx == 256) { fx=0; ix++; } +@@ -162,10 +206,10 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) { + if( iy >= height-2 ) iy = height-2; + if ( ix-x > -128 && ix-x < 128 && iy-y > -128 && iy-y < 128 ) { + Offset offset = { ix-x, iy-y, fx, fy }; +- grid[y*width+x] = offset; ++ grid->offset[y*width+x] = offset; + } else { + Offset offset = { 0, 0, 0, 0 }; +- grid[y*width+x] = offset; ++ grid->offset[y*width+x] = offset; + } + } + } +@@ -173,11 +217,11 @@ void CameraIntrinsics::ComputeLookupGrid(Offset* grid, int width, int height) { + + // TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup + template +-static void Warp(const Offset* grid, const T* src, T* dst, ++static void Warp(const Grid* grid, const T* src, T* dst, + int width, int height) { + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { +- Offset offset = grid[y*width+x]; ++ Offset offset = grid->offset[y*width+x]; + const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N]; + for (int i = 0; i < N; i++) { + dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy) +@@ -188,8 +232,17 @@ static void Warp(const Offset* grid, const T* src, T* dst, + } + + void CameraIntrinsics::FreeLookupGrid() { +- if(distort_) delete distort_, distort_=0; +- if(undistort_) delete undistort_, undistort_=0; ++ if(distort_) { ++ delete distort_->offset; ++ delete distort_; ++ distort_ = NULL; ++ } ++ ++ if(undistort_) { ++ delete undistort_->offset; ++ delete undistort_; ++ undistort_ = NULL; ++ } + } + + // FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method. +@@ -211,11 +264,50 @@ struct InvertIntrinsicsFunction { + } + }; + +-void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) { +- if(!distort_) { +- distort_ = new Offset[width*height]; +- ComputeLookupGrid(distort_,width,height); ++void CameraIntrinsics::CheckDistortLookupGrid(int width, int height) ++{ ++ if(distort_) { ++ if(distort_->width != width || distort_->height != height) { ++ delete [] distort_->offset; ++ distort_->offset = NULL; ++ } ++ } else { ++ distort_ = new Grid; ++ distort_->offset = NULL; ++ } ++ ++ if(!distort_->offset) { ++ distort_->offset = new Offset[width*height]; ++ ComputeLookupGrid(distort_,width,height); + } ++ ++ distort_->width = width; ++ distort_->height = height; ++} ++ ++void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height) ++{ ++ if(undistort_) { ++ if(undistort_->width != width || undistort_->height != height) { ++ delete [] undistort_->offset; ++ undistort_->offset = NULL; ++ } ++ } else { ++ undistort_ = new Grid; ++ undistort_->offset = NULL; ++ } ++ ++ if(!undistort_->offset) { ++ undistort_->offset = new Offset[width*height]; ++ ComputeLookupGrid(undistort_,width,height); ++ } ++ ++ undistort_->width = width; ++ undistort_->height = height; ++} ++ ++void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, int channels) { ++ CheckDistortLookupGrid(width, height); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); +@@ -224,10 +316,7 @@ void CameraIntrinsics::Distort(const float* src, float* dst, int width, int heig + } + + void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) { +- if(!distort_) { +- distort_ = new Offset[width*height]; +- ComputeLookupGrid(distort_,width,height); +- } ++ CheckDistortLookupGrid(width, height); + if(channels==1) Warp(distort_,src,dst,width,height); + else if(channels==2) Warp(distort_,src,dst,width,height); + else if(channels==3) Warp(distort_,src,dst,width,height); +@@ -236,10 +325,7 @@ void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int + } + + void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, int channels) { +- if(!undistort_) { +- undistort_ = new Offset[width*height]; +- ComputeLookupGrid(undistort_,width,height); +- } ++ CheckUndistortLookupGrid(width, height); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); +@@ -248,10 +334,7 @@ void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int he + } + + void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, int channels) { +- if(!undistort_) { +- undistort_ = new Offset[width*height]; +- ComputeLookupGrid(undistort_,width,height); +- } ++ CheckUndistortLookupGrid(width, height); + if(channels==1) Warp(undistort_,src,dst,width,height); + else if(channels==2) Warp(undistort_,src,dst,width,height); + else if(channels==3) Warp(undistort_,src,dst,width,height); +diff --git a/src/libmv/simple_pipeline/camera_intrinsics.h b/src/libmv/simple_pipeline/camera_intrinsics.h +index 29bc8a1..f525571 100644 +--- a/src/libmv/simple_pipeline/camera_intrinsics.h ++++ b/src/libmv/simple_pipeline/camera_intrinsics.h +@@ -26,11 +26,12 @@ typedef Eigen::Matrix Mat3; + + namespace libmv { + +-struct Offset; ++struct Grid; + + class CameraIntrinsics { + public: + CameraIntrinsics(); ++ CameraIntrinsics(const CameraIntrinsics &from); + ~CameraIntrinsics(); + + const Mat3 &K() const { return K_; } +@@ -123,7 +124,9 @@ class CameraIntrinsics { + int width, int height, int channels); + + private: +- template void ComputeLookupGrid(Offset* grid, int width, int height); ++ template void ComputeLookupGrid(struct Grid* grid, int width, int height); ++ void CheckUndistortLookupGrid(int width, int height); ++ void CheckDistortLookupGrid(int width, int height); + void FreeLookupGrid(); + + // The traditional intrinsics matrix from x = K[R|t]X. +@@ -140,8 +143,8 @@ class CameraIntrinsics { + // independent of image size. + double k1_, k2_, k3_, p1_, p2_; + +- Offset* distort_; +- Offset* undistort_; ++ struct Grid *distort_; ++ struct Grid *undistort_; + }; + + } // namespace libmv diff --git a/extern/libmv/patches/series b/extern/libmv/patches/series new file mode 100644 index 00000000000..00a52c1cfaa --- /dev/null +++ b/extern/libmv/patches/series @@ -0,0 +1,13 @@ +v3d_verbosity.patch +snrptinf_fix.patch +bundle_tweaks.patch +fast.patch +config_mac.patch +levenberg_marquardt.patch +function_derivative.patch +high_distortion_crash_fix.patch +mingw.patch +msvc2010.patch +scaled_distortion.patch +overscan.patch +detect.patch diff --git a/extern/libmv/patches/snrptinf_fix.patch b/extern/libmv/patches/snrptinf_fix.patch new file mode 100644 index 00000000000..e886a671de0 --- /dev/null +++ b/extern/libmv/patches/snrptinf_fix.patch @@ -0,0 +1,15 @@ +diff --git a/src/libmv/simple_pipeline/pipeline.cc b/src/libmv/simple_pipeline/pipeline.cc +index 652d70c..25cd2c2 100644 +--- a/src/libmv/simple_pipeline/pipeline.cc ++++ b/src/libmv/simple_pipeline/pipeline.cc +@@ -28,6 +28,10 @@ + #include "libmv/simple_pipeline/tracks.h" + #include "libmv/simple_pipeline/camera_intrinsics.h" + ++#ifdef _MSC_VER ++# define snprintf _snprintf ++#endif ++ + namespace libmv { + + void CompleteReconstruction(const Tracks &tracks, diff --git a/extern/libmv/patches/v3d_verbosity.patch b/extern/libmv/patches/v3d_verbosity.patch new file mode 100644 index 00000000000..a54f3dc44be --- /dev/null +++ b/extern/libmv/patches/v3d_verbosity.patch @@ -0,0 +1,12 @@ +diff --git a/src/libmv/simple_pipeline/bundle.cc b/src/libmv/simple_pipeline/bundle.cc +index 310660d..f819603 100644 +--- a/src/libmv/simple_pipeline/bundle.cc ++++ b/src/libmv/simple_pipeline/bundle.cc +@@ -141,7 +141,6 @@ void Bundle(const Tracks &tracks, Reconstruction *reconstruction) { + v3d_distortion.p2 = 0; + + // Finally, run the bundle adjustment. +- V3D::optimizerVerbosenessLevel = 1; + double const inlierThreshold = 500000.0; + V3D::CommonInternalsMetricBundleOptimizer opt(V3D::FULL_BUNDLE_METRIC, + inlierThreshold, diff --git a/extern/libmv/third_party/fast/LICENSE b/extern/libmv/third_party/fast/LICENSE new file mode 100644 index 00000000000..f347008d6ef --- /dev/null +++ b/extern/libmv/third_party/fast/LICENSE @@ -0,0 +1,30 @@ +Copyright (c) 2006, 2008 Edward Rosten +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + + *Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + *Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + *Neither the name of the University of Cambridge nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extern/libmv/third_party/fast/README b/extern/libmv/third_party/fast/README new file mode 100644 index 00000000000..77017078d08 --- /dev/null +++ b/extern/libmv/third_party/fast/README @@ -0,0 +1,31 @@ +FAST feature detectors in C Version 2.0 +--------------------------------------- + +The files are valid C and C++ code, and have no special requirements for +compiling, and they do not depend on any libraries. Just compile them along with +the rest of your project. + +To use the functions, #include "fast.h" + +The corner detectors have the following prototype (where X is 9, 10, 11 or 12): + +xy* fastX_detect_nonmax(const unsigned char * data, int xsize, int ysize, int stride, int threshold, int* numcorners) + +Where xy is the following simple struct typedef: + +typedef struct +{ + int x, y; +} xy; + +The image is passed in as a block of data and dimensions, and the list of +corners is returned as an array of xy structs, and an integer (numcorners) +with the number of corners returned. The data can be deallocated with free(). +Nonmaximal suppression is performed on the corners. Note that the stride +is the number of bytes between rows. If your image has no padding, then this +is the same as xsize. + +The detection, scoring and nonmaximal suppression are available as individual +functions. To see how to use the individual functions, see fast.c + + diff --git a/extern/libmv/third_party/fast/README.libmv b/extern/libmv/third_party/fast/README.libmv new file mode 100644 index 00000000000..2110976dd14 --- /dev/null +++ b/extern/libmv/third_party/fast/README.libmv @@ -0,0 +1,9 @@ +Project: FAST (FAST Corner Detection) +URL: http://mi.eng.cam.ac.uk/~er258/work/fast-C-src/ +License: BSD +Upstream version: 2.1, released 12-Jan-2009 + +Local modifications: +- Created CMakeLists.txt for CMake build. +- Update CMakeLists to be sure that the library is a compatible with C++ linkage. +- Update CMakeLists to not include fast.h to compile fast library with VS2005. diff --git a/extern/libmv/third_party/fast/fast.c b/extern/libmv/third_party/fast/fast.c new file mode 100644 index 00000000000..c675f0af883 --- /dev/null +++ b/extern/libmv/third_party/fast/fast.c @@ -0,0 +1,71 @@ +#include +#include "fast.h" + + +xy* fast9_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + xy* corners; + int num_corners; + int* scores; + xy* nonmax; + + corners = fast9_detect(im, xsize, ysize, stride, b, &num_corners); + scores = fast9_score(im, stride, corners, num_corners, b); + nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners); + + free(corners); + free(scores); + + return nonmax; +} + +xy* fast10_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + xy* corners; + int num_corners; + int* scores; + xy* nonmax; + + corners = fast10_detect(im, xsize, ysize, stride, b, &num_corners); + scores = fast10_score(im, stride, corners, num_corners, b); + nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners); + + free(corners); + free(scores); + + return nonmax; +} + +xy* fast11_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + xy* corners; + int num_corners; + int* scores; + xy* nonmax; + + corners = fast11_detect(im, xsize, ysize, stride, b, &num_corners); + scores = fast11_score(im, stride, corners, num_corners, b); + nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners); + + free(corners); + free(scores); + + return nonmax; +} + +xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + xy* corners; + int num_corners; + int* scores; + xy* nonmax; + + corners = fast12_detect(im, xsize, ysize, stride, b, &num_corners); + scores = fast12_score(im, stride, corners, num_corners, b); + nonmax = nonmax_suppression(corners, scores, num_corners, ret_num_corners); + + free(corners); + free(scores); + + return nonmax; +} diff --git a/extern/libmv/third_party/fast/fast.h b/extern/libmv/third_party/fast/fast.h new file mode 100644 index 00000000000..06fa90ec98c --- /dev/null +++ b/extern/libmv/third_party/fast/fast.h @@ -0,0 +1,39 @@ +#ifndef FAST_H +#define FAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { int x, y; } xy; +typedef unsigned char byte; + +int fast9_corner_score(const byte* p, const int pixel[], int bstart); +int fast10_corner_score(const byte* p, const int pixel[], int bstart); +int fast11_corner_score(const byte* p, const int pixel[], int bstart); +int fast12_corner_score(const byte* p, const int pixel[], int bstart); + +xy* fast9_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast10_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast11_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast12_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); + +int* fast9_score(const byte* i, int stride, xy* corners, int num_corners, int b); +int* fast10_score(const byte* i, int stride, xy* corners, int num_corners, int b); +int* fast11_score(const byte* i, int stride, xy* corners, int num_corners, int b); +int* fast12_score(const byte* i, int stride, xy* corners, int num_corners, int b); + + +xy* fast9_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast10_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast11_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); +xy* fast12_detect_nonmax(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners); + +xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/extern/libmv/third_party/fast/fast_10.c b/extern/libmv/third_party/fast/fast_10.c new file mode 100644 index 00000000000..3af63869478 --- /dev/null +++ b/extern/libmv/third_party/fast/fast_10.c @@ -0,0 +1,4666 @@ +/*This is mechanically generated code*/ +#include + +typedef struct { int x, y; } xy; +typedef unsigned char byte; + +int fast10_corner_score(const byte* p, const int pixel[], int bstart) +{ + int bmin = bstart; + int bmax = 255; + int b = (bmax + bmin)/2; + + /*Compute the score using binary search*/ + for(;;) + { + int cb = *p + b; + int c_b= *p - b; + + + if( p[pixel[0]] > cb) + if( p[pixel[1]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[15]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[14]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[0]] < c_b) + if( p[pixel[1]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[2]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[3]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[4]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[10]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[5]] > cb) + if( p[pixel[15]] < c_b) + if( p[pixel[11]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[1]] > cb) + goto is_a_corner; + else + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + if( p[pixel[1]] < c_b) + goto is_a_corner; + else + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin=b; + goto end_if; + + is_not_a_corner: + bmax=b; + goto end_if; + + end_if: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b = (bmin + bmax) / 2; + } +} + +static void make_offsets(int pixel[], int row_stride) +{ + pixel[0] = 0 + row_stride * 3; + pixel[1] = 1 + row_stride * 3; + pixel[2] = 2 + row_stride * 2; + pixel[3] = 3 + row_stride * 1; + pixel[4] = 3 + row_stride * 0; + pixel[5] = 3 + row_stride * -1; + pixel[6] = 2 + row_stride * -2; + pixel[7] = 1 + row_stride * -3; + pixel[8] = 0 + row_stride * -3; + pixel[9] = -1 + row_stride * -3; + pixel[10] = -2 + row_stride * -2; + pixel[11] = -3 + row_stride * -1; + pixel[12] = -3 + row_stride * 0; + pixel[13] = -3 + row_stride * 1; + pixel[14] = -2 + row_stride * 2; + pixel[15] = -1 + row_stride * 3; +} + + + +int* fast10_score(const byte* i, int stride, xy* corners, int num_corners, int b) +{ + int* scores = (int*)malloc(sizeof(int)* num_corners); + int n; + + int pixel[16]; + make_offsets(pixel, stride); + + for(n=0; n < num_corners; n++) + scores[n] = fast10_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b); + + return scores; +} + + +xy* fast10_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + int num_corners=0; + xy* ret_corners; + int rsize=512; + int pixel[16]; + int x, y; + + ret_corners = (xy*)malloc(sizeof(xy)*rsize); + make_offsets(pixel, stride); + + for(y=3; y < ysize - 3; y++) + for(x=3; x < xsize - 3; x++) + { + const byte* p = im + y*stride + x; + + int cb = *p + b; + int c_b= *p - b; + if(p[pixel[0]] > cb) + if(p[pixel[1]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[15]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[14]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + {} + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + {} + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[0]] < c_b) + if(p[pixel[1]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[2]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[3]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[4]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[5]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[10]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[5]] > cb) + if(p[pixel[15]] < c_b) + if(p[pixel[11]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[5]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[14]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[13]] > cb) + {} + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[12]] > cb) + {} + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[1]] > cb) + {} + else + if(p[pixel[11]] > cb) + {} + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + if(p[pixel[1]] < c_b) + {} + else + if(p[pixel[11]] < c_b) + {} + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + if(num_corners == rsize) + { + rsize*=2; + ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize); + } + + ret_corners[num_corners].x = x; + ret_corners[num_corners].y = y; + num_corners++; + } + + *ret_num_corners = num_corners; + return ret_corners; + +} + + diff --git a/extern/libmv/third_party/fast/fast_11.c b/extern/libmv/third_party/fast/fast_11.c new file mode 100644 index 00000000000..b4af4309521 --- /dev/null +++ b/extern/libmv/third_party/fast/fast_11.c @@ -0,0 +1,3910 @@ +/*This is mechanically generated code*/ +#include + +typedef struct { int x, y; } xy; +typedef unsigned char byte; + +int fast11_corner_score(const byte* p, const int pixel[], int bstart) +{ + int bmin = bstart; + int bmax = 255; + int b = (bmax + bmin)/2; + + /*Compute the score using binary search*/ + for(;;) + { + int cb = *p + b; + int c_b= *p - b; + + + if( p[pixel[0]] > cb) + if( p[pixel[1]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[15]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[14]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[0]] < c_b) + if( p[pixel[1]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[2]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[3]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[8]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[4]] > cb) + if( p[pixel[15]] < c_b) + if( p[pixel[9]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[5]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[1]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + if( p[pixel[1]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin=b; + goto end_if; + + is_not_a_corner: + bmax=b; + goto end_if; + + end_if: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b = (bmin + bmax) / 2; + } +} + +static void make_offsets(int pixel[], int row_stride) +{ + pixel[0] = 0 + row_stride * 3; + pixel[1] = 1 + row_stride * 3; + pixel[2] = 2 + row_stride * 2; + pixel[3] = 3 + row_stride * 1; + pixel[4] = 3 + row_stride * 0; + pixel[5] = 3 + row_stride * -1; + pixel[6] = 2 + row_stride * -2; + pixel[7] = 1 + row_stride * -3; + pixel[8] = 0 + row_stride * -3; + pixel[9] = -1 + row_stride * -3; + pixel[10] = -2 + row_stride * -2; + pixel[11] = -3 + row_stride * -1; + pixel[12] = -3 + row_stride * 0; + pixel[13] = -3 + row_stride * 1; + pixel[14] = -2 + row_stride * 2; + pixel[15] = -1 + row_stride * 3; +} + + + +int* fast11_score(const byte* i, int stride, xy* corners, int num_corners, int b) +{ + int* scores = (int*)malloc(sizeof(int)* num_corners); + int n; + + int pixel[16]; + make_offsets(pixel, stride); + + for(n=0; n < num_corners; n++) + scores[n] = fast11_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b); + + return scores; +} + + +xy* fast11_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + int num_corners=0; + xy* ret_corners; + int rsize=512; + int pixel[16]; + int x, y; + + ret_corners = (xy*)malloc(sizeof(xy)*rsize); + make_offsets(pixel, stride); + + for(y=3; y < ysize - 3; y++) + for(x=3; x < xsize - 3; x++) + { + const byte* p = im + y*stride + x; + + int cb = *p + b; + int c_b= *p - b; + if(p[pixel[0]] > cb) + if(p[pixel[1]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[15]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[14]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + {} + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[0]] < c_b) + if(p[pixel[1]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[2]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[3]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[8]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[4]] > cb) + if(p[pixel[15]] < c_b) + if(p[pixel[9]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[5]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[14]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[13]] > cb) + {} + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[1]] > cb) + {} + else + if(p[pixel[12]] > cb) + {} + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + if(p[pixel[1]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + {} + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + if(num_corners == rsize) + { + rsize*=2; + ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize); + } + + ret_corners[num_corners].x = x; + ret_corners[num_corners].y = y; + num_corners++; + } + + *ret_num_corners = num_corners; + return ret_corners; + +} + + diff --git a/extern/libmv/third_party/fast/fast_12.c b/extern/libmv/third_party/fast/fast_12.c new file mode 100644 index 00000000000..f73f68dd043 --- /dev/null +++ b/extern/libmv/third_party/fast/fast_12.c @@ -0,0 +1,3134 @@ +/*This is mechanically generated code*/ +#include + +typedef struct { int x, y; } xy; +typedef unsigned char byte; + +int fast12_corner_score(const byte* p, const int pixel[], int bstart) +{ + int bmin = bstart; + int bmax = 255; + int b = (bmax + bmin)/2; + + /*Compute the score using binary search*/ + for(;;) + { + int cb = *p + b; + int c_b= *p - b; + + + if( p[pixel[0]] > cb) + if( p[pixel[1]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[15]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[0]] < c_b) + if( p[pixel[1]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[2]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[3]] > cb) + if( p[pixel[15]] < c_b) + if( p[pixel[7]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[4]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[1]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + if( p[pixel[1]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin=b; + goto end_if; + + is_not_a_corner: + bmax=b; + goto end_if; + + end_if: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b = (bmin + bmax) / 2; + } +} + +static void make_offsets(int pixel[], int row_stride) +{ + pixel[0] = 0 + row_stride * 3; + pixel[1] = 1 + row_stride * 3; + pixel[2] = 2 + row_stride * 2; + pixel[3] = 3 + row_stride * 1; + pixel[4] = 3 + row_stride * 0; + pixel[5] = 3 + row_stride * -1; + pixel[6] = 2 + row_stride * -2; + pixel[7] = 1 + row_stride * -3; + pixel[8] = 0 + row_stride * -3; + pixel[9] = -1 + row_stride * -3; + pixel[10] = -2 + row_stride * -2; + pixel[11] = -3 + row_stride * -1; + pixel[12] = -3 + row_stride * 0; + pixel[13] = -3 + row_stride * 1; + pixel[14] = -2 + row_stride * 2; + pixel[15] = -1 + row_stride * 3; +} + + + +int* fast12_score(const byte* i, int stride, xy* corners, int num_corners, int b) +{ + int* scores = (int*)malloc(sizeof(int)* num_corners); + int n; + + int pixel[16]; + make_offsets(pixel, stride); + + for(n=0; n < num_corners; n++) + scores[n] = fast12_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b); + + return scores; +} + + +xy* fast12_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + int num_corners=0; + xy* ret_corners; + int rsize=512; + int pixel[16]; + int x, y; + + ret_corners = (xy*)malloc(sizeof(xy)*rsize); + make_offsets(pixel, stride); + + for(y=3; y < ysize - 3; y++) + for(x=3; x < xsize - 3; x++) + { + const byte* p = im + y*stride + x; + + int cb = *p + b; + int c_b= *p - b; + if(p[pixel[0]] > cb) + if(p[pixel[1]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[15]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[0]] < c_b) + if(p[pixel[1]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[2]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[3]] > cb) + if(p[pixel[15]] < c_b) + if(p[pixel[7]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[4]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[14]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[1]] > cb) + {} + else + if(p[pixel[13]] > cb) + {} + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + if(p[pixel[1]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + {} + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + if(num_corners == rsize) + { + rsize*=2; + ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize); + } + + ret_corners[num_corners].x = x; + ret_corners[num_corners].y = y; + num_corners++; + } + + *ret_num_corners = num_corners; + return ret_corners; + +} + + diff --git a/extern/libmv/third_party/fast/fast_9.c b/extern/libmv/third_party/fast/fast_9.c new file mode 100644 index 00000000000..6d33daeffbb --- /dev/null +++ b/extern/libmv/third_party/fast/fast_9.c @@ -0,0 +1,5910 @@ +/*This is mechanically generated code*/ +#include + +typedef struct { int x, y; } xy; +typedef unsigned char byte; + +int fast9_corner_score(const byte* p, const int pixel[], int bstart) +{ + int bmin = bstart; + int bmax = 255; + int b = (bmax + bmin)/2; + + /*Compute the score using binary search*/ + for(;;) + { + int cb = *p + b; + int c_b= *p - b; + + + if( p[pixel[0]] > cb) + if( p[pixel[1]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[15]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[14]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[6]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[13]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + goto is_a_corner; + else + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + goto is_a_corner; + else + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + goto is_a_corner; + else + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + goto is_a_corner; + else + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[0]] < c_b) + if( p[pixel[1]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[1]] < c_b) + if( p[pixel[2]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[2]] < c_b) + if( p[pixel[3]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[3]] < c_b) + if( p[pixel[4]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[11]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[4]] < c_b) + if( p[pixel[5]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[12]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[6]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[5]] < c_b) + if( p[pixel[6]] > cb) + if( p[pixel[15]] < c_b) + if( p[pixel[13]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[6]] < c_b) + if( p[pixel[7]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[6]] > cb) + goto is_a_corner; + else + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + goto is_a_corner; + else + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + goto is_a_corner; + else + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[9]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + goto is_a_corner; + else + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[8]] > cb) + if( p[pixel[7]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[10]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + goto is_a_corner; + else + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[2]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[7]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[7]] > cb) + if( p[pixel[8]] > cb) + if( p[pixel[9]] > cb) + if( p[pixel[6]] > cb) + if( p[pixel[5]] > cb) + if( p[pixel[4]] > cb) + if( p[pixel[3]] > cb) + if( p[pixel[2]] > cb) + if( p[pixel[1]] > cb) + goto is_a_corner; + else + if( p[pixel[10]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] > cb) + if( p[pixel[11]] > cb) + if( p[pixel[12]] > cb) + if( p[pixel[13]] > cb) + if( p[pixel[14]] > cb) + if( p[pixel[15]] > cb) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else if( p[pixel[7]] < c_b) + if( p[pixel[8]] < c_b) + if( p[pixel[9]] < c_b) + if( p[pixel[6]] < c_b) + if( p[pixel[5]] < c_b) + if( p[pixel[4]] < c_b) + if( p[pixel[3]] < c_b) + if( p[pixel[2]] < c_b) + if( p[pixel[1]] < c_b) + goto is_a_corner; + else + if( p[pixel[10]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + if( p[pixel[10]] < c_b) + if( p[pixel[11]] < c_b) + if( p[pixel[12]] < c_b) + if( p[pixel[13]] < c_b) + if( p[pixel[14]] < c_b) + if( p[pixel[15]] < c_b) + goto is_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + else + goto is_not_a_corner; + + is_a_corner: + bmin=b; + goto end_if; + + is_not_a_corner: + bmax=b; + goto end_if; + + end_if: + + if(bmin == bmax - 1 || bmin == bmax) + return bmin; + b = (bmin + bmax) / 2; + } +} + +static void make_offsets(int pixel[], int row_stride) +{ + pixel[0] = 0 + row_stride * 3; + pixel[1] = 1 + row_stride * 3; + pixel[2] = 2 + row_stride * 2; + pixel[3] = 3 + row_stride * 1; + pixel[4] = 3 + row_stride * 0; + pixel[5] = 3 + row_stride * -1; + pixel[6] = 2 + row_stride * -2; + pixel[7] = 1 + row_stride * -3; + pixel[8] = 0 + row_stride * -3; + pixel[9] = -1 + row_stride * -3; + pixel[10] = -2 + row_stride * -2; + pixel[11] = -3 + row_stride * -1; + pixel[12] = -3 + row_stride * 0; + pixel[13] = -3 + row_stride * 1; + pixel[14] = -2 + row_stride * 2; + pixel[15] = -1 + row_stride * 3; +} + + + +int* fast9_score(const byte* i, int stride, xy* corners, int num_corners, int b) +{ + int* scores = (int*)malloc(sizeof(int)* num_corners); + int n; + + int pixel[16]; + make_offsets(pixel, stride); + + for(n=0; n < num_corners; n++) + scores[n] = fast9_corner_score(i + corners[n].y*stride + corners[n].x, pixel, b); + + return scores; +} + + +xy* fast9_detect(const byte* im, int xsize, int ysize, int stride, int b, int* ret_num_corners) +{ + int num_corners=0; + xy* ret_corners; + int rsize=512; + int pixel[16]; + int x, y; + + ret_corners = (xy*)malloc(sizeof(xy)*rsize); + make_offsets(pixel, stride); + + for(y=3; y < ysize - 3; y++) + for(x=3; x < xsize - 3; x++) + { + const byte* p = im + y*stride + x; + + int cb = *p + b; + int c_b= *p - b; + if(p[pixel[0]] > cb) + if(p[pixel[1]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[15]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[14]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[6]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[13]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + {} + else + if(p[pixel[14]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + {} + else + if(p[pixel[13]] < c_b) + {} + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + {} + else + if(p[pixel[12]] < c_b) + {} + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + {} + else + if(p[pixel[11]] < c_b) + {} + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[0]] < c_b) + if(p[pixel[1]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[1]] < c_b) + if(p[pixel[2]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[2]] < c_b) + if(p[pixel[3]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[3]] < c_b) + if(p[pixel[4]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + {} + else + if(p[pixel[14]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[11]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[4]] < c_b) + if(p[pixel[5]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[6]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[12]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[6]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[5]] < c_b) + if(p[pixel[6]] > cb) + if(p[pixel[15]] < c_b) + if(p[pixel[13]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[6]] < c_b) + if(p[pixel[7]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + if(p[pixel[15]] < c_b) + {} + else + continue; + else + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[6]] > cb) + {} + else + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + {} + else + if(p[pixel[14]] > cb) + {} + else + continue; + else + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + {} + else + if(p[pixel[13]] > cb) + {} + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[9]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + {} + else + if(p[pixel[12]] > cb) + {} + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[8]] > cb) + if(p[pixel[7]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[10]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + {} + else + if(p[pixel[11]] > cb) + {} + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[2]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[7]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[7]] > cb) + if(p[pixel[8]] > cb) + if(p[pixel[9]] > cb) + if(p[pixel[6]] > cb) + if(p[pixel[5]] > cb) + if(p[pixel[4]] > cb) + if(p[pixel[3]] > cb) + if(p[pixel[2]] > cb) + if(p[pixel[1]] > cb) + {} + else + if(p[pixel[10]] > cb) + {} + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + {} + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] > cb) + if(p[pixel[11]] > cb) + if(p[pixel[12]] > cb) + if(p[pixel[13]] > cb) + if(p[pixel[14]] > cb) + if(p[pixel[15]] > cb) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else if(p[pixel[7]] < c_b) + if(p[pixel[8]] < c_b) + if(p[pixel[9]] < c_b) + if(p[pixel[6]] < c_b) + if(p[pixel[5]] < c_b) + if(p[pixel[4]] < c_b) + if(p[pixel[3]] < c_b) + if(p[pixel[2]] < c_b) + if(p[pixel[1]] < c_b) + {} + else + if(p[pixel[10]] < c_b) + {} + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + {} + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + if(p[pixel[10]] < c_b) + if(p[pixel[11]] < c_b) + if(p[pixel[12]] < c_b) + if(p[pixel[13]] < c_b) + if(p[pixel[14]] < c_b) + if(p[pixel[15]] < c_b) + {} + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + else + continue; + if(num_corners == rsize) + { + rsize*=2; + ret_corners = (xy*)realloc(ret_corners, sizeof(xy)*rsize); + } + ret_corners[num_corners].x = x; + ret_corners[num_corners].y = y; + num_corners++; + + } + + *ret_num_corners = num_corners; + return ret_corners; + +} + + diff --git a/extern/libmv/third_party/fast/nonmax.c b/extern/libmv/third_party/fast/nonmax.c new file mode 100644 index 00000000000..6ed0f580906 --- /dev/null +++ b/extern/libmv/third_party/fast/nonmax.c @@ -0,0 +1,117 @@ +#include +#include "fast.h" + + +#define Compare(X, Y) ((X)>=(Y)) + +xy* nonmax_suppression(const xy* corners, const int* scores, int num_corners, int* ret_num_nonmax) +{ + int num_nonmax=0; + int last_row; + int* row_start; + int i, j; + xy* ret_nonmax; + const int sz = (int)num_corners; + + /*Point above points (roughly) to the pixel above the one of interest, if there + is a feature there.*/ + int point_above = 0; + int point_below = 0; + + + if(num_corners < 1) + { + *ret_num_nonmax = 0; + return 0; + } + + ret_nonmax = (xy*)malloc(num_corners * sizeof(xy)); + + /* Find where each row begins + (the corners are output in raster scan order). A beginning of -1 signifies + that there are no corners on that row. */ + last_row = corners[num_corners-1].y; + row_start = (int*)malloc((last_row+1)*sizeof(int)); + + for(i=0; i < last_row+1; i++) + row_start[i] = -1; + + { + int prev_row = -1; + for(i=0; i< num_corners; i++) + if(corners[i].y != prev_row) + { + row_start[corners[i].y] = i; + prev_row = corners[i].y; + } + } + + + + for(i=0; i < sz; i++) + { + int score = scores[i]; + xy pos = corners[i]; + + /*Check left */ + if(i > 0) + if(corners[i-1].x == pos.x-1 && corners[i-1].y == pos.y && Compare(scores[i-1], score)) + continue; + + /*Check right*/ + if(i < (sz - 1)) + if(corners[i+1].x == pos.x+1 && corners[i+1].y == pos.y && Compare(scores[i+1], score)) + continue; + + /*Check above (if there is a valid row above)*/ + if(pos.y != 0 && row_start[pos.y - 1] != -1) + { + /*Make sure that current point_above is one + row above.*/ + if(corners[point_above].y < pos.y - 1) + point_above = row_start[pos.y-1]; + + /*Make point_above point to the first of the pixels above the current point, + if it exists.*/ + for(; corners[point_above].y < pos.y && corners[point_above].x < pos.x - 1; point_above++) + {} + + + for(j=point_above; corners[j].y < pos.y && corners[j].x <= pos.x + 1; j++) + { + int x = corners[j].x; + if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j], score)) + goto cont; + } + + } + + /*Check below (if there is anything below)*/ + if(pos.y != last_row && row_start[pos.y + 1] != -1 && point_below < sz) /*Nothing below*/ + { + if(corners[point_below].y < pos.y + 1) + point_below = row_start[pos.y+1]; + + /* Make point below point to one of the pixels belowthe current point, if it + exists.*/ + for(; point_below < sz && corners[point_below].y == pos.y+1 && corners[point_below].x < pos.x - 1; point_below++) + {} + + for(j=point_below; j < sz && corners[j].y == pos.y+1 && corners[j].x <= pos.x + 1; j++) + { + int x = corners[j].x; + if( (x == pos.x - 1 || x ==pos.x || x == pos.x+1) && Compare(scores[j],score)) + goto cont; + } + } + + ret_nonmax[num_nonmax++] = corners[i]; + cont: + ; + } + + free(row_start); + *ret_num_nonmax = num_nonmax; + return ret_nonmax; +} + diff --git a/extern/libmv/third_party/gflags/README.libmv b/extern/libmv/third_party/gflags/README.libmv new file mode 100644 index 00000000000..f2bdef6563e --- /dev/null +++ b/extern/libmv/third_party/gflags/README.libmv @@ -0,0 +1,14 @@ +Project: Google Flags +URL: http://code.google.com/p/google-gflags/ +License: New BSD +Upstream version: 1.5 +Local modifications: + +- Flattened the tree and only included files needed for libmv. This involved + changing some of the includes to point to the current directory instead of a + nested gflags directory. + +- Added a poor-man's version of upstream's port.cc/h to make gflags compile on + windows. This isn't sufficient but is a stopgap for now. + + TODO(keir): Import and use gflags for Windows from upstream. diff --git a/extern/libmv/third_party/gflags/config.h b/extern/libmv/third_party/gflags/config.h new file mode 100644 index 00000000000..ca2c1276c44 --- /dev/null +++ b/extern/libmv/third_party/gflags/config.h @@ -0,0 +1,110 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Always the empty-string on non-windows systems. On windows, should be + "__declspec(dllexport)". This way, when we compile the dll, we export our + functions/classes. It's safe to define this here because config.h is only + used internally, to compile the DLL, and every DLL source file #includes + "config.h" before anything else. */ +#define GFLAGS_DLL_DECL /**/ + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE ::google + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#undef HAVE_FNMATCH_H + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* define if the compiler implements namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the `putenv' function. */ +#define HAVE_PUTENV 1 + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strtoll' function. */ +#define HAVE_STRTOLL 1 + +/* Define to 1 if you have the `strtoq' function. */ +#define HAVE_STRTOQ 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "gflags" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opensource@google.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "gflags" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "gflags 1.5" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "gflags" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.5" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* Version number of package */ +#define VERSION "1.5" + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { diff --git a/extern/libmv/third_party/gflags/gflags.cc b/extern/libmv/third_party/gflags/gflags.cc new file mode 100644 index 00000000000..34fe95dac59 --- /dev/null +++ b/extern/libmv/third_party/gflags/gflags.cc @@ -0,0 +1,1971 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// Author: Ray Sidney +// Revamped and reorganized by Craig Silverstein +// +// This file contains the implementation of all our command line flags +// stuff. Here's how everything fits together +// +// * FlagRegistry owns CommandLineFlags owns FlagValue. +// * FlagSaver holds a FlagRegistry (saves it at construct time, +// restores it at destroy time). +// * CommandLineFlagParser lives outside that hierarchy, but works on +// CommandLineFlags (modifying the FlagValues). +// * Free functions like SetCommandLineOption() work via one of the +// above (such as CommandLineFlagParser). +// +// In more detail: +// +// -- The main classes that hold flag data: +// +// FlagValue holds the current value of a flag. It's +// pseudo-templatized: every operation on a FlagValue is typed. It +// also deals with storage-lifetime issues (so flag values don't go +// away in a destructor), which is why we need a whole class to hold a +// variable's value. +// +// CommandLineFlag is all the information about a single command-line +// flag. It has a FlagValue for the flag's current value, but also +// the flag's name, type, etc. +// +// FlagRegistry is a collection of CommandLineFlags. There's the +// global registry, which is where flags defined via DEFINE_foo() +// live. But it's possible to define your own flag, manually, in a +// different registry you create. (In practice, multiple registries +// are used only by FlagSaver). +// +// A given FlagValue is owned by exactly one CommandLineFlag. A given +// CommandLineFlag is owned by exactly one FlagRegistry. FlagRegistry +// has a lock; any operation that writes to a FlagValue or +// CommandLineFlag owned by that registry must acquire the +// FlagRegistry lock before doing so. +// +// --- Some other classes and free functions: +// +// CommandLineFlagInfo is a client-exposed version of CommandLineFlag. +// Once it's instantiated, it has no dependencies or relationships +// with any other part of this file. +// +// FlagRegisterer is the helper class used by the DEFINE_* macros to +// allow work to be done at global initialization time. +// +// CommandLineFlagParser is the class that reads from the commandline +// and instantiates flag values based on that. It needs to poke into +// the innards of the FlagValue->CommandLineFlag->FlagRegistry class +// hierarchy to do that. It's careful to acquire the FlagRegistry +// lock before doing any writing or other non-const actions. +// +// GetCommandLineOption is just a hook into registry routines to +// retrieve a flag based on its name. SetCommandLineOption, on the +// other hand, hooks into CommandLineFlagParser. Other API functions +// are, similarly, mostly hooks into the functionality described above. + +#include "config.h" +// This comes first to ensure we define __STDC_FORMAT_MACROS in time. +#ifdef HAVE_INTTYPES_H +#ifndef __STDC_FORMAT_MACROS +# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc. +#endif +#include +#endif // HAVE_INTTYPES_H +#include // for snprintf +#include +#include +#include +#include // For va_list and related operations +#include +#include +#ifdef HAVE_FNMATCH_H +#include +#endif // HAVE_FNMATCH_H +#include +#include +#include +#include // for pair<> +#include +#include "gflags.h" +#include "mutex.h" + +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR '/' +#endif + +// Work properly if either strtoll or strtoq is on this system +#ifdef HAVE_STRTOLL +# define strtoint64 strtoll +# define strtouint64 strtoull +#elif HAVE_STRTOQ +# define strtoint64 strtoq +# define strtouint64 strtouq +#else +// Neither strtoll nor strtoq are defined. I hope strtol works! +# define strtoint64 strtol +# define strtouint64 strtoul +#endif + +// If we have inttypes.h, it will have defined PRId32/etc for us. If +// not, take our best guess. +#ifndef PRId32 +# define PRId32 "d" +#endif +#ifndef PRId64 +# define PRId64 "lld" +#endif +#ifndef PRIu64 +# define PRIu64 "llu" +#endif + +// Windows is missing random bits like strcasecmp, strtoll, strtoull, and +// snprintf in the usual locations. Put them somewhere sensible. +// +// TODO(keir): Get the upstream Windows port and use that instead. +#ifdef _MSC_VER +# define snprintf _snprintf +# undef strtoint64 +# define strtoint64 _strtoi64 +# undef strtouint64 +# define strtouint64 _strtoui64 +# define strcasecmp _stricmp +#endif + +typedef signed char int8; +typedef unsigned char uint8; + +// Special flags, type 1: the 'recursive' flags. They set another flag's val. +DEFINE_string(flagfile, "", + "load flags from file"); +DEFINE_string(fromenv, "", + "set flags from the environment" + " [use 'export FLAGS_flag1=value']"); +DEFINE_string(tryfromenv, "", + "set flags from the environment if present"); + +// Special flags, type 2: the 'parsing' flags. They modify how we parse. +DEFINE_string(undefok, "", + "comma-separated list of flag names that it is okay to specify " + "on the command line even if the program does not define a flag " + "with that name. IMPORTANT: flags in this list that have " + "arguments MUST use the flag=value format"); + +_START_GOOGLE_NAMESPACE_ + +using std::map; +using std::pair; +using std::sort; +using std::string; +using std::vector; + +// The help message indicating that the commandline flag has been +// 'stripped'. It will not show up when doing "-help" and its +// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1 +// before including gflags/gflags.h. + +// This is used by this file, and also in commandlineflags_reporting.cc +const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001"; + +// This is used by the unittest to test error-exit code +void GFLAGS_DLL_DECL (*commandlineflags_exitfunc)(int) = &exit; // from stdlib.h + +namespace { + +// There are also 'reporting' flags, in commandlineflags_reporting.cc. + +static const char kError[] = "ERROR: "; + +// Indicates that undefined options are to be ignored. +// Enables deferred processing of flags in dynamically loaded libraries. +static bool allow_command_line_reparsing = false; + +static bool logging_is_probably_set_up = false; + +// This is a 'prototype' validate-function. 'Real' validate +// functions, take a flag-value as an argument: ValidateFn(bool) or +// ValidateFn(uint64). However, for easier storage, we strip off this +// argument and then restore it when actually calling the function on +// a flag value. +typedef bool (*ValidateFnProto)(); + +// Whether we should die when reporting an error. +enum DieWhenReporting { DIE, DO_NOT_DIE }; + +// Report Error and exit if requested. +static void ReportError(DieWhenReporting should_die, const char* format, ...) { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + if (should_die == DIE) + commandlineflags_exitfunc(1); // almost certainly exit() +} + + +// -------------------------------------------------------------------- +// FlagValue +// This represent the value a single flag might have. The major +// functionality is to convert from a string to an object of a +// given type, and back. Thread-compatible. +// -------------------------------------------------------------------- + +class CommandLineFlag; +class FlagValue { + public: + FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value); + ~FlagValue(); + + bool ParseFrom(const char* spec); + string ToString() const; + + private: + friend class CommandLineFlag; // for many things, including Validate() + friend class GOOGLE_NAMESPACE::FlagSaverImpl; // calls New() + friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map + template friend T GetFromEnv(const char*, const char*, T); + friend bool TryParseLocked(const CommandLineFlag*, FlagValue*, + const char*, string*); // for New(), CopyFrom() + + enum ValueType { + FV_BOOL = 0, + FV_INT32 = 1, + FV_INT64 = 2, + FV_UINT64 = 3, + FV_DOUBLE = 4, + FV_STRING = 5, + FV_MAX_INDEX = 5, + }; + const char* TypeName() const; + bool Equal(const FlagValue& x) const; + FlagValue* New() const; // creates a new one with default value + void CopyFrom(const FlagValue& x); + int ValueSize() const; + + // Calls the given validate-fn on value_buffer_, and returns + // whatever it returns. But first casts validate_fn_proto to a + // function that takes our value as an argument (eg void + // (*validate_fn)(bool) for a bool flag). + bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const; + + void* value_buffer_; // points to the buffer holding our data + int8 type_; // how to interpret value_ + bool owns_value_; // whether to free value on destruct + + FlagValue(const FlagValue&); // no copying! + void operator=(const FlagValue&); +}; + + +// This could be a templated method of FlagValue, but doing so adds to the +// size of the .o. Since there's no type-safety here anyway, macro is ok. +#define VALUE_AS(type) *reinterpret_cast(value_buffer_) +#define OTHER_VALUE_AS(fv, type) *reinterpret_cast(fv.value_buffer_) +#define SET_VALUE_AS(type, value) VALUE_AS(type) = (value) + +FlagValue::FlagValue(void* valbuf, const char* type, + bool transfer_ownership_of_value) + : value_buffer_(valbuf), + owns_value_(transfer_ownership_of_value) { + for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) { + if (!strcmp(type, TypeName())) { + break; + } + } + assert(type_ <= FV_MAX_INDEX); // Unknown typename +} + +FlagValue::~FlagValue() { + if (!owns_value_) { + return; + } + switch (type_) { + case FV_BOOL: delete reinterpret_cast(value_buffer_); break; + case FV_INT32: delete reinterpret_cast(value_buffer_); break; + case FV_INT64: delete reinterpret_cast(value_buffer_); break; + case FV_UINT64: delete reinterpret_cast(value_buffer_); break; + case FV_DOUBLE: delete reinterpret_cast(value_buffer_); break; + case FV_STRING: delete reinterpret_cast(value_buffer_); break; + } +} + +bool FlagValue::ParseFrom(const char* value) { + if (type_ == FV_BOOL) { + const char* kTrue[] = { "1", "t", "true", "y", "yes" }; + const char* kFalse[] = { "0", "f", "false", "n", "no" }; + for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) { + if (strcasecmp(value, kTrue[i]) == 0) { + SET_VALUE_AS(bool, true); + return true; + } else if (strcasecmp(value, kFalse[i]) == 0) { + SET_VALUE_AS(bool, false); + return true; + } + } + return false; // didn't match a legal input + + } else if (type_ == FV_STRING) { + SET_VALUE_AS(string, value); + return true; + } + + // OK, it's likely to be numeric, and we'll be using a strtoXXX method. + if (value[0] == '\0') // empty-string is only allowed for string type. + return false; + char* end; + // Leading 0x puts us in base 16. But leading 0 does not put us in base 8! + // It caused too many bugs when we had that behavior. + int base = 10; // by default + if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) + base = 16; + errno = 0; + + switch (type_) { + case FV_INT32: { + const int64 r = strtoint64(value, &end, base); + if (errno || end != value + strlen(value)) return false; // bad parse + if (static_cast(r) != r) // worked, but number out of range + return false; + SET_VALUE_AS(int32, static_cast(r)); + return true; + } + case FV_INT64: { + const int64 r = strtoint64(value, &end, base); + if (errno || end != value + strlen(value)) return false; // bad parse + SET_VALUE_AS(int64, r); + return true; + } + case FV_UINT64: { + while (*value == ' ') value++; + if (*value == '-') return false; // negative number + const uint64 r = strtouint64(value, &end, base); + if (errno || end != value + strlen(value)) return false; // bad parse + SET_VALUE_AS(uint64, r); + return true; + } + case FV_DOUBLE: { + const double r = strtod(value, &end); + if (errno || end != value + strlen(value)) return false; // bad parse + SET_VALUE_AS(double, r); + return true; + } + default: { + assert(false); // unknown type + return false; + } + } +} + +string FlagValue::ToString() const { + char intbuf[64]; // enough to hold even the biggest number + switch (type_) { + case FV_BOOL: + return VALUE_AS(bool) ? "true" : "false"; + case FV_INT32: + snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32)); + return intbuf; + case FV_INT64: + snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64)); + return intbuf; + case FV_UINT64: + snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64)); + return intbuf; + case FV_DOUBLE: + snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double)); + return intbuf; + case FV_STRING: + return VALUE_AS(string); + default: + assert(false); + return ""; // unknown type + } +} + +bool FlagValue::Validate(const char* flagname, + ValidateFnProto validate_fn_proto) const { + switch (type_) { + case FV_BOOL: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(bool)); + case FV_INT32: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(int32)); + case FV_INT64: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(int64)); + case FV_UINT64: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(uint64)); + case FV_DOUBLE: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(double)); + case FV_STRING: + return reinterpret_cast( + validate_fn_proto)(flagname, VALUE_AS(string)); + default: + assert(false); // unknown type + return false; + } +} + +const char* FlagValue::TypeName() const { + static const char types[] = + "bool\0xx" + "int32\0x" + "int64\0x" + "uint64\0" + "double\0" + "string"; + if (type_ > FV_MAX_INDEX) { + assert(false); + return ""; + } + // Directly indexing the strigns in the 'types' string, each of them + // is 7 bytes long. + return &types[type_ * 7]; +} + +bool FlagValue::Equal(const FlagValue& x) const { + if (type_ != x.type_) + return false; + switch (type_) { + case FV_BOOL: return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool); + case FV_INT32: return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32); + case FV_INT64: return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64); + case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64); + case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double); + case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string); + default: assert(false); return false; // unknown type + } +} + +FlagValue* FlagValue::New() const { + const char *type = TypeName(); + switch (type_) { + case FV_BOOL: return new FlagValue(new bool(false), type, true); + case FV_INT32: return new FlagValue(new int32(0), type, true); + case FV_INT64: return new FlagValue(new int64(0), type, true); + case FV_UINT64: return new FlagValue(new uint64(0), type, true); + case FV_DOUBLE: return new FlagValue(new double(0.0), type, true); + case FV_STRING: return new FlagValue(new string, type, true); + default: assert(false); return NULL; // unknown type + } +} + +void FlagValue::CopyFrom(const FlagValue& x) { + assert(type_ == x.type_); + switch (type_) { + case FV_BOOL: SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool)); break; + case FV_INT32: SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32)); break; + case FV_INT64: SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64)); break; + case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64)); break; + case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double)); break; + case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string)); break; + default: assert(false); // unknown type + } +} + +int FlagValue::ValueSize() const { + if (type_ > FV_MAX_INDEX) { + assert(false); // unknown type + return 0; + } + static const uint8 valuesize[] = { + sizeof(bool), + sizeof(int32), + sizeof(int64), + sizeof(uint64), + sizeof(double), + sizeof(string), + }; + return valuesize[type_]; +} + +// -------------------------------------------------------------------- +// CommandLineFlag +// This represents a single flag, including its name, description, +// default value, and current value. Mostly this serves as a +// struct, though it also knows how to register itself. +// All CommandLineFlags are owned by a (exactly one) +// FlagRegistry. If you wish to modify fields in this class, you +// should acquire the FlagRegistry lock for the registry that owns +// this flag. +// -------------------------------------------------------------------- + +class CommandLineFlag { + public: + // Note: we take over memory-ownership of current_val and default_val. + CommandLineFlag(const char* name, const char* help, const char* filename, + FlagValue* current_val, FlagValue* default_val); + ~CommandLineFlag(); + + const char* name() const { return name_; } + const char* help() const { return help_; } + const char* filename() const { return file_; } + const char* CleanFileName() const; // nixes irrelevant prefix such as homedir + string current_value() const { return current_->ToString(); } + string default_value() const { return defvalue_->ToString(); } + const char* type_name() const { return defvalue_->TypeName(); } + ValidateFnProto validate_function() const { return validate_fn_proto_; } + + void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result); + + // If validate_fn_proto_ is non-NULL, calls it on value, returns result. + bool Validate(const FlagValue& value) const; + bool ValidateCurrent() const { return Validate(*current_); } + + private: + // for SetFlagLocked() and setting flags_by_ptr_ + friend class FlagRegistry; + friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values + // set validate_fn + friend bool AddFlagValidator(const void*, ValidateFnProto); + + // This copies all the non-const members: modified, processed, defvalue, etc. + void CopyFrom(const CommandLineFlag& src); + + void UpdateModifiedBit(); + + const char* const name_; // Flag name + const char* const help_; // Help message + const char* const file_; // Which file did this come from? + bool modified_; // Set after default assignment? + FlagValue* defvalue_; // Default value for flag + FlagValue* current_; // Current value for flag + // This is a casted, 'generic' version of validate_fn, which actually + // takes a flag-value as an arg (void (*validate_fn)(bool), say). + // When we pass this to current_->Validate(), it will cast it back to + // the proper type. This may be NULL to mean we have no validate_fn. + ValidateFnProto validate_fn_proto_; + + CommandLineFlag(const CommandLineFlag&); // no copying! + void operator=(const CommandLineFlag&); +}; + +CommandLineFlag::CommandLineFlag(const char* name, const char* help, + const char* filename, + FlagValue* current_val, FlagValue* default_val) + : name_(name), help_(help), file_(filename), modified_(false), + defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) { +} + +CommandLineFlag::~CommandLineFlag() { + delete current_; + delete defvalue_; +} + +const char* CommandLineFlag::CleanFileName() const { + // Compute top-level directory & file that this appears in + // search full path backwards. + // Stop going backwards at kRootDir; and skip by the first slash. + static const char kRootDir[] = ""; // can set this to root directory, + // e.g. "myproject" + + if (sizeof(kRootDir)-1 == 0) // no prefix to strip + return filename(); + + const char* clean_name = filename() + strlen(filename()) - 1; + while ( clean_name > filename() ) { + if (*clean_name == PATH_SEPARATOR) { + if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) { + // ".../myproject/base/logging.cc" ==> "base/logging.cc" + clean_name += sizeof(kRootDir)-1; // past "/myproject/" + break; + } + } + --clean_name; + } + while ( *clean_name == PATH_SEPARATOR ) ++clean_name; // Skip any slashes + return clean_name; +} + +void CommandLineFlag::FillCommandLineFlagInfo( + CommandLineFlagInfo* result) { + result->name = name(); + result->type = type_name(); + result->description = help(); + result->current_value = current_value(); + result->default_value = default_value(); + result->filename = CleanFileName(); + UpdateModifiedBit(); + result->is_default = !modified_; + result->has_validator_fn = validate_function() != NULL; +} + +void CommandLineFlag::UpdateModifiedBit() { + // Update the "modified" bit in case somebody bypassed the + // Flags API and wrote directly through the FLAGS_name variable. + if (!modified_ && !current_->Equal(*defvalue_)) { + modified_ = true; + } +} + +void CommandLineFlag::CopyFrom(const CommandLineFlag& src) { + // Note we only copy the non-const members; others are fixed at construct time + if (modified_ != src.modified_) modified_ = src.modified_; + if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_); + if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_); + if (validate_fn_proto_ != src.validate_fn_proto_) + validate_fn_proto_ = src.validate_fn_proto_; +} + +bool CommandLineFlag::Validate(const FlagValue& value) const { + if (validate_function() == NULL) + return true; + else + return value.Validate(name(), validate_function()); +} + + +// -------------------------------------------------------------------- +// FlagRegistry +// A FlagRegistry singleton object holds all flag objects indexed +// by their names so that if you know a flag's name (as a C +// string), you can access or set it. If the function is named +// FooLocked(), you must own the registry lock before calling +// the function; otherwise, you should *not* hold the lock, and +// the function will acquire it itself if needed. +// -------------------------------------------------------------------- + +struct StringCmp { // Used by the FlagRegistry map class to compare char*'s + bool operator() (const char* s1, const char* s2) const { + return (strcmp(s1, s2) < 0); + } +}; + +class FlagRegistry { + public: + FlagRegistry() { } + ~FlagRegistry() { + for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) { + CommandLineFlag* flag = p->second; + delete flag; + } + } + + static void DeleteGlobalRegistry() { + delete global_registry_; + global_registry_ = NULL; + } + + void Lock() { lock_.Lock(); } + void Unlock() { lock_.Unlock(); } + + // Store a flag in this registry. Takes ownership of the given pointer. + void RegisterFlag(CommandLineFlag* flag); + + // Returns the flag object for the specified name, or NULL if not found. + CommandLineFlag* FindFlagLocked(const char* name); + + // Returns the flag object whose current-value is stored at flag_ptr. + // That is, for whom current_->value_buffer_ == flag_ptr + CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr); + + // A fancier form of FindFlag that works correctly if name is of the + // form flag=value. In that case, we set key to point to flag, and + // modify v to point to the value (if present), and return the flag + // with the given name. If the flag does not exist, returns NULL + // and sets error_message. + CommandLineFlag* SplitArgumentLocked(const char* argument, + string* key, const char** v, + string* error_message); + + // Set the value of a flag. If the flag was successfully set to + // value, set msg to indicate the new flag-value, and return true. + // Otherwise, set msg to indicate the error, leave flag unchanged, + // and return false. msg can be NULL. + bool SetFlagLocked(CommandLineFlag* flag, const char* value, + FlagSettingMode set_mode, string* msg); + + static FlagRegistry* GlobalRegistry(); // returns a singleton registry + + private: + friend class GOOGLE_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them + friend class CommandLineFlagParser; // for ValidateAllFlags + friend void GOOGLE_NAMESPACE::GetAllFlags(vector*); + + // The map from name to flag, for FindFlagLocked(). + typedef map FlagMap; + typedef FlagMap::iterator FlagIterator; + typedef FlagMap::const_iterator FlagConstIterator; + FlagMap flags_; + + // The map from current-value pointer to flag, fo FindFlagViaPtrLocked(). + typedef map FlagPtrMap; + FlagPtrMap flags_by_ptr_; + + Mutex lock_; + + static FlagRegistry* global_registry_; // a singleton registry + static Mutex global_registry_lock_; // guards creation of global_registry_ + + // Disallow + FlagRegistry(const FlagRegistry&); + FlagRegistry& operator=(const FlagRegistry&); +}; + +FlagRegistry* FlagRegistry::global_registry_ = NULL; +Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED); + +FlagRegistry* FlagRegistry::GlobalRegistry() { + MutexLock acquire_lock(&global_registry_lock_); + if (!global_registry_) { + global_registry_ = new FlagRegistry; + } + return global_registry_; +} + +void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { + Lock(); + pair ins = + flags_.insert(pair(flag->name(), flag)); + if (ins.second == false) { // means the name was already in the map + if (strcmp(ins.first->second->filename(), flag->filename()) != 0) { + ReportError(DIE, "ERROR: flag '%s' was defined more than once " + "(in files '%s' and '%s').\n", + flag->name(), + ins.first->second->filename(), + flag->filename()); + } else { + ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'. " + "One possibility: file '%s' is being linked both statically " + "and dynamically into this executable.\n", + flag->name(), + flag->filename(), flag->filename()); + } + } + // Also add to the flags_by_ptr_ map. + flags_by_ptr_[flag->current_->value_buffer_] = flag; + Unlock(); +} + +CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) { + FlagConstIterator i = flags_.find(name); + if (i == flags_.end()) { + return NULL; + } else { + return i->second; + } +} + +CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) { + FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr); + if (i == flags_by_ptr_.end()) { + return NULL; + } else { + return i->second; + } +} + +CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg, + string* key, + const char** v, + string* error_message) { + // Find the flag object for this option + const char* flag_name; + const char* value = strchr(arg, '='); + if (value == NULL) { + key->assign(arg); + *v = NULL; + } else { + // Strip out the "=value" portion from arg + key->assign(arg, value-arg); + *v = ++value; // advance past the '=' + } + flag_name = key->c_str(); + + CommandLineFlag* flag = FindFlagLocked(flag_name); + + if (flag == NULL) { + // If we can't find the flag-name, then we should return an error. + // The one exception is if 1) the flag-name is 'nox', 2) there + // exists a flag named 'x', and 3) 'x' is a boolean flag. + // In that case, we want to return flag 'x'. + if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) { + // flag-name is not 'nox', so we're not in the exception case. + *error_message = (string(kError) + + "unknown command line flag '" + *key + "'\n"); + return NULL; + } + flag = FindFlagLocked(flag_name+2); + if (flag == NULL) { + // No flag named 'x' exists, so we're not in the exception case. + *error_message = (string(kError) + + "unknown command line flag '" + *key + "'\n"); + return NULL; + } + if (strcmp(flag->type_name(), "bool") != 0) { + // 'x' exists but is not boolean, so we're not in the exception case. + *error_message = (string(kError) + + "boolean value (" + *key + ") specified for " + + flag->type_name() + " command line flag\n"); + return NULL; + } + // We're in the exception case! + // Make up a fake value to replace the "no" we stripped out + key->assign(flag_name+2); // the name without the "no" + *v = "0"; + } + + // Assign a value if this is a boolean flag + if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) { + *v = "1"; // the --nox case was already handled, so this is the --x case + } + + return flag; +} + +bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value, + const char* value, string* msg) { + // Use tenative_value, not flag_value, until we know value is valid. + FlagValue* tentative_value = flag_value->New(); + if (!tentative_value->ParseFrom(value)) { + if (msg) { + *msg += (string(kError) + "illegal value '" + value + + + "' specified for " + flag->type_name() + " flag '" + + flag->name() + "'\n"); + } + delete tentative_value; + return false; + } else if (!flag->Validate(*tentative_value)) { + if (msg) { + *msg += (string(kError) + "failed validation of new value " + + "'" + tentative_value->ToString() + "' for flag '" + + + flag->name() + "'\n"); + } + delete tentative_value; + return false; + } else { + flag_value->CopyFrom(*tentative_value); + if (msg) { + *msg += (string(flag->name()) + " set to " + flag_value->ToString() + + "\n"); + } + delete tentative_value; + return true; + } +} + +bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag, + const char* value, + FlagSettingMode set_mode, + string* msg) { + flag->UpdateModifiedBit(); + switch (set_mode) { + case SET_FLAGS_VALUE: { + // set or modify the flag's value + if (!TryParseLocked(flag, flag->current_, value, msg)) + return false; + flag->modified_ = true; + break; + } + case SET_FLAG_IF_DEFAULT: { + // set the flag's value, but only if it hasn't been set by someone else + if (!flag->modified_) { + if (!TryParseLocked(flag, flag->current_, value, msg)) + return false; + flag->modified_ = true; + } else { + *msg = string(flag->name()) + " set to " + flag->current_value(); + } + break; + } + case SET_FLAGS_DEFAULT: { + // modify the flag's default-value + if (!TryParseLocked(flag, flag->defvalue_, value, msg)) + return false; + if (!flag->modified_) { + // Need to set both defvalue *and* current, in this case + TryParseLocked(flag, flag->current_, value, NULL); + } + break; + } + default: { + // unknown set_mode + assert(false); + return false; + } + } + + return true; +} + +class FlagRegistryLock { + public: + explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); } + ~FlagRegistryLock() { fr_->Unlock(); } + private: + FlagRegistry *const fr_; +}; + +// -------------------------------------------------------------------- +// CommandLineFlagParser +// Parsing is done in two stages. In the first, we go through +// argv. For every flag-like arg we can make sense of, we parse +// it and set the appropriate FLAGS_* variable. For every flag- +// like arg we can't make sense of, we store it in a vector, +// along with an explanation of the trouble. In stage 2, we +// handle the 'reporting' flags like --help and --mpm_version. +// (This is via a call to HandleCommandLineHelpFlags(), in +// gflags_reporting.cc.) +// An optional stage 3 prints out the error messages. +// This is a bit of a simplification. For instance, --flagfile +// is handled as soon as it's seen in stage 1, not in stage 2. +// -------------------------------------------------------------------- + +class CommandLineFlagParser { + public: + // The argument is the flag-registry to register the parsed flags in + explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {} + ~CommandLineFlagParser() {} + + // Stage 1: Every time this is called, it reads all flags in argv. + // However, it ignores all flags that have been successfully set + // before. Typically this is only called once, so this 'reparsing' + // behavior isn't important. It can be useful when trying to + // reparse after loading a dll, though. + uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags); + + // Stage 2: print reporting info and exit, if requested. + // In gflags_reporting.cc:HandleCommandLineHelpFlags(). + + // Stage 3: validate all the commandline flags that have validators + // registered. + void ValidateAllFlags(); + + // Stage 4: report any errors and return true if any were found. + bool ReportErrors(); + + // Set a particular command line option. "newval" is a string + // describing the new value that the option has been set to. If + // option_name does not specify a valid option name, or value is not + // a valid value for option_name, newval is empty. Does recursive + // processing for --flagfile and --fromenv. Returns the new value + // if everything went ok, or empty-string if not. (Actually, the + // return-string could hold many flag/value pairs due to --flagfile.) + // NB: Must have called registry_->Lock() before calling this function. + string ProcessSingleOptionLocked(CommandLineFlag* flag, + const char* value, + FlagSettingMode set_mode); + + // Set a whole batch of command line options as specified by contentdata, + // which is in flagfile format (and probably has been read from a flagfile). + // Returns the new value if everything went ok, or empty-string if + // not. (Actually, the return-string could hold many flag/value + // pairs due to --flagfile.) + // NB: Must have called registry_->Lock() before calling this function. + string ProcessOptionsFromStringLocked(const string& contentdata, + FlagSettingMode set_mode); + + // These are the 'recursive' flags, defined at the top of this file. + // Whenever we see these flags on the commandline, we must take action. + // These are called by ProcessSingleOptionLocked and, similarly, return + // new values if everything went ok, or the empty-string if not. + string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode); + // diff fromenv/tryfromenv + string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode, + bool errors_are_fatal); + + private: + FlagRegistry* const registry_; + map error_flags_; // map from name to error message + // This could be a set, but we reuse the map to minimize the .o size + map undefined_names_; // --[flag] name was not registered +}; + + +// Parse a list of (comma-separated) flags. +static void ParseFlagList(const char* value, vector* flags) { + for (const char *p = value; p && *p; value = p) { + p = strchr(value, ','); + int len; + if (p) { + len = static_cast(p - value); + p++; + } else { + len = static_cast(strlen(value)); + } + + if (len == 0) + ReportError(DIE, "ERROR: empty flaglist entry\n"); + if (value[0] == '-') + ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value); + + flags->push_back(string(value, len)); + } +} + +// Snarf an entire file into a C++ string. This is just so that we +// can do all the I/O in one place and not worry about it everywhere. +// Plus, it's convenient to have the whole file contents at hand. +// Adds a newline at the end of the file. +#define PFATAL(s) do { perror(s); commandlineflags_exitfunc(1); } while (0) + +static string ReadFileIntoString(const char* filename) { + const int kBufSize = 8092; + char buffer[kBufSize]; + string s; + FILE* fp = fopen(filename, "r"); + if (!fp) PFATAL(filename); + size_t n; + while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) { + if (ferror(fp)) PFATAL(filename); + s.append(buffer, n); + } + fclose(fp); + return s; +} + +uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv, + bool remove_flags) { + const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR); // nix path + program_name = (program_name == NULL ? (*argv)[0] : program_name+1); + + int first_nonopt = *argc; // for non-options moved to the end + + registry_->Lock(); + for (int i = 1; i < first_nonopt; i++) { + char* arg = (*argv)[i]; + + // Like getopt(), we permute non-option flags to be at the end. + if (arg[0] != '-' || // must be a program argument + (arg[0] == '-' && arg[1] == '\0')) { // "-" is an argument, not a flag + memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i])); + (*argv)[*argc-1] = arg; // we go last + first_nonopt--; // we've been pushed onto the stack + i--; // to undo the i++ in the loop + continue; + } + + if (arg[0] == '-') arg++; // allow leading '-' + if (arg[0] == '-') arg++; // or leading '--' + + // -- alone means what it does for GNU: stop options parsing + if (*arg == '\0') { + first_nonopt = i+1; + break; + } + + // Find the flag object for this option + string key; + const char* value; + string error_message; + CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value, + &error_message); + if (flag == NULL) { + undefined_names_[key] = ""; // value isn't actually used + error_flags_[key] = error_message; + continue; + } + + if (value == NULL) { + // Boolean options are always assigned a value by SplitArgumentLocked() + assert(strcmp(flag->type_name(), "bool") != 0); + if (i+1 >= first_nonopt) { + // This flag needs a value, but there is nothing available + error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'" + + " is missing its argument"); + if (flag->help() && flag->help()[0] > '\001') { + // Be useful in case we have a non-stripped description. + error_flags_[key] += string("; flag description: ") + flag->help(); + } + error_flags_[key] += "\n"; + break; // we treat this as an unrecoverable error + } else { + value = (*argv)[++i]; // read next arg for value + + // Heuristic to detect the case where someone treats a string arg + // like a bool: + // --my_string_var --foo=bar + // We look for a flag of string type, whose value begins with a + // dash, and where the flag-name and value are separated by a + // space rather than an '='. + // To avoid false positives, we also require the word "true" + // or "false" in the help string. Without this, a valid usage + // "-lat -30.5" would trigger the warning. The common cases we + // want to solve talk about true and false as values. + if (value[0] == '-' + && strcmp(flag->type_name(), "string") == 0 + && (strstr(flag->help(), "true") + || strstr(flag->help(), "false"))) { + fprintf(stderr, "Did you really mean to set flag '%s'" + " to the value '%s'?\n", + flag->name(), value); + } + } + } + + // TODO(csilvers): only set a flag if we hadn't set it before here + ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE); + } + registry_->Unlock(); + + if (remove_flags) { // Fix up argc and argv by removing command line flags + (*argv)[first_nonopt-1] = (*argv)[0]; + (*argv) += (first_nonopt-1); + (*argc) -= (first_nonopt-1); + first_nonopt = 1; // because we still don't count argv[0] + } + + logging_is_probably_set_up = true; // because we've parsed --logdir, etc. + + return first_nonopt; +} + +string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval, + FlagSettingMode set_mode) { + if (flagval.empty()) + return ""; + + string msg; + vector filename_list; + ParseFlagList(flagval.c_str(), &filename_list); // take a list of filenames + for (size_t i = 0; i < filename_list.size(); ++i) { + const char* file = filename_list[i].c_str(); + msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode); + } + return msg; +} + +string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval, + FlagSettingMode set_mode, + bool errors_are_fatal) { + if (flagval.empty()) + return ""; + + string msg; + vector flaglist; + ParseFlagList(flagval.c_str(), &flaglist); + + for (size_t i = 0; i < flaglist.size(); ++i) { + const char* flagname = flaglist[i].c_str(); + CommandLineFlag* flag = registry_->FindFlagLocked(flagname); + if (flag == NULL) { + error_flags_[flagname] = (string(kError) + "unknown command line flag" + + " '" + flagname + "'" + + " (via --fromenv or --tryfromenv)\n"); + undefined_names_[flagname] = ""; + continue; + } + + const string envname = string("FLAGS_") + string(flagname); + const char* envval = getenv(envname.c_str()); + if (!envval) { + if (errors_are_fatal) { + error_flags_[flagname] = (string(kError) + envname + + " not found in environment\n"); + } + continue; + } + + // Avoid infinite recursion. + if ((strcmp(envval, "fromenv") == 0) || + (strcmp(envval, "tryfromenv") == 0)) { + error_flags_[flagname] = (string(kError) + "infinite recursion on " + + "environment flag '" + envval + "'\n"); + continue; + } + + msg += ProcessSingleOptionLocked(flag, envval, set_mode); + } + return msg; +} + +string CommandLineFlagParser::ProcessSingleOptionLocked( + CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) { + string msg; + if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) { + error_flags_[flag->name()] = msg; + return ""; + } + + // The recursive flags, --flagfile and --fromenv and --tryfromenv, + // must be dealt with as soon as they're seen. They will emit + // messages of their own. + if (strcmp(flag->name(), "flagfile") == 0) { + msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode); + + } else if (strcmp(flag->name(), "fromenv") == 0) { + // last arg indicates envval-not-found is fatal (unlike in --tryfromenv) + msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true); + + } else if (strcmp(flag->name(), "tryfromenv") == 0) { + msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false); + } + + return msg; +} + +void CommandLineFlagParser::ValidateAllFlags() { + FlagRegistryLock frl(registry_); + for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin(); + i != registry_->flags_.end(); ++i) { + if (!i->second->ValidateCurrent()) { + // only set a message if one isn't already there. (If there's + // an error message, our job is done, even if it's not exactly + // the same error.) + if (error_flags_[i->second->name()].empty()) + error_flags_[i->second->name()] = + string(kError) + "--" + i->second->name() + + " must be set on the commandline" + " (default value fails validation)\n"; + } + } +} + +bool CommandLineFlagParser::ReportErrors() { + // error_flags_ indicates errors we saw while parsing. + // But we ignore undefined-names if ok'ed by --undef_ok + if (!FLAGS_undefok.empty()) { + vector flaglist; + ParseFlagList(FLAGS_undefok.c_str(), &flaglist); + for (size_t i = 0; i < flaglist.size(); ++i) { + // We also deal with --no, in case the flagname was boolean + const string no_version = string("no") + flaglist[i]; + if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) { + error_flags_[flaglist[i]] = ""; // clear the error message + } else if (undefined_names_.find(no_version) != undefined_names_.end()) { + error_flags_[no_version] = ""; + } + } + } + // Likewise, if they decided to allow reparsing, all undefined-names + // are ok; we just silently ignore them now, and hope that a future + // parse will pick them up somehow. + if (allow_command_line_reparsing) { + for (map::const_iterator it = undefined_names_.begin(); + it != undefined_names_.end(); ++it) + error_flags_[it->first] = ""; // clear the error message + } + + bool found_error = false; + string error_message; + for (map::const_iterator it = error_flags_.begin(); + it != error_flags_.end(); ++it) { + if (!it->second.empty()) { + error_message.append(it->second.data(), it->second.size()); + found_error = true; + } + } + if (found_error) + ReportError(DO_NOT_DIE, "%s", error_message.c_str()); + return found_error; +} + +string CommandLineFlagParser::ProcessOptionsFromStringLocked( + const string& contentdata, FlagSettingMode set_mode) { + string retval; + const char* flagfile_contents = contentdata.c_str(); + bool flags_are_relevant = true; // set to false when filenames don't match + bool in_filename_section = false; + + const char* line_end = flagfile_contents; + // We read this file a line at a time. + for (; line_end; flagfile_contents = line_end + 1) { + while (*flagfile_contents && isspace(*flagfile_contents)) + ++flagfile_contents; + line_end = strchr(flagfile_contents, '\n'); + size_t len = line_end ? static_cast(line_end - flagfile_contents) + : strlen(flagfile_contents); + string line(flagfile_contents, len); + + // Each line can be one of four things: + // 1) A comment line -- we skip it + // 2) An empty line -- we skip it + // 3) A list of filenames -- starts a new filenames+flags section + // 4) A --flag=value line -- apply if previous filenames match + if (line.empty() || line[0] == '#') { + // comment or empty line; just ignore + + } else if (line[0] == '-') { // flag + in_filename_section = false; // instead, it was a flag-line + if (!flags_are_relevant) // skip this flag; applies to someone else + continue; + + const char* name_and_val = line.c_str() + 1; // skip the leading - + if (*name_and_val == '-') + name_and_val++; // skip second - too + string key; + const char* value; + string error_message; + CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val, + &key, &value, + &error_message); + // By API, errors parsing flagfile lines are silently ignored. + if (flag == NULL) { + // "WARNING: flagname '" + key + "' not found\n" + } else if (value == NULL) { + // "WARNING: flagname '" + key + "' missing a value\n" + } else { + retval += ProcessSingleOptionLocked(flag, value, set_mode); + } + + } else { // a filename! + if (!in_filename_section) { // start over: assume filenames don't match + in_filename_section = true; + flags_are_relevant = false; + } + + // Split the line up at spaces into glob-patterns + const char* space = line.c_str(); // just has to be non-NULL + for (const char* word = line.c_str(); *space; word = space+1) { + if (flags_are_relevant) // we can stop as soon as we match + break; + space = strchr(word, ' '); + if (space == NULL) + space = word + strlen(word); + const string glob(word, space - word); + // We try matching both against the full argv0 and basename(argv0) +#ifdef HAVE_FNMATCH_H + if (fnmatch(glob.c_str(), + ProgramInvocationName(), + FNM_PATHNAME) == 0 || + fnmatch(glob.c_str(), + ProgramInvocationShortName(), + FNM_PATHNAME) == 0) { +#else // !HAVE_FNMATCH_H + if ((glob == ProgramInvocationName()) || + (glob == ProgramInvocationShortName())) { +#endif // HAVE_FNMATCH_H + flags_are_relevant = true; + } + } + } + } + return retval; +} + +// -------------------------------------------------------------------- +// GetFromEnv() +// AddFlagValidator() +// These are helper functions for routines like BoolFromEnv() and +// RegisterFlagValidator, defined below. They're defined here so +// they can live in the unnamed namespace (which makes friendship +// declarations for these classes possible). +// -------------------------------------------------------------------- + +template +T GetFromEnv(const char *varname, const char* type, T dflt) { + const char* const valstr = getenv(varname); + if (!valstr) + return dflt; + FlagValue ifv(new T, type, true); + if (!ifv.ParseFrom(valstr)) + ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n", + varname, valstr); + return OTHER_VALUE_AS(ifv, T); +} + +bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) { + // We want a lock around this routine, in case two threads try to + // add a validator (hopefully the same one!) at once. We could use + // our own thread, but we need to loook at the registry anyway, so + // we just steal that one. + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + // First, find the flag whose current-flag storage is 'flag'. + // This is the CommandLineFlag whose current_->value_buffer_ == flag + CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr); + if (!flag) { + // WARNING << "Ignoring RegisterValidateFunction() for flag pointer " + // << flag_ptr << ": no flag found at that address"; + return false; + } else if (validate_fn_proto == flag->validate_function()) { + return true; // ok to register the same function over and over again + } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) { + // WARNING << "Ignoring RegisterValidateFunction() for flag '" + // << flag->name() << "': validate-fn already registered"; + return false; + } else { + flag->validate_fn_proto_ = validate_fn_proto; + return true; + } +} + +} // end unnamed namespaces + + +// Now define the functions that are exported via the .h file + +// -------------------------------------------------------------------- +// FlagRegisterer +// This class exists merely to have a global constructor (the +// kind that runs before main(), that goes an initializes each +// flag that's been declared. Note that it's very important we +// don't have a destructor that deletes flag_, because that would +// cause us to delete current_storage/defvalue_storage as well, +// which can cause a crash if anything tries to access the flag +// values in a global destructor. +// -------------------------------------------------------------------- + +FlagRegisterer::FlagRegisterer(const char* name, const char* type, + const char* help, const char* filename, + void* current_storage, void* defvalue_storage) { + if (help == NULL) + help = ""; + // FlagValue expects the type-name to not include any namespace + // components, so we get rid of those, if any. + if (strchr(type, ':')) + type = strrchr(type, ':') + 1; + FlagValue* current = new FlagValue(current_storage, type, false); + FlagValue* defvalue = new FlagValue(defvalue_storage, type, false); + // Importantly, flag_ will never be deleted, so storage is always good. + CommandLineFlag* flag = new CommandLineFlag(name, help, filename, + current, defvalue); + FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry +} + +// -------------------------------------------------------------------- +// GetAllFlags() +// The main way the FlagRegistry class exposes its data. This +// returns, as strings, all the info about all the flags in +// the main registry, sorted first by filename they are defined +// in, and then by flagname. +// -------------------------------------------------------------------- + +struct FilenameFlagnameCmp { + bool operator()(const CommandLineFlagInfo& a, + const CommandLineFlagInfo& b) const { + int cmp = strcmp(a.filename.c_str(), b.filename.c_str()); + if (cmp == 0) + cmp = strcmp(a.name.c_str(), b.name.c_str()); // secondary sort key + return cmp < 0; + } +}; + +void GetAllFlags(vector* OUTPUT) { + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + registry->Lock(); + for (FlagRegistry::FlagConstIterator i = registry->flags_.begin(); + i != registry->flags_.end(); ++i) { + CommandLineFlagInfo fi; + i->second->FillCommandLineFlagInfo(&fi); + OUTPUT->push_back(fi); + } + registry->Unlock(); + // Now sort the flags, first by filename they occur in, then alphabetically + sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp()); +} + +// -------------------------------------------------------------------- +// SetArgv() +// GetArgvs() +// GetArgv() +// GetArgv0() +// ProgramInvocationName() +// ProgramInvocationShortName() +// SetUsageMessage() +// ProgramUsage() +// Functions to set and get argv. Typically the setter is called +// by ParseCommandLineFlags. Also can get the ProgramUsage string, +// set by SetUsageMessage. +// -------------------------------------------------------------------- + +// These values are not protected by a Mutex because they are normally +// set only once during program startup. +static const char* argv0 = "UNKNOWN"; // just the program name +static const char* cmdline = ""; // the entire command-line +static vector argvs; +static uint32 argv_sum = 0; +static const char* program_usage = NULL; + +void SetArgv(int argc, const char** argv) { + static bool called_set_argv = false; + if (called_set_argv) // we already have an argv for you + return; + + called_set_argv = true; + + assert(argc > 0); // every program has at least a progname + argv0 = strdup(argv[0]); // small memory leak, but fn only called once + assert(argv0); + + string cmdline_string; // easier than doing strcats + for (int i = 0; i < argc; i++) { + if (i != 0) { + cmdline_string += " "; + } + cmdline_string += argv[i]; + argvs.push_back(argv[i]); + } + cmdline = strdup(cmdline_string.c_str()); // another small memory leak + assert(cmdline); + + // Compute a simple sum of all the chars in argv + for (const char* c = cmdline; *c; c++) + argv_sum += *c; +} + +const vector& GetArgvs() { return argvs; } +const char* GetArgv() { return cmdline; } +const char* GetArgv0() { return argv0; } +uint32 GetArgvSum() { return argv_sum; } +const char* ProgramInvocationName() { // like the GNU libc fn + return GetArgv0(); +} +const char* ProgramInvocationShortName() { // like the GNU libc fn + const char* slash = strrchr(argv0, '/'); +#ifdef OS_WINDOWS + if (!slash) slash = strrchr(argv0, '\\'); +#endif + return slash ? slash + 1 : argv0; +} + +void SetUsageMessage(const string& usage) { + if (program_usage != NULL) + ReportError(DIE, "ERROR: SetUsageMessage() called twice\n"); + program_usage = strdup(usage.c_str()); // small memory leak +} + +const char* ProgramUsage() { + if (program_usage) { + return program_usage; + } + return "Warning: SetUsageMessage() never called"; +} + +// -------------------------------------------------------------------- +// GetCommandLineOption() +// GetCommandLineFlagInfo() +// GetCommandLineFlagInfoOrDie() +// SetCommandLineOption() +// SetCommandLineOptionWithMode() +// The programmatic way to set a flag's value, using a string +// for its name rather than the variable itself (that is, +// SetCommandLineOption("foo", x) rather than FLAGS_foo = x). +// There's also a bit more flexibility here due to the various +// set-modes, but typically these are used when you only have +// that flag's name as a string, perhaps at runtime. +// All of these work on the default, global registry. +// For GetCommandLineOption, return false if no such flag +// is known, true otherwise. We clear "value" if a suitable +// flag is found. +// -------------------------------------------------------------------- + + +bool GetCommandLineOption(const char* name, string* value) { + if (NULL == name) + return false; + assert(value); + + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + CommandLineFlag* flag = registry->FindFlagLocked(name); + if (flag == NULL) { + return false; + } else { + *value = flag->current_value(); + return true; + } +} + +bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) { + if (NULL == name) return false; + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + CommandLineFlag* flag = registry->FindFlagLocked(name); + if (flag == NULL) { + return false; + } else { + assert(OUTPUT); + flag->FillCommandLineFlagInfo(OUTPUT); + return true; + } +} + +CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) { + CommandLineFlagInfo info; + if (!GetCommandLineFlagInfo(name, &info)) { + fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name); + commandlineflags_exitfunc(1); // almost certainly exit() + } + return info; +} + +string SetCommandLineOptionWithMode(const char* name, const char* value, + FlagSettingMode set_mode) { + string result; + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagRegistryLock frl(registry); + CommandLineFlag* flag = registry->FindFlagLocked(name); + if (flag) { + CommandLineFlagParser parser(registry); + result = parser.ProcessSingleOptionLocked(flag, value, set_mode); + if (!result.empty()) { // in the error case, we've already logged + // You could consider logging this change, if you wanted to know it: + //fprintf(stderr, "%sFLAGS_%s\n", + // (set_mode == SET_FLAGS_DEFAULT ? "default value of " : ""), + // result); + } + } + // The API of this function is that we return empty string on error + return result; +} + +string SetCommandLineOption(const char* name, const char* value) { + return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE); +} + +// -------------------------------------------------------------------- +// FlagSaver +// FlagSaverImpl +// This class stores the states of all flags at construct time, +// and restores all flags to that state at destruct time. +// Its major implementation challenge is that it never modifies +// pointers in the 'main' registry, so global FLAG_* vars always +// point to the right place. +// -------------------------------------------------------------------- + +class FlagSaverImpl { + public: + // Constructs an empty FlagSaverImpl object. + explicit FlagSaverImpl(FlagRegistry* main_registry) + : main_registry_(main_registry) { } + ~FlagSaverImpl() { + // reclaim memory from each of our CommandLineFlags + vector::const_iterator it; + for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) + delete *it; + } + + // Saves the flag states from the flag registry into this object. + // It's an error to call this more than once. + // Must be called when the registry mutex is not held. + void SaveFromRegistry() { + FlagRegistryLock frl(main_registry_); + assert(backup_registry_.empty()); // call only once! + for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin(); + it != main_registry_->flags_.end(); + ++it) { + const CommandLineFlag* main = it->second; + // Sets up all the const variables in backup correctly + CommandLineFlag* backup = new CommandLineFlag( + main->name(), main->help(), main->filename(), + main->current_->New(), main->defvalue_->New()); + // Sets up all the non-const variables in backup correctly + backup->CopyFrom(*main); + backup_registry_.push_back(backup); // add it to a convenient list + } + } + + // Restores the saved flag states into the flag registry. We + // assume no flags were added or deleted from the registry since + // the SaveFromRegistry; if they were, that's trouble! Must be + // called when the registry mutex is not held. + void RestoreToRegistry() { + FlagRegistryLock frl(main_registry_); + vector::const_iterator it; + for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) { + CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name()); + if (main != NULL) { // if NULL, flag got deleted from registry(!) + main->CopyFrom(**it); + } + } + } + + private: + FlagRegistry* const main_registry_; + vector backup_registry_; + + FlagSaverImpl(const FlagSaverImpl&); // no copying! + void operator=(const FlagSaverImpl&); +}; + +FlagSaver::FlagSaver() + : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) { + impl_->SaveFromRegistry(); +} + +FlagSaver::~FlagSaver() { + impl_->RestoreToRegistry(); + delete impl_; +} + + +// -------------------------------------------------------------------- +// CommandlineFlagsIntoString() +// ReadFlagsFromString() +// AppendFlagsIntoFile() +// ReadFromFlagsFile() +// These are mostly-deprecated routines that stick the +// commandline flags into a file/string and read them back +// out again. I can see a use for CommandlineFlagsIntoString, +// for creating a flagfile, but the rest don't seem that useful +// -- some, I think, are a poor-man's attempt at FlagSaver -- +// and are included only until we can delete them from callers. +// Note they don't save --flagfile flags (though they do save +// the result of having called the flagfile, of course). +// -------------------------------------------------------------------- + +static string TheseCommandlineFlagsIntoString( + const vector& flags) { + vector::const_iterator i; + + size_t retval_space = 0; + for (i = flags.begin(); i != flags.end(); ++i) { + // An (over)estimate of how much space it will take to print this flag + retval_space += i->name.length() + i->current_value.length() + 5; + } + + string retval; + retval.reserve(retval_space); + for (i = flags.begin(); i != flags.end(); ++i) { + retval += "--"; + retval += i->name; + retval += "="; + retval += i->current_value; + retval += "\n"; + } + return retval; +} + +string CommandlineFlagsIntoString() { + vector sorted_flags; + GetAllFlags(&sorted_flags); + return TheseCommandlineFlagsIntoString(sorted_flags); +} + +bool ReadFlagsFromString(const string& flagfilecontents, + const char* /*prog_name*/, // TODO(csilvers): nix this + bool errors_are_fatal) { + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + FlagSaverImpl saved_states(registry); + saved_states.SaveFromRegistry(); + + CommandLineFlagParser parser(registry); + registry->Lock(); + parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE); + registry->Unlock(); + // Should we handle --help and such when reading flags from a string? Sure. + HandleCommandLineHelpFlags(); + if (parser.ReportErrors()) { + // Error. Restore all global flags to their previous values. + if (errors_are_fatal) + commandlineflags_exitfunc(1); // almost certainly exit() + saved_states.RestoreToRegistry(); + return false; + } + return true; +} + +// TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName() +bool AppendFlagsIntoFile(const string& filename, const char *prog_name) { + FILE *fp = fopen(filename.c_str(), "a"); + if (!fp) { + return false; + } + + if (prog_name) + fprintf(fp, "%s\n", prog_name); + + vector flags; + GetAllFlags(&flags); + // But we don't want --flagfile, which leads to weird recursion issues + vector::iterator i; + for (i = flags.begin(); i != flags.end(); ++i) { + if (strcmp(i->name.c_str(), "flagfile") == 0) { + flags.erase(i); + break; + } + } + fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str()); + + fclose(fp); + return true; +} + +bool ReadFromFlagsFile(const string& filename, const char* prog_name, + bool errors_are_fatal) { + return ReadFlagsFromString(ReadFileIntoString(filename.c_str()), + prog_name, errors_are_fatal); +} + + +// -------------------------------------------------------------------- +// BoolFromEnv() +// Int32FromEnv() +// Int64FromEnv() +// Uint64FromEnv() +// DoubleFromEnv() +// StringFromEnv() +// Reads the value from the environment and returns it. +// We use an FlagValue to make the parsing easy. +// Example usage: +// DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever"); +// -------------------------------------------------------------------- + +bool BoolFromEnv(const char *v, bool dflt) { + return GetFromEnv(v, "bool", dflt); +} +int32 Int32FromEnv(const char *v, int32 dflt) { + return GetFromEnv(v, "int32", dflt); +} +int64 Int64FromEnv(const char *v, int64 dflt) { + return GetFromEnv(v, "int64", dflt); +} +uint64 Uint64FromEnv(const char *v, uint64 dflt) { + return GetFromEnv(v, "uint64", dflt); +} +double DoubleFromEnv(const char *v, double dflt) { + return GetFromEnv(v, "double", dflt); +} +const char *StringFromEnv(const char *varname, const char *dflt) { + const char* const val = getenv(varname); + return val ? val : dflt; +} + + +// -------------------------------------------------------------------- +// RegisterFlagValidator() +// RegisterFlagValidator() is the function that clients use to +// 'decorate' a flag with a validation function. Once this is +// done, every time the flag is set (including when the flag +// is parsed from argv), the validator-function is called. +// These functions return true if the validator was added +// successfully, or false if not: the flag already has a validator, +// (only one allowed per flag), the 1st arg isn't a flag, etc. +// This function is not thread-safe. +// -------------------------------------------------------------------- + +bool RegisterFlagValidator(const bool* flag, + bool (*validate_fn)(const char*, bool)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} +bool RegisterFlagValidator(const int32* flag, + bool (*validate_fn)(const char*, int32)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} +bool RegisterFlagValidator(const int64* flag, + bool (*validate_fn)(const char*, int64)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} +bool RegisterFlagValidator(const uint64* flag, + bool (*validate_fn)(const char*, uint64)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} +bool RegisterFlagValidator(const double* flag, + bool (*validate_fn)(const char*, double)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} +bool RegisterFlagValidator(const string* flag, + bool (*validate_fn)(const char*, const string&)) { + return AddFlagValidator(flag, reinterpret_cast(validate_fn)); +} + + +// -------------------------------------------------------------------- +// ParseCommandLineFlags() +// ParseCommandLineNonHelpFlags() +// HandleCommandLineHelpFlags() +// This is the main function called from main(), to actually +// parse the commandline. It modifies argc and argv as described +// at the top of gflags.h. You can also divide this +// function into two parts, if you want to do work between +// the parsing of the flags and the printing of any help output. +// -------------------------------------------------------------------- + +static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv, + bool remove_flags, bool do_report) { + SetArgv(*argc, const_cast(*argv)); // save it for later + + FlagRegistry* const registry = FlagRegistry::GlobalRegistry(); + CommandLineFlagParser parser(registry); + + // When we parse the commandline flags, we'll handle --flagfile, + // --tryfromenv, etc. as we see them (since flag-evaluation order + // may be important). But sometimes apps set FLAGS_tryfromenv/etc. + // manually before calling ParseCommandLineFlags. We want to evaluate + // those too, as if they were the first flags on the commandline. + registry->Lock(); + parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE); + // Last arg here indicates whether flag-not-found is a fatal error or not + parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true); + parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false); + registry->Unlock(); + + // Now get the flags specified on the commandline + const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags); + + if (do_report) + HandleCommandLineHelpFlags(); // may cause us to exit on --help, etc. + + // See if any of the unset flags fail their validation checks + parser.ValidateAllFlags(); + + if (parser.ReportErrors()) // may cause us to exit on illegal flags + commandlineflags_exitfunc(1); // almost certainly exit() + return r; +} + +uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) { + return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true); +} + +uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv, + bool remove_flags) { + return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false); +} + +// -------------------------------------------------------------------- +// AllowCommandLineReparsing() +// ReparseCommandLineNonHelpFlags() +// This is most useful for shared libraries. The idea is if +// a flag is defined in a shared library that is dlopen'ed +// sometime after main(), you can ParseCommandLineFlags before +// the dlopen, then ReparseCommandLineNonHelpFlags() after the +// dlopen, to get the new flags. But you have to explicitly +// Allow() it; otherwise, you get the normal default behavior +// of unrecognized flags calling a fatal error. +// TODO(csilvers): this isn't used. Just delete it? +// -------------------------------------------------------------------- + +void AllowCommandLineReparsing() { + allow_command_line_reparsing = true; +} + +uint32 ReparseCommandLineNonHelpFlags() { + // We make a copy of argc and argv to pass in + const vector& argvs = GetArgvs(); + int tmp_argc = static_cast(argvs.size()); + char** tmp_argv = new char* [tmp_argc + 1]; + for (int i = 0; i < tmp_argc; ++i) + tmp_argv[i] = strdup(argvs[i].c_str()); // TODO(csilvers): don't dup + + const int retval = ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false); + + for (int i = 0; i < tmp_argc; ++i) + free(tmp_argv[i]); + delete[] tmp_argv; + + return retval; +} + +void ShutDownCommandLineFlags() { + FlagRegistry::DeleteGlobalRegistry(); +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/gflags/gflags.h b/extern/libmv/third_party/gflags/gflags.h new file mode 100644 index 00000000000..cefbd62ae51 --- /dev/null +++ b/extern/libmv/third_party/gflags/gflags.h @@ -0,0 +1,589 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// Author: Ray Sidney +// Revamped and reorganized by Craig Silverstein +// +// This is the file that should be included by any file which declares +// or defines a command line flag or wants to parse command line flags +// or print a program usage message (which will include information about +// flags). Executive summary, in the form of an example foo.cc file: +// +// #include "foo.h" // foo.h has a line "DECLARE_int32(start);" +// #include "validators.h" // hypothetical file defining ValidateIsFile() +// +// DEFINE_int32(end, 1000, "The last record to read"); +// +// DEFINE_string(filename, "my_file.txt", "The file to read"); +// // Crash if the specified file does not exist. +// static bool dummy = RegisterFlagValidator(&FLAGS_filename, +// &ValidateIsFile); +// +// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...) +// +// void MyFunc() { +// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); +// } +// +// Then, at the command-line: +// ./foo --noverbose --start=5 --end=100 +// +// For more details, see +// doc/gflags.html +// +// --- A note about thread-safety: +// +// We describe many functions in this routine as being thread-hostile, +// thread-compatible, or thread-safe. Here are the meanings we use: +// +// thread-safe: it is safe for multiple threads to call this routine +// (or, when referring to a class, methods of this class) +// concurrently. +// thread-hostile: it is not safe for multiple threads to call this +// routine (or methods of this class) concurrently. In gflags, +// most thread-hostile routines are intended to be called early in, +// or even before, main() -- that is, before threads are spawned. +// thread-compatible: it is safe for multiple threads to read from +// this variable (when applied to variables), or to call const +// methods of this class (when applied to classes), as long as no +// other thread is writing to the variable or calling non-const +// methods of this class. + +#ifndef GOOGLE_GFLAGS_H_ +#define GOOGLE_GFLAGS_H_ + +#include +#include + +// We care a lot about number of bits things take up. Unfortunately, +// systems define their bit-specific ints in a lot of different ways. +// We use our own way, and have a typedef to get there. +// Note: these commands below may look like "#if 1" or "#if 0", but +// that's because they were constructed that way at ./configure time. +// Look at gflags.h.in to see how they're calculated (based on your config). +#if 1 +#include // the normal place uint16_t is defined +#endif +#if 1 +#include // the normal place u_int16_t is defined +#endif +#if 1 +#include // a third place for uint16_t or u_int16_t +#endif + +namespace google { + +#if 1 // the C99 format +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +#elif 1 // the BSD format +typedef int32_t int32; +typedef u_int32_t uint32; +typedef int64_t int64; +typedef u_int64_t uint64; +#elif 0 // the windows (vc7) format +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +#error Do not know how to define a 32-bit integer quantity on your system +#endif + +// -------------------------------------------------------------------- +// To actually define a flag in a file, use DEFINE_bool, +// DEFINE_string, etc. at the bottom of this file. You may also find +// it useful to register a validator with the flag. This ensures that +// when the flag is parsed from the commandline, or is later set via +// SetCommandLineOption, we call the validation function. It is _not_ +// called when you assign the value to the flag directly using the = operator. +// +// The validation function should return true if the flag value is valid, and +// false otherwise. If the function returns false for the new setting of the +// flag, the flag will retain its current value. If it returns false for the +// default value, ParseCommandLineFlags() will die. +// +// This function is safe to call at global construct time (as in the +// example below). +// +// Example use: +// static bool ValidatePort(const char* flagname, int32 value) { +// if (value > 0 && value < 32768) // value is ok +// return true; +// printf("Invalid value for --%s: %d\n", flagname, (int)value); +// return false; +// } +// DEFINE_int32(port, 0, "What port to listen on"); +// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort); + +// Returns true if successfully registered, false if not (because the +// first argument doesn't point to a command-line flag, or because a +// validator is already registered for this flag). +bool RegisterFlagValidator(const bool* flag, + bool (*validate_fn)(const char*, bool)); +bool RegisterFlagValidator(const int32* flag, + bool (*validate_fn)(const char*, int32)); +bool RegisterFlagValidator(const int64* flag, + bool (*validate_fn)(const char*, int64)); +bool RegisterFlagValidator(const uint64* flag, + bool (*validate_fn)(const char*, uint64)); +bool RegisterFlagValidator(const double* flag, + bool (*validate_fn)(const char*, double)); +bool RegisterFlagValidator(const std::string* flag, + bool (*validate_fn)(const char*, const std::string&)); + + +// -------------------------------------------------------------------- +// These methods are the best way to get access to info about the +// list of commandline flags. Note that these routines are pretty slow. +// GetAllFlags: mostly-complete info about the list, sorted by file. +// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does) +// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr +// +// In addition to accessing flags, you can also access argv[0] (the program +// name) and argv (the entire commandline), which we sock away a copy of. +// These variables are static, so you should only set them once. + +struct CommandLineFlagInfo { + std::string name; // the name of the flag + std::string type; // the type of the flag: int32, etc + std::string description; // the "help text" associated with the flag + std::string current_value; // the current value, as a string + std::string default_value; // the default value, as a string + std::string filename; // 'cleaned' version of filename holding the flag + bool has_validator_fn; // true if RegisterFlagValidator called on flag + bool is_default; // true if the flag has the default value and + // has not been set explicitly from the cmdline + // or via SetCommandLineOption +}; + +// Using this inside of a validator is a recipe for a deadlock. +// TODO(wojtekm) Fix locking when validators are running, to make it safe to +// call validators during ParseAllFlags. +// Also make sure then to uncomment the corresponding unit test in +// commandlineflags_unittest.sh +extern void GetAllFlags(std::vector* OUTPUT); +// These two are actually defined in commandlineflags_reporting.cc. +extern void ShowUsageWithFlags(const char *argv0); // what --help does +extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); + +// Create a descriptive string for a flag. +// Goes to some trouble to make pretty line breaks. +extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag); + +// Thread-hostile; meant to be called before any threads are spawned. +extern void SetArgv(int argc, const char** argv); +// The following functions are thread-safe as long as SetArgv() is +// only called before any threads start. +extern const std::vector& GetArgvs(); // all of argv as a vector +extern const char* GetArgv(); // all of argv as a string +extern const char* GetArgv0(); // only argv0 +extern uint32 GetArgvSum(); // simple checksum of argv +extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set +extern const char* ProgramInvocationShortName(); // basename(argv0) +// ProgramUsage() is thread-safe as long as SetUsageMessage() is only +// called before any threads start. +extern const char* ProgramUsage(); // string set by SetUsageMessage() + + +// -------------------------------------------------------------------- +// Normally you access commandline flags by just saying "if (FLAGS_foo)" +// or whatever, and set them by calling "FLAGS_foo = bar" (or, more +// commonly, via the DEFINE_foo macro). But if you need a bit more +// control, we have programmatic ways to get/set the flags as well. +// These programmatic ways to access flags are thread-safe, but direct +// access is only thread-compatible. + +// Return true iff the flagname was found. +// OUTPUT is set to the flag's value, or unchanged if we return false. +extern bool GetCommandLineOption(const char* name, std::string* OUTPUT); + +// Return true iff the flagname was found. OUTPUT is set to the flag's +// CommandLineFlagInfo or unchanged if we return false. +extern bool GetCommandLineFlagInfo(const char* name, + CommandLineFlagInfo* OUTPUT); + +// Return the CommandLineFlagInfo of the flagname. exit() if name not found. +// Example usage, to check if a flag's value is currently the default value: +// if (GetCommandLineFlagInfoOrDie("foo").is_default) ... +extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); + +enum FlagSettingMode { + // update the flag's value (can call this multiple times). + SET_FLAGS_VALUE, + // update the flag's value, but *only if* it has not yet been updated + // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef". + SET_FLAG_IF_DEFAULT, + // set the flag's default value to this. If the flag has not yet updated + // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef") + // change the flag's current value to the new default value as well. + SET_FLAGS_DEFAULT +}; + +// Set a particular flag ("command line option"). Returns a string +// describing the new value that the option has been set to. The +// return value API is not well-specified, so basically just depend on +// it to be empty if the setting failed for some reason -- the name is +// not a valid flag name, or the value is not a valid value -- and +// non-empty else. + +// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) +extern std::string SetCommandLineOption(const char* name, const char* value); +extern std::string SetCommandLineOptionWithMode(const char* name, const char* value, + FlagSettingMode set_mode); + + +// -------------------------------------------------------------------- +// Saves the states (value, default value, whether the user has set +// the flag, registered validators, etc) of all flags, and restores +// them when the FlagSaver is destroyed. This is very useful in +// tests, say, when you want to let your tests change the flags, but +// make sure that they get reverted to the original states when your +// test is complete. +// +// Example usage: +// void TestFoo() { +// FlagSaver s1; +// FLAG_foo = false; +// FLAG_bar = "some value"; +// +// // test happens here. You can return at any time +// // without worrying about restoring the FLAG values. +// } +// +// Note: This class is marked with __attribute__((unused)) because all the +// work is done in the constructor and destructor, so in the standard +// usage example above, the compiler would complain that it's an +// unused variable. +// +// This class is thread-safe. + +class FlagSaver { + public: + FlagSaver(); + ~FlagSaver(); + + private: + class FlagSaverImpl* impl_; // we use pimpl here to keep API steady + + FlagSaver(const FlagSaver&); // no copying! + void operator=(const FlagSaver&); +} +#ifndef _MSC_VER +__attribute__ ((unused)) +#endif +; + +// -------------------------------------------------------------------- +// Some deprecated or hopefully-soon-to-be-deprecated functions. + +// This is often used for logging. TODO(csilvers): figure out a better way +extern std::string CommandlineFlagsIntoString(); +// Usually where this is used, a FlagSaver should be used instead. +extern bool ReadFlagsFromString(const std::string& flagfilecontents, + const char* prog_name, + bool errors_are_fatal); // uses SET_FLAGS_VALUE + +// These let you manually implement --flagfile functionality. +// DEPRECATED. +extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); +extern bool SaveCommandFlags(); // actually defined in google.cc ! +extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, + bool errors_are_fatal); // uses SET_FLAGS_VALUE + + +// -------------------------------------------------------------------- +// Useful routines for initializing flags from the environment. +// In each case, if 'varname' does not exist in the environment +// return defval. If 'varname' does exist but is not valid +// (e.g., not a number for an int32 flag), abort with an error. +// Otherwise, return the value. NOTE: for booleans, for true use +// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. + +extern bool BoolFromEnv(const char *varname, bool defval); +extern int32 Int32FromEnv(const char *varname, int32 defval); +extern int64 Int64FromEnv(const char *varname, int64 defval); +extern uint64 Uint64FromEnv(const char *varname, uint64 defval); +extern double DoubleFromEnv(const char *varname, double defval); +extern const char *StringFromEnv(const char *varname, const char *defval); + + +// -------------------------------------------------------------------- +// The next two functions parse commandlineflags from main(): + +// Set the "usage" message for this program. For example: +// string usage("This program does nothing. Sample usage:\n"); +// usage += argv[0] + " "; +// SetUsageMessage(usage); +// Do not include commandline flags in the usage: we do that for you! +// Thread-hostile; meant to be called before any threads are spawned. +extern void SetUsageMessage(const std::string& usage); + +// Looks for flags in argv and parses them. Rearranges argv to put +// flags first, or removes them entirely if remove_flags is true. +// If a flag is defined more than once in the command line or flag +// file, the last definition is used. Returns the index (into argv) +// of the first non-flag argument. +// See top-of-file for more details on this function. +#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. +extern uint32 ParseCommandLineFlags(int *argc, char*** argv, + bool remove_flags); +#endif + + +// Calls to ParseCommandLineNonHelpFlags and then to +// HandleCommandLineHelpFlags can be used instead of a call to +// ParseCommandLineFlags during initialization, in order to allow for +// changing default values for some FLAGS (via +// e.g. SetCommandLineOptionWithMode calls) between the time of +// command line parsing and the time of dumping help information for +// the flags as a result of command line parsing. If a flag is +// defined more than once in the command line or flag file, the last +// definition is used. Returns the index (into argv) of the first +// non-flag argument. (If remove_flags is true, will always return 1.) +extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, + bool remove_flags); +// This is actually defined in commandlineflags_reporting.cc. +// This function is misnamed (it also handles --version, etc.), but +// it's too late to change that now. :-( +extern void HandleCommandLineHelpFlags(); // in commandlineflags_reporting.cc + +// Allow command line reparsing. Disables the error normally +// generated when an unknown flag is found, since it may be found in a +// later parse. Thread-hostile; meant to be called before any threads +// are spawned. +extern void AllowCommandLineReparsing(); + +// Reparse the flags that have not yet been recognized. Only flags +// registered since the last parse will be recognized. Any flag value +// must be provided as part of the argument using "=", not as a +// separate command line argument that follows the flag argument. +// Intended for handling flags from dynamically loaded libraries, +// since their flags are not registered until they are loaded. +// Returns the index (into the original argv) of the first non-flag +// argument. (If remove_flags is true, will always return 1.) +extern uint32 ReparseCommandLineNonHelpFlags(); + +// Clean up memory allocated by flags. This is only needed to reduce +// the quantity of "potentially leaked" reports emitted by memory +// debugging tools such as valgrind. It is not required for normal +// operation, or for the perftools heap-checker. It must only be called +// when the process is about to exit, and all threads that might +// access flags are quiescent. Referencing flags after this is called +// will have unexpected consequences. This is not safe to run when +// multiple threads might be running: the function is thread-hostile. +extern void ShutDownCommandLineFlags(); + + +// -------------------------------------------------------------------- +// Now come the command line flag declaration/definition macros that +// will actually be used. They're kind of hairy. A major reason +// for this is initialization: we want people to be able to access +// variables in global constructors and have that not crash, even if +// their global constructor runs before the global constructor here. +// (Obviously, we can't guarantee the flags will have the correct +// default value in that case, but at least accessing them is safe.) +// The only way to do that is have flags point to a static buffer. +// So we make one, using a union to ensure proper alignment, and +// then use placement-new to actually set up the flag with the +// correct default value. In the same vein, we have to worry about +// flag access in global destructors, so FlagRegisterer has to be +// careful never to destroy the flag-values it constructs. +// +// Note that when we define a flag variable FLAGS_, we also +// preemptively define a junk variable, FLAGS_no. This is to +// cause a link-time error if someone tries to define 2 flags with +// names like "logging" and "nologging". We do this because a bool +// flag FLAG can be set from the command line to true with a "-FLAG" +// argument, and to false with a "-noFLAG" argument, and so this can +// potentially avert confusion. +// +// We also put flags into their own namespace. It is purposefully +// named in an opaque way that people should have trouble typing +// directly. The idea is that DEFINE puts the flag in the weird +// namespace, and DECLARE imports the flag from there into the current +// namespace. The net result is to force people to use DECLARE to get +// access to a flag, rather than saying "extern bool FLAGS_whatever;" +// or some such instead. We want this so we can put extra +// functionality (like sanity-checking) in DECLARE if we want, and +// make sure it is picked up everywhere. +// +// We also put the type of the variable in the namespace, so that +// people can't DECLARE_int32 something that they DEFINE_bool'd +// elsewhere. + +class FlagRegisterer { + public: + FlagRegisterer(const char* name, const char* type, + const char* help, const char* filename, + void* current_storage, void* defvalue_storage); +}; + +extern bool FlagsTypeWarn(const char *name); + +// If your application #defines STRIP_FLAG_HELP to a non-zero value +// before #including this file, we remove the help message from the +// binary file. This can reduce the size of the resulting binary +// somewhat, and may also be useful for security reasons. + +extern const char kStrippedFlagHelp[]; + +} + +#ifndef SWIG // In swig, ignore the main flag declarations + +#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 +// Need this construct to avoid the 'defined but not used' warning. +#define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : ::google::kStrippedFlagHelp) +#else +#define MAYBE_STRIPPED_HELP(txt) txt +#endif + +// Each command-line flag has two variables associated with it: one +// with the current value, and one with the default value. However, +// we have a third variable, which is where value is assigned; it's a +// constant. This guarantees that FLAG_##value is initialized at +// static initialization time (e.g. before program-start) rather than +// than global construction time (which is after program-start but +// before main), at least when 'value' is a compile-time constant. We +// use a small trick for the "default value" variable, and call it +// FLAGS_no. This serves the second purpose of assuring a +// compile error if someone tries to define a flag named no +// which is illegal (--foo and --nofoo both affect the "foo" flag). +#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ + namespace fL##shorttype { \ + static const type FLAGS_nono##name = value; \ + type FLAGS_##name = FLAGS_nono##name; \ + type FLAGS_no##name = FLAGS_nono##name; \ + static ::google::FlagRegisterer o_##name( \ + #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \ + &FLAGS_##name, &FLAGS_no##name); \ + } \ + using fL##shorttype::FLAGS_##name + +#define DECLARE_VARIABLE(type, shorttype, name) \ + namespace fL##shorttype { \ + extern type FLAGS_##name; \ + } \ + using fL##shorttype::FLAGS_##name + +// For DEFINE_bool, we want to do the extra check that the passed-in +// value is actually a bool, and not a string or something that can be +// coerced to a bool. These declarations (no definition needed!) will +// help us do that, and never evaluate From, which is important. +// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires +// that the compiler have different sizes for bool & double. Since +// this is not guaranteed by the standard, we check it with a +// compile-time assert (msg[-1] will give a compile-time error). +namespace fLB { +struct CompileAssert {}; +typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ + (sizeof(double) != sizeof(bool)) ? 1 : -1]; +template double IsBoolFlag(const From& from); +bool IsBoolFlag(bool from); +} // namespace fLB + +#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name) +#define DEFINE_bool(name, val, txt) \ + namespace fLB { \ + typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \ + (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double)) ? 1 : -1]; \ + } \ + DEFINE_VARIABLE(bool, B, name, val, txt) + +#define DECLARE_int32(name) DECLARE_VARIABLE(::google::int32, I, name) +#define DEFINE_int32(name,val,txt) DEFINE_VARIABLE(::google::int32, I, name, val, txt) + +#define DECLARE_int64(name) DECLARE_VARIABLE(::google::int64, I64, name) +#define DEFINE_int64(name,val,txt) DEFINE_VARIABLE(::google::int64, I64, name, val, txt) + +#define DECLARE_uint64(name) DECLARE_VARIABLE(::google::uint64, U64, name) +#define DEFINE_uint64(name,val,txt) DEFINE_VARIABLE(::google::uint64, U64, name, val, txt) + +#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name) +#define DEFINE_double(name, val, txt) DEFINE_VARIABLE(double, D, name, val, txt) + +// Strings are trickier, because they're not a POD, so we can't +// construct them at static-initialization time (instead they get +// constructed at global-constructor time, which is much later). To +// try to avoid crashes in that case, we use a char buffer to store +// the string, which we can static-initialize, and then placement-new +// into it later. It's not perfect, but the best we can do. + +namespace fLS { +// The meaning of "string" might be different between now and when the +// macros below get invoked (e.g., if someone is experimenting with +// other string implementations that get defined after this file is +// included). Save the current meaning now and use it in the macros. +typedef std::string clstring; + +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + const char *value) { + return new(stringspot) clstring(value); +} +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + const clstring &value) { + return new(stringspot) clstring(value); +} +inline clstring* dont_pass0toDEFINE_string(char *stringspot, + int value); +} // namespace fLS + +#define DECLARE_string(name) namespace fLS { extern ::fLS::clstring& FLAGS_##name; } \ + using fLS::FLAGS_##name + +// We need to define a var named FLAGS_no##name so people don't define +// --string and --nostring. And we need a temporary place to put val +// so we don't have to evaluate it twice. Two great needs that go +// great together! +// The weird 'using' + 'extern' inside the fLS namespace is to work around +// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See +// http://code.google.com/p/google-gflags/issues/detail?id=20 +#define DEFINE_string(name, val, txt) \ + namespace fLS { \ + using ::fLS::clstring; \ + static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \ + clstring* const FLAGS_no##name = ::fLS:: \ + dont_pass0toDEFINE_string(s_##name[0].s, \ + val); \ + static ::google::FlagRegisterer o_##name( \ + #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ + s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ + extern clstring& FLAGS_##name; \ + using fLS::FLAGS_##name; \ + clstring& FLAGS_##name = *FLAGS_no##name; \ + } \ + using fLS::FLAGS_##name + +#endif // SWIG + +#endif // GOOGLE_GFLAGS_H_ diff --git a/extern/libmv/third_party/gflags/gflags_completions.cc b/extern/libmv/third_party/gflags/gflags_completions.cc new file mode 100644 index 00000000000..a129611d8a1 --- /dev/null +++ b/extern/libmv/third_party/gflags/gflags_completions.cc @@ -0,0 +1,765 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --- +// Author: Dave Nicponski +// +// Bash-style command line flag completion for C++ binaries +// +// This module implements bash-style completions. It achieves this +// goal in the following broad chunks: +// +// 1) Take a to-be-completed word, and examine it for search hints +// 2) Identify all potentially matching flags +// 2a) If there are no matching flags, do nothing. +// 2b) If all matching flags share a common prefix longer than the +// completion word, output just that matching prefix +// 3) Categorize those flags to produce a rough ordering of relevence. +// 4) Potentially trim the set of flags returned to a smaller number +// that bash is happier with +// 5) Output the matching flags in groups ordered by relevence. +// 5a) Force bash to place most-relevent groups at the top of the list +// 5b) Trim most flag's descriptions to fit on a single terminal line + + +#include "config.h" +#include +#include +#include // for strlen + +#include +#include +#include +#include + +#include "gflags.h" + +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR '/' +#endif + +DEFINE_string(tab_completion_word, "", + "If non-empty, HandleCommandLineCompletions() will hijack the " + "process and attempt to do bash-style command line flag " + "completion on this value."); +DEFINE_int32(tab_completion_columns, 80, + "Number of columns to use in output for tab completion"); + +_START_GOOGLE_NAMESPACE_ + +namespace { + +using std::set; +using std::string; +using std::vector; + +// Function prototypes and Type forward declarations. Code may be +// more easily understood if it is roughly ordered according to +// control flow, rather than by C's "declare before use" ordering +struct CompletionOptions; +struct NotableFlags; + +// The entry point if flag completion is to be used. +static void PrintFlagCompletionInfo(void); + + +// 1) Examine search word +static void CanonicalizeCursorWordAndSearchOptions( + const string &cursor_word, + string *canonical_search_token, + CompletionOptions *options); + +static bool RemoveTrailingChar(string *str, char c); + + +// 2) Find all matches +static void FindMatchingFlags( + const vector &all_flags, + const CompletionOptions &options, + const string &match_token, + set *all_matches, + string *longest_common_prefix); + +static bool DoesSingleFlagMatch( + const CommandLineFlagInfo &flag, + const CompletionOptions &options, + const string &match_token); + + +// 3) Categorize matches +static void CategorizeAllMatchingFlags( + const set &all_matches, + const string &search_token, + const string &module, + const string &package_dir, + NotableFlags *notable_flags); + +static void TryFindModuleAndPackageDir( + const vector all_flags, + string *module, + string *package_dir); + + +// 4) Decide which flags to use +static void FinalizeCompletionOutput( + const set &matching_flags, + CompletionOptions *options, + NotableFlags *notable_flags, + vector *completions); + +static void RetrieveUnusedFlags( + const set &matching_flags, + const NotableFlags ¬able_flags, + set *unused_flags); + + +// 5) Output matches +static void OutputSingleGroupWithLimit( + const set &group, + const string &line_indentation, + const string &header, + const string &footer, + bool long_output_format, + int *remaining_line_limit, + size_t *completion_elements_added, + vector *completions); + +// (helpers for #5) +static string GetShortFlagLine( + const string &line_indentation, + const CommandLineFlagInfo &info); + +static string GetLongFlagLine( + const string &line_indentation, + const CommandLineFlagInfo &info); + + +// +// Useful types + +// Try to deduce the intentions behind this completion attempt. Return the +// canonical search term in 'canonical_search_token'. Binary search options +// are returned in the various booleans, which should all have intuitive +// semantics, possibly except: +// - return_all_matching_flags: Generally, we'll trim the number of +// returned candidates to some small number, showing those that are +// most likely to be useful first. If this is set, however, the user +// really does want us to return every single flag as an option. +// - force_no_update: Any time we output lines, all of which share a +// common prefix, bash will 'helpfully' not even bother to show the +// output, instead changing the current word to be that common prefix. +// If it's clear this shouldn't happen, we'll set this boolean +struct CompletionOptions { + bool flag_name_substring_search; + bool flag_location_substring_search; + bool flag_description_substring_search; + bool return_all_matching_flags; + bool force_no_update; +}; + +// Notable flags are flags that are special or preferred for some +// reason. For example, flags that are defined in the binary's module +// are expected to be much more relevent than flags defined in some +// other random location. These sets are specified roughly in precedence +// order. Once a flag is placed in one of these 'higher' sets, it won't +// be placed in any of the 'lower' sets. +struct NotableFlags { + typedef set FlagSet; + FlagSet perfect_match_flag; + FlagSet module_flags; // Found in module file + FlagSet package_flags; // Found in same directory as module file + FlagSet most_common_flags; // One of the XXX most commonly supplied flags + FlagSet subpackage_flags; // Found in subdirectories of package +}; + + +// +// Tab completion implementation - entry point +static void PrintFlagCompletionInfo(void) { + string cursor_word = FLAGS_tab_completion_word; + string canonical_token; + CompletionOptions options = { }; + CanonicalizeCursorWordAndSearchOptions( + cursor_word, + &canonical_token, + &options); + + //VLOG(1) << "Identified canonical_token: '" << canonical_token << "'"; + + vector all_flags; + set matching_flags; + GetAllFlags(&all_flags); + //VLOG(2) << "Found " << all_flags.size() << " flags overall"; + + string longest_common_prefix; + FindMatchingFlags( + all_flags, + options, + canonical_token, + &matching_flags, + &longest_common_prefix); + //VLOG(1) << "Identified " << matching_flags.size() << " matching flags"; + //VLOG(1) << "Identified " << longest_common_prefix + // << " as longest common prefix."; + if (longest_common_prefix.size() > canonical_token.size()) { + // There's actually a shared common prefix to all matching flags, + // so may as well output that and quit quickly. + //VLOG(1) << "The common prefix '" << longest_common_prefix + // << "' was longer than the token '" << canonical_token + // << "'. Returning just this prefix for completion."; + fprintf(stdout, "--%s", longest_common_prefix.c_str()); + return; + } + if (matching_flags.empty()) { + //VLOG(1) << "There were no matching flags, returning nothing."; + return; + } + + string module; + string package_dir; + TryFindModuleAndPackageDir(all_flags, &module, &package_dir); + //VLOG(1) << "Identified module: '" << module << "'"; + //VLOG(1) << "Identified package_dir: '" << package_dir << "'"; + + NotableFlags notable_flags; + CategorizeAllMatchingFlags( + matching_flags, + canonical_token, + module, + package_dir, + ¬able_flags); + //VLOG(2) << "Categorized matching flags:"; + //VLOG(2) << " perfect_match: " << notable_flags.perfect_match_flag.size(); + //VLOG(2) << " module: " << notable_flags.module_flags.size(); + //VLOG(2) << " package: " << notable_flags.package_flags.size(); + //VLOG(2) << " most common: " << notable_flags.most_common_flags.size(); + //VLOG(2) << " subpackage: " << notable_flags.subpackage_flags.size(); + + vector completions; + FinalizeCompletionOutput( + matching_flags, + &options, + ¬able_flags, + &completions); + + if (options.force_no_update) + completions.push_back("~"); + + //VLOG(1) << "Finalized with " << completions.size() + // << " chosen completions"; + + for (vector::const_iterator it = completions.begin(); + it != completions.end(); + ++it) { + //VLOG(9) << " Completion entry: '" << *it << "'"; + fprintf(stdout, "%s\n", it->c_str()); + } +} + + +// 1) Examine search word (and helper method) +static void CanonicalizeCursorWordAndSearchOptions( + const string &cursor_word, + string *canonical_search_token, + CompletionOptions *options) { + *canonical_search_token = cursor_word; + if (canonical_search_token->empty()) return; + + // Get rid of leading quotes and dashes in the search term + if ((*canonical_search_token)[0] == '"') + *canonical_search_token = canonical_search_token->substr(1); + while ((*canonical_search_token)[0] == '-') + *canonical_search_token = canonical_search_token->substr(1); + + options->flag_name_substring_search = false; + options->flag_location_substring_search = false; + options->flag_description_substring_search = false; + options->return_all_matching_flags = false; + options->force_no_update = false; + + // Look for all search options we can deduce now. Do this by walking + // backwards through the term, looking for up to three '?' and up to + // one '+' as suffixed characters. Consume them if found, and remove + // them from the canonical search token. + int found_question_marks = 0; + int found_plusses = 0; + while (true) { + if (found_question_marks < 3 && + RemoveTrailingChar(canonical_search_token, '?')) { + ++found_question_marks; + continue; + } + if (found_plusses < 1 && + RemoveTrailingChar(canonical_search_token, '+')) { + ++found_plusses; + continue; + } + break; + } + + switch (found_question_marks) { // all fallthroughs + case 3: options->flag_description_substring_search = true; + case 2: options->flag_location_substring_search = true; + case 1: options->flag_name_substring_search = true; + }; + + options->return_all_matching_flags = (found_plusses > 0); +} + +// Returns true if a char was removed +static bool RemoveTrailingChar(string *str, char c) { + if (str->empty()) return false; + if ((*str)[str->size() - 1] == c) { + *str = str->substr(0, str->size() - 1); + return true; + } + return false; +} + + +// 2) Find all matches (and helper methods) +static void FindMatchingFlags( + const vector &all_flags, + const CompletionOptions &options, + const string &match_token, + set *all_matches, + string *longest_common_prefix) { + all_matches->clear(); + bool first_match = true; + for (vector::const_iterator it = all_flags.begin(); + it != all_flags.end(); + ++it) { + if (DoesSingleFlagMatch(*it, options, match_token)) { + all_matches->insert(&*it); + if (first_match) { + first_match = false; + *longest_common_prefix = it->name; + } else { + if (longest_common_prefix->empty() || it->name.empty()) { + longest_common_prefix->clear(); + continue; + } + string::size_type pos = 0; + while (pos < longest_common_prefix->size() && + pos < it->name.size() && + (*longest_common_prefix)[pos] == it->name[pos]) + ++pos; + longest_common_prefix->erase(pos); + } + } + } +} + +// Given the set of all flags, the parsed match options, and the +// canonical search token, produce the set of all candidate matching +// flags for subsequent analysis or filtering. +static bool DoesSingleFlagMatch( + const CommandLineFlagInfo &flag, + const CompletionOptions &options, + const string &match_token) { + // Is there a prefix match? + string::size_type pos = flag.name.find(match_token); + if (pos == 0) return true; + + // Is there a substring match if we want it? + if (options.flag_name_substring_search && + pos != string::npos) + return true; + + // Is there a location match if we want it? + if (options.flag_location_substring_search && + flag.filename.find(match_token) != string::npos) + return true; + + // TODO(daven): All searches should probably be case-insensitive + // (especially this one...) + if (options.flag_description_substring_search && + flag.description.find(match_token) != string::npos) + return true; + + return false; +} + +// 3) Categorize matches (and helper method) + +// Given a set of matching flags, categorize them by +// likely relevence to this specific binary +static void CategorizeAllMatchingFlags( + const set &all_matches, + const string &search_token, + const string &module, // empty if we couldn't find any + const string &package_dir, // empty if we couldn't find any + NotableFlags *notable_flags) { + notable_flags->perfect_match_flag.clear(); + notable_flags->module_flags.clear(); + notable_flags->package_flags.clear(); + notable_flags->most_common_flags.clear(); + notable_flags->subpackage_flags.clear(); + + for (set::const_iterator it = + all_matches.begin(); + it != all_matches.end(); + ++it) { + //VLOG(2) << "Examining match '" << (*it)->name << "'"; + //VLOG(7) << " filename: '" << (*it)->filename << "'"; + string::size_type pos = string::npos; + if (!package_dir.empty()) + pos = (*it)->filename.find(package_dir); + string::size_type slash = string::npos; + if (pos != string::npos) // candidate for package or subpackage match + slash = (*it)->filename.find( + PATH_SEPARATOR, + pos + package_dir.size() + 1); + + if ((*it)->name == search_token) { + // Exact match on some flag's name + notable_flags->perfect_match_flag.insert(*it); + //VLOG(3) << "Result: perfect match"; + } else if (!module.empty() && (*it)->filename == module) { + // Exact match on module filename + notable_flags->module_flags.insert(*it); + //VLOG(3) << "Result: module match"; + } else if (!package_dir.empty() && + pos != string::npos && slash == string::npos) { + // In the package, since there was no slash after the package portion + notable_flags->package_flags.insert(*it); + //VLOG(3) << "Result: package match"; + } else if (false) { + // In the list of the XXX most commonly supplied flags overall + // TODO(daven): Compile this list. + //VLOG(3) << "Result: most-common match"; + } else if (!package_dir.empty() && + pos != string::npos && slash != string::npos) { + // In a subdirectory of the package + notable_flags->subpackage_flags.insert(*it); + //VLOG(3) << "Result: subpackage match"; + } + + //VLOG(3) << "Result: not special match"; + } +} + +static void PushNameWithSuffix(vector* suffixes, const char* suffix) { + string s("/"); + s += ProgramInvocationShortName(); + s += suffix; + suffixes->push_back(s); +} + +static void TryFindModuleAndPackageDir( + const vector all_flags, + string *module, + string *package_dir) { + module->clear(); + package_dir->clear(); + + vector suffixes; + // TODO(daven): There's some inherant ambiguity here - multiple directories + // could share the same trailing folder and file structure (and even worse, + // same file names), causing us to be unsure as to which of the two is the + // actual package for this binary. In this case, we'll arbitrarily choose. + PushNameWithSuffix(&suffixes, "."); + PushNameWithSuffix(&suffixes, "-main."); + PushNameWithSuffix(&suffixes, "_main."); + // These four are new but probably merited? + PushNameWithSuffix(&suffixes, "-test."); + PushNameWithSuffix(&suffixes, "_test."); + PushNameWithSuffix(&suffixes, "-unittest."); + PushNameWithSuffix(&suffixes, "_unittest."); + + for (vector::const_iterator it = all_flags.begin(); + it != all_flags.end(); + ++it) { + for (vector::const_iterator suffix = suffixes.begin(); + suffix != suffixes.end(); + ++suffix) { + // TODO(daven): Make sure the match is near the end of the string + if (it->filename.find(*suffix) != string::npos) { + *module = it->filename; + string::size_type sep = it->filename.rfind(PATH_SEPARATOR); + *package_dir = it->filename.substr(0, (sep == string::npos) ? 0 : sep); + return; + } + } + } +} + +// Can't specialize template type on a locally defined type. Silly C++... +struct DisplayInfoGroup { + const char* header; + const char* footer; + set *group; + + int SizeInLines() const { + int size_in_lines = static_cast(group->size()) + 1; + if (strlen(header) > 0) { + size_in_lines++; + } + if (strlen(footer) > 0) { + size_in_lines++; + } + return size_in_lines; + } +}; + +// 4) Finalize and trim output flag set +static void FinalizeCompletionOutput( + const set &matching_flags, + CompletionOptions *options, + NotableFlags *notable_flags, + vector *completions) { + + // We want to output lines in groups. Each group needs to be indented + // the same to keep its lines together. Unless otherwise required, + // only 99 lines should be output to prevent bash from harassing the + // user. + + // First, figure out which output groups we'll actually use. For each + // nonempty group, there will be ~3 lines of header & footer, plus all + // output lines themselves. + int max_desired_lines = // "999999 flags should be enough for anyone. -dave" + (options->return_all_matching_flags ? 999999 : 98); + int lines_so_far = 0; + + vector output_groups; + bool perfect_match_found = false; + if (lines_so_far < max_desired_lines && + !notable_flags->perfect_match_flag.empty()) { + perfect_match_found = true; + DisplayInfoGroup group = + { "", + "==========", + ¬able_flags->perfect_match_flag }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + if (lines_so_far < max_desired_lines && + !notable_flags->module_flags.empty()) { + DisplayInfoGroup group = { + "-* Matching module flags *-", + "===========================", + ¬able_flags->module_flags }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + if (lines_so_far < max_desired_lines && + !notable_flags->package_flags.empty()) { + DisplayInfoGroup group = { + "-* Matching package flags *-", + "============================", + ¬able_flags->package_flags }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + if (lines_so_far < max_desired_lines && + !notable_flags->most_common_flags.empty()) { + DisplayInfoGroup group = { + "-* Commonly used flags *-", + "=========================", + ¬able_flags->most_common_flags }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + if (lines_so_far < max_desired_lines && + !notable_flags->subpackage_flags.empty()) { + DisplayInfoGroup group = { + "-* Matching sub-package flags *-", + "================================", + ¬able_flags->subpackage_flags }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + + set obscure_flags; // flags not notable + if (lines_so_far < max_desired_lines) { + RetrieveUnusedFlags(matching_flags, *notable_flags, &obscure_flags); + if (!obscure_flags.empty()) { + DisplayInfoGroup group = { + "-* Other flags *-", + "", + &obscure_flags }; + lines_so_far += group.SizeInLines(); + output_groups.push_back(group); + } + } + + // Second, go through each of the chosen output groups and output + // as many of those flags as we can, while remaining below our limit + int remaining_lines = max_desired_lines; + size_t completions_output = 0; + int indent = static_cast(output_groups.size()) - 1; + for (vector::const_iterator it = + output_groups.begin(); + it != output_groups.end(); + ++it, --indent) { + OutputSingleGroupWithLimit( + *it->group, // group + string(indent, ' '), // line indentation + string(it->header), // header + string(it->footer), // footer + perfect_match_found, // long format + &remaining_lines, // line limit - reduces this by number printed + &completions_output, // completions (not lines) added + completions); // produced completions + perfect_match_found = false; + } + + if (completions_output != matching_flags.size()) { + options->force_no_update = false; + completions->push_back("~ (Remaining flags hidden) ~"); + } else { + options->force_no_update = true; + } +} + +static void RetrieveUnusedFlags( + const set &matching_flags, + const NotableFlags ¬able_flags, + set *unused_flags) { + // Remove from 'matching_flags' set all members of the sets of + // flags we've already printed (specifically, those in notable_flags) + for (set::const_iterator it = + matching_flags.begin(); + it != matching_flags.end(); + ++it) { + if (notable_flags.perfect_match_flag.count(*it) || + notable_flags.module_flags.count(*it) || + notable_flags.package_flags.count(*it) || + notable_flags.most_common_flags.count(*it) || + notable_flags.subpackage_flags.count(*it)) + continue; + unused_flags->insert(*it); + } +} + +// 5) Output matches (and helper methods) + +static void OutputSingleGroupWithLimit( + const set &group, + const string &line_indentation, + const string &header, + const string &footer, + bool long_output_format, + int *remaining_line_limit, + size_t *completion_elements_output, + vector *completions) { + if (group.empty()) return; + if (!header.empty()) { + if (*remaining_line_limit < 2) return; + *remaining_line_limit -= 2; + completions->push_back(line_indentation + header); + completions->push_back(line_indentation + string(header.size(), '-')); + } + for (set::const_iterator it = group.begin(); + it != group.end() && *remaining_line_limit > 0; + ++it) { + --*remaining_line_limit; + ++*completion_elements_output; + completions->push_back( + (long_output_format + ? GetLongFlagLine(line_indentation, **it) + : GetShortFlagLine(line_indentation, **it))); + } + if (!footer.empty()) { + if (*remaining_line_limit < 1) return; + --*remaining_line_limit; + completions->push_back(line_indentation + footer); + } +} + +static string GetShortFlagLine( + const string &line_indentation, + const CommandLineFlagInfo &info) { + string prefix = + line_indentation + "--" + info.name + " [" + + (info.type == "string" ? + ("'" + info.default_value + "'") : + info.default_value) + + "] "; + int remainder = + FLAGS_tab_completion_columns - static_cast(prefix.size()); + string suffix; + if (remainder > 0) + suffix = + (static_cast(info.description.size()) > remainder ? + (info.description.substr(0, remainder - 3) + "...").c_str() : + info.description.c_str()); + return prefix + suffix; +} + +static string GetLongFlagLine( + const string &line_indentation, + const CommandLineFlagInfo &info) { + + string output = DescribeOneFlag(info); + + // Replace '-' with '--', and remove trailing newline before appending + // the module definition location. + string old_flagname = "-" + info.name; + output.replace( + output.find(old_flagname), + old_flagname.size(), + "-" + old_flagname); + // Stick a newline and indentation in front of the type and default + // portions of DescribeOneFlag()s description + static const char kNewlineWithIndent[] = "\n "; + output.replace(output.find(" type:"), 1, string(kNewlineWithIndent)); + output.replace(output.find(" default:"), 1, string(kNewlineWithIndent)); + output = line_indentation + " Details for '--" + info.name + "':\n" + + output + " defined: " + info.filename; + + // Eliminate any doubled newlines that crept in. Specifically, if + // DescribeOneFlag() decided to break the line just before "type" + // or "default", we don't want to introduce an extra blank line + static const string line_of_spaces(FLAGS_tab_completion_columns, ' '); + static const char kDoubledNewlines[] = "\n \n"; + for (string::size_type newlines = output.find(kDoubledNewlines); + newlines != string::npos; + newlines = output.find(kDoubledNewlines)) + // Replace each 'doubled newline' with a single newline + output.replace(newlines, sizeof(kDoubledNewlines) - 1, string("\n")); + + for (string::size_type newline = output.find('\n'); + newline != string::npos; + newline = output.find('\n')) { + int newline_pos = static_cast(newline) % FLAGS_tab_completion_columns; + int missing_spaces = FLAGS_tab_completion_columns - newline_pos; + output.replace(newline, 1, line_of_spaces, 1, missing_spaces); + } + return output; +} +} // anonymous + +void HandleCommandLineCompletions(void) { + if (FLAGS_tab_completion_word.empty()) return; + PrintFlagCompletionInfo(); + exit(0); +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/gflags/gflags_completions.h b/extern/libmv/third_party/gflags/gflags_completions.h new file mode 100644 index 00000000000..9d9ce7a5f75 --- /dev/null +++ b/extern/libmv/third_party/gflags/gflags_completions.h @@ -0,0 +1,121 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --- +// Author: Dave Nicponski +// +// Implement helpful bash-style command line flag completions +// +// ** Functional API: +// HandleCommandLineCompletions() should be called early during +// program startup, but after command line flag code has been +// initialized, such as the beginning of HandleCommandLineHelpFlags(). +// It checks the value of the flag --tab_completion_word. If this +// flag is empty, nothing happens here. If it contains a string, +// however, then HandleCommandLineCompletions() will hijack the +// process, attempting to identify the intention behind this +// completion. Regardless of the outcome of this deduction, the +// process will be terminated, similar to --helpshort flag +// handling. +// +// ** Overview of Bash completions: +// Bash can be told to programatically determine completions for the +// current 'cursor word'. It does this by (in this case) invoking a +// command with some additional arguments identifying the command +// being executed, the word being completed, and the previous word +// (if any). Bash then expects a sequence of output lines to be +// printed to stdout. If these lines all contain a common prefix +// longer than the cursor word, bash will replace the cursor word +// with that common prefix, and display nothing. If there isn't such +// a common prefix, bash will display the lines in pages using 'more'. +// +// ** Strategy taken for command line completions: +// If we can deduce either the exact flag intended, or a common flag +// prefix, we'll output exactly that. Otherwise, if information +// must be displayed to the user, we'll take the opportunity to add +// some helpful information beyond just the flag name (specifically, +// we'll include the default flag value and as much of the flag's +// description as can fit on a single terminal line width, as specified +// by the flag --tab_completion_columns). Furthermore, we'll try to +// make bash order the output such that the most useful or relevent +// flags are the most likely to be shown at the top. +// +// ** Additional features: +// To assist in finding that one really useful flag, substring matching +// was implemented. Before pressing a to get completion for the +// current word, you can append one or more '?' to the flag to do +// substring matching. Here's the semantics: +// --foo Show me all flags with names prefixed by 'foo' +// --foo? Show me all flags with 'foo' somewhere in the name +// --foo?? Same as prior case, but also search in module +// definition path for 'foo' +// --foo??? Same as prior case, but also search in flag +// descriptions for 'foo' +// Finally, we'll trim the output to a relatively small number of +// flags to keep bash quiet about the verbosity of output. If one +// really wanted to see all possible matches, appending a '+' to the +// search word will force the exhaustive list of matches to be printed. +// +// ** How to have bash accept completions from a binary: +// Bash requires that it be informed about each command that programmatic +// completion should be enabled for. Example addition to a .bashrc +// file would be (your path to gflags_completions.sh file may differ): + +/* +$ complete -o bashdefault -o default -o nospace -C \ + '/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ + time env binary_name another_binary [...] +*/ + +// This would allow the following to work: +// $ /path/to/binary_name --vmodule +// Or: +// $ ./bin/path/another_binary --gfs_u +// (etc) +// +// Sadly, it appears that bash gives no easy way to force this behavior for +// all commands. That's where the "time" in the above example comes in. +// If you haven't specifically added a command to the list of completion +// supported commands, you can still get completions by prefixing the +// entire command with "env". +// $ env /some/brand/new/binary --vmod +// Assuming that "binary" is a newly compiled binary, this should still +// produce the expected completion output. + + +#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ +#define GOOGLE_GFLAGS_COMPLETIONS_H_ + +namespace google { + +void HandleCommandLineCompletions(void); + +} + +#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ diff --git a/extern/libmv/third_party/gflags/gflags_reporting.cc b/extern/libmv/third_party/gflags/gflags_reporting.cc new file mode 100644 index 00000000000..fa3024d974e --- /dev/null +++ b/extern/libmv/third_party/gflags/gflags_reporting.cc @@ -0,0 +1,446 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// Author: Ray Sidney +// Revamped and reorganized by Craig Silverstein +// +// This file contains code for handling the 'reporting' flags. These +// are flags that, when present, cause the program to report some +// information and then exit. --help and --version are the canonical +// reporting flags, but we also have flags like --helpxml, etc. +// +// There's only one function that's meant to be called externally: +// HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(), +// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called +// externally too, but there's little need for it.) These are all +// declared in the main commandlineflags.h header file. +// +// HandleCommandLineHelpFlags() will check what 'reporting' flags have +// been defined, if any -- the "help" part of the function name is a +// bit misleading -- and do the relevant reporting. It should be +// called after all flag-values have been assigned, that is, after +// parsing the command-line. + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include "gflags.h" +#include "gflags_completions.h" + +#ifndef PATH_SEPARATOR +#define PATH_SEPARATOR '/' +#endif + +// The 'reporting' flags. They all call exit(). +DEFINE_bool(help, false, + "show help on all flags [tip: all flags can have two dashes]"); +DEFINE_bool(helpfull, false, + "show help on all flags -- same as -help"); +DEFINE_bool(helpshort, false, + "show help on only the main module for this program"); +DEFINE_string(helpon, "", + "show help on the modules named by this flag value"); +DEFINE_string(helpmatch, "", + "show help on modules whose name contains the specified substr"); +DEFINE_bool(helppackage, false, + "show help on all modules in the main package"); +DEFINE_bool(helpxml, false, + "produce an xml version of help"); +DEFINE_bool(version, false, + "show version and build info and exit"); + +_START_GOOGLE_NAMESPACE_ + +using std::string; +using std::vector; + +// -------------------------------------------------------------------- +// DescribeOneFlag() +// DescribeOneFlagInXML() +// Routines that pretty-print info about a flag. These use +// a CommandLineFlagInfo, which is the way the commandlineflags +// API exposes static info about a flag. +// -------------------------------------------------------------------- + +static const int kLineLength = 80; + +static void AddString(const string& s, + string* final_string, int* chars_in_line) { + const int slen = static_cast(s.length()); + if (*chars_in_line + 1 + slen >= kLineLength) { // < 80 chars/line + *final_string += "\n "; + *chars_in_line = 6; + } else { + *final_string += " "; + *chars_in_line += 1; + } + *final_string += s; + *chars_in_line += slen; +} + +static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag, + const string& text, bool current) { + const char* c_string = (current ? flag.current_value.c_str() : + flag.default_value.c_str()); + if (strcmp(flag.type.c_str(), "string") == 0) { // add quotes for strings + return text + ": \"" + c_string + "\""; + } else { + return text + ": " + c_string; + } +} + +// Create a descriptive string for a flag. +// Goes to some trouble to make pretty line breaks. +string DescribeOneFlag(const CommandLineFlagInfo& flag) { + string main_part = (string(" -") + flag.name + + " (" + flag.description + ')'); + const char* c_string = main_part.c_str(); + int chars_left = static_cast(main_part.length()); + string final_string = ""; + int chars_in_line = 0; // how many chars in current line so far? + while (1) { + assert(chars_left == strlen(c_string)); // Unless there's a \0 in there? + const char* newline = strchr(c_string, '\n'); + if (newline == NULL && chars_in_line+chars_left < kLineLength) { + // The whole remainder of the string fits on this line + final_string += c_string; + chars_in_line += chars_left; + break; + } + if (newline != NULL && newline - c_string < kLineLength - chars_in_line) { + int n = static_cast(newline - c_string); + final_string.append(c_string, n); + chars_left -= n + 1; + c_string += n + 1; + } else { + // Find the last whitespace on this 80-char line + int whitespace = kLineLength-chars_in_line-1; // < 80 chars/line + while ( whitespace > 0 && !isspace(c_string[whitespace]) ) { + --whitespace; + } + if (whitespace <= 0) { + // Couldn't find any whitespace to make a line break. Just dump the + // rest out! + final_string += c_string; + chars_in_line = kLineLength; // next part gets its own line for sure! + break; + } + final_string += string(c_string, whitespace); + chars_in_line += whitespace; + while (isspace(c_string[whitespace])) ++whitespace; + c_string += whitespace; + chars_left -= whitespace; + } + if (*c_string == '\0') + break; + final_string += "\n "; + chars_in_line = 6; + } + + // Append data type + AddString(string("type: ") + flag.type, &final_string, &chars_in_line); + // The listed default value will be the actual default from the flag + // definition in the originating source file, unless the value has + // subsequently been modified using SetCommandLineOptionWithMode() with mode + // SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before initializing. + AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string, + &chars_in_line); + if (!flag.is_default) { + AddString(PrintStringFlagsWithQuotes(flag, "currently", true), + &final_string, &chars_in_line); + } + + final_string += '\n'; + return final_string; +} + +// Simple routine to xml-escape a string: escape & and < only. +static string XMLText(const string& txt) { + string ans = txt; + for (string::size_type pos = 0; (pos = ans.find("&", pos)) != string::npos; ) + ans.replace(pos++, 1, "&"); + for (string::size_type pos = 0; (pos = ans.find("<", pos)) != string::npos; ) + ans.replace(pos++, 1, "<"); + return ans; +} + +static void AddXMLTag(string* r, const char* tag, const string& txt) { + *r += ('<'); + *r += (tag); + *r += ('>'); + *r += (XMLText(txt)); + *r += ("'); +} + +static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) { + // The file and flagname could have been attributes, but default + // and meaning need to avoid attribute normalization. This way it + // can be parsed by simple programs, in addition to xml parsers. + string r(""); + AddXMLTag(&r, "file", flag.filename); + AddXMLTag(&r, "name", flag.name); + AddXMLTag(&r, "meaning", flag.description); + AddXMLTag(&r, "default", flag.default_value); + AddXMLTag(&r, "current", flag.current_value); + AddXMLTag(&r, "type", flag.type); + r += ""; + return r; +} + +// -------------------------------------------------------------------- +// ShowUsageWithFlags() +// ShowUsageWithFlagsRestrict() +// ShowXMLOfFlags() +// These routines variously expose the registry's list of flag +// values. ShowUsage*() prints the flag-value information +// to stdout in a user-readable format (that's what --help uses). +// The Restrict() version limits what flags are shown. +// ShowXMLOfFlags() prints the flag-value information to stdout +// in a machine-readable format. In all cases, the flags are +// sorted: first by filename they are defined in, then by flagname. +// -------------------------------------------------------------------- + +static const char* Basename(const char* filename) { + const char* sep = strrchr(filename, PATH_SEPARATOR); + return sep ? sep + 1 : filename; +} + +static string Dirname(const string& filename) { + string::size_type sep = filename.rfind(PATH_SEPARATOR); + return filename.substr(0, (sep == string::npos) ? 0 : sep); +} + +// Test whether a filename contains at least one of the substrings. +static bool FileMatchesSubstring(const string& filename, + const vector& substrings) { + for (vector::const_iterator target = substrings.begin(); + target != substrings.end(); + ++target) { + if (strstr(filename.c_str(), target->c_str()) != NULL) + return true; + // If the substring starts with a '/', that means that we want + // the string to be at the beginning of a directory component. + // That should match the first directory component as well, so + // we allow '/foo' to match a filename of 'foo'. + if (!target->empty() && (*target)[0] == '/' && + strncmp(filename.c_str(), target->c_str() + 1, + strlen(target->c_str() + 1)) == 0) + return true; + } + return false; +} + +// Show help for every filename which matches any of the target substrings. +// If substrings is empty, shows help for every file. If a flag's help message +// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1' before +// including gflags/gflags.h), then this flag will not be displayed by +// '--help' and its variants. +static void ShowUsageWithFlagsMatching(const char *argv0, + const vector &substrings) { + fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage()); + + vector flags; + GetAllFlags(&flags); // flags are sorted by filename, then flagname + + string last_filename; // so we know when we're at a new file + bool first_directory = true; // controls blank lines between dirs + bool found_match = false; // stays false iff no dir matches restrict + for (vector::const_iterator flag = flags.begin(); + flag != flags.end(); + ++flag) { + if (substrings.empty() || + FileMatchesSubstring(flag->filename, substrings)) { + // If the flag has been stripped, pretend that it doesn't exist. + if (flag->description == kStrippedFlagHelp) continue; + found_match = true; // this flag passed the match! + if (flag->filename != last_filename) { // new file + if (Dirname(flag->filename) != Dirname(last_filename)) { // new dir! + if (!first_directory) + fprintf(stdout, "\n\n"); // put blank lines between directories + first_directory = false; + } + fprintf(stdout, "\n Flags from %s:\n", flag->filename.c_str()); + last_filename = flag->filename; + } + // Now print this flag + fprintf(stdout, "%s", DescribeOneFlag(*flag).c_str()); + } + } + if (!found_match && !substrings.empty()) { + fprintf(stdout, "\n No modules matched: use -help\n"); + } +} + +void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict) { + vector substrings; + if (restrict != NULL && *restrict != '\0') { + substrings.push_back(restrict); + } + ShowUsageWithFlagsMatching(argv0, substrings); +} + +void ShowUsageWithFlags(const char *argv0) { + ShowUsageWithFlagsRestrict(argv0, ""); +} + +// Convert the help, program, and usage to xml. +static void ShowXMLOfFlags(const char *prog_name) { + vector flags; + GetAllFlags(&flags); // flags are sorted: by filename, then flagname + + // XML. There is no corresponding schema yet + fprintf(stdout, "\n"); + // The document + fprintf(stdout, "\n"); + // the program name and usage + fprintf(stdout, "%s\n", + XMLText(Basename(prog_name)).c_str()); + fprintf(stdout, "%s\n", + XMLText(ProgramUsage()).c_str()); + // All the flags + for (vector::const_iterator flag = flags.begin(); + flag != flags.end(); + ++flag) { + if (flag->description != kStrippedFlagHelp) + fprintf(stdout, "%s\n", DescribeOneFlagInXML(*flag).c_str()); + } + // The end of the document + fprintf(stdout, "\n"); +} + +// -------------------------------------------------------------------- +// ShowVersion() +// Called upon --version. Prints build-related info. +// -------------------------------------------------------------------- + +static void ShowVersion() { + fprintf(stdout, "%s\n", ProgramInvocationShortName()); + // TODO: add other stuff, like a timestamp, who built it, what + // target they built, etc. + +# if !defined(NDEBUG) + fprintf(stdout, "Debug build (NDEBUG not #defined)\n"); +# endif +} + +static void AppendPrognameStrings(vector* substrings, + const char* progname) { + string r("/"); + r += progname; + substrings->push_back(r + "."); + substrings->push_back(r + "-main."); + substrings->push_back(r + "_main."); +} + +// -------------------------------------------------------------------- +// HandleCommandLineHelpFlags() +// Checks all the 'reporting' commandline flags to see if any +// have been set. If so, handles them appropriately. Note +// that all of them, by definition, cause the program to exit +// if they trigger. +// -------------------------------------------------------------------- + +void HandleCommandLineHelpFlags() { + const char* progname = ProgramInvocationShortName(); + extern void (*commandlineflags_exitfunc)(int); // in gflags.cc + + HandleCommandLineCompletions(); + + vector substrings; + AppendPrognameStrings(&substrings, progname); + + if (FLAGS_helpshort) { + // show only flags related to this binary: + // E.g. for fileutil.cc, want flags containing ... "/fileutil." cc + ShowUsageWithFlagsMatching(progname, substrings); + commandlineflags_exitfunc(1); // almost certainly exit() + + } else if (FLAGS_help || FLAGS_helpfull) { + // show all options + ShowUsageWithFlagsRestrict(progname, ""); // empty restrict + commandlineflags_exitfunc(1); + + } else if (!FLAGS_helpon.empty()) { + string restrict = "/" + FLAGS_helpon + "."; + ShowUsageWithFlagsRestrict(progname, restrict.c_str()); + commandlineflags_exitfunc(1); + + } else if (!FLAGS_helpmatch.empty()) { + ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str()); + commandlineflags_exitfunc(1); + + } else if (FLAGS_helppackage) { + // Shows help for all files in the same directory as main(). We + // don't want to resort to looking at dirname(progname), because + // the user can pick progname, and it may not relate to the file + // where main() resides. So instead, we search the flags for a + // filename like "/progname.cc", and take the dirname of that. + vector flags; + GetAllFlags(&flags); + string last_package; + for (vector::const_iterator flag = flags.begin(); + flag != flags.end(); + ++flag) { + if (!FileMatchesSubstring(flag->filename, substrings)) + continue; + const string package = Dirname(flag->filename) + "/"; + if (package != last_package) { + ShowUsageWithFlagsRestrict(progname, package.c_str()); + if (!last_package.empty()) { // means this isn't our first pkg + fprintf(stderr, "WARNING: Multiple packages contain a file=%s\n", + progname); + } + last_package = package; + } + } + if (last_package.empty()) { // never found a package to print + fprintf(stderr, "WARNING: Unable to find a package for file=%s\n", + progname); + } + commandlineflags_exitfunc(1); + + } else if (FLAGS_helpxml) { + ShowXMLOfFlags(progname); + commandlineflags_exitfunc(1); + + } else if (FLAGS_version) { + ShowVersion(); + // Unlike help, we may be asking for version in a script, so return 0 + commandlineflags_exitfunc(0); + } +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/gflags/mutex.h b/extern/libmv/third_party/gflags/mutex.h new file mode 100644 index 00000000000..6e1e8976b6d --- /dev/null +++ b/extern/libmv/third_party/gflags/mutex.h @@ -0,0 +1,349 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --- +// Author: Craig Silverstein. +// +// A simple mutex wrapper, supporting locks and read-write locks. +// You should assume the locks are *not* re-entrant. +// +// To use: you should define the following macros in your configure.ac: +// ACX_PTHREAD +// AC_RWLOCK +// The latter is defined in ../autoconf. +// +// This class is meant to be internal-only and should be wrapped by an +// internal namespace. Before you use this module, please give the +// name of your internal namespace for this module. Or, if you want +// to expose it, you'll want to move it to the Google namespace. We +// cannot put this class in global namespace because there can be some +// problems when we have multiple versions of Mutex in each shared object. +// +// NOTE: by default, we have #ifdef'ed out the TryLock() method. +// This is for two reasons: +// 1) TryLock() under Windows is a bit annoying (it requires a +// #define to be defined very early). +// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG +// mode. +// If you need TryLock(), and either these two caveats are not a +// problem for you, or you're willing to work around them, then +// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs +// in the code below. +// +// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: +// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html +// Because of that, we might as well use windows locks for +// cygwin. They seem to be more reliable than the cygwin pthreads layer. +// +// TRICKY IMPLEMENTATION NOTE: +// This class is designed to be safe to use during +// dynamic-initialization -- that is, by global constructors that are +// run before main() starts. The issue in this case is that +// dynamic-initialization happens in an unpredictable order, and it +// could be that someone else's dynamic initializer could call a +// function that tries to acquire this mutex -- but that all happens +// before this mutex's constructor has run. (This can happen even if +// the mutex and the function that uses the mutex are in the same .cc +// file.) Basically, because Mutex does non-trivial work in its +// constructor, it's not, in the naive implementation, safe to use +// before dynamic initialization has run on it. +// +// The solution used here is to pair the actual mutex primitive with a +// bool that is set to true when the mutex is dynamically initialized. +// (Before that it's false.) Then we modify all mutex routines to +// look at the bool, and not try to lock/unlock until the bool makes +// it to true (which happens after the Mutex constructor has run.) +// +// This works because before main() starts -- particularly, during +// dynamic initialization -- there are no threads, so a) it's ok that +// the mutex operations are a no-op, since we don't need locking then +// anyway; and b) we can be quite confident our bool won't change +// state between a call to Lock() and a call to Unlock() (that would +// require a global constructor in one translation unit to call Lock() +// and another global constructor in another translation unit to call +// Unlock() later, which is pretty perverse). +// +// That said, it's tricky, and can conceivably fail; it's safest to +// avoid trying to acquire a mutex in a global constructor, if you +// can. One way it can fail is that a really smart compiler might +// initialize the bool to true at static-initialization time (too +// early) rather than at dynamic-initialization time. To discourage +// that, we set is_safe_ to true in code (not the constructor +// colon-initializer) and set it to true via a function that always +// evaluates to true, but that the compiler can't know always +// evaluates to true. This should be good enough. +// +// A related issue is code that could try to access the mutex +// after it's been destroyed in the global destructors (because +// the Mutex global destructor runs before some other global +// destructor, that tries to acquire the mutex). The way we +// deal with this is by taking a constructor arg that global +// mutexes should pass in, that causes the destructor to do no +// work. We still depend on the compiler not doing anything +// weird to a Mutex's memory after it is destroyed, but for a +// static global variable, that's pretty safe. + +#ifndef GOOGLE_MUTEX_H_ +#define GOOGLE_MUTEX_H_ + +#include "config.h" // to figure out pthreads support + +#if defined(NO_THREADS) + typedef int MutexType; // to keep a lock-count +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) +# define WIN32_LEAN_AND_MEAN // We only need minimal includes +# ifdef GMUTEX_TRYLOCK + // We need Windows NT or later for TryEnterCriticalSection(). If you + // don't need that functionality, you can remove these _WIN32_WINNT + // lines, and change TryLock() to assert(0) or something. +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# endif +# include + typedef CRITICAL_SECTION MutexType; +#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) + // Needed for pthread_rwlock_*. If it causes problems, you could take it + // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it + // *does* cause problems for FreeBSD, or MacOSX, but isn't needed + // for locking there.) +# ifdef __linux__ +# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls +# endif +# include + typedef pthread_rwlock_t MutexType; +#elif defined(HAVE_PTHREAD) +# include + typedef pthread_mutex_t MutexType; +#else +# error Need to implement mutex.h for your architecture, or #define NO_THREADS +#endif + +#include +#include // for abort() + +#define MUTEX_NAMESPACE gflags_mutex_namespace + +namespace MUTEX_NAMESPACE { + +class Mutex { + public: + // This is used for the single-arg constructor + enum LinkerInitialized { LINKER_INITIALIZED }; + + // Create a Mutex that is not held by anybody. This constructor is + // typically used for Mutexes allocated on the heap or the stack. + inline Mutex(); + // This constructor should be used for global, static Mutex objects. + // It inhibits work being done by the destructor, which makes it + // safer for code that tries to acqiure this mutex in their global + // destructor. + inline Mutex(LinkerInitialized); + + // Destructor + inline ~Mutex(); + + inline void Lock(); // Block if needed until free then acquire exclusively + inline void Unlock(); // Release a lock acquired via Lock() +#ifdef GMUTEX_TRYLOCK + inline bool TryLock(); // If free, Lock() and return true, else return false +#endif + // Note that on systems that don't support read-write locks, these may + // be implemented as synonyms to Lock() and Unlock(). So you can use + // these for efficiency, but don't use them anyplace where being able + // to do shared reads is necessary to avoid deadlock. + inline void ReaderLock(); // Block until free or shared then acquire a share + inline void ReaderUnlock(); // Release a read share of this Mutex + inline void WriterLock() { Lock(); } // Acquire an exclusive lock + inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() + + private: + MutexType mutex_; + // We want to make sure that the compiler sets is_safe_ to true only + // when we tell it to, and never makes assumptions is_safe_ is + // always true. volatile is the most reliable way to do that. + volatile bool is_safe_; + // This indicates which constructor was called. + bool destroy_; + + inline void SetIsSafe() { is_safe_ = true; } + + // Catch the error of writing Mutex when intending MutexLock. + Mutex(Mutex* /*ignored*/) {} + // Disallow "evil" constructors + Mutex(const Mutex&); + void operator=(const Mutex&); +}; + +// Now the implementation of Mutex for various systems +#if defined(NO_THREADS) + +// When we don't have threads, we can be either reading or writing, +// but not both. We can have lots of readers at once (in no-threads +// mode, that's most likely to happen in recursive function calls), +// but only one writer. We represent this by having mutex_ be -1 when +// writing and a number > 0 when reading (and 0 when no lock is held). +// +// In debug mode, we assert these invariants, while in non-debug mode +// we do nothing, for efficiency. That's why everything is in an +// assert. + +Mutex::Mutex() : mutex_(0) { } +Mutex::Mutex(Mutex::LinkerInitialized) : mutex_(0) { } +Mutex::~Mutex() { assert(mutex_ == 0); } +void Mutex::Lock() { assert(--mutex_ == -1); } +void Mutex::Unlock() { assert(mutex_++ == -1); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } +#endif +void Mutex::ReaderLock() { assert(++mutex_ > 0); } +void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } + +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) + +Mutex::Mutex() : destroy_(true) { + InitializeCriticalSection(&mutex_); + SetIsSafe(); +} +Mutex::Mutex(LinkerInitialized) : destroy_(false) { + InitializeCriticalSection(&mutex_); + SetIsSafe(); +} +Mutex::~Mutex() { if (destroy_) DeleteCriticalSection(&mutex_); } +void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } +void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + TryEnterCriticalSection(&mutex_) != 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks +void Mutex::ReaderUnlock() { Unlock(); } + +#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() : destroy_(true) { + SetIsSafe(); + if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); +} +Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) { + SetIsSafe(); + if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_rwlock_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_rwlock_trywrlock(&mutex_) == 0 : true; } +#endif +void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } +void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#undef SAFE_PTHREAD + +#elif defined(HAVE_PTHREAD) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() : destroy_(true) { + SetIsSafe(); + if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); +} +Mutex::Mutex(Mutex::LinkerInitialized) : destroy_(false) { + SetIsSafe(); + if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { if (destroy_) SAFE_PTHREAD(pthread_mutex_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_mutex_trylock(&mutex_) == 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } +void Mutex::ReaderUnlock() { Unlock(); } +#undef SAFE_PTHREAD + +#endif + +// -------------------------------------------------------------------------- +// Some helper classes + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } + ~MutexLock() { mu_->Unlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + MutexLock(const MutexLock&); + void operator=(const MutexLock&); +}; + +// ReaderMutexLock and WriterMutexLock do the same, for rwlocks +class ReaderMutexLock { + public: + explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } + ~ReaderMutexLock() { mu_->ReaderUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + ReaderMutexLock(const ReaderMutexLock&); + void operator=(const ReaderMutexLock&); +}; + +class WriterMutexLock { + public: + explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } + ~WriterMutexLock() { mu_->WriterUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + WriterMutexLock(const WriterMutexLock&); + void operator=(const WriterMutexLock&); +}; + +// Catch bug where variable name is omitted, e.g. MutexLock (&mu); +#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) +#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) +#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) + +} // namespace MUTEX_NAMESPACE + +using namespace MUTEX_NAMESPACE; + +#undef MUTEX_NAMESPACE + +#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/extern/libmv/third_party/glog/AUTHORS b/extern/libmv/third_party/glog/AUTHORS new file mode 100644 index 00000000000..ee92be88dcf --- /dev/null +++ b/extern/libmv/third_party/glog/AUTHORS @@ -0,0 +1,2 @@ +opensource@google.com + diff --git a/extern/libmv/third_party/glog/COPYING b/extern/libmv/third_party/glog/COPYING new file mode 100644 index 00000000000..38396b580b3 --- /dev/null +++ b/extern/libmv/third_party/glog/COPYING @@ -0,0 +1,65 @@ +Copyright (c) 2008, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +A function gettimeofday in utilities.cc is based on + +http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd + +The license of this code is: + +Copyright (c) 2003-2008, Jouni Malinen and contributors +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name(s) of the above-listed copyright holder(s) nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extern/libmv/third_party/glog/ChangeLog b/extern/libmv/third_party/glog/ChangeLog new file mode 100644 index 00000000000..350fee921e3 --- /dev/null +++ b/extern/libmv/third_party/glog/ChangeLog @@ -0,0 +1,59 @@ +2010-06-15 Google Inc. + + * google-glog: version 0.3.1 + * GLOG_* environment variables now work even when gflags is installed. + * Snow leopard support. + * Now we can build and test from out side tree. + * Add DCHECK_NOTNULL. + * Add ShutdownGoogleLogging to close syslog (thanks DGunchev) + * Fix --enable-frame-pointers option (thanks kazuki.ohta) + * Fix libunwind detection (thanks giantchen) + +2009-07-30 Google Inc. + + * google-glog: version 0.3.0 + * Fix a deadlock happened when user uses glog with recent gflags. + * Suppress several unnecessary warnings (thanks keir). + * NetBSD and OpenBSD support. + * Use Win32API GetComputeNameA properly (thanks magila). + * Fix user name detection for Windows (thanks ademin). + * Fix several minor bugs. + +2009-04-10 Google Inc. + * google-glog: version 0.2.1 + * Fix timestamps of VC++ version. + * Add pkg-config support (thanks Tomasz) + * Fix build problem when building with gtest (thanks Michael) + * Add --with-gflags option for configure (thanks Michael) + * Fixes for GCC 4.4 (thanks John) + +2009-01-23 Google Inc. + * google-glog: version 0.2 + * Add initial Windows VC++ support. + * Google testing/mocking frameworks integration. + * Link pthread library automatically. + * Flush logs in signal handlers. + * Add macros LOG_TO_STRING, LOG_AT_LEVEL, DVLOG, and LOG_TO_SINK_ONLY. + * Log microseconds. + * Add --log_backtrace_at option. + * Fix some minor bugs. + +2008-11-18 Google Inc. + * google-glog: version 0.1.2 + * Add InstallFailureSignalHandler(). (satorux) + * Re-organize the way to produce stacktraces. + * Don't define unnecessary macro DISALLOW_EVIL_CONSTRUCTORS. + +2008-10-15 Google Inc. + * google-glog: version 0.1.1 + * Support symbolize for MacOSX 10.5. + * BUG FIX: --vmodule didn't work with gflags. + * BUG FIX: symbolize_unittest failed with GCC 4.3. + * Several fixes on the document. + +2008-10-07 Google Inc. + + * google-glog: initial release: + The glog package contains a library that implements application-level + logging. This library provides logging APIs based on C++-style + streams and various helper macros. diff --git a/extern/libmv/third_party/glog/NEWS b/extern/libmv/third_party/glog/NEWS new file mode 100644 index 00000000000..e69de29bb2d diff --git a/extern/libmv/third_party/glog/README b/extern/libmv/third_party/glog/README new file mode 100644 index 00000000000..77efd37505a --- /dev/null +++ b/extern/libmv/third_party/glog/README @@ -0,0 +1,5 @@ +This repository contains a C++ implementation of the Google logging +module. Documentation for the implementation is in doc/. + +See INSTALL for (generic) installation instructions for C++: basically + ./configure && make && make install diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv new file mode 100644 index 00000000000..8f1243b2430 --- /dev/null +++ b/extern/libmv/third_party/glog/README.libmv @@ -0,0 +1,38 @@ +Project: Google Logging +URL: http://code.google.com/p/google-glog/ +License: New BSD +Upstream version: 0.3.1 +Local modifications: + +Upgrading Notes +* Had to change #include to #include "gflags/gflags.h" +* Make sure to copy over a config_YOUR_PLATFORM.h and put it in config.h + +Old changes which got obsoleted (maybe?) by 0.3.1 merge: +* The config_linux.h is generated by configure on Keir's Ubuntu 9.04 desktop. +* Commented out some struct ::tm weirdness causing compile failures on + ubuntu 8.10 and 9.04. +* Switched several initializers to memset instead of = {}. +* Changed some includes pointing to gflags. Not sure why the regular inclusion + didn't work. +* Added some compile flags to silence various warnings, allowing us to keep the + differences between upstream small. +* Don't redefine _XOPEN_SOURCE. +* Added "google::" to GetReferenceableValue in CHECK_OP_LOG. +* Add virtual destructor to Thread in googletest.h. +* Update windows/glog/log_severity to build with QT library that include WinGDI + (It cause a double definition of ERROR variable). + +Old changes which got obsoleted (maybe?) by 0.2.1 merge: +* Added #ifndef / def REG_EIP; not sure what that is. +* Added (void) arg stuff to prevent unused variable warnings. +* Added google:: namespace prefix to GetReferencableValue +* Added assignments for several functions marked with no_ignore_return, where + the return value was ignored. +* Commented out the unused function DumpPCAndSymbol() in utilities.cc to silent + gcc on the mac + +TODO(keir): Remove any obsoleted changes above if they are not necessary after +testing on more platforms. + +WARNING: Mac port not updated for 0.2.1 diff --git a/extern/libmv/third_party/glog/src/base/commandlineflags.h b/extern/libmv/third_party/glog/src/base/commandlineflags.h new file mode 100644 index 00000000000..6c529ccd847 --- /dev/null +++ b/extern/libmv/third_party/glog/src/base/commandlineflags.h @@ -0,0 +1,132 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// This file is a compatibility layer that defines Google's version of +// command line flags that are used for configuration. +// +// We put flags into their own namespace. It is purposefully +// named in an opaque way that people should have trouble typing +// directly. The idea is that DEFINE puts the flag in the weird +// namespace, and DECLARE imports the flag from there into the +// current namespace. The net result is to force people to use +// DECLARE to get access to a flag, rather than saying +// extern bool FLAGS_logtostderr; +// or some such instead. We want this so we can put extra +// functionality (like sanity-checking) in DECLARE if we want, +// and make sure it is picked up everywhere. +// +// We also put the type of the variable in the namespace, so that +// people can't DECLARE_int32 something that they DEFINE_bool'd +// elsewhere. +#ifndef BASE_COMMANDLINEFLAGS_H__ +#define BASE_COMMANDLINEFLAGS_H__ + +#include "config.h" +#include +#include // for memchr +#include // for getenv + +#ifdef HAVE_LIB_GFLAGS + +#include "third_party/gflags/gflags.h" + +#else + +#include "glog/logging.h" + +#define DECLARE_VARIABLE(type, name, tn) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name +#define DEFINE_VARIABLE(type, name, value, meaning, tn) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ + GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ + char FLAGS_no##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name + +// bool specialization +#define DECLARE_bool(name) \ + DECLARE_VARIABLE(bool, name, bool) +#define DEFINE_bool(name, value, meaning) \ + DEFINE_VARIABLE(bool, name, value, meaning, bool) + +// int32 specialization +#define DECLARE_int32(name) \ + DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, name, int32) +#define DEFINE_int32(name, value, meaning) \ + DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, name, value, meaning, int32) + +// Special case for string, because we have to specify the namespace +// std::string, which doesn't play nicely with our FLAG__namespace hackery. +#define DECLARE_string(name) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#define DEFINE_string(name, value, meaning) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ + GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name(value); \ + char FLAGS_no##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name + +#endif // HAVE_LIB_GFLAGS + +// Define GLOG_DEFINE_* using DEFINE_* . By using these macros, we +// have GLOG_* environ variables even if we have gflags installed. +// +// If both an environment variable and a flag are specified, the value +// specified by a flag wins. E.g., if GLOG_v=0 and --v=1, the +// verbosity will be 1, not 0. + +#define GLOG_DEFINE_bool(name, value, meaning) \ + DEFINE_bool(name, EnvToBool("GLOG_" #name, value), meaning) + +#define GLOG_DEFINE_int32(name, value, meaning) \ + DEFINE_int32(name, EnvToInt("GLOG_" #name, value), meaning) + +#define GLOG_DEFINE_string(name, value, meaning) \ + DEFINE_string(name, EnvToString("GLOG_" #name, value), meaning) + +// These macros (could be functions, but I don't want to bother with a .cc +// file), make it easier to initialize flags from the environment. + +#define EnvToString(envname, dflt) \ + (!getenv(envname) ? (dflt) : getenv(envname)) + +#define EnvToBool(envname, dflt) \ + (!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL) + +#define EnvToInt(envname, dflt) \ + (!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10)) + +#endif // BASE_COMMANDLINEFLAGS_H__ diff --git a/extern/libmv/third_party/glog/src/base/googleinit.h b/extern/libmv/third_party/glog/src/base/googleinit.h new file mode 100644 index 00000000000..c907308e852 --- /dev/null +++ b/extern/libmv/third_party/glog/src/base/googleinit.h @@ -0,0 +1,51 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --- +// Author: Jacob Hoffman-Andrews + +#ifndef _GOOGLEINIT_H +#define _GOOGLEINIT_H + +class GoogleInitializer { + public: + typedef void (*void_function)(void); + GoogleInitializer(const char* name, void_function f) { + f(); + } +}; + +#define REGISTER_MODULE_INITIALIZER(name, body) \ + namespace { \ + static void google_init_module_##name () { body; } \ + GoogleInitializer google_initializer_module_##name(#name, \ + google_init_module_##name); \ + } + +#endif /* _GOOGLEINIT_H */ diff --git a/extern/libmv/third_party/glog/src/base/mutex.h b/extern/libmv/third_party/glog/src/base/mutex.h new file mode 100644 index 00000000000..7ba88cb5a63 --- /dev/null +++ b/extern/libmv/third_party/glog/src/base/mutex.h @@ -0,0 +1,325 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --- +// Author: Craig Silverstein. +// +// A simple mutex wrapper, supporting locks and read-write locks. +// You should assume the locks are *not* re-entrant. +// +// To use: you should define the following macros in your configure.ac: +// ACX_PTHREAD +// AC_RWLOCK +// The latter is defined in ../autoconf. +// +// This class is meant to be internal-only and should be wrapped by an +// internal namespace. Before you use this module, please give the +// name of your internal namespace for this module. Or, if you want +// to expose it, you'll want to move it to the Google namespace. We +// cannot put this class in global namespace because there can be some +// problems when we have multiple versions of Mutex in each shared object. +// +// NOTE: by default, we have #ifdef'ed out the TryLock() method. +// This is for two reasons: +// 1) TryLock() under Windows is a bit annoying (it requires a +// #define to be defined very early). +// 2) TryLock() is broken for NO_THREADS mode, at least in NDEBUG +// mode. +// If you need TryLock(), and either these two caveats are not a +// problem for you, or you're willing to work around them, then +// feel free to #define GMUTEX_TRYLOCK, or to remove the #ifdefs +// in the code below. +// +// CYGWIN NOTE: Cygwin support for rwlock seems to be buggy: +// http://www.cygwin.com/ml/cygwin/2008-12/msg00017.html +// Because of that, we might as well use windows locks for +// cygwin. They seem to be more reliable than the cygwin pthreads layer. +// +// TRICKY IMPLEMENTATION NOTE: +// This class is designed to be safe to use during +// dynamic-initialization -- that is, by global constructors that are +// run before main() starts. The issue in this case is that +// dynamic-initialization happens in an unpredictable order, and it +// could be that someone else's dynamic initializer could call a +// function that tries to acquire this mutex -- but that all happens +// before this mutex's constructor has run. (This can happen even if +// the mutex and the function that uses the mutex are in the same .cc +// file.) Basically, because Mutex does non-trivial work in its +// constructor, it's not, in the naive implementation, safe to use +// before dynamic initialization has run on it. +// +// The solution used here is to pair the actual mutex primitive with a +// bool that is set to true when the mutex is dynamically initialized. +// (Before that it's false.) Then we modify all mutex routines to +// look at the bool, and not try to lock/unlock until the bool makes +// it to true (which happens after the Mutex constructor has run.) +// +// This works because before main() starts -- particularly, during +// dynamic initialization -- there are no threads, so a) it's ok that +// the mutex operations are a no-op, since we don't need locking then +// anyway; and b) we can be quite confident our bool won't change +// state between a call to Lock() and a call to Unlock() (that would +// require a global constructor in one translation unit to call Lock() +// and another global constructor in another translation unit to call +// Unlock() later, which is pretty perverse). +// +// That said, it's tricky, and can conceivably fail; it's safest to +// avoid trying to acquire a mutex in a global constructor, if you +// can. One way it can fail is that a really smart compiler might +// initialize the bool to true at static-initialization time (too +// early) rather than at dynamic-initialization time. To discourage +// that, we set is_safe_ to true in code (not the constructor +// colon-initializer) and set it to true via a function that always +// evaluates to true, but that the compiler can't know always +// evaluates to true. This should be good enough. + +#ifndef GOOGLE_MUTEX_H_ +#define GOOGLE_MUTEX_H_ + +#include "config.h" // to figure out pthreads support + +#if defined(NO_THREADS) + typedef int MutexType; // to keep a lock-count +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) +# define WIN32_LEAN_AND_MEAN // We only need minimal includes +# ifdef GMUTEX_TRYLOCK + // We need Windows NT or later for TryEnterCriticalSection(). If you + // don't need that functionality, you can remove these _WIN32_WINNT + // lines, and change TryLock() to assert(0) or something. +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# endif +// To avoid macro definition of ERROR. +# define NOGDI +// To avoid macro definition of min/max. +# define NOMINMAX +# include + typedef CRITICAL_SECTION MutexType; +#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) + // Needed for pthread_rwlock_*. If it causes problems, you could take it + // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it + // *does* cause problems for FreeBSD, or MacOSX, but isn't needed + // for locking there.) +# ifdef __linux__ +# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls +# endif +# include + typedef pthread_rwlock_t MutexType; +#elif defined(HAVE_PTHREAD) +# include + typedef pthread_mutex_t MutexType; +#else +# error Need to implement mutex.h for your architecture, or #define NO_THREADS +#endif + +// We need to include these header files after defining _XOPEN_SOURCE +// as they may define the _XOPEN_SOURCE macro. +#include +#include // for abort() + +#define MUTEX_NAMESPACE glog_internal_namespace_ + +namespace MUTEX_NAMESPACE { + +class Mutex { + public: + // Create a Mutex that is not held by anybody. This constructor is + // typically used for Mutexes allocated on the heap or the stack. + // See below for a recommendation for constructing global Mutex + // objects. + inline Mutex(); + + // Destructor + inline ~Mutex(); + + inline void Lock(); // Block if needed until free then acquire exclusively + inline void Unlock(); // Release a lock acquired via Lock() +#ifdef GMUTEX_TRYLOCK + inline bool TryLock(); // If free, Lock() and return true, else return false +#endif + // Note that on systems that don't support read-write locks, these may + // be implemented as synonyms to Lock() and Unlock(). So you can use + // these for efficiency, but don't use them anyplace where being able + // to do shared reads is necessary to avoid deadlock. + inline void ReaderLock(); // Block until free or shared then acquire a share + inline void ReaderUnlock(); // Release a read share of this Mutex + inline void WriterLock() { Lock(); } // Acquire an exclusive lock + inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() + + // TODO(hamaji): Do nothing, implement correctly. + inline void AssertHeld() {} + + private: + MutexType mutex_; + // We want to make sure that the compiler sets is_safe_ to true only + // when we tell it to, and never makes assumptions is_safe_ is + // always true. volatile is the most reliable way to do that. + volatile bool is_safe_; + + inline void SetIsSafe() { is_safe_ = true; } + + // Catch the error of writing Mutex when intending MutexLock. + Mutex(Mutex* /*ignored*/) {} + // Disallow "evil" constructors + Mutex(const Mutex&); + void operator=(const Mutex&); +}; + +// Now the implementation of Mutex for various systems +#if defined(NO_THREADS) + +// When we don't have threads, we can be either reading or writing, +// but not both. We can have lots of readers at once (in no-threads +// mode, that's most likely to happen in recursive function calls), +// but only one writer. We represent this by having mutex_ be -1 when +// writing and a number > 0 when reading (and 0 when no lock is held). +// +// In debug mode, we assert these invariants, while in non-debug mode +// we do nothing, for efficiency. That's why everything is in an +// assert. + +Mutex::Mutex() : mutex_(0) { } +Mutex::~Mutex() { assert(mutex_ == 0); } +void Mutex::Lock() { assert(--mutex_ == -1); } +void Mutex::Unlock() { assert(mutex_++ == -1); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } +#endif +void Mutex::ReaderLock() { assert(++mutex_ > 0); } +void Mutex::ReaderUnlock() { assert(mutex_-- > 0); } + +#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) + +Mutex::Mutex() { InitializeCriticalSection(&mutex_); SetIsSafe(); } +Mutex::~Mutex() { DeleteCriticalSection(&mutex_); } +void Mutex::Lock() { if (is_safe_) EnterCriticalSection(&mutex_); } +void Mutex::Unlock() { if (is_safe_) LeaveCriticalSection(&mutex_); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + TryEnterCriticalSection(&mutex_) != 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } // we don't have read-write locks +void Mutex::ReaderUnlock() { Unlock(); } + +#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() { + SetIsSafe(); + if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_rwlock_trywrlock(&mutex_) == 0 : + true; } +#endif +void Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock); } +void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); } +#undef SAFE_PTHREAD + +#elif defined(HAVE_PTHREAD) + +#define SAFE_PTHREAD(fncall) do { /* run fncall if is_safe_ is true */ \ + if (is_safe_ && fncall(&mutex_) != 0) abort(); \ +} while (0) + +Mutex::Mutex() { + SetIsSafe(); + if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); +} +Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } +void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } +void Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock); } +#ifdef GMUTEX_TRYLOCK +bool Mutex::TryLock() { return is_safe_ ? + pthread_mutex_trylock(&mutex_) == 0 : true; } +#endif +void Mutex::ReaderLock() { Lock(); } +void Mutex::ReaderUnlock() { Unlock(); } +#undef SAFE_PTHREAD + +#endif + +// -------------------------------------------------------------------------- +// Some helper classes + +// MutexLock(mu) acquires mu when constructed and releases it when destroyed. +class MutexLock { + public: + explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } + ~MutexLock() { mu_->Unlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + MutexLock(const MutexLock&); + void operator=(const MutexLock&); +}; + +// ReaderMutexLock and WriterMutexLock do the same, for rwlocks +class ReaderMutexLock { + public: + explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } + ~ReaderMutexLock() { mu_->ReaderUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + ReaderMutexLock(const ReaderMutexLock&); + void operator=(const ReaderMutexLock&); +}; + +class WriterMutexLock { + public: + explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } + ~WriterMutexLock() { mu_->WriterUnlock(); } + private: + Mutex * const mu_; + // Disallow "evil" constructors + WriterMutexLock(const WriterMutexLock&); + void operator=(const WriterMutexLock&); +}; + +// Catch bug where variable name is omitted, e.g. MutexLock (&mu); +#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) +#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) +#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) + +} // namespace MUTEX_NAMESPACE + +using namespace MUTEX_NAMESPACE; + +#undef MUTEX_NAMESPACE + +#endif /* #define GOOGLE_MUTEX_H__ */ diff --git a/extern/libmv/third_party/glog/src/config.h b/extern/libmv/third_party/glog/src/config.h new file mode 100644 index 00000000000..ed8d56e7799 --- /dev/null +++ b/extern/libmv/third_party/glog/src/config.h @@ -0,0 +1,11 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Namespace for Google classes */ +#ifdef __APPLE__ + #include "config_mac.h" +#elif __GNUC__ + #include "config_linux.h" +#elif _MSC_VER + #include "windows/config.h" +#endif diff --git a/extern/libmv/third_party/glog/src/config_linux.h b/extern/libmv/third_party/glog/src/config_linux.h new file mode 100644 index 00000000000..df6956c9ecf --- /dev/null +++ b/extern/libmv/third_party/glog/src/config_linux.h @@ -0,0 +1,164 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google + +/* Define if you have the `dladdr' function */ +/* #undef HAVE_DLADDR */ + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define if you have the `fcntl' function */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LIBUNWIND_H */ + +/* define if you have google gflags library */ +#define HAVE_LIB_GFLAGS 1 + +/* define if you have google gmock library */ +/* #undef HAVE_LIB_GMOCK */ + +/* define if you have google gtest library */ +/* #undef HAVE_LIB_GTEST */ + +/* define if you have libunwind */ +/* #undef HAVE_LIB_UNWIND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* define if the compiler implements namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* define if the compiler implements pthread_rwlock_* */ +#define HAVE_RWLOCK 1 + +/* Define if you have the `sigaltstack' function */ +#define HAVE_SIGALTSTACK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSCALL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UCONTEXT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UCONTEXT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* define if the compiler supports using expression for operator */ +#define HAVE_USING_OPERATOR 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* define if your compiler has __builtin_expect */ +#define HAVE___BUILTIN_EXPECT 1 + +/* define if your compiler has __sync_val_compare_and_swap */ +/* #undef HAVE___SYNC_VAL_COMPARE_AND_SWAP */ + +/* Name of package */ +#define PACKAGE "glog" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opensource@google.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "glog" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "glog 0.3.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "glog" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.3.1" + +/* How to access the PC from a struct ucontext */ +#if defined(_M_X64) || defined(__amd64__) + #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_RIP] +#else + #define PC_FROM_UCONTEXT uc_mcontext.gregs[REG_EIP] +#endif + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 8 + +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +#define STDC_HEADERS 1 +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* location of source code */ +#define TEST_SRC_DIR "." + +/* Version number of package */ +#define VERSION "0.3.1" + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { diff --git a/extern/libmv/third_party/glog/src/config_mac.h b/extern/libmv/third_party/glog/src/config_mac.h new file mode 100644 index 00000000000..5f953d17ba9 --- /dev/null +++ b/extern/libmv/third_party/glog/src/config_mac.h @@ -0,0 +1,159 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google + +/* Define if you have the `dladdr' function */ +#define HAVE_DLADDR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_EXECINFO_H 1 + +/* Define if you have the `fcntl' function */ +#define HAVE_FCNTL 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_GLOB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIBUNWIND_H 1 + +/* define if you have google gflags library */ +#define HAVE_LIB_GFLAGS 1 + +/* define if you have google gmock library */ +/* #undef HAVE_LIB_GMOCK */ + +/* define if you have google gtest library */ +//#define HAVE_LIB_GTEST 1 + +/* define if you have libunwind */ +/* #undef HAVE_LIB_UNWIND */ + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* define if the compiler implements namespaces */ +#define HAVE_NAMESPACES 1 + +/* Define if you have POSIX threads libraries and header files. */ +#define HAVE_PTHREAD 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_PWD_H 1 + +/* define if the compiler implements pthread_rwlock_* */ +#define HAVE_RWLOCK 1 + +/* Define if you have the `sigaltstack' function */ +#define HAVE_SIGALTSTACK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYSCALL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UCONTEXT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UTSNAME_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_UCONTEXT_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* define if the compiler supports using expression for operator */ +#define HAVE_USING_OPERATOR 1 + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* define if your compiler has __builtin_expect */ +#define HAVE___BUILTIN_EXPECT 1 + +/* define if your compiler has __sync_val_compare_and_swap */ +/* #undef HAVE___SYNC_VAL_COMPARE_AND_SWAP */ + +/* Name of package */ +#define PACKAGE "glog" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "opensource@google.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "glog" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "glog 0.3.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "glog" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.3.1" + +/* How to access the PC from a struct ucontext */ +#undef PC_FROM_UCONTEXT + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +/* #undef PTHREAD_CREATE_JOINABLE */ + +/* The size of `void *', as computed by sizeof. */ +#define SIZEOF_VOID_P 8 + +/* Define to 1 if you have the ANSI C header files. */ +/* #undef STDC_HEADERS */ + +/* the namespace where STL code like vector<> is defined */ +#define STL_NAMESPACE std + +/* location of source code */ +#define TEST_SRC_DIR "." + +/* Version number of package */ +#define VERSION "0.3.1" + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { diff --git a/extern/libmv/third_party/glog/src/demangle.cc b/extern/libmv/third_party/glog/src/demangle.cc new file mode 100644 index 00000000000..46556bf3c13 --- /dev/null +++ b/extern/libmv/third_party/glog/src/demangle.cc @@ -0,0 +1,1231 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Satoru Takabayashi + +#include // for NULL +#include "demangle.h" + +_START_GOOGLE_NAMESPACE_ + +typedef struct { + const char *abbrev; + const char *real_name; +} AbbrevPair; + +// List of operators from Itanium C++ ABI. +static const AbbrevPair kOperatorList[] = { + { "nw", "new" }, + { "na", "new[]" }, + { "dl", "delete" }, + { "da", "delete[]" }, + { "ps", "+" }, + { "ng", "-" }, + { "ad", "&" }, + { "de", "*" }, + { "co", "~" }, + { "pl", "+" }, + { "mi", "-" }, + { "ml", "*" }, + { "dv", "/" }, + { "rm", "%" }, + { "an", "&" }, + { "or", "|" }, + { "eo", "^" }, + { "aS", "=" }, + { "pL", "+=" }, + { "mI", "-=" }, + { "mL", "*=" }, + { "dV", "/=" }, + { "rM", "%=" }, + { "aN", "&=" }, + { "oR", "|=" }, + { "eO", "^=" }, + { "ls", "<<" }, + { "rs", ">>" }, + { "lS", "<<=" }, + { "rS", ">>=" }, + { "eq", "==" }, + { "ne", "!=" }, + { "lt", "<" }, + { "gt", ">" }, + { "le", "<=" }, + { "ge", ">=" }, + { "nt", "!" }, + { "aa", "&&" }, + { "oo", "||" }, + { "pp", "++" }, + { "mm", "--" }, + { "cm", "," }, + { "pm", "->*" }, + { "pt", "->" }, + { "cl", "()" }, + { "ix", "[]" }, + { "qu", "?" }, + { "st", "sizeof" }, + { "sz", "sizeof" }, + { NULL, NULL }, +}; + +// List of builtin types from Itanium C++ ABI. +static const AbbrevPair kBuiltinTypeList[] = { + { "v", "void" }, + { "w", "wchar_t" }, + { "b", "bool" }, + { "c", "char" }, + { "a", "signed char" }, + { "h", "unsigned char" }, + { "s", "short" }, + { "t", "unsigned short" }, + { "i", "int" }, + { "j", "unsigned int" }, + { "l", "long" }, + { "m", "unsigned long" }, + { "x", "long long" }, + { "y", "unsigned long long" }, + { "n", "__int128" }, + { "o", "unsigned __int128" }, + { "f", "float" }, + { "d", "double" }, + { "e", "long double" }, + { "g", "__float128" }, + { "z", "ellipsis" }, + { NULL, NULL } +}; + +// List of substitutions Itanium C++ ABI. +static const AbbrevPair kSubstitutionList[] = { + { "St", "" }, + { "Sa", "allocator" }, + { "Sb", "basic_string" }, + // std::basic_string,std::allocator > + { "Ss", "string"}, + // std::basic_istream > + { "Si", "istream" }, + // std::basic_ostream > + { "So", "ostream" }, + // std::basic_iostream > + { "Sd", "iostream" }, + { NULL, NULL } +}; + +// State needed for demangling. +typedef struct { + const char *mangled_cur; // Cursor of mangled name. + const char *mangled_end; // End of mangled name. + char *out_cur; // Cursor of output string. + const char *out_begin; // Beginning of output string. + const char *out_end; // End of output string. + const char *prev_name; // For constructors/destructors. + int prev_name_length; // For constructors/destructors. + int nest_level; // For nested names. + int number; // Remember the previous number. + bool append; // Append flag. + bool overflowed; // True if output gets overflowed. +} State; + +// We don't use strlen() in libc since it's not guaranteed to be async +// signal safe. +static size_t StrLen(const char *str) { + size_t len = 0; + while (*str != '\0') { + ++str; + ++len; + } + return len; +} + +// Returns true if "str" has "prefix" as a prefix. +static bool StrPrefix(const char *str, const char *prefix) { + size_t i = 0; + while (str[i] != '\0' && prefix[i] != '\0' && + str[i] == prefix[i]) { + ++i; + } + return prefix[i] == '\0'; // Consumed everything in "prefix". +} + +static void InitState(State *state, const char *mangled, + char *out, int out_size) { + state->mangled_cur = mangled; + state->mangled_end = mangled + StrLen(mangled); + state->out_cur = out; + state->out_begin = out; + state->out_end = out + out_size; + state->prev_name = NULL; + state->prev_name_length = -1; + state->nest_level = -1; + state->number = -1; + state->append = true; + state->overflowed = false; +} + +// Calculates the remaining length of the mangled name. +static int RemainingLength(State *state) { + return state->mangled_end - state->mangled_cur; +} + +// Returns true and advances "mangled_cur" if we find "c" at +// "mangled_cur" position. +static bool ParseChar(State *state, const char c) { + if (RemainingLength(state) >= 1 && *state->mangled_cur == c) { + ++state->mangled_cur; + return true; + } + return false; +} + +// Returns true and advances "mangled_cur" if we find "two_chars" at +// "mangled_cur" position. +static bool ParseTwoChar(State *state, const char *two_chars) { + if (RemainingLength(state) >= 2 && + state->mangled_cur[0] == two_chars[0] && + state->mangled_cur[1] == two_chars[1]) { + state->mangled_cur += 2; + return true; + } + return false; +} + +// Returns true and advances "mangled_cur" if we find any character in +// "char_class" at "mangled_cur" position. +static bool ParseCharClass(State *state, const char *char_class) { + if (state->mangled_cur == state->mangled_end) { + return false; + } + const char *p = char_class; + for (; *p != '\0'; ++p) { + if (*state->mangled_cur == *p) { + state->mangled_cur += 1; + return true; + } + } + return false; +} + +// This function is used for handling an optional non-terminal. +static bool Optional(bool status) { + return true; +} + +// This function is used for handling + syntax. +typedef bool (*ParseFunc)(State *); +static bool OneOrMore(ParseFunc parse_func, State *state) { + if (parse_func(state)) { + while (parse_func(state)) { + } + return true; + } + return false; +} + +// Append "str" at "out_cur". If there is an overflow, "overflowed" +// is set to true for later use. The output string is ensured to +// always terminate with '\0' as long as there is no overflow. +static void Append(State *state, const char * const str, const int length) { + int i; + for (i = 0; i < length; ++i) { + if (state->out_cur + 1 < state->out_end) { // +1 for '\0' + *state->out_cur = str[i]; + ++state->out_cur; + } else { + state->overflowed = true; + break; + } + } + if (!state->overflowed) { + *state->out_cur = '\0'; // Terminate it with '\0' + } +} + +// We don't use equivalents in libc to avoid locale issues. +static bool IsLower(char c) { + return c >= 'a' && c <= 'z'; +} + +static bool IsAlpha(char c) { + return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); +} + +// Append "str" with some tweaks, iff "append" state is true. +// Returns true so that it can be placed in "if" conditions. +static void MaybeAppendWithLength(State *state, const char * const str, + const int length) { + if (state->append && length > 0) { + // Append a space if the output buffer ends with '<' and "str" + // starts with '<' to avoid <<<. + if (str[0] == '<' && state->out_begin < state->out_cur && + state->out_cur[-1] == '<') { + Append(state, " ", 1); + } + // Remember the last identifier name for ctors/dtors. + if (IsAlpha(str[0]) || str[0] == '_') { + state->prev_name = state->out_cur; + state->prev_name_length = length; + } + Append(state, str, length); + } +} + +// A convenient wrapper arount MaybeAppendWithLength(). +static bool MaybeAppend(State *state, const char * const str) { + if (state->append) { + int length = StrLen(str); + MaybeAppendWithLength(state, str, length); + } + return true; +} + +// This function is used for handling nested names. +static bool EnterNestedName(State *state) { + state->nest_level = 0; + return true; +} + +// This function is used for handling nested names. +static bool LeaveNestedName(State *state, int prev_value) { + state->nest_level = prev_value; + return true; +} + +// Disable the append mode not to print function parameters, etc. +static bool DisableAppend(State *state) { + state->append = false; + return true; +} + +// Restore the append mode to the previous state. +static bool RestoreAppend(State *state, bool prev_value) { + state->append = prev_value; + return true; +} + +// Increase the nest level for nested names. +static void MaybeIncreaseNestLevel(State *state) { + if (state->nest_level > -1) { + ++state->nest_level; + } +} + +// Appends :: for nested names if necessary. +static void MaybeAppendSeparator(State *state) { + if (state->nest_level >= 1) { + MaybeAppend(state, "::"); + } +} + +// Cancel the last separator if necessary. +static void MaybeCancelLastSeparator(State *state) { + if (state->nest_level >= 1 && state->append && + state->out_begin <= state->out_cur - 2) { + state->out_cur -= 2; + *state->out_cur = '\0'; + } +} + +// Returns true if identifier pointed by "mangled_cur" is anonymous +// namespace. +static bool IdentifierIsAnonymousNamespace(State *state) { + const char anon_prefix[] = "_GLOBAL__N_"; + return (state->number > sizeof(anon_prefix) - 1 && // Should be longer. + StrPrefix(state->mangled_cur, anon_prefix)); +} + +// Forward declarations of our parsing functions. +static bool ParseMangledName(State *state); +static bool ParseEncoding(State *state); +static bool ParseName(State *state); +static bool ParseUnscopedName(State *state); +static bool ParseUnscopedTemplateName(State *state); +static bool ParseNestedName(State *state); +static bool ParsePrefix(State *state); +static bool ParseUnqualifiedName(State *state); +static bool ParseSourceName(State *state); +static bool ParseLocalSourceName(State *state); +static bool ParseNumber(State *state); +static bool ParseFloatNumber(State *state); +static bool ParseSeqId(State *state); +static bool ParseIdentifier(State *state); +static bool ParseOperatorName(State *state); +static bool ParseSpecialName(State *state); +static bool ParseCallOffset(State *state); +static bool ParseNVOffset(State *state); +static bool ParseVOffset(State *state); +static bool ParseCtorDtorName(State *state); +static bool ParseType(State *state); +static bool ParseCVQualifiers(State *state); +static bool ParseBuiltinType(State *state); +static bool ParseFunctionType(State *state); +static bool ParseBareFunctionType(State *state); +static bool ParseClassEnumType(State *state); +static bool ParseArrayType(State *state); +static bool ParsePointerToMemberType(State *state); +static bool ParseTemplateParam(State *state); +static bool ParseTemplateTemplateParam(State *state); +static bool ParseTemplateArgs(State *state); +static bool ParseTemplateArg(State *state); +static bool ParseExpression(State *state); +static bool ParseExprPrimary(State *state); +static bool ParseLocalName(State *state); +static bool ParseDiscriminator(State *state); +static bool ParseSubstitution(State *state); + +// Implementation note: the following code is a straightforward +// translation of the Itanium C++ ABI defined in BNF with a couple of +// exceptions. +// +// - Support GNU extensions not defined in the Itanium C++ ABI +// - and are combined to avoid infinite loop +// - Reorder patterns to shorten the code +// - Reorder patterns to give greedier functions precedence +// We'll mark "Less greedy than" for these cases in the code +// +// Each parsing function changes the state and returns true on +// success. Otherwise, don't change the state and returns false. To +// ensure that the state isn't changed in the latter case, we save the +// original state before we call more than one parsing functions +// consecutively with &&, and restore the state if unsuccessful. See +// ParseEncoding() as an example of this convention. We follow the +// convention throughout the code. +// +// Originally we tried to do demangling without following the full ABI +// syntax but it turned out we needed to follow the full syntax to +// parse complicated cases like nested template arguments. Note that +// implementing a full-fledged demangler isn't trivial (libiberty's +// cp-demangle.c has +4300 lines). +// +// Note that (foo) in <(foo) ...> is a modifier to be ignored. +// +// Reference: +// - Itanium C++ ABI +// + +// ::= _Z +static bool ParseMangledName(State *state) { + if (ParseTwoChar(state, "_Z") && ParseEncoding(state)) { + // Append trailing version suffix if any. + // ex. _Z3foo@@GLIBCXX_3.4 + if (state->mangled_cur < state->mangled_end && + state->mangled_cur[0] == '@') { + MaybeAppend(state, state->mangled_cur); + state->mangled_cur = state->mangled_end; + } + return true; + } + return false; +} + +// ::= <(function) name> +// ::= <(data) name> +// ::= +static bool ParseEncoding(State *state) { + State copy = *state; + if (ParseName(state) && ParseBareFunctionType(state)) { + return true; + } + *state = copy; + + if (ParseName(state) || ParseSpecialName(state)) { + return true; + } + return false; +} + +// ::= +// ::= +// ::= +// ::= +static bool ParseName(State *state) { + if (ParseNestedName(state) || ParseLocalName(state)) { + return true; + } + + State copy = *state; + if (ParseUnscopedTemplateName(state) && + ParseTemplateArgs(state)) { + return true; + } + *state = copy; + + // Less greedy than . + if (ParseUnscopedName(state)) { + return true; + } + return false; +} + +// ::= +// ::= St +static bool ParseUnscopedName(State *state) { + if (ParseUnqualifiedName(state)) { + return true; + } + + State copy = *state; + if (ParseTwoChar(state, "St") && + MaybeAppend(state, "std::") && + ParseUnqualifiedName(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= +// ::= +static bool ParseUnscopedTemplateName(State *state) { + return ParseUnscopedName(state) || ParseSubstitution(state); +} + +// ::= N [] E +// ::= N [] E +static bool ParseNestedName(State *state) { + State copy = *state; + if (ParseChar(state, 'N') && + EnterNestedName(state) && + Optional(ParseCVQualifiers(state)) && + ParsePrefix(state) && + LeaveNestedName(state, copy.nest_level) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + return false; +} + +// This part is tricky. If we literally translate them to code, we'll +// end up infinite loop. Hence we merge them to avoid the case. +// +// ::= +// ::= +// ::= +// ::= +// ::= # empty +// ::= <(template) unqualified-name> +// ::= +// ::= +static bool ParsePrefix(State *state) { + bool has_something = false; + while (true) { + MaybeAppendSeparator(state); + if (ParseTemplateParam(state) || + ParseSubstitution(state) || + ParseUnscopedName(state)) { + has_something = true; + MaybeIncreaseNestLevel(state); + continue; + } + MaybeCancelLastSeparator(state); + if (has_something && ParseTemplateArgs(state)) { + return ParsePrefix(state); + } else { + break; + } + } + return true; +} + +// ::= +// ::= +// ::= +// ::= +static bool ParseUnqualifiedName(State *state) { + return (ParseOperatorName(state) || + ParseCtorDtorName(state) || + ParseSourceName(state) || + ParseLocalSourceName(state)); +} + +// ::= +static bool ParseSourceName(State *state) { + State copy = *state; + if (ParseNumber(state) && ParseIdentifier(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= L [] +// +// References: +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 +// http://gcc.gnu.org/viewcvs?view=rev&revision=124467 +static bool ParseLocalSourceName(State *state) { + State copy = *state; + if (ParseChar(state, 'L') && ParseSourceName(state) && + Optional(ParseDiscriminator(state))) { + return true; + } + *state = copy; + return false; +} + +// ::= [n] +static bool ParseNumber(State *state) { + int sign = 1; + if (ParseChar(state, 'n')) { + sign = -1; + } + const char *p = state->mangled_cur; + int number = 0; + for (;p < state->mangled_end; ++p) { + if ((*p >= '0' && *p <= '9')) { + number = number * 10 + (*p - '0'); + } else { + break; + } + } + if (p != state->mangled_cur) { // Conversion succeeded. + state->mangled_cur = p; + state->number = number * sign; + return true; + } + return false; +} + +// Floating-point literals are encoded using a fixed-length lowercase +// hexadecimal string. +static bool ParseFloatNumber(State *state) { + const char *p = state->mangled_cur; + int number = 0; + for (;p < state->mangled_end; ++p) { + if ((*p >= '0' && *p <= '9')) { + number = number * 16 + (*p - '0'); + } else if (*p >= 'a' && *p <= 'f') { + number = number * 16 + (*p - 'a' + 10); + } else { + break; + } + } + if (p != state->mangled_cur) { // Conversion succeeded. + state->mangled_cur = p; + state->number = number; + return true; + } + return false; +} + +// The is a sequence number in base 36, +// using digits and upper case letters +static bool ParseSeqId(State *state) { + const char *p = state->mangled_cur; + int number = 0; + for (;p < state->mangled_end; ++p) { + if ((*p >= '0' && *p <= '9')) { + number = number * 36 + (*p - '0'); + } else if (*p >= 'A' && *p <= 'Z') { + number = number * 36 + (*p - 'A' + 10); + } else { + break; + } + } + if (p != state->mangled_cur) { // Conversion succeeded. + state->mangled_cur = p; + state->number = number; + return true; + } + return false; +} + +// ::= +static bool ParseIdentifier(State *state) { + if (state->number == -1 || + RemainingLength(state) < state->number) { + return false; + } + if (IdentifierIsAnonymousNamespace(state)) { + MaybeAppend(state, "(anonymous namespace)"); + } else { + MaybeAppendWithLength(state, state->mangled_cur, state->number); + } + state->mangled_cur += state->number; + state->number = -1; // Reset the number. + return true; +} + +// ::= nw, and other two letters cases +// ::= cv # (cast) +// ::= v # vendor extended operator +static bool ParseOperatorName(State *state) { + if (RemainingLength(state) < 2) { + return false; + } + // First check with "cv" (cast) case. + State copy = *state; + if (ParseTwoChar(state, "cv") && + MaybeAppend(state, "operator ") && + EnterNestedName(state) && + ParseType(state) && + LeaveNestedName(state, copy.nest_level)) { + return true; + } + *state = copy; + + // Then vendor extended operators. + if (ParseChar(state, 'v') && ParseCharClass(state, "0123456789") && + ParseSourceName(state)) { + return true; + } + *state = copy; + + // Other operator names should start with a lower alphabet followed + // by a lower/upper alphabet. + if (!(IsLower(state->mangled_cur[0]) && + IsAlpha(state->mangled_cur[1]))) { + return false; + } + // We may want to perform a binary search if we really need speed. + const AbbrevPair *p; + for (p = kOperatorList; p->abbrev != NULL; ++p) { + if (state->mangled_cur[0] == p->abbrev[0] && + state->mangled_cur[1] == p->abbrev[1]) { + MaybeAppend(state, "operator"); + if (IsLower(*p->real_name)) { // new, delete, etc. + MaybeAppend(state, " "); + } + MaybeAppend(state, p->real_name); + state->mangled_cur += 2; + return true; + } + } + return false; +} + +// ::= TV +// ::= TT +// ::= TI +// ::= TS +// ::= Tc <(base) encoding> +// ::= GV <(object) name> +// ::= T <(base) encoding> +// G++ extensions: +// ::= TC <(offset) number> _ <(base) type> +// ::= TF +// ::= TJ +// ::= GR +// ::= GA +// ::= Th <(base) encoding> +// ::= Tv <(base) encoding> +// +// Note: we don't care much about them since they don't appear in +// stack traces. The are special data. +static bool ParseSpecialName(State *state) { + State copy = *state; + if (ParseChar(state, 'T') && + ParseCharClass(state, "VTIS") && + ParseType(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "Tc") && ParseCallOffset(state) && + ParseCallOffset(state) && ParseEncoding(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "GV") && + ParseName(state)) { + return true; + } + *state = copy; + + if (ParseChar(state, 'T') && ParseCallOffset(state) && + ParseEncoding(state)) { + return true; + } + *state = copy; + + // G++ extensions + if (ParseTwoChar(state, "TC") && ParseType(state) && + ParseNumber(state) && ParseChar(state, '_') && + DisableAppend(state) && + ParseType(state)) { + RestoreAppend(state, copy.append); + return true; + } + *state = copy; + + if (ParseChar(state, 'T') && ParseCharClass(state, "FJ") && + ParseType(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "GR") && ParseName(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "GA") && ParseEncoding(state)) { + return true; + } + *state = copy; + + if (ParseChar(state, 'T') && ParseCharClass(state, "hv") && + ParseCallOffset(state) && ParseEncoding(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= h _ +// ::= v _ +static bool ParseCallOffset(State *state) { + State copy = *state; + if (ParseChar(state, 'h') && + ParseNVOffset(state) && ParseChar(state, '_')) { + return true; + } + *state = copy; + + if (ParseChar(state, 'v') && + ParseVOffset(state) && ParseChar(state, '_')) { + return true; + } + *state = copy; + + return false; +} + +// ::= <(offset) number> +static bool ParseNVOffset(State *state) { + return ParseNumber(state); +} + +// ::= <(offset) number> _ <(virtual offset) number> +static bool ParseVOffset(State *state) { + State copy = *state; + if (ParseNumber(state) && ParseChar(state, '_') && + ParseNumber(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= C1 | C2 | C3 +// ::= D0 | D1 | D2 +static bool ParseCtorDtorName(State *state) { + State copy = *state; + if (ParseChar(state, 'C') && + ParseCharClass(state, "123")) { + const char * const prev_name = state->prev_name; + const int prev_name_length = state->prev_name_length; + MaybeAppendWithLength(state, prev_name, prev_name_length); + return true; + } + *state = copy; + + if (ParseChar(state, 'D') && + ParseCharClass(state, "012")) { + const char * const prev_name = state->prev_name; + const int prev_name_length = state->prev_name_length; + MaybeAppend(state, "~"); + MaybeAppendWithLength(state, prev_name, prev_name_length); + return true; + } + *state = copy; + return false; +} + +// ::= +// ::= P +// ::= R +// ::= C +// ::= G +// ::= U +// ::= +// ::= +// ::= +// ::= +// ::= +// ::= +// ::= +// ::= +static bool ParseType(State *state) { + // We should check CV-qualifers, and PRGC things first. + State copy = *state; + if (ParseCVQualifiers(state) && ParseType(state)) { + return true; + } + *state = copy; + + if (ParseCharClass(state, "PRCG") && ParseType(state)) { + return true; + } + *state = copy; + + if (ParseChar(state, 'U') && ParseSourceName(state) && + ParseType(state)) { + return true; + } + *state = copy; + + if (ParseBuiltinType(state) || + ParseFunctionType(state) || + ParseClassEnumType(state) || + ParseArrayType(state) || + ParsePointerToMemberType(state) || + ParseSubstitution(state)) { + return true; + } + + if (ParseTemplateTemplateParam(state) && + ParseTemplateArgs(state)) { + return true; + } + *state = copy; + + // Less greedy than . + if (ParseTemplateParam(state)) { + return true; + } + + return false; +} + +// ::= [r] [V] [K] +// We don't allow empty to avoid infinite loop in +// ParseType(). +static bool ParseCVQualifiers(State *state) { + int num_cv_qualifiers = 0; + num_cv_qualifiers += ParseChar(state, 'r'); + num_cv_qualifiers += ParseChar(state, 'V'); + num_cv_qualifiers += ParseChar(state, 'K'); + return num_cv_qualifiers > 0; +} + +// ::= v, etc. +// ::= u +static bool ParseBuiltinType(State *state) { + const AbbrevPair *p; + for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) { + if (state->mangled_cur[0] == p->abbrev[0]) { + MaybeAppend(state, p->real_name); + ++state->mangled_cur; + return true; + } + } + + State copy = *state; + if (ParseChar(state, 'u') && ParseSourceName(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= F [Y] E +static bool ParseFunctionType(State *state) { + State copy = *state; + if (ParseChar(state, 'F') && Optional(ParseChar(state, 'Y')) && + ParseBareFunctionType(state) && ParseChar(state, 'E')) { + return true; + } + *state = copy; + return false; +} + +// ::= <(signature) type>+ +static bool ParseBareFunctionType(State *state) { + State copy = *state; + DisableAppend(state); + if (OneOrMore(ParseType, state)) { + RestoreAppend(state, copy.append); + MaybeAppend(state, "()"); + return true; + } + *state = copy; + return false; +} + +// ::= +static bool ParseClassEnumType(State *state) { + return ParseName(state); +} + +// ::= A <(positive dimension) number> _ <(element) type> +// ::= A [<(dimension) expression>] _ <(element) type> +static bool ParseArrayType(State *state) { + State copy = *state; + if (ParseChar(state, 'A') && ParseNumber(state) && + ParseChar(state, '_') && ParseType(state)) { + return true; + } + *state = copy; + + if (ParseChar(state, 'A') && Optional(ParseExpression(state)) && + ParseChar(state, '_') && ParseType(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= M <(class) type> <(member) type> +static bool ParsePointerToMemberType(State *state) { + State copy = *state; + if (ParseChar(state, 'M') && ParseType(state) && + ParseType(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= T_ +// ::= T _ +static bool ParseTemplateParam(State *state) { + if (ParseTwoChar(state, "T_")) { + MaybeAppend(state, "?"); // We don't support template substitutions. + return true; + } + + State copy = *state; + if (ParseChar(state, 'T') && ParseNumber(state) && + ParseChar(state, '_')) { + MaybeAppend(state, "?"); // We don't support template substitutions. + return true; + } + *state = copy; + return false; +} + + +// ::= +// ::= +static bool ParseTemplateTemplateParam(State *state) { + return (ParseTemplateParam(state) || + ParseSubstitution(state)); +} + +// ::= I + E +static bool ParseTemplateArgs(State *state) { + State copy = *state; + DisableAppend(state); + if (ParseChar(state, 'I') && + OneOrMore(ParseTemplateArg, state) && + ParseChar(state, 'E')) { + RestoreAppend(state, copy.append); + MaybeAppend(state, "<>"); + return true; + } + *state = copy; + return false; +} + +// ::= +// ::= +// ::= X E +static bool ParseTemplateArg(State *state) { + if (ParseType(state) || + ParseExprPrimary(state)) { + return true; + } + + State copy = *state; + if (ParseChar(state, 'X') && ParseExpression(state) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + return false; +} + +// ::= +// ::= +// ::= +// ::= +// ::= +// +// ::= st +// ::= sr +// ::= sr +static bool ParseExpression(State *state) { + if (ParseTemplateParam(state) || ParseExprPrimary(state)) { + return true; + } + + State copy = *state; + if (ParseOperatorName(state) && + ParseExpression(state) && + ParseExpression(state) && + ParseExpression(state)) { + return true; + } + *state = copy; + + if (ParseOperatorName(state) && + ParseExpression(state) && + ParseExpression(state)) { + return true; + } + *state = copy; + + if (ParseOperatorName(state) && + ParseExpression(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "st") && ParseType(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "sr") && ParseType(state) && + ParseUnqualifiedName(state) && + ParseTemplateArgs(state)) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "sr") && ParseType(state) && + ParseUnqualifiedName(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= L <(value) number> E +// ::= L <(value) float> E +// ::= L E +// // A bug in g++'s C++ ABI version 2 (-fabi-version=2). +// ::= LZ E +static bool ParseExprPrimary(State *state) { + State copy = *state; + if (ParseChar(state, 'L') && ParseType(state) && + ParseNumber(state) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + + if (ParseChar(state, 'L') && ParseType(state) && + ParseFloatNumber(state) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + + if (ParseChar(state, 'L') && ParseMangledName(state) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + + if (ParseTwoChar(state, "LZ") && ParseEncoding(state) && + ParseChar(state, 'E')) { + return true; + } + *state = copy; + + return false; +} + +// := Z <(function) encoding> E <(entity) name> +// [] +// := Z <(function) encoding> E s [] +static bool ParseLocalName(State *state) { + State copy = *state; + if (ParseChar(state, 'Z') && ParseEncoding(state) && + ParseChar(state, 'E') && MaybeAppend(state, "::") && + ParseName(state) && Optional(ParseDiscriminator(state))) { + return true; + } + *state = copy; + + if (ParseChar(state, 'Z') && ParseEncoding(state) && + ParseTwoChar(state, "Es") && Optional(ParseDiscriminator(state))) { + return true; + } + *state = copy; + return false; +} + +// := _ <(non-negative) number> +static bool ParseDiscriminator(State *state) { + State copy = *state; + if (ParseChar(state, '_') && ParseNumber(state)) { + return true; + } + *state = copy; + return false; +} + +// ::= S_ +// ::= S _ +// ::= St, etc. +static bool ParseSubstitution(State *state) { + if (ParseTwoChar(state, "S_")) { + MaybeAppend(state, "?"); // We don't support substitutions. + return true; + } + + State copy = *state; + if (ParseChar(state, 'S') && ParseSeqId(state) && + ParseChar(state, '_')) { + MaybeAppend(state, "?"); // We don't support substitutions. + return true; + } + *state = copy; + + // Expand abbreviations like "St" => "std". + if (ParseChar(state, 'S')) { + const AbbrevPair *p; + for (p = kSubstitutionList; p->abbrev != NULL; ++p) { + if (state->mangled_cur[0] == p->abbrev[1]) { + MaybeAppend(state, "std"); + if (p->real_name[0] != '\0') { + MaybeAppend(state, "::"); + MaybeAppend(state, p->real_name); + } + state->mangled_cur += 1; + return true; + } + } + } + *state = copy; + return false; +} + +// The demangler entry point. +bool Demangle(const char *mangled, char *out, int out_size) { + State state; + InitState(&state, mangled, out, out_size); + return (ParseMangledName(&state) && + state.overflowed == false && + RemainingLength(&state) == 0); +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/demangle.h b/extern/libmv/third_party/glog/src/demangle.h new file mode 100644 index 00000000000..9c7591527c0 --- /dev/null +++ b/extern/libmv/third_party/glog/src/demangle.h @@ -0,0 +1,84 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Satoru Takabayashi +// +// An async-signal-safe and thread-safe demangler for Itanium C++ ABI +// (aka G++ V3 ABI). + +// The demangler is implemented to be used in async signal handlers to +// symbolize stack traces. We cannot use libstdc++'s +// abi::__cxa_demangle() in such signal handlers since it's not async +// signal safe (it uses malloc() internally). +// +// Note that this demangler doesn't support full demangling. More +// specifically, it doesn't print types of function parameters and +// types of template arguments. It just skips them. However, it's +// still very useful to extract basic information such as class, +// function, constructor, destructor, and operator names. +// +// See the implementation note in demangle.cc if you are interested. +// +// Example: +// +// | Mangled Name | The Demangler | abi::__cxa_demangle() +// |---------------|---------------|----------------------- +// | _Z1fv | f() | f() +// | _Z1fi | f() | f(int) +// | _Z3foo3bar | foo() | foo(bar) +// | _Z1fIiEvi | f<>() | void f(int) +// | _ZN1N1fE | N::f | N::f +// | _ZN3Foo3BarEv | Foo::Bar() | Foo::Bar() +// | _Zrm1XS_" | operator%() | operator%(X, X) +// | _ZN3FooC1Ev | Foo::Foo() | Foo::Foo() +// | _Z1fSs | f() | f(std::basic_string, +// | | | std::allocator >) +// +// See the unit test for more examples. +// +// Note: we might want to write demanglers for ABIs other than Itanium +// C++ ABI in the future. +// + +#ifndef BASE_DEMANGLE_H_ +#define BASE_DEMANGLE_H_ + +#include "config.h" + +_START_GOOGLE_NAMESPACE_ + +// Demangle "mangled". On success, return true and write the +// demangled symbol name to "out". Otherwise, return false. +// "out" is modified even if demangling is unsuccessful. +bool Demangle(const char *mangled, char *out, int out_size); + +_END_GOOGLE_NAMESPACE_ + +#endif // BASE_DEMANGLE_H_ diff --git a/extern/libmv/third_party/glog/src/glog/log_severity.h b/extern/libmv/third_party/glog/src/glog/log_severity.h new file mode 100644 index 00000000000..17805fbadd4 --- /dev/null +++ b/extern/libmv/third_party/glog/src/glog/log_severity.h @@ -0,0 +1,84 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef BASE_LOG_SEVERITY_H__ +#define BASE_LOG_SEVERITY_H__ + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// Variables of type LogSeverity are widely taken to lie in the range +// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if +// you ever need to change their values or add a new severity. +typedef int LogSeverity; + +const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; + +// DFATAL is FATAL in debug mode, ERROR in normal mode +#ifdef NDEBUG +#define DFATAL_LEVEL ERROR +#else +#define DFATAL_LEVEL FATAL +#endif + +extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; + +// NDEBUG usage helpers related to (RAW_)DCHECK: +// +// DEBUG_MODE is for small !NDEBUG uses like +// if (DEBUG_MODE) foo.CheckThatFoo(); +// instead of substantially more verbose +// #ifndef NDEBUG +// foo.CheckThatFoo(); +// #endif +// +// IF_DEBUG_MODE is for small !NDEBUG uses like +// IF_DEBUG_MODE( string error; ) +// DCHECK(Foo(&error)) << error; +// instead of substantially more verbose +// #ifndef NDEBUG +// string error; +// DCHECK(Foo(&error)) << error; +// #endif +// +#ifdef NDEBUG +enum { DEBUG_MODE = 0 }; +#define IF_DEBUG_MODE(x) +#else +enum { DEBUG_MODE = 1 }; +#define IF_DEBUG_MODE(x) x +#endif + +#endif // BASE_LOG_SEVERITY_H__ diff --git a/extern/libmv/third_party/glog/src/glog/logging.h b/extern/libmv/third_party/glog/src/glog/logging.h new file mode 100644 index 00000000000..a58d478ab17 --- /dev/null +++ b/extern/libmv/third_party/glog/src/glog/logging.h @@ -0,0 +1,1507 @@ +// Copyright (c) 1999, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Ray Sidney +// +// This file contains #include information about logging-related stuff. +// Pretty much everybody needs to #include this file so that they can +// log various happenings. +// + +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +#include +#include +#include +#include +#if 1 +# include +#endif +#ifdef __DEPRECATED +// Make GCC quiet. +# undef __DEPRECATED +# include +# define __DEPRECATED +#else +# include +#endif +#include + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// We care a lot about number of bits things take up. Unfortunately, +// systems define their bit-specific ints in a lot of different ways. +// We use our own way, and have a typedef to get there. +// Note: these commands below may look like "#if 1" or "#if 0", but +// that's because they were constructed that way at ./configure time. +// Look at logging.h.in to see how they're calculated (based on your config). +#if 1 +#include // the normal place uint16_t is defined +#endif +#if 1 +#include // the normal place u_int16_t is defined +#endif +#if 1 +#include // a third place for uint16_t or u_int16_t +#endif + +#if 1 +#include "third_party/gflags/gflags.h" +#endif + +namespace google { + +#if 1 // the C99 format +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +#elif 1 // the BSD format +typedef int32_t int32; +typedef u_int32_t uint32; +typedef int64_t int64; +typedef u_int64_t uint64; +#elif 0 // the windows (vc7) format +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +#error Do not know how to define a 32-bit integer quantity on your system +#endif + +} + +// The global value of GOOGLE_STRIP_LOG. All the messages logged to +// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. +// If it can be determined at compile time that the message will not be +// printed, the statement will be compiled out. +// +// Example: to strip out all INFO and WARNING messages, use the value +// of 2 below. To make an exception for WARNING messages from a single +// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including +// base/logging.h +#ifndef GOOGLE_STRIP_LOG +#define GOOGLE_STRIP_LOG 0 +#endif + +// GCC can be told that a certain branch is not likely to be taken (for +// instance, a CHECK failure), and use that information in static analysis. +// Giving it this information can help it optimize for the common case in +// the absence of better information (ie. -fprofile-arcs). +// +#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN +#if 1 +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x +#endif +#endif + +// Make a bunch of macros for logging. The way to log things is to stream +// things to LOG(). E.g., +// +// LOG(INFO) << "Found " << num_cookies << " cookies"; +// +// You can capture log messages in a string, rather than reporting them +// immediately: +// +// vector errors; +// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; +// +// This pushes back the new error onto 'errors'; if given a NULL pointer, +// it reports the error via LOG(ERROR). +// +// You can also do conditional logging: +// +// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// You can also do occasional logging (log every n'th occurrence of an +// event): +// +// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// The above will cause log messages to be output on the 1st, 11th, 21st, ... +// times it is executed. Note that the special COUNTER value is used to +// identify which repetition is happening. +// +// You can also do occasional conditional logging (log every n'th +// occurrence of an event, when condition is satisfied): +// +// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER +// << "th big cookie"; +// +// You can log messages the first N times your code executes a line. E.g. +// +// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie"; +// +// Outputs log messages for the first 20 times it is executed. +// +// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. +// These log to syslog as well as to the normal logs. If you use these at +// all, you need to be aware that syslog can drastically reduce performance, +// especially if it is configured for remote logging! Don't use these +// unless you fully understand this and have a concrete need to use them. +// Even then, try to minimize your use of them. +// +// There are also "debug mode" logging macros like the ones above: +// +// DLOG(INFO) << "Found cookies"; +// +// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// All "debug mode" logging is compiled away to nothing for non-debug mode +// compiles. +// +// We also have +// +// LOG_ASSERT(assertion); +// DLOG_ASSERT(assertion); +// +// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; +// +// There are "verbose level" logging macros. They look like +// +// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; +// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; +// +// These always log at the INFO log level (when they log at all). +// The verbose logging can also be turned on module-by-module. For instance, +// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 +// will cause: +// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} +// b. VLOG(1) and lower messages to be printed from file.{h,cc} +// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" +// d. VLOG(0) and lower messages to be printed from elsewhere +// +// The wildcarding functionality shown by (c) supports both '*' (match +// 0 or more characters) and '?' (match any single character) wildcards. +// +// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as +// +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished with just VLOG(2) << ...; +// } +// +// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" +// condition macros for sample cases, when some extra computation and +// preparation for logs is not needed. +// VLOG_IF(1, (size > 1024)) +// << "I'm printed when size is more than 1024 and when you run the " +// "program with --v=1 or more"; +// VLOG_EVERY_N(1, 10) +// << "I'm printed every 10th occurrence, and when you run the program " +// "with --v=1 or more. Present occurence is " << COUNTER; +// VLOG_IF_EVERY_N(1, (size > 1024), 10) +// << "I'm printed on every 10th occurence of case when size is more " +// " than 1024, when you run the program with --v=1 or more. "; +// "Present occurence is " << COUNTER; +// +// The supported severity levels for macros that allow you to specify one +// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. +// Note that messages of a given severity are logged not only in the +// logfile for that severity, but also in all logfiles of lower severity. +// E.g., a message of severity FATAL will be logged to the logfiles of +// severity FATAL, ERROR, WARNING, and INFO. +// +// There is also the special severity of DFATAL, which logs FATAL in +// debug mode, ERROR in normal mode. +// +// Very important: logging a message at the FATAL severity level causes +// the program to terminate (after the message is logged). +// +// Unless otherwise specified, logs will be written to the filename +// "...log..", followed +// by the date, time, and pid (you can't prevent the date, time, and pid +// from being in the filename). +// +// The logging code takes two flags: +// --v=# set the verbose level +// --logtostderr log all the messages to stderr instead of to logfiles + +// LOG LINE PREFIX FORMAT +// +// Log lines have this form: +// +// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... +// +// where the fields are defined as follows: +// +// L A single character, representing the log level +// (eg 'I' for INFO) +// mm The month (zero padded; ie May is '05') +// dd The day (zero padded) +// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds +// threadid The space-padded thread ID as returned by GetTID() +// (this matches the PID on Linux) +// file The file name +// line The line number +// msg The user-supplied message +// +// Example: +// +// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog +// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 +// +// NOTE: although the microseconds are useful for comparing events on +// a single machine, clocks on different machines may not be well +// synchronized. Hence, use caution when comparing the low bits of +// timestamps from different machines. + +#ifndef DECLARE_VARIABLE +#define MUST_UNDEF_GFLAGS_DECLARE_MACROS +#define DECLARE_VARIABLE(type, name, tn) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name + +// bool specialization +#define DECLARE_bool(name) \ + DECLARE_VARIABLE(bool, name, bool) + +// int32 specialization +#define DECLARE_int32(name) \ + DECLARE_VARIABLE(google::int32, name, int32) + +// Special case for string, because we have to specify the namespace +// std::string, which doesn't play nicely with our FLAG__namespace hackery. +#define DECLARE_string(name) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#endif + +// Set whether log messages go to stderr instead of logfiles +DECLARE_bool(logtostderr); + +// Set whether log messages go to stderr in addition to logfiles. +DECLARE_bool(alsologtostderr); + +// Log messages at a level >= this flag are automatically sent to +// stderr in addition to log files. +DECLARE_int32(stderrthreshold); + +// Set whether the log prefix should be prepended to each line of output. +DECLARE_bool(log_prefix); + +// Log messages at a level <= this flag are buffered. +// Log messages at a higher level are flushed immediately. +DECLARE_int32(logbuflevel); + +// Sets the maximum number of seconds which logs may be buffered for. +DECLARE_int32(logbufsecs); + +// Log suppression level: messages logged at a lower level than this +// are suppressed. +DECLARE_int32(minloglevel); + +// If specified, logfiles are written into this directory instead of the +// default logging directory. +DECLARE_string(log_dir); + +// Sets the path of the directory into which to put additional links +// to the log files. +DECLARE_string(log_link); + +DECLARE_int32(v); // in vlog_is_on.cc + +// Sets the maximum log file size (in MB). +DECLARE_int32(max_log_size); + +// Sets whether to avoid logging to the disk if the disk is full. +DECLARE_bool(stop_logging_if_full_disk); + +#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef DECLARE_VARIABLE +#undef DECLARE_bool +#undef DECLARE_int32 +#undef DECLARE_string +#endif + +// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for +// security reasons. See LOG(severtiy) below. + +// A few definitions of macros that don't generate much code. Since +// LOG(INFO) and its ilk are used all over our code, it's +// better to have compact code for these operations. + +#if GOOGLE_STRIP_LOG == 0 +#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \ + __FILE__, __LINE__) +#define LOG_TO_STRING_INFO(message) google::LogMessage( \ + __FILE__, __LINE__, google::INFO, message) +#else +#define COMPACT_GOOGLE_LOG_INFO google::NullStream() +#define LOG_TO_STRING_INFO(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 1 +#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \ + __FILE__, __LINE__, google::WARNING) +#define LOG_TO_STRING_WARNING(message) google::LogMessage( \ + __FILE__, __LINE__, google::WARNING, message) +#else +#define COMPACT_GOOGLE_LOG_WARNING google::NullStream() +#define LOG_TO_STRING_WARNING(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 2 +#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \ + __FILE__, __LINE__, google::ERROR) +#define LOG_TO_STRING_ERROR(message) google::LogMessage( \ + __FILE__, __LINE__, google::ERROR, message) +#else +#define COMPACT_GOOGLE_LOG_ERROR google::NullStream() +#define LOG_TO_STRING_ERROR(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 3 +#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \ + __FILE__, __LINE__) +#define LOG_TO_STRING_FATAL(message) google::LogMessage( \ + __FILE__, __LINE__, google::FATAL, message) +#else +#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal() +#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal() +#endif + +// For DFATAL, we want to use LogMessage (as opposed to +// LogMessageFatal), to be consistent with the original behavior. +#ifdef NDEBUG +#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR +#elif GOOGLE_STRIP_LOG <= 3 +#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \ + __FILE__, __LINE__, google::FATAL) +#else +#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() +#endif + +#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::INFO, counter, &google::LogMessage::SendToLog) +#define SYSLOG_INFO(counter) \ + google::LogMessage(__FILE__, __LINE__, google::INFO, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToSyslogAndLog) + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) +// A very useful logging macro to log windows errors: +#define LOG_SYSRESULT(result) \ + if (FAILED(result)) { \ + LPTSTR message = NULL; \ + LPTSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + FORMAT_MESSAGE_FROM_SYSTEM, \ + 0, result, 0, msg, 100, NULL); \ + if (message_length > 0) { \ + google::LogMessage(__FILE__, __LINE__, ERROR, 0, \ + &google::LogMessage::SendToLog).stream() << message; \ + LocalFree(message); \ + } \ + } +#endif + +// We use the preprocessor's merging operator, "##", so that, e.g., +// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny +// subtle difference between ostream member streaming functions (e.g., +// ostream::operator<<(int) and ostream non-member streaming functions +// (e.g., ::operator<<(ostream&, string&): it turns out that it's +// impossible to stream something like a string directly to an unnamed +// ostream. We employ a neat hack by calling the stream() member +// function of LogMessage which seems to avoid the problem. +#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() +#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() + +namespace google { + +// They need the definitions of integer types. +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Initialize google's logging library. You will see the program name +// specified by argv0 in log outputs. +GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); + +// Shutdown google's logging library. +GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); + +// Install a function which will be called after LOG(FATAL). +GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); + +class LogSink; // defined below + +// If a non-NULL sink pointer is given, we push this message to that sink. +// For LOG_TO_SINK we then do normal LOG(severity) logging as well. +// This is useful for capturing messages and passing/storing them +// somewhere more specific than the global log of the process. +// Argument types: +// LogSink* sink; +// LogSeverity severity; +// The cast is to disambiguate NULL arguments. +#define LOG_TO_SINK(sink, severity) \ + google::LogMessage( \ + __FILE__, __LINE__, \ + google::severity, \ + static_cast(sink), true).stream() +#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ + google::LogMessage( \ + __FILE__, __LINE__, \ + google::severity, \ + static_cast(sink), false).stream() + +// If a non-NULL string pointer is given, we write this message to that string. +// We then do normal LOG(severity) logging as well. +// This is useful for capturing messages and storing them somewhere more +// specific than the global log of the process. +// Argument types: +// string* message; +// LogSeverity severity; +// The cast is to disambiguate NULL arguments. +// NOTE: LOG(severity) expands to LogMessage().stream() for the specified +// severity. +#define LOG_TO_STRING(severity, message) \ + LOG_TO_STRING_##severity(static_cast(message)).stream() + +// If a non-NULL pointer is given, we push the message onto the end +// of a vector of strings; otherwise, we report it with LOG(severity). +// This is handy for capturing messages and perhaps passing them back +// to the caller, rather than reporting them immediately. +// Argument types: +// LogSeverity severity; +// vector *outvec; +// The cast is to disambiguate NULL arguments. +#define LOG_STRING(severity, outvec) \ + LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() + +#define LOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) +#define SYSLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) + +#define LOG_ASSERT(condition) \ + LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition +#define SYSLOG_ASSERT(condition) \ + SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK(fp->Write(x) == 4) +#define CHECK(condition) \ + LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A container for a string pointer which can be evaluated to a bool - +// true iff the pointer is NULL. +struct CheckOpString { + CheckOpString(std::string* str) : str_(str) { } + // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), + // so there's no point in cleaning up str_. + operator bool() const { + return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); + } + std::string* str_; +}; + +// Function is overloaded for integral types to allow static const +// integrals declared in classes and not defined to be used as arguments to +// CHECK* macros. It's not encouraged though. +template +inline const T& GetReferenceableValue(const T& t) { return t; } +inline char GetReferenceableValue(char t) { return t; } +inline unsigned char GetReferenceableValue(unsigned char t) { return t; } +inline signed char GetReferenceableValue(signed char t) { return t; } +inline short GetReferenceableValue(short t) { return t; } +inline unsigned short GetReferenceableValue(unsigned short t) { return t; } +inline int GetReferenceableValue(int t) { return t; } +inline unsigned int GetReferenceableValue(unsigned int t) { return t; } +inline long GetReferenceableValue(long t) { return t; } +inline unsigned long GetReferenceableValue(unsigned long t) { return t; } +inline long long GetReferenceableValue(long long t) { return t; } +inline unsigned long long GetReferenceableValue(unsigned long long t) { + return t; +} + +// This is a dummy class to define the following operator. +struct DummyClassToDefineOperator {}; + +} + +// Define global operator<< to declare using ::operator<<. +// This declaration will allow use to use CHECK macros for user +// defined classes which have operator<< (e.g., stl_logging.h). +inline std::ostream& operator<<( + std::ostream& out, const google::DummyClassToDefineOperator&) { + return out; +} + +namespace google { + +// Build the error message string. +template +std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { + // It means that we cannot use stl_logging if compiler doesn't + // support using expression for operator. + // TODO(hamaji): Figure out a way to fix. +#if 1 + using ::operator<<; +#endif + std::strstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + return new std::string(ss.str(), ss.pcount()); +} + +// Helper functions for CHECK_OP macro. +// The (int, int) specialization works around the issue that the compiler +// will not instantiate the template version of the function on values of +// unnamed enum type - see comment below. +#define DEFINE_CHECK_OP_IMPL(name, op) \ + template \ + inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ + const char* names) { \ + if (v1 op v2) return NULL; \ + else return MakeCheckOpString(v1, v2, names); \ + } \ + inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ + return Check##name##Impl(v1, v2, names); \ + } + +// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h +// provides its own #defines for the simpler names EQ, NE, LE, etc. +// This happens if, for example, those are used as token names in a +// yacc grammar. +DEFINE_CHECK_OP_IMPL(_EQ, ==) +DEFINE_CHECK_OP_IMPL(_NE, !=) +DEFINE_CHECK_OP_IMPL(_LE, <=) +DEFINE_CHECK_OP_IMPL(_LT, < ) +DEFINE_CHECK_OP_IMPL(_GE, >=) +DEFINE_CHECK_OP_IMPL(_GT, > ) +#undef DEFINE_CHECK_OP_IMPL + +// Helper macro for binary operators. +// Don't use this macro directly in your code, use CHECK_EQ et al below. + +#if defined(STATIC_ANALYSIS) +// Only for static analysis tool to know that it is equivalent to assert +#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) +#elif !defined(NDEBUG) +// In debug mode, avoid constructing CheckOpStrings if possible, +// to reduce the overhead of CHECK statments by 2x. +// Real DCHECK-heavy tests have seen 1.5x speedups. + +// The meaning of "string" might be different between now and +// when this macro gets invoked (e.g., if someone is experimenting +// with other string implementations that get defined after this +// file is included). Save the current meaning now and use it +// in the macro. +typedef std::string _Check_string; +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::_Check_string* _result = \ + google::Check##name##Impl( \ + google::GetReferenceableValue(val1), \ + google::GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, \ + google::CheckOpString(_result)).stream() +#else +// In optimized mode, use CheckOpString to hint to compiler that +// the while condition is unlikely. +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::CheckOpString _result = \ + google::Check##name##Impl( \ + google::GetReferenceableValue(val1), \ + google::GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, _result).stream() +#endif // STATIC_ANALYSIS, !NDEBUG + +#if GOOGLE_STRIP_LOG <= 3 +#define CHECK_OP(name, op, val1, val2) \ + CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal) +#else +#define CHECK_OP(name, op, val1, val2) \ + CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal) +#endif // STRIP_LOG <= 3 + +// Equality/Inequality checks - compare two values, and log a FATAL message +// including the two values when the result is not as expected. The values +// must have operator<<(ostream, ...) defined. +// +// You may append to the error message like so: +// CHECK_NE(1, 2) << ": The world must be ending!"; +// +// We are very careful to ensure that each argument is evaluated exactly +// once, and that anything which is legal to pass as a function argument is +// legal here. In particular, the arguments may be temporary expressions +// which will end up being destroyed at the end of the apparent statement, +// for example: +// CHECK_EQ(string("abc")[1], 'b'); +// +// WARNING: These don't compile correctly if one of the arguments is a pointer +// and the other is NULL. To work around this, simply static_cast NULL to the +// type of the desired pointer. + +#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) +#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) +#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) +#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) +#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) +#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) + +// Check that the input is non NULL. This very useful in constructor +// initializer lists. + +#define CHECK_NOTNULL(val) \ + google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) + +// Helper functions for string comparisons. +// To avoid bloat, the definitions are in logging.cc. +#define DECLARE_CHECK_STROP_IMPL(func, expected) \ + GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ + const char* s1, const char* s2, const char* names); +DECLARE_CHECK_STROP_IMPL(strcmp, true) +DECLARE_CHECK_STROP_IMPL(strcmp, false) +DECLARE_CHECK_STROP_IMPL(strcasecmp, true) +DECLARE_CHECK_STROP_IMPL(strcasecmp, false) +#undef DECLARE_CHECK_STROP_IMPL + +// Helper macro for string comparisons. +// Don't use this macro directly in your code, use CHECK_STREQ et al below. +#define CHECK_STROP(func, op, expected, s1, s2) \ + while (google::CheckOpString _result = \ + google::Check##func##expected##Impl((s1), (s2), \ + #s1 " " #op " " #s2)) \ + LOG(FATAL) << *_result.str_ + + +// String (char*) equality/inequality checks. +// CASE versions are case-insensitive. +// +// Note that "s1" and "s2" may be temporary strings which are destroyed +// by the compiler at the end of the current "full expression" +// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). + +#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) +#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) +#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) +#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) + +#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) +#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) + +#define CHECK_DOUBLE_EQ(val1, val2) \ + do { \ + CHECK_LE((val1), (val2)+0.000000000000001L); \ + CHECK_GE((val1), (val2)-0.000000000000001L); \ + } while (0) + +#define CHECK_NEAR(val1, val2, margin) \ + do { \ + CHECK_LE((val1), (val2)+(margin)); \ + CHECK_GE((val1), (val2)-(margin)); \ + } while (0) + +// perror()..googly style! +// +// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and +// CHECK equivalents with the addition that they postpend a description +// of the current state of errno to their output lines. + +#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() + +#define GOOGLE_PLOG(severity, counter) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, counter, \ + &google::LogMessage::SendToLog) + +#define PLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) + +// A CHECK() macro that postpends errno if the condition is false. E.g. +// +// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } +#define PCHECK(condition) \ + PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A CHECK() macro that lets you assert the success of a function that +// returns -1 and sets errno in case of an error. E.g. +// +// CHECK_ERR(mkdir(path, 0700)); +// +// or +// +// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; +#define CHECK_ERR(invocation) \ +PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ + << #invocation + +// Use macro expansion to create, for each use of LOG_EVERY_N(), static +// variables with the __LINE__ expansion as part of the variable name. +#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) +#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line + +#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) +#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) + +#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (condition && \ + ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0; \ + if (LOG_OCCURRENCES <= n) \ + ++LOG_OCCURRENCES; \ + if (LOG_OCCURRENCES <= n) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +namespace glog_internal_namespace_ { +template +struct CompileAssert { +}; +struct CrashReason; +} // namespace glog_internal_namespace_ + +#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \ + typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] + +#define LOG_EVERY_N(severity, n) \ + GOOGLE_GLOG_COMPILE_ASSERT(google::severity < \ + google::NUM_SEVERITIES, \ + INVALID_REQUESTED_LOG_SEVERITY); \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define SYSLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) + +#define PLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_FIRST_N(severity, n) \ + SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_IF_EVERY_N(severity, condition, n) \ + SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) + +// We want the special COUNTER value available for LOG_EVERY_X()'ed messages +enum PRIVATE_Counter {COUNTER}; + + +// Plus some debug-logging macros that get compiled to nothing for production + +#ifndef NDEBUG + +#define DLOG(severity) LOG(severity) +#define DVLOG(verboselevel) VLOG(verboselevel) +#define DLOG_IF(severity, condition) LOG_IF(severity, condition) +#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) +#define DLOG_IF_EVERY_N(severity, condition, n) \ + LOG_IF_EVERY_N(severity, condition, n) +#define DLOG_ASSERT(condition) LOG_ASSERT(condition) + +// debug-only checking. not executed in NDEBUG mode. +#define DCHECK(condition) CHECK(condition) +#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) +#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) +#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) +#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) +#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) +#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) +#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val) +#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) +#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) +#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) +#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) + +#else // NDEBUG + +#define DLOG(severity) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DVLOG(verboselevel) \ + (true || !VLOG_IS_ON(verboselevel)) ?\ + (void) 0 : google::LogMessageVoidify() & LOG(INFO) + +#define DLOG_IF(severity, condition) \ + (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_EVERY_N(severity, n) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_IF_EVERY_N(severity, condition, n) \ + (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_ASSERT(condition) \ + true ? (void) 0 : LOG_ASSERT(condition) + +#define DCHECK(condition) \ + while (false) \ + CHECK(condition) + +#define DCHECK_EQ(val1, val2) \ + while (false) \ + CHECK_EQ(val1, val2) + +#define DCHECK_NE(val1, val2) \ + while (false) \ + CHECK_NE(val1, val2) + +#define DCHECK_LE(val1, val2) \ + while (false) \ + CHECK_LE(val1, val2) + +#define DCHECK_LT(val1, val2) \ + while (false) \ + CHECK_LT(val1, val2) + +#define DCHECK_GE(val1, val2) \ + while (false) \ + CHECK_GE(val1, val2) + +#define DCHECK_GT(val1, val2) \ + while (false) \ + CHECK_GT(val1, val2) + +#define DCHECK_NOTNULL(val) (val) + +#define DCHECK_STREQ(str1, str2) \ + while (false) \ + CHECK_STREQ(str1, str2) + +#define DCHECK_STRCASEEQ(str1, str2) \ + while (false) \ + CHECK_STRCASEEQ(str1, str2) + +#define DCHECK_STRNE(str1, str2) \ + while (false) \ + CHECK_STRNE(str1, str2) + +#define DCHECK_STRCASENE(str1, str2) \ + while (false) \ + CHECK_STRCASENE(str1, str2) + + +#endif // NDEBUG + +// Log only in verbose mode. + +#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) + +#define VLOG_IF(verboselevel, condition) \ + LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) + +#define VLOG_EVERY_N(verboselevel, n) \ + LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) + +#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ + LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) + +// +// This class more or less represents a particular log message. You +// create an instance of LogMessage and then stream stuff to it. +// When you finish streaming to it, ~LogMessage is called and the +// full message gets streamed to the appropriate destination. +// +// You shouldn't actually use LogMessage's constructor to log things, +// though. You should use the LOG() macro (and variants thereof) +// above. +class GOOGLE_GLOG_DLL_DECL LogMessage { +public: + enum { + // Passing kNoLogPrefix for the line number disables the + // log-message prefix. Useful for using the LogMessage + // infrastructure as a printing utility. See also the --log_prefix + // flag for controlling the log-message prefix on an + // application-wide basis. + kNoLogPrefix = -1 + }; + + // LogStream inherit from non-DLL-exported class (std::ostrstream) + // and VC++ produces a warning for this situation. + // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ + // 2005 if you are deriving from a type in the Standard C++ Library" + // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx + // Let's just ignore the warning. +#ifdef _MSC_VER +# pragma warning(disable: 4275) +#endif + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { +#ifdef _MSC_VER +# pragma warning(default: 4275) +#endif + public: + LogStream(char *buf, int len, int ctr) + : ostrstream(buf, len), + ctr_(ctr) { + self_ = this; + } + + int ctr() const { return ctr_; } + void set_ctr(int ctr) { ctr_ = ctr; } + LogStream* self() const { return self_; } + + private: + int ctr_; // Counter hack (for the LOG_EVERY_X() macro) + LogStream *self_; // Consistency check hack + }; + +public: + // icc 8 requires this typedef to avoid an internal compiler error. + typedef void (LogMessage::*SendMethod)(); + + LogMessage(const char* file, int line, LogSeverity severity, int ctr, + SendMethod send_method); + + // Two special constructors that generate reduced amounts of code at + // LOG call sites for common cases. + + // Used for LOG(INFO): Implied are: + // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. + // + // Using this constructor instead of the more complex constructor above + // saves 19 bytes per call site. + LogMessage(const char* file, int line); + + // Used for LOG(severity) where severity != INFO. Implied + // are: ctr = 0, send_method = &LogMessage::SendToLog + // + // Using this constructor instead of the more complex constructor above + // saves 17 bytes per call site. + LogMessage(const char* file, int line, LogSeverity severity); + + // Constructor to log this message to a specified sink (if not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if + // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. + LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, + bool also_send_to_log); + + // Constructor where we also give a vector pointer + // for storing the messages (if the pointer is not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. + LogMessage(const char* file, int line, LogSeverity severity, + std::vector* outvec); + + // Constructor where we also give a string pointer for storing the + // message (if the pointer is not NULL). Implied are: ctr = 0, + // send_method = &LogMessage::WriteToStringAndLog. + LogMessage(const char* file, int line, LogSeverity severity, + std::string* message); + + // A special constructor used for check failures + LogMessage(const char* file, int line, const CheckOpString& result); + + ~LogMessage(); + + // Flush a buffered message to the sink set in the constructor. Always + // called by the destructor, it may also be called from elsewhere if + // needed. Only the first call is actioned; any later ones are ignored. + void Flush(); + + // An arbitrary limit on the length of a single log message. This + // is so that streaming can be done more efficiently. + static const size_t kMaxLogMessageLen; + + // Theses should not be called directly outside of logging.*, + // only passed as SendMethod arguments to other LogMessage methods: + void SendToLog(); // Actually dispatch to the logs + void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs + + // Call abort() or similar to perform LOG(FATAL) crash. + static void Fail() __attribute__ ((noreturn)); + + std::ostream& stream() { return *(data_->stream_); } + + int preserved_errno() const { return data_->preserved_errno_; } + + // Must be called without the log_mutex held. (L < log_mutex) + static int64 num_messages(int severity); + +private: + // Fully internal SendMethod cases: + void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs + void SendToSink(); // Send to sink if provided, do nothing otherwise. + + // Write to string if provided and dispatch to the logs. + void WriteToStringAndLog(); + + void SaveOrSendToLog(); // Save to stringvec if provided, else to logs + + void Init(const char* file, int line, LogSeverity severity, + void (LogMessage::*send_method)()); + + // Used to fill in crash information during LOG(FATAL) failures. + void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); + + // Counts of messages sent at each priority: + static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex + + // We keep the data in a separate struct so that each instance of + // LogMessage uses less stack space. + struct GOOGLE_GLOG_DLL_DECL LogMessageData { + LogMessageData() {}; + + int preserved_errno_; // preserved errno + char* buf_; + char* message_text_; // Complete message text (points to selected buffer) + LogStream* stream_alloc_; + LogStream* stream_; + char severity_; // What level is this LogMessage logged at? + int line_; // line number where logging call is. + void (LogMessage::*send_method_)(); // Call this in destructor to send + union { // At most one of these is used: union to keep the size low. + LogSink* sink_; // NULL or sink to send message to + std::vector* outvec_; // NULL or vector to push message onto + std::string* message_; // NULL or string to write message into + }; + time_t timestamp_; // Time of creation of LogMessage + struct ::tm tm_time_; // Time of creation of LogMessage + size_t num_prefix_chars_; // # of chars of prefix in this message + size_t num_chars_to_log_; // # of chars of msg to send to log + size_t num_chars_to_syslog_; // # of chars of msg to send to syslog + const char* basename_; // basename of file that called LOG + const char* fullname_; // fullname of file that called LOG + bool has_been_flushed_; // false => data has not been flushed + bool first_fatal_; // true => this was first fatal msg + + ~LogMessageData(); + private: + LogMessageData(const LogMessageData&); + void operator=(const LogMessageData&); + }; + + static LogMessageData fatal_msg_data_exclusive_; + static LogMessageData fatal_msg_data_shared_; + + LogMessageData* allocated_; + LogMessageData* data_; + + friend class LogDestination; + + LogMessage(const LogMessage&); + void operator=(const LogMessage&); +}; + +// This class happens to be thread-hostile because all instances share +// a single data buffer, but since it can only be created just before +// the process dies, we don't worry so much. +class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { + public: + LogMessageFatal(const char* file, int line); + LogMessageFatal(const char* file, int line, const CheckOpString& result); + ~LogMessageFatal() __attribute__ ((noreturn)); +}; + +// A non-macro interface to the log facility; (useful +// when the logging level is not a compile-time constant). +inline void LogAtLevel(int const severity, std::string const &msg) { + LogMessage(__FILE__, __LINE__, severity).stream() << msg; +} + +// A macro alternative of LogAtLevel. New code may want to use this +// version since there are two advantages: 1. this version outputs the +// file name and the line number where this macro is put like other +// LOG macros, 2. this macro can be used as C++ stream. +#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream() + +// A small helper for CHECK_NOTNULL(). +template +T* CheckNotNull(const char *file, int line, const char *names, T* t) { + if (t == NULL) { + LogMessageFatal(file, line, new std::string(names)); + } + return t; +} + +// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This +// only works if ostream is a LogStream. If the ostream is not a +// LogStream you'll get an assert saying as much at runtime. +GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, + const PRIVATE_Counter&); + + +// Derived class for PLOG*() above. +class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { + public: + + ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, + void (LogMessage::*send_method)()); + + // Postpends ": strerror(errno) [errno]". + ~ErrnoLogMessage(); + + private: + ErrnoLogMessage(const ErrnoLogMessage&); + void operator=(const ErrnoLogMessage&); +}; + + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". + +class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { + public: + LogMessageVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(std::ostream&) { } +}; + + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-safe. +GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-hostile because it ignores +// locking -- used for catastrophic failures. +GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); + +// +// Set the destination to which a particular severity level of log +// messages is sent. If base_filename is "", it means "don't log this +// severity". Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, + const char* base_filename); + +// +// Set the basename of the symlink to the latest log file at a given +// severity. If symlink_basename is empty, do not make a symlink. If +// you don't call this function, the symlink basename is the +// invocation name of the program. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); + +// +// Used to send logs to some other kind of destination +// Users should subclass LogSink and override send to do whatever they want. +// Implementations must be thread-safe because a shared instance will +// be called from whichever thread ran the LOG(XXX) line. +class GOOGLE_GLOG_DLL_DECL LogSink { + public: + virtual ~LogSink(); + + // Sink's logging logic (message_len is such as to exclude '\n' at the end). + // This method can't use LOG() or CHECK() as logging system mutex(s) are held + // during this call. + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) = 0; + + // Redefine this to implement waiting for + // the sink's logging logic to complete. + // It will be called after each send() returns, + // but before that LogMessage exits or crashes. + // By default this function does nothing. + // Using this function one can implement complex logic for send() + // that itself involves logging; and do all this w/o causing deadlocks and + // inconsistent rearrangement of log messages. + // E.g. if a LogSink has thread-specific actions, the send() method + // can simply add the message to a queue and wake up another thread that + // handles real logging while itself making some LOG() calls; + // WaitTillSent() can be implemented to wait for that logic to complete. + // See our unittest for an example. + virtual void WaitTillSent(); + + // Returns the normal text output of the log message. + // Can be useful to implement send(). + static std::string ToString(LogSeverity severity, const char* file, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len); +}; + +// Add or remove a LogSink as a consumer of logging data. Thread-safe. +GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); +GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); + +// +// Specify an "extension" added to the filename specified via +// SetLogDestination. This applies to all severity levels. It's +// often used to append the port we're listening on to the logfile +// name. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( + const char* filename_extension); + +// +// Make it so that all log messages of at least a particular severity +// are logged to stderr (in addition to logging to the usual log +// file(s)). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); + +// +// Make it so that all log messages go only to stderr. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void LogToStderr(); + +// +// Make it so that all log messages of at least a particular severity are +// logged via email to a list of addresses (in addition to logging to the +// usual log file(s)). The list of addresses is just a string containing +// the email addresses to send to (separated by spaces, say). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, + const char* addresses); + +// A simple function that sends email. dest is a commma-separated +// list of addressess. Thread-safe. +GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, + const char *subject, const char *body); + +GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); + +// For tests only: Clear the internal [cached] list of logging directories to +// force a refresh the next time GetLoggingDirectories is called. +// Thread-hostile. +void TestOnly_ClearLoggingDirectoriesList(); + +// Returns a set of existing temporary directories, which will be a +// subset of the directories returned by GetLogginDirectories(). +// Thread-safe. +GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( + std::vector* list); + +// Print any fatal message again -- useful to call from signal handler +// so that the last thing in the output is the fatal message. +// Thread-hostile, but a race is unlikely. +GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); + +// Truncate a log file that may be the append-only output of multiple +// processes and hence can't simply be renamed/reopened (typically a +// stdout/stderr). If the file "path" is > "limit" bytes, copy the +// last "keep" bytes to offset 0 and truncate the rest. Since we could +// be racing with other writers, this approach has the potential to +// lose very small amounts of data. For security, only follow symlinks +// if the path is /proc/self/fd/* +GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, + int64 limit, int64 keep); + +// Truncate stdout and stderr if they are over the value specified by +// --max_log_size; keep the final 1MB. This function has the same +// race condition as TruncateLogFile. +GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); + +// Return the string representation of the provided LogSeverity level. +// Thread-safe. +GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); + +// --------------------------------------------------------------------- +// Implementation details that are not useful to most clients +// --------------------------------------------------------------------- + +// A Logger is the interface used by logging modules to emit entries +// to a log. A typical implementation will dump formatted data to a +// sequence of files. We also provide interfaces that will forward +// the data to another thread so that the invoker never blocks. +// Implementations should be thread-safe since the logging system +// will write to them from multiple threads. + +namespace base { + +class GOOGLE_GLOG_DLL_DECL Logger { + public: + virtual ~Logger(); + + // Writes "message[0,message_len-1]" corresponding to an event that + // occurred at "timestamp". If "force_flush" is true, the log file + // is flushed immediately. + // + // The input message has already been formatted as deemed + // appropriate by the higher level logging facility. For example, + // textual log messages already contain timestamps, and the + // file:linenumber header. + virtual void Write(bool force_flush, + time_t timestamp, + const char* message, + int message_len) = 0; + + // Flush any buffered messages + virtual void Flush() = 0; + + // Get the current LOG file size. + // The returned value is approximate since some + // logged data may not have been flushed to disk yet. + virtual uint32 LogSize() = 0; +}; + +// Get the logger for the specified severity level. The logger +// remains the property of the logging module and should not be +// deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); + +// Set the logger for the specified severity level. The logger +// becomes the property of the logging module and should not +// be deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); + +} + +// glibc has traditionally implemented two incompatible versions of +// strerror_r(). There is a poorly defined convention for picking the +// version that we want, but it is not clear whether it even works with +// all versions of glibc. +// So, instead, we provide this wrapper that automatically detects the +// version that is in use, and then implements POSIX semantics. +// N.B. In addition to what POSIX says, we also guarantee that "buf" will +// be set to an empty string, if this function failed. This means, in most +// cases, you do not need to check the error code and you can directly +// use the value of "buf". It will never have an undefined value. +GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); + + +// A class for which we define operator<<, which does nothing. +class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { + public: + // Initialize the LogStream so the messages can be written somewhere + // (they'll never be actually displayed). This will be needed if a + // NullStream& is implicitly converted to LogStream&, in which case + // the overloaded NullStream::operator<< will not be invoked. + NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } + NullStream(const char* /*file*/, int /*line*/, + const CheckOpString& /*result*/) : + LogMessage::LogStream(message_buffer_, 1, 0) { } + NullStream &stream() { return *this; } + private: + // A very short buffer for messages (which we discard anyway). This + // will be needed if NullStream& converted to LogStream& (e.g. as a + // result of a conditional expression). + char message_buffer_[2]; +}; + +// Do nothing. This operator is inline, allowing the message to be +// compiled away. The message will not be compiled away if we do +// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when +// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly +// converted to LogStream and the message will be computed and then +// quietly discarded. +template +inline NullStream& operator<<(NullStream &str, const T &value) { return str; } + +// Similar to NullStream, but aborts the program (without stack +// trace), like LogMessageFatal. +class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { + public: + NullStreamFatal() { } + NullStreamFatal(const char* file, int line, const CheckOpString& result) : + NullStream(file, line, result) { } + __attribute__ ((noreturn)) ~NullStreamFatal() { _exit(1); } +}; + +// Install a signal handler that will dump signal information and a stack +// trace when the program crashes on certain signals. We'll install the +// signal handler for the following signals. +// +// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. +// +// By default, the signal handler will write the failure dump to the +// standard error. You can customize the destination by installing your +// own writer function by InstallFailureWriter() below. +// +// Note on threading: +// +// The function should be called before threads are created, if you want +// to use the failure signal handler for all threads. The stack trace +// will be shown only for the thread that receives the signal. In other +// words, stack traces of other threads won't be shown. +GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); + +// Installs a function that is used for writing the failure dump. "data" +// is the pointer to the beginning of a message to be written, and "size" +// is the size of the message. You should not expect the data is +// terminated with '\0'. +GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( + void (*writer)(const char* data, int size)); + +} + +#endif // _LOGGING_H_ diff --git a/extern/libmv/third_party/glog/src/glog/raw_logging.h b/extern/libmv/third_party/glog/src/glog/raw_logging.h new file mode 100644 index 00000000000..9e9b3772f3b --- /dev/null +++ b/extern/libmv/third_party/glog/src/glog/raw_logging.h @@ -0,0 +1,185 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Maxim Lifantsev +// +// Thread-safe logging routines that do not allocate any memory or +// acquire any locks, and can therefore be used by low-level memory +// allocation and synchronization code. + +#ifndef BASE_RAW_LOGGING_H_ +#define BASE_RAW_LOGGING_H_ + +#include + +namespace google { + +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// This is similar to LOG(severity) << format... and VLOG(level) << format.., +// but +// * it is to be used ONLY by low-level modules that can't use normal LOG() +// * it is desiged to be a low-level logger that does not allocate any +// memory and does not need any locks, hence: +// * it logs straight and ONLY to STDERR w/o buffering +// * it uses an explicit format and arguments list +// * it will silently chop off really long message strings +// Usage example: +// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); +// RAW_VLOG(3, "status is %i", status); +// These will print an almost standard log lines like this to stderr only: +// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file +// I0821 211317 file.cc:142] RAW: status is 20 +#define RAW_LOG(severity, ...) \ + do { \ + switch (google::severity) { \ + case 0: \ + RAW_LOG_INFO(__VA_ARGS__); \ + break; \ + case 1: \ + RAW_LOG_WARNING(__VA_ARGS__); \ + break; \ + case 2: \ + RAW_LOG_ERROR(__VA_ARGS__); \ + break; \ + case 3: \ + RAW_LOG_FATAL(__VA_ARGS__); \ + break; \ + default: \ + break; \ + } \ + } while (0) + +// The following STRIP_LOG testing is performed in the header file so that it's +// possible to completely compile out the logging code and the log messages. +#if STRIP_LOG == 0 +#define RAW_VLOG(verboselevel, ...) \ + do { \ + if (VLOG_IS_ON(verboselevel)) { \ + RAW_LOG_INFO(__VA_ARGS__); \ + } \ + } while (0) +#else +#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG == 0 + +#if STRIP_LOG == 0 +#define RAW_LOG_INFO(...) google::RawLog__(google::INFO, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG == 0 + +#if STRIP_LOG <= 1 +#define RAW_LOG_WARNING(...) google::RawLog__(google::WARNING, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG <= 1 + +#if STRIP_LOG <= 2 +#define RAW_LOG_ERROR(...) google::RawLog__(google::ERROR, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG <= 2 + +#if STRIP_LOG <= 3 +#define RAW_LOG_FATAL(...) google::RawLog__(google::FATAL, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_FATAL(...) \ + do { \ + google::RawLogStub__(0, __VA_ARGS__); \ + exit(1); \ + } while (0) +#endif // STRIP_LOG <= 3 + +// Similar to CHECK(condition) << message, +// but for low-level modules: we use only RAW_LOG that does not allocate memory. +// We do not want to provide args list here to encourage this usage: +// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); +// so that the args are not computed when not needed. +#define RAW_CHECK(condition, message) \ + do { \ + if (!(condition)) { \ + RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ + } \ + } while (0) + +// Debug versions of RAW_LOG and RAW_CHECK +#ifndef NDEBUG + +#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) + +#else // NDEBUG + +#define RAW_DLOG(severity, ...) \ + while (false) \ + RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) \ + while (false) \ + RAW_CHECK(condition, message) + +#endif // NDEBUG + +// Stub log function used to work around for unused variable warnings when +// building with STRIP_LOG > 0. +static inline void RawLogStub__(int ignored, ...) { +} + +// Helper function to implement RAW_LOG and RAW_VLOG +// Logs format... at "severity" level, reporting it +// as called from file:line. +// This does not allocate memory or acquire locks. +GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, + const char* file, + int line, + const char* format, ...) + __attribute__((__format__ (__printf__, 4, 5))); + +// Hack to propagate time information into this module so that +// this module does not have to directly call localtime_r(), +// which could allocate memory. +GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs); + +} + +#endif // BASE_RAW_LOGGING_H_ diff --git a/extern/libmv/third_party/glog/src/glog/vlog_is_on.h b/extern/libmv/third_party/glog/src/glog/vlog_is_on.h new file mode 100644 index 00000000000..02b0b867097 --- /dev/null +++ b/extern/libmv/third_party/glog/src/glog/vlog_is_on.h @@ -0,0 +1,129 @@ +// Copyright (c) 1999, 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Ray Sidney and many others +// +// Defines the VLOG_IS_ON macro that controls the variable-verbosity +// conditional logging. +// +// It's used by VLOG and VLOG_IF in logging.h +// and by RAW_VLOG in raw_logging.h to trigger the logging. +// +// It can also be used directly e.g. like this: +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished e.g. via just VLOG(2) << ...; +// } +// +// The truth value that VLOG_IS_ON(level) returns is determined by +// the three verbosity level flags: +// --v= Gives the default maximal active V-logging level; +// 0 is the default. +// Normally positive values are used for V-logging levels. +// --vmodule= Gives the per-module maximal V-logging levels to override +// the value given by --v. +// E.g. "my_module=2,foo*=3" would change the logging level +// for all code in source files "my_module.*" and "foo*.*" +// ("-inl" suffixes are also disregarded for this matching). +// +// SetVLOGLevel helper function is provided to do limited dynamic control over +// V-logging by overriding the per-module settings given via --vmodule flag. +// +// CAVEAT: --vmodule functionality is not available in non gcc compilers. +// + +#ifndef BASE_VLOG_IS_ON_H_ +#define BASE_VLOG_IS_ON_H_ + +#include "glog/log_severity.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +#if defined(__GNUC__) +// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. +// (Normally) the first time every VLOG_IS_ON(n) site is hit, +// we determine what variable will dynamically control logging at this site: +// it's either FLAGS_v or an appropriate internal variable +// matching the current source file that represents results of +// parsing of --vmodule flag and/or SetVLOGLevel calls. +#define VLOG_IS_ON(verboselevel) \ + __extension__ \ + ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ + google::int32 verbose_level__ = (verboselevel); \ + (*vlocal__ >= verbose_level__) && \ + ((vlocal__ != &google::kLogSiteUninitialized) || \ + (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ + __FILE__, verbose_level__))); }) +#else +// GNU extensions not available, so we do not support --vmodule. +// Dynamic value of FLAGS_v always controls the logging level. +#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) +#endif + +// Set VLOG(_IS_ON) level for module_pattern to log_level. +// This lets us dynamically control what is normally set by the --vmodule flag. +// Returns the level that previously applied to module_pattern. +// NOTE: To change the log level for VLOG(_IS_ON) sites +// that have already executed after/during InitGoogleLogging, +// one needs to supply the exact --vmodule pattern that applied to them. +// (If no --vmodule pattern applied to them +// the value of FLAGS_v will continue to control them.) +extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, + int log_level); + +// Various declarations needed for VLOG_IS_ON above: ========================= + +// Special value used to indicate that a VLOG_IS_ON site has not been +// initialized. We make this a large value, so the common-case check +// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition +// passes in such cases and InitVLOG3__ is then triggered. +extern google::int32 kLogSiteUninitialized; + +// Helper routine which determines the logging info for a particalur VLOG site. +// site_flag is the address of the site-local pointer to the controlling +// verbosity level +// site_default is the default to use for *site_flag +// fname is the current source file name +// verbose_level is the argument to VLOG_IS_ON +// We will return the return value for VLOG_IS_ON +// and if possible set *site_flag appropriately. +extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( + google::int32** site_flag, + google::int32* site_default, + const char* fname, + google::int32 verbose_level); + +#endif // BASE_VLOG_IS_ON_H_ diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc new file mode 100644 index 00000000000..1bb3867aa10 --- /dev/null +++ b/extern/libmv/third_party/glog/src/logging.cc @@ -0,0 +1,1783 @@ +// Copyright (c) 1999, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite() + +#include "utilities.h" + +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include // For _exit. +#endif +#include +#include +#include +#ifdef HAVE_SYS_UTSNAME_H +# include // For uname. +#endif +#include +#include +#include +#include +#include +#ifdef HAVE_PWD_H +# include +#endif +#ifdef HAVE_SYSLOG_H +# include +#endif +#include +#include // for errno +#include +#include "base/commandlineflags.h" // to get the program name +#include +#include +#include "base/googleinit.h" + +#ifdef HAVE_STACKTRACE +# include "stacktrace.h" +#endif + +using std::string; +using std::vector; +using std::ostrstream; +using std::setw; +using std::setfill; +using std::hex; +using std::dec; +using std::min; +using std::ostream; +using std::ostringstream; +using std::strstream; + +// There is no thread annotation support. +#define EXCLUSIVE_LOCKS_REQUIRED(mu) + +static bool BoolFromEnv(const char *varname, bool defval) { + const char* const valstr = getenv(varname); + if (!valstr) { + return defval; + } + return memchr("tTyY1\0", valstr[0], 6) != NULL; +} + +GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), + "log messages go to stderr instead of logfiles"); +GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), + "log messages go to stderr in addition to logfiles"); +#ifdef OS_LINUX +GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " + "Logs can grow very quickly and they are rarely read before they " + "need to be evicted from memory. Instead, drop them from memory " + "as soon as they are flushed to disk."); +_START_GOOGLE_NAMESPACE_ +namespace logging { +static const int64 kPageSize = getpagesize(); +} +_END_GOOGLE_NAMESPACE_ +#endif + +// By default, errors (including fatal errors) get logged to stderr as +// well as the file. +// +// The default is ERROR instead of FATAL so that users can see problems +// when they run a program without having to look in another file. +DEFINE_int32(stderrthreshold, + GOOGLE_NAMESPACE::ERROR, + "log messages at or above this level are copied to stderr in " + "addition to logfiles. This flag obsoletes --alsologtostderr."); + +GLOG_DEFINE_string(alsologtoemail, "", + "log messages go to these email addresses " + "in addition to logfiles"); +GLOG_DEFINE_bool(log_prefix, true, + "Prepend the log prefix to the start of each log line"); +GLOG_DEFINE_int32(minloglevel, 0, "Messages logged at a lower level than this don't " + "actually get logged anywhere"); +GLOG_DEFINE_int32(logbuflevel, 0, + "Buffer log messages logged at this level or lower" + " (-1 means don't buffer; 0 means buffer INFO only;" + " ...)"); +GLOG_DEFINE_int32(logbufsecs, 30, + "Buffer log messages for at most this many seconds"); +GLOG_DEFINE_int32(logemaillevel, 999, + "Email log messages logged at this level or higher" + " (0 means email all; 3 means email FATAL only;" + " ...)"); +GLOG_DEFINE_string(logmailer, "/bin/mail", + "Mailer used to send logging email"); + +// Compute the default value for --log_dir +static const char* DefaultLogDir() { + const char* env; + env = getenv("GOOGLE_LOG_DIR"); + if (env != NULL && env[0] != '\0') { + return env; + } + env = getenv("TEST_TMPDIR"); + if (env != NULL && env[0] != '\0') { + return env; + } + return ""; +} + +GLOG_DEFINE_string(log_dir, DefaultLogDir(), + "If specified, logfiles are written into this directory instead " + "of the default logging directory."); +GLOG_DEFINE_string(log_link, "", "Put additional links to the log " + "files in this directory"); + +GLOG_DEFINE_int32(max_log_size, 1800, + "approx. maximum log file size (in MB). A value of 0 will " + "be silently overridden to 1."); + +GLOG_DEFINE_bool(stop_logging_if_full_disk, false, + "Stop attempting to log to disk if the disk is full."); + +GLOG_DEFINE_string(log_backtrace_at, "", + "Emit a backtrace when logging at file:linenum."); + +// TODO(hamaji): consider windows +#define PATH_SEPARATOR '/' + +static void GetHostName(string* hostname) { +#if defined(HAVE_SYS_UTSNAME_H) + struct utsname buf; + if (0 != uname(&buf)) { + // ensure null termination on failure + *buf.nodename = '\0'; + } + *hostname = buf.nodename; +#elif defined(OS_WINDOWS) + char buf[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD len = MAX_COMPUTERNAME_LENGTH + 1; + if (GetComputerNameA(buf, &len)) { + *hostname = buf; + } else { + hostname->clear(); + } +#else +# warning There is no way to retrieve the host name. + *hostname = "(unknown)"; +#endif +} + +_START_GOOGLE_NAMESPACE_ + +// Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 +static int32 MaxLogSize() { + return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); +} + +// A mutex that allows only one thread to log at a time, to keep things from +// getting jumbled. Some other very uncommon logging operations (like +// changing the destination file for log messages of a given severity) also +// lock this mutex. Please be sure that anybody who might possibly need to +// lock it does so. +static Mutex log_mutex; + +// Number of messages sent at each severity. Under log_mutex. +int64 LogMessage::num_messages_[NUM_SEVERITIES] = {0, 0, 0, 0}; + +// Globally disable log writing (if disk is full) +static bool stop_writing = false; + +const char*const LogSeverityNames[NUM_SEVERITIES] = { + "INFO", "WARNING", "ERROR", "FATAL" +}; + +// Has the user called SetExitOnDFatal(true)? +static bool exit_on_dfatal = true; + +const char* GetLogSeverityName(LogSeverity severity) { + return LogSeverityNames[severity]; +} + +static bool SendEmailInternal(const char*dest, const char *subject, + const char*body, bool use_logging); + +base::Logger::~Logger() { +} + +namespace { + +// Encapsulates all file-system related state +class LogFileObject : public base::Logger { + public: + LogFileObject(LogSeverity severity, const char* base_filename); + ~LogFileObject(); + + virtual void Write(bool force_flush, // Should we force a flush here? + time_t timestamp, // Timestamp for this entry + const char* message, + int message_len); + + // Configuration options + void SetBasename(const char* basename); + void SetExtension(const char* ext); + void SetSymlinkBasename(const char* symlink_basename); + + // Normal flushing routine + virtual void Flush(); + + // It is the actual file length for the system loggers, + // i.e., INFO, ERROR, etc. + virtual uint32 LogSize() { + MutexLock l(&lock_); + return file_length_; + } + + // Internal flush routine. Exposed so that FlushLogFilesUnsafe() + // can avoid grabbing a lock. Usually Flush() calls it after + // acquiring lock_. + void FlushUnlocked(); + + private: + static const uint32 kRolloverAttemptFrequency = 0x20; + + Mutex lock_; + bool base_filename_selected_; + string base_filename_; + string symlink_basename_; + string filename_extension_; // option users can specify (eg to add port#) + FILE* file_; + LogSeverity severity_; + uint32 bytes_since_flush_; + uint32 file_length_; + unsigned int rollover_attempt_; + int64 next_flush_time_; // cycle count at which to flush log + + // Actually create a logfile using the value of base_filename_ and the + // supplied argument time_pid_string + // REQUIRES: lock_ is held + bool CreateLogfile(const char* time_pid_string); +}; + +} // namespace + +class LogDestination { + public: + friend class LogMessage; + friend void ReprintFatalMessage(); + friend base::Logger* base::GetLogger(LogSeverity); + friend void base::SetLogger(LogSeverity, base::Logger*); + + // These methods are just forwarded to by their global versions. + static void SetLogDestination(LogSeverity severity, + const char* base_filename); + static void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); + static void AddLogSink(LogSink *destination); + static void RemoveLogSink(LogSink *destination); + static void SetLogFilenameExtension(const char* filename_extension); + static void SetStderrLogging(LogSeverity min_severity); + static void SetEmailLogging(LogSeverity min_severity, const char* addresses); + static void LogToStderr(); + // Flush all log files that are at least at the given severity level + static void FlushLogFiles(int min_severity); + static void FlushLogFilesUnsafe(int min_severity); + + // we set the maximum size of our packet to be 1400, the logic being + // to prevent fragmentation. + // Really this number is arbitrary. + static const int kNetworkBytes = 1400; + + static const string& hostname(); + private: + + LogDestination(LogSeverity severity, const char* base_filename); + ~LogDestination() { } + + // Take a log message of a particular severity and log it to stderr + // iff it's of a high enough severity to deserve it. + static void MaybeLogToStderr(LogSeverity severity, const char* message, + size_t len); + + // Take a log message of a particular severity and log it to email + // iff it's of a high enough severity to deserve it. + static void MaybeLogToEmail(LogSeverity severity, const char* message, + size_t len); + // Take a log message of a particular severity and log it to a file + // iff the base filename is not "" (which means "don't log to me") + static void MaybeLogToLogfile(LogSeverity severity, + time_t timestamp, + const char* message, size_t len); + // Take a log message of a particular severity and log it to the file + // for that severity and also for all files with severity less than + // this severity. + static void LogToAllLogfiles(LogSeverity severity, + time_t timestamp, + const char* message, size_t len); + + // Send logging info to all registered sinks. + static void LogToSinks(LogSeverity severity, + const char *full_filename, + const char *base_filename, + int line, + const struct ::tm* tm_time, + const char* message, + size_t message_len); + + // Wait for all registered sinks via WaitTillSent + // including the optional one in "data". + static void WaitForSinks(LogMessage::LogMessageData* data); + + static LogDestination* log_destination(LogSeverity severity); + + LogFileObject fileobject_; + base::Logger* logger_; // Either &fileobject_, or wrapper around it + + static LogDestination* log_destinations_[NUM_SEVERITIES]; + static LogSeverity email_logging_severity_; + static string addresses_; + static string hostname_; + + // arbitrary global logging destinations. + static vector* sinks_; + + // Protects the vector sinks_, + // but not the LogSink objects its elements reference. + static Mutex sink_mutex_; + + // Disallow + LogDestination(const LogDestination&); + LogDestination& operator=(const LogDestination&); +}; + +// Errors do not get logged to email by default. +LogSeverity LogDestination::email_logging_severity_ = 99999; + +string LogDestination::addresses_; +string LogDestination::hostname_; + +vector* LogDestination::sinks_ = NULL; +Mutex LogDestination::sink_mutex_; + +/* static */ +const string& LogDestination::hostname() { + if (hostname_.empty()) { + GetHostName(&hostname_); + if (hostname_.empty()) { + hostname_ = "(unknown)"; + } + } + return hostname_; +} + +LogDestination::LogDestination(LogSeverity severity, + const char* base_filename) + : fileobject_(severity, base_filename), + logger_(&fileobject_) { +} + +inline void LogDestination::FlushLogFilesUnsafe(int min_severity) { + // assume we have the log_mutex or we simply don't care + // about it + for (int i = min_severity; i < NUM_SEVERITIES; i++) { + LogDestination* log = log_destination(i); + if (log != NULL) { + // Flush the base fileobject_ logger directly instead of going + // through any wrappers to reduce chance of deadlock. + log->fileobject_.FlushUnlocked(); + } + } +} + +inline void LogDestination::FlushLogFiles(int min_severity) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + for (int i = min_severity; i < NUM_SEVERITIES; i++) { + LogDestination* log = log_destination(i); + if (log != NULL) { + log->logger_->Flush(); + } + } +} + +inline void LogDestination::SetLogDestination(LogSeverity severity, + const char* base_filename) { + assert(severity >= 0 && severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + log_destination(severity)->fileobject_.SetBasename(base_filename); +} + +inline void LogDestination::SetLogSymlink(LogSeverity severity, + const char* symlink_basename) { + CHECK_GE(severity, 0); + CHECK_LT(severity, NUM_SEVERITIES); + MutexLock l(&log_mutex); + log_destination(severity)->fileobject_.SetSymlinkBasename(symlink_basename); +} + +inline void LogDestination::AddLogSink(LogSink *destination) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&sink_mutex_); + if (!sinks_) sinks_ = new vector; + sinks_->push_back(destination); +} + +inline void LogDestination::RemoveLogSink(LogSink *destination) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&sink_mutex_); + // This doesn't keep the sinks in order, but who cares? + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + if ((*sinks_)[i] == destination) { + (*sinks_)[i] = (*sinks_)[sinks_->size() - 1]; + sinks_->pop_back(); + break; + } + } + } +} + +inline void LogDestination::SetLogFilenameExtension(const char* ext) { + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + for ( int severity = 0; severity < NUM_SEVERITIES; ++severity ) { + log_destination(severity)->fileobject_.SetExtension(ext); + } +} + +inline void LogDestination::SetStderrLogging(LogSeverity min_severity) { + assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + FLAGS_stderrthreshold = min_severity; +} + +inline void LogDestination::LogToStderr() { + // *Don't* put this stuff in a mutex lock, since SetStderrLogging & + // SetLogDestination already do the locking! + SetStderrLogging(0); // thus everything is "also" logged to stderr + for ( int i = 0; i < NUM_SEVERITIES; ++i ) { + SetLogDestination(i, ""); // "" turns off logging to a logfile + } +} + +inline void LogDestination::SetEmailLogging(LogSeverity min_severity, + const char* addresses) { + assert(min_severity >= 0 && min_severity < NUM_SEVERITIES); + // Prevent any subtle race conditions by wrapping a mutex lock around + // all this stuff. + MutexLock l(&log_mutex); + LogDestination::email_logging_severity_ = min_severity; + LogDestination::addresses_ = addresses; +} + +static void WriteToStderr(const char* message, size_t len) { + // Avoid using cerr from this module since we may get called during + // exit code, and cerr may be partially or fully destroyed by then. + write(STDERR_FILENO, message, len); +} + +inline void LogDestination::MaybeLogToStderr(LogSeverity severity, + const char* message, size_t len) { + if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { + WriteToStderr(message, len); +#ifdef OS_WINDOWS + // On Windows, also output to the debugger + ::OutputDebugStringA(string(message,len).c_str()); +#endif + } +} + + +inline void LogDestination::MaybeLogToEmail(LogSeverity severity, + const char* message, size_t len) { + if (severity >= email_logging_severity_ || + severity >= FLAGS_logemaillevel) { + string to(FLAGS_alsologtoemail); + if (!addresses_.empty()) { + if (!to.empty()) { + to += ","; + } + to += addresses_; + } + const string subject(string("[LOG] ") + LogSeverityNames[severity] + ": " + + glog_internal_namespace_::ProgramInvocationShortName()); + string body(hostname()); + body += "\n\n"; + body.append(message, len); + + // should NOT use SendEmail(). The caller of this function holds the + // log_mutex and SendEmail() calls LOG/VLOG which will block trying to + // acquire the log_mutex object. Use SendEmailInternal() and set + // use_logging to false. + SendEmailInternal(to.c_str(), subject.c_str(), body.c_str(), false); + } +} + + +inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { + const bool should_flush = severity > FLAGS_logbuflevel; + LogDestination* destination = log_destination(severity); + destination->logger_->Write(should_flush, timestamp, message, len); +} + +inline void LogDestination::LogToAllLogfiles(LogSeverity severity, + time_t timestamp, + const char* message, + size_t len) { + + if ( FLAGS_logtostderr ) // global flag: never log to file + WriteToStderr(message, len); + else + for (int i = severity; i >= 0; --i) + LogDestination::MaybeLogToLogfile(i, timestamp, message, len); + +} + +inline void LogDestination::LogToSinks(LogSeverity severity, + const char *full_filename, + const char *base_filename, + int line, + const struct ::tm* tm_time, + const char* message, + size_t message_len) { + ReaderMutexLock l(&sink_mutex_); + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + (*sinks_)[i]->send(severity, full_filename, base_filename, + line, tm_time, message, message_len); + } + } +} + +inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) { + ReaderMutexLock l(&sink_mutex_); + if (sinks_) { + for (int i = sinks_->size() - 1; i >= 0; i--) { + (*sinks_)[i]->WaitTillSent(); + } + } + const bool send_to_sink = + (data->send_method_ == &LogMessage::SendToSink) || + (data->send_method_ == &LogMessage::SendToSinkAndLog); + if (send_to_sink && data->sink_ != NULL) { + data->sink_->WaitTillSent(); + } +} + +LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES]; + +inline LogDestination* LogDestination::log_destination(LogSeverity severity) { + assert(severity >=0 && severity < NUM_SEVERITIES); + if (!log_destinations_[severity]) { + log_destinations_[severity] = new LogDestination(severity, NULL); + } + return log_destinations_[severity]; +} + +namespace { + +LogFileObject::LogFileObject(LogSeverity severity, + const char* base_filename) + : base_filename_selected_(base_filename != NULL), + base_filename_((base_filename != NULL) ? base_filename : ""), + symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), + filename_extension_(), + file_(NULL), + severity_(severity), + bytes_since_flush_(0), + file_length_(0), + rollover_attempt_(kRolloverAttemptFrequency-1), + next_flush_time_(0) { + assert(severity >= 0); + assert(severity < NUM_SEVERITIES); +} + +LogFileObject::~LogFileObject() { + MutexLock l(&lock_); + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + } +} + +void LogFileObject::SetBasename(const char* basename) { + MutexLock l(&lock_); + base_filename_selected_ = true; + if (base_filename_ != basename) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + base_filename_ = basename; + } +} + +void LogFileObject::SetExtension(const char* ext) { + MutexLock l(&lock_); + if (filename_extension_ != ext) { + // Get rid of old log file since we are changing names + if (file_ != NULL) { + fclose(file_); + file_ = NULL; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + filename_extension_ = ext; + } +} + +void LogFileObject::SetSymlinkBasename(const char* symlink_basename) { + MutexLock l(&lock_); + symlink_basename_ = symlink_basename; +} + +void LogFileObject::Flush() { + MutexLock l(&lock_); + FlushUnlocked(); +} + +void LogFileObject::FlushUnlocked(){ + if (file_ != NULL) { + fflush(file_); + bytes_since_flush_ = 0; + } + // Figure out when we are due for another flush. + const int64 next = (FLAGS_logbufsecs + * static_cast(1000000)); // in usec + next_flush_time_ = CycleClock_Now() + UsecToCycles(next); +} + +bool LogFileObject::CreateLogfile(const char* time_pid_string) { + string string_filename = base_filename_+filename_extension_+ + time_pid_string; + const char* filename = string_filename.c_str(); + int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0664); + if (fd == -1) return false; +#ifdef HAVE_FCNTL + // Mark the file close-on-exec. We don't really care if this fails + fcntl(fd, F_SETFD, FD_CLOEXEC); +#endif + + file_ = fdopen(fd, "a"); // Make a FILE*. + if (file_ == NULL) { // Man, we're screwed! + close(fd); + unlink(filename); // Erase the half-baked evidence: an unusable log file + return false; + } + + // We try to create a symlink called ., + // which is easier to use. (Every time we create a new logfile, + // we destroy the old symlink and create a new one, so it always + // points to the latest logfile.) If it fails, we're sad but it's + // no error. + if (!symlink_basename_.empty()) { + // take directory from filename + const char* slash = strrchr(filename, PATH_SEPARATOR); + const string linkname = + symlink_basename_ + '.' + LogSeverityNames[severity_]; + string linkpath; + if ( slash ) linkpath = string(filename, slash-filename+1); // get dirname + linkpath += linkname; + unlink(linkpath.c_str()); // delete old one if it exists + + // We must have unistd.h. +#ifdef HAVE_UNISTD_H + // Make the symlink be relative (in the same dir) so that if the + // entire log directory gets relocated the link is still valid. + const char *linkdest = slash ? (slash + 1) : filename; + symlink(linkdest, linkpath.c_str()); // silently ignore failures + + // Make an additional link to the log file in a place specified by + // FLAGS_log_link, if indicated + if (!FLAGS_log_link.empty()) { + linkpath = FLAGS_log_link + "/" + linkname; + unlink(linkpath.c_str()); // delete old one if it exists + symlink(filename, linkpath.c_str()); // silently ignore failures + } +#endif + } + + return true; // Everything worked +} + +void LogFileObject::Write(bool force_flush, + time_t timestamp, + const char* message, + int message_len) { + MutexLock l(&lock_); + + // We don't log if the base_name_ is "" (which means "don't write") + if (base_filename_selected_ && base_filename_.empty()) { + return; + } + + if (static_cast(file_length_ >> 20) >= MaxLogSize()) { + if (file_ != NULL) fclose(file_); + file_ = NULL; + file_length_ = bytes_since_flush_ = 0; + rollover_attempt_ = kRolloverAttemptFrequency-1; + } + + // If there's no destination file, make one before outputting + if (file_ == NULL) { + // Try to rollover the log file every 32 log messages. The only time + // this could matter would be when we have trouble creating the log + // file. If that happens, we'll lose lots of log messages, of course! + if (++rollover_attempt_ != kRolloverAttemptFrequency) return; + rollover_attempt_ = 0; + + struct ::tm tm_time; + localtime_r(×tamp, &tm_time); + + // The logfile's filename will have the date/time & pid in it + char time_pid_string[256]; // More than enough chars for time, pid, \0 + ostrstream time_pid_stream(time_pid_string, sizeof(time_pid_string)); + time_pid_stream.fill('0'); + time_pid_stream << 1900+tm_time.tm_year + << setw(2) << 1+tm_time.tm_mon + << setw(2) << tm_time.tm_mday + << '-' + << setw(2) << tm_time.tm_hour + << setw(2) << tm_time.tm_min + << setw(2) << tm_time.tm_sec + << '.' + << GetMainThreadPid() + << '\0'; + + if (base_filename_selected_) { + if (!CreateLogfile(time_pid_string)) { + perror("Could not create log file"); + fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", time_pid_string); + return; + } + } else { + // If no base filename for logs of this severity has been set, use a + // default base filename of + // "...log..". So + // logfiles will have names like + // webserver.examplehost.root.log.INFO.19990817-150000.4354, where + // 19990817 is a date (1999 August 17), 150000 is a time (15:00:00), + // and 4354 is the pid of the logging process. The date & time reflect + // when the file was created for output. + // + // Where does the file get put? Successively try the directories + // "/tmp", and "." + string stripped_filename( + glog_internal_namespace_::ProgramInvocationShortName()); + string hostname; + GetHostName(&hostname); + + string uidname = MyUserName(); + // We should not call CHECK() here because this function can be + // called after holding on to log_mutex. We don't want to + // attempt to hold on to the same mutex, and get into a + // deadlock. Simply use a name like invalid-user. + if (uidname.empty()) uidname = "invalid-user"; + + stripped_filename = stripped_filename+'.'+hostname+'.' + +uidname+".log." + +LogSeverityNames[severity_]+'.'; + // We're going to (potentially) try to put logs in several different dirs + const vector & log_dirs = GetLoggingDirectories(); + + // Go through the list of dirs, and try to create the log file in each + // until we succeed or run out of options + bool success = false; + for (vector::const_iterator dir = log_dirs.begin(); + dir != log_dirs.end(); + ++dir) { + base_filename_ = *dir + "/" + stripped_filename; + if ( CreateLogfile(time_pid_string) ) { + success = true; + break; + } + } + // If we never succeeded, we have to give up + if ( success == false ) { + perror("Could not create logging file"); + fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", time_pid_string); + return; + } + } + + // Write a header message into the log file + char file_header_string[512]; // Enough chars for time and binary info + ostrstream file_header_stream(file_header_string, + sizeof(file_header_string)); + file_header_stream.fill('0'); + file_header_stream << "Log file created at: " + << 1900+tm_time.tm_year << '/' + << setw(2) << 1+tm_time.tm_mon << '/' + << setw(2) << tm_time.tm_mday + << ' ' + << setw(2) << tm_time.tm_hour << ':' + << setw(2) << tm_time.tm_min << ':' + << setw(2) << tm_time.tm_sec << '\n' + << "Running on machine: " + << LogDestination::hostname() << '\n' + << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " + << "threadid file:line] msg" << '\n' + << '\0'; + int header_len = strlen(file_header_string); + fwrite(file_header_string, 1, header_len, file_); + file_length_ += header_len; + bytes_since_flush_ += header_len; + } + + // Write to LOG file + if ( !stop_writing ) { + // fwrite() doesn't return an error when the disk is full, for + // messages that are less than 4096 bytes. When the disk is full, + // it returns the message length for messages that are less than + // 4096 bytes. fwrite() returns 4096 for message lengths that are + // greater than 4096, thereby indicating an error. + errno = 0; + fwrite(message, 1, message_len, file_); + if ( FLAGS_stop_logging_if_full_disk && + errno == ENOSPC ) { // disk full, stop writing to disk + stop_writing = true; // until the disk is + return; + } else { + file_length_ += message_len; + bytes_since_flush_ += message_len; + } + } else { + if ( CycleClock_Now() >= next_flush_time_ ) + stop_writing = false; // check to see if disk has free space. + return; // no need to flush + } + + // See important msgs *now*. Also, flush logs at least every 10^6 chars, + // or every "FLAGS_logbufsecs" seconds. + if ( force_flush || + (bytes_since_flush_ >= 1000000) || + (CycleClock_Now() >= next_flush_time_) ) { + FlushUnlocked(); +#ifdef OS_LINUX + if (FLAGS_drop_log_memory) { + if (file_length_ >= logging::kPageSize) { + // don't evict the most recent page + uint32 len = file_length_ & ~(logging::kPageSize - 1); + posix_fadvise(fileno(file_), 0, len, POSIX_FADV_DONTNEED); + } + } +#endif + } +} + +} // namespace + +// An arbitrary limit on the length of a single log message. This +// is so that streaming can be done more efficiently. +const size_t LogMessage::kMaxLogMessageLen = 30000; + +// Static log data space to avoid alloc failures in a LOG(FATAL) +// +// Since multiple threads may call LOG(FATAL), and we want to preserve +// the data from the first call, we allocate two sets of space. One +// for exclusive use by the first thread, and one for shared use by +// all other threads. +static Mutex fatal_msg_lock; +static CrashReason crash_reason; +static bool fatal_msg_exclusive = true; +static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1]; +static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1]; +static LogMessage::LogStream fatal_msg_stream_exclusive( + fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0); +static LogMessage::LogStream fatal_msg_stream_shared( + fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0); +LogMessage::LogMessageData LogMessage::fatal_msg_data_exclusive_; +LogMessage::LogMessageData LogMessage::fatal_msg_data_shared_; + +LogMessage::LogMessageData::~LogMessageData() { + delete[] buf_; + delete stream_alloc_; +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + int ctr, void (LogMessage::*send_method)()) { + Init(file, line, severity, send_method); + data_->stream_->set_ctr(ctr); +} + +LogMessage::LogMessage(const char* file, int line, + const CheckOpString& result) { + Init(file, line, FATAL, &LogMessage::SendToLog); + stream() << "Check failed: " << (*result.str_) << " "; +} + +LogMessage::LogMessage(const char* file, int line) { + Init(file, line, INFO, &LogMessage::SendToLog); +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity) { + Init(file, line, severity, &LogMessage::SendToLog); +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + LogSink* sink, bool also_send_to_log) { + Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : + &LogMessage::SendToSink); + data_->sink_ = sink; // override Init()'s setting to NULL +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + vector *outvec) { + Init(file, line, severity, &LogMessage::SaveOrSendToLog); + data_->outvec_ = outvec; // override Init()'s setting to NULL +} + +LogMessage::LogMessage(const char* file, int line, LogSeverity severity, + string *message) { + Init(file, line, severity, &LogMessage::WriteToStringAndLog); + data_->message_ = message; // override Init()'s setting to NULL +} + +void LogMessage::Init(const char* file, + int line, + LogSeverity severity, + void (LogMessage::*send_method)()) { + allocated_ = NULL; + if (severity != FATAL || !exit_on_dfatal) { + allocated_ = new LogMessageData(); + data_ = allocated_; + data_->buf_ = new char[kMaxLogMessageLen+1]; + data_->message_text_ = data_->buf_; + data_->stream_alloc_ = + new LogStream(data_->message_text_, kMaxLogMessageLen, 0); + data_->stream_ = data_->stream_alloc_; + data_->first_fatal_ = false; + } else { + MutexLock l(&fatal_msg_lock); + if (fatal_msg_exclusive) { + fatal_msg_exclusive = false; + data_ = &fatal_msg_data_exclusive_; + data_->message_text_ = fatal_msg_buf_exclusive; + data_->stream_ = &fatal_msg_stream_exclusive; + data_->first_fatal_ = true; + } else { + data_ = &fatal_msg_data_shared_; + data_->message_text_ = fatal_msg_buf_shared; + data_->stream_ = &fatal_msg_stream_shared; + data_->first_fatal_ = false; + } + data_->stream_alloc_ = NULL; + } + + stream().fill('0'); + data_->preserved_errno_ = errno; + data_->severity_ = severity; + data_->line_ = line; + data_->send_method_ = send_method; + data_->sink_ = NULL; + data_->outvec_ = NULL; + WallTime now = WallTime_Now(); + data_->timestamp_ = static_cast(now); + localtime_r(&data_->timestamp_, &data_->tm_time_); + int usecs = static_cast((now - data_->timestamp_) * 1000000); + RawLog__SetLastTime(data_->tm_time_, usecs); + + data_->num_chars_to_log_ = 0; + data_->num_chars_to_syslog_ = 0; + data_->basename_ = const_basename(file); + data_->fullname_ = file; + data_->has_been_flushed_ = false; + + // If specified, prepend a prefix to each line. For example: + // I1018 160715 f5d4fbb0 logging.cc:1153] + // (log level, GMT month, date, time, thread_id, file basename, line) + // We exclude the thread_id for the default thread. + if (FLAGS_log_prefix && (line != kNoLogPrefix)) { + stream() << LogSeverityNames[severity][0] + << setw(2) << 1+data_->tm_time_.tm_mon + << setw(2) << data_->tm_time_.tm_mday + << ' ' + << setw(2) << data_->tm_time_.tm_hour << ':' + << setw(2) << data_->tm_time_.tm_min << ':' + << setw(2) << data_->tm_time_.tm_sec << "." + << setw(6) << usecs + << ' ' + << setfill(' ') << setw(5) + << static_cast(GetTID()) << setfill('0') + << ' ' + << data_->basename_ << ':' << data_->line_ << "] "; + } + data_->num_prefix_chars_ = data_->stream_->pcount(); + + if (!FLAGS_log_backtrace_at.empty()) { + char fileline[128]; + snprintf(fileline, sizeof(fileline), "%s:%d", data_->basename_, line); +#ifdef HAVE_STACKTRACE + if (!strcmp(FLAGS_log_backtrace_at.c_str(), fileline)) { + string stacktrace; + DumpStackTraceToString(&stacktrace); + stream() << " (stacktrace:\n" << stacktrace << ") "; + } +#endif + } +} + +LogMessage::~LogMessage() { + Flush(); + delete allocated_; +} + +// Flush buffered message, called by the destructor, or any other function +// that needs to synchronize the log. +void LogMessage::Flush() { + if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) + return; + + data_->num_chars_to_log_ = data_->stream_->pcount(); + data_->num_chars_to_syslog_ = + data_->num_chars_to_log_ - data_->num_prefix_chars_; + + // Do we need to add a \n to the end of this message? + bool append_newline = + (data_->message_text_[data_->num_chars_to_log_-1] != '\n'); + char original_final_char = '\0'; + + // If we do need to add a \n, we'll do it by violating the memory of the + // ostrstream buffer. This is quick, and we'll make sure to undo our + // modification before anything else is done with the ostrstream. It + // would be preferable not to do things this way, but it seems to be + // the best way to deal with this. + if (append_newline) { + original_final_char = data_->message_text_[data_->num_chars_to_log_]; + data_->message_text_[data_->num_chars_to_log_++] = '\n'; + } + + // Prevent any subtle race conditions by wrapping a mutex lock around + // the actual logging action per se. + { + MutexLock l(&log_mutex); + (this->*(data_->send_method_))(); + ++num_messages_[static_cast(data_->severity_)]; + } + LogDestination::WaitForSinks(data_); + + if (append_newline) { + // Fix the ostrstream back how it was before we screwed with it. + // It's 99.44% certain that we don't need to worry about doing this. + data_->message_text_[data_->num_chars_to_log_-1] = original_final_char; + } + + // If errno was already set before we enter the logging call, we'll + // set it back to that value when we return from the logging call. + // It happens often that we log an error message after a syscall + // failure, which can potentially set the errno to some other + // values. We would like to preserve the original errno. + if (data_->preserved_errno_ != 0) { + errno = data_->preserved_errno_; + } + + // Note that this message is now safely logged. If we're asked to flush + // again, as a result of destruction, say, we'll do nothing on future calls. + data_->has_been_flushed_ = true; +} + +// Copy of first FATAL log message so that we can print it out again +// after all the stack traces. To preserve legacy behavior, we don't +// use fatal_msg_buf_exclusive. +static time_t fatal_time; +static char fatal_message[256]; + +void ReprintFatalMessage() { + if (fatal_message[0]) { + const int n = strlen(fatal_message); + if (!FLAGS_logtostderr) { + // Also write to stderr + WriteToStderr(fatal_message, n); + } + LogDestination::LogToAllLogfiles(ERROR, fatal_time, fatal_message, n); + } +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + static bool already_warned_before_initgoogle = false; + + log_mutex.AssertHeld(); + + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + + // Messages of a given severity get logged to lower severity logs, too + + if (!already_warned_before_initgoogle && !IsGoogleLoggingInitialized()) { + const char w[] = "WARNING: Logging before InitGoogleLogging() is " + "written to STDERR\n"; + WriteToStderr(w, strlen(w)); + already_warned_before_initgoogle = true; + } + + // global flag: never log to file if set. Also -- don't log to a + // file if we haven't parsed the command line flags to get the + // program name. + if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { + WriteToStderr(data_->message_text_, data_->num_chars_to_log_); + + // this could be protected by a flag if necessary. + LogDestination::LogToSinks(data_->severity_, + data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ - + data_->num_prefix_chars_ - 1)); + } else { + + // log this message to all log files of severity <= severity_ + LogDestination::LogToAllLogfiles(data_->severity_, data_->timestamp_, + data_->message_text_, + data_->num_chars_to_log_); + + LogDestination::MaybeLogToStderr(data_->severity_, data_->message_text_, + data_->num_chars_to_log_); + LogDestination::MaybeLogToEmail(data_->severity_, data_->message_text_, + data_->num_chars_to_log_); + LogDestination::LogToSinks(data_->severity_, + data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ + - data_->num_prefix_chars_ - 1)); + // NOTE: -1 removes trailing \n + } + + // If we log a FATAL message, flush all the log destinations, then toss + // a signal for others to catch. We leave the logs in a state that + // someone else can use them (as long as they flush afterwards) + if (data_->severity_ == FATAL && exit_on_dfatal) { + if (data_->first_fatal_) { + // Store crash information so that it is accessible from within signal + // handlers that may be invoked later. + RecordCrashReason(&crash_reason); + SetCrashReason(&crash_reason); + + // Store shortened fatal message for other logs and GWQ status + const int copy = min(data_->num_chars_to_log_, + sizeof(fatal_message)-1); + memcpy(fatal_message, data_->message_text_, copy); + fatal_message[copy] = '\0'; + fatal_time = data_->timestamp_; + } + + if (!FLAGS_logtostderr) { + for (int i = 0; i < NUM_SEVERITIES; ++i) { + if ( LogDestination::log_destinations_[i] ) + LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); + } + } + + // release the lock that our caller (directly or indirectly) + // LogMessage::~LogMessage() grabbed so that signal handlers + // can use the logging facility. Alternately, we could add + // an entire unsafe logging interface to bypass locking + // for signal handlers but this seems simpler. + log_mutex.Unlock(); + LogDestination::WaitForSinks(data_); + + const char* message = "*** Check failure stack trace: ***\n"; + write(STDERR_FILENO, message, strlen(message)); + Fail(); + } +} + +void LogMessage::RecordCrashReason( + glog_internal_namespace_::CrashReason* reason) { + reason->filename = fatal_msg_data_exclusive_.fullname_; + reason->line_number = fatal_msg_data_exclusive_.line_; + reason->message = fatal_msg_buf_exclusive + + fatal_msg_data_exclusive_.num_prefix_chars_; +#ifdef HAVE_STACKTRACE + // Retrieve the stack trace, omitting the logging frames that got us here. + reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); +#else + reason->depth = 0; +#endif +} + +static void logging_fail() { +// #if defined(_DEBUG) && defined(_MSC_VER) +// doesn't work for my laptop (sergey) +#if 0 + // When debugging on windows, avoid the obnoxious dialog and make + // it possible to continue past a LOG(FATAL) in the debugger + _asm int 3 +#else + abort(); +#endif +} + +#ifdef HAVE___ATTRIBUTE__ +GOOGLE_GLOG_DLL_DECL +void (*g_logging_fail_func)() __attribute__((noreturn)) = &logging_fail; +#else +GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)() = &logging_fail; +#endif + +void InstallFailureFunction(void (*fail_func)()) { + g_logging_fail_func = fail_func; +} + +void LogMessage::Fail() { + g_logging_fail_func(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->sink_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, + data_->line_, &data_->tm_time_, + data_->message_text_ + data_->num_prefix_chars_, + (data_->num_chars_to_log_ - + data_->num_prefix_chars_ - 1)); + } +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + SendToSink(); + SendToLog(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->outvec_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + // Omit prefix of message and trailing newline when recording in outvec_. + const char *start = data_->message_text_ + data_->num_prefix_chars_; + int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + data_->outvec_->push_back(string(start, len)); + } else { + SendToLog(); + } +} + +void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { + if (data_->message_ != NULL) { + RAW_DCHECK(data_->num_chars_to_log_ > 0 && + data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); + // Omit prefix of message and trailing newline when writing to message_. + const char *start = data_->message_text_ + data_->num_prefix_chars_; + int len = data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1; + data_->message_->assign(start, len); + } + SendToLog(); +} + +// L >= log_mutex (callers must hold the log_mutex). +void LogMessage::SendToSyslogAndLog() { +#ifdef HAVE_SYSLOG_H + // Before any calls to syslog(), make a single call to openlog() + static bool openlog_already_called = false; + if (!openlog_already_called) { + openlog(glog_internal_namespace_::ProgramInvocationShortName(), + LOG_CONS | LOG_NDELAY | LOG_PID, + LOG_USER); + openlog_already_called = true; + } + + // This array maps Google severity levels to syslog levels + const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; + syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast(data_->severity_)], "%.*s", + int(data_->num_chars_to_syslog_), + data_->message_text_ + data_->num_prefix_chars_); + SendToLog(); +#else + LOG(ERROR) << "No syslog support: message=" << data_->message_text_; +#endif +} + +base::Logger* base::GetLogger(LogSeverity severity) { + MutexLock l(&log_mutex); + return LogDestination::log_destination(severity)->logger_; +} + +void base::SetLogger(LogSeverity severity, base::Logger* logger) { + MutexLock l(&log_mutex); + LogDestination::log_destination(severity)->logger_ = logger; +} + +// L < log_mutex. Acquires and releases mutex_. +int64 LogMessage::num_messages(int severity) { + MutexLock l(&log_mutex); + return num_messages_[severity]; +} + +// Output the COUNTER value. This is only valid if ostream is a +// LogStream. +ostream& operator<<(ostream &os, const PRIVATE_Counter&) { + LogMessage::LogStream *log = dynamic_cast(&os); + CHECK(log == log->self()); + os << log->ctr(); + return os; +} + +ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, + LogSeverity severity, int ctr, + void (LogMessage::*send_method)()) + : LogMessage(file, line, severity, ctr, send_method) { +} + +ErrnoLogMessage::~ErrnoLogMessage() { + // Don't access errno directly because it may have been altered + // while streaming the message. + char buf[100]; + posix_strerror_r(preserved_errno(), buf, sizeof(buf)); + stream() << ": " << buf << " [" << preserved_errno() << "]"; +} + +void FlushLogFiles(LogSeverity min_severity) { + LogDestination::FlushLogFiles(min_severity); +} + +void FlushLogFilesUnsafe(LogSeverity min_severity) { + LogDestination::FlushLogFilesUnsafe(min_severity); +} + +void SetLogDestination(LogSeverity severity, const char* base_filename) { + LogDestination::SetLogDestination(severity, base_filename); +} + +void SetLogSymlink(LogSeverity severity, const char* symlink_basename) { + LogDestination::SetLogSymlink(severity, symlink_basename); +} + +LogSink::~LogSink() { +} + +void LogSink::WaitTillSent() { + // noop default +} + +string LogSink::ToString(LogSeverity severity, const char* file, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) { + ostringstream stream(string(message, message_len)); + stream.fill('0'); + + // FIXME(jrvb): Updating this to use the correct value for usecs + // requires changing the signature for both this method and + // LogSink::send(). This change needs to be done in a separate CL + // so subclasses of LogSink can be updated at the same time. + int usecs = 0; + + stream << LogSeverityNames[severity][0] + << setw(2) << 1+tm_time->tm_mon + << setw(2) << tm_time->tm_mday + << ' ' + << setw(2) << tm_time->tm_hour << ':' + << setw(2) << tm_time->tm_min << ':' + << setw(2) << tm_time->tm_sec << '.' + << setw(6) << usecs + << ' ' + << setfill(' ') << setw(5) << GetTID() << setfill('0') + << ' ' + << file << ':' << line << "] "; + + stream << string(message, message_len); + return stream.str(); +} + +void AddLogSink(LogSink *destination) { + LogDestination::AddLogSink(destination); +} + +void RemoveLogSink(LogSink *destination) { + LogDestination::RemoveLogSink(destination); +} + +void SetLogFilenameExtension(const char* ext) { + LogDestination::SetLogFilenameExtension(ext); +} + +void SetStderrLogging(LogSeverity min_severity) { + LogDestination::SetStderrLogging(min_severity); +} + +void SetEmailLogging(LogSeverity min_severity, const char* addresses) { + LogDestination::SetEmailLogging(min_severity, addresses); +} + +void LogToStderr() { + LogDestination::LogToStderr(); +} + +namespace base { +namespace internal { + +bool GetExitOnDFatal() { + MutexLock l(&log_mutex); + return exit_on_dfatal; +} + +// Determines whether we exit the program for a LOG(DFATAL) message in +// debug mode. It does this by skipping the call to Fail/FailQuietly. +// This is intended for testing only. +// +// This can have some effects on LOG(FATAL) as well. Failure messages +// are always allocated (rather than sharing a buffer), the crash +// reason is not recorded, the "gwq" status message is not updated, +// and the stack trace is not recorded. The LOG(FATAL) *will* still +// exit the program. Since this function is used only in testing, +// these differences are acceptable. +void SetExitOnDFatal(bool value) { + MutexLock l(&log_mutex); + exit_on_dfatal = value; +} + +} // namespace internal +} // namespace base + +// use_logging controls whether the logging functions LOG/VLOG are used +// to log errors. It should be set to false when the caller holds the +// log_mutex. +static bool SendEmailInternal(const char*dest, const char *subject, + const char*body, bool use_logging) { + if (dest && *dest) { + if ( use_logging ) { + VLOG(1) << "Trying to send TITLE:" << subject + << " BODY:" << body << " to " << dest; + } else { + fprintf(stderr, "Trying to send TITLE: %s BODY: %s to %s\n", + subject, body, dest); + } + + string cmd = + FLAGS_logmailer + " -s\"" + subject + "\" " + dest; + FILE* pipe = popen(cmd.c_str(), "w"); + if (pipe != NULL) { + // Add the body if we have one + if (body) + fwrite(body, sizeof(char), strlen(body), pipe); + bool ok = pclose(pipe) != -1; + if ( !ok ) { + if ( use_logging ) { + char buf[100]; + posix_strerror_r(errno, buf, sizeof(buf)); + LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf; + } else { + char buf[100]; + posix_strerror_r(errno, buf, sizeof(buf)); + fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf); + } + } + return ok; + } else { + if ( use_logging ) { + LOG(ERROR) << "Unable to send mail to " << dest; + } else { + fprintf(stderr, "Unable to send mail to %s\n", dest); + } + } + } + return false; +} + +bool SendEmail(const char*dest, const char *subject, const char*body){ + return SendEmailInternal(dest, subject, body, true); +} + +static void GetTempDirectories(vector* list) { + list->clear(); +#ifdef OS_WINDOWS + // On windows we'll try to find a directory in this order: + // C:/Documents & Settings/whomever/TEMP (or whatever GetTempPath() is) + // C:/TMP/ + // C:/TEMP/ + // C:/WINDOWS/ or C:/WINNT/ + // . + char tmp[MAX_PATH]; + if (GetTempPathA(MAX_PATH, tmp)) + list->push_back(tmp); + list->push_back("C:\\tmp\\"); + list->push_back("C:\\temp\\"); +#else + // Directories, in order of preference. If we find a dir that + // exists, we stop adding other less-preferred dirs + const char * candidates[] = { + // Non-null only during unittest/regtest + getenv("TEST_TMPDIR"), + + // Explicitly-supplied temp dirs + getenv("TMPDIR"), getenv("TMP"), + + // If all else fails + "/tmp", + }; + + for (int i = 0; i < ARRAYSIZE(candidates); i++) { + const char *d = candidates[i]; + if (!d) continue; // Empty env var + + // Make sure we don't surprise anyone who's expecting a '/' + string dstr = d; + if (dstr[dstr.size() - 1] != '/') { + dstr += "/"; + } + list->push_back(dstr); + + struct stat statbuf; + if (!stat(d, &statbuf) && S_ISDIR(statbuf.st_mode)) { + // We found a dir that exists - we're done. + return; + } + } + +#endif +} + +static vector* logging_directories_list; + +const vector& GetLoggingDirectories() { + // Not strictly thread-safe but we're called early in InitGoogle(). + if (logging_directories_list == NULL) { + logging_directories_list = new vector; + + if ( !FLAGS_log_dir.empty() ) { + // A dir was specified, we should use it + logging_directories_list->push_back(FLAGS_log_dir.c_str()); + } else { + GetTempDirectories(logging_directories_list); +#ifdef OS_WINDOWS + char tmp[MAX_PATH]; + if (GetWindowsDirectoryA(tmp, MAX_PATH)) + logging_directories_list->push_back(tmp); + logging_directories_list->push_back(".\\"); +#else + logging_directories_list->push_back("./"); +#endif + } + } + return *logging_directories_list; +} + +void TestOnly_ClearLoggingDirectoriesList() { + fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " + "called from test code.\n"); + delete logging_directories_list; + logging_directories_list = NULL; +} + +void GetExistingTempDirectories(vector* list) { + GetTempDirectories(list); + vector::iterator i_dir = list->begin(); + while( i_dir != list->end() ) { + // zero arg to access means test for existence; no constant + // defined on windows + if ( access(i_dir->c_str(), 0) ) { + i_dir = list->erase(i_dir); + } else { + ++i_dir; + } + } +} + +void TruncateLogFile(const char *path, int64 limit, int64 keep) { +#ifdef HAVE_UNISTD_H + struct stat statbuf; + const int kCopyBlockSize = 8 << 10; + char copybuf[kCopyBlockSize]; + int64 read_offset, write_offset; + // Don't follow symlinks unless they're our own fd symlinks in /proc + int flags = O_RDWR; + const char *procfd_prefix = "/proc/self/fd/"; + if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; + + int fd = open(path, flags); + if (fd == -1) { + if (errno == EFBIG) { + // The log file in question has got too big for us to open. The + // real fix for this would be to compile logging.cc (or probably + // all of base/...) with -D_FILE_OFFSET_BITS=64 but that's + // rather scary. + // Instead just truncate the file to something we can manage + if (truncate(path, 0) == -1) { + PLOG(ERROR) << "Unable to truncate " << path; + } else { + LOG(ERROR) << "Truncated " << path << " due to EFBIG error"; + } + } else { + PLOG(ERROR) << "Unable to open " << path; + } + return; + } + + if (fstat(fd, &statbuf) == -1) { + PLOG(ERROR) << "Unable to fstat()"; + goto out_close_fd; + } + + // See if the path refers to a regular file bigger than the + // specified limit + if (!S_ISREG(statbuf.st_mode)) goto out_close_fd; + if (statbuf.st_size <= limit) goto out_close_fd; + if (statbuf.st_size <= keep) goto out_close_fd; + + // This log file is too large - we need to truncate it + LOG(INFO) << "Truncating " << path << " to " << keep << " bytes"; + + // Copy the last "keep" bytes of the file to the beginning of the file + read_offset = statbuf.st_size - keep; + write_offset = 0; + int bytesin, bytesout; + while ((bytesin = pread(fd, copybuf, sizeof(copybuf), read_offset)) > 0) { + bytesout = pwrite(fd, copybuf, bytesin, write_offset); + if (bytesout == -1) { + PLOG(ERROR) << "Unable to write to " << path; + break; + } else if (bytesout != bytesin) { + LOG(ERROR) << "Expected to write " << bytesin << ", wrote " << bytesout; + } + read_offset += bytesin; + write_offset += bytesout; + } + if (bytesin == -1) PLOG(ERROR) << "Unable to read from " << path; + + // Truncate the remainder of the file. If someone else writes to the + // end of the file after our last read() above, we lose their latest + // data. Too bad ... + if (ftruncate(fd, write_offset) == -1) { + PLOG(ERROR) << "Unable to truncate " << path; + } + + out_close_fd: + close(fd); +#else + LOG(ERROR) << "No log truncation support."; +#endif +} + +void TruncateStdoutStderr() { +#ifdef HAVE_UNISTD_H + int64 limit = MaxLogSize() << 20; + int64 keep = 1 << 20; + TruncateLogFile("/proc/self/fd/1", limit, keep); + TruncateLogFile("/proc/self/fd/2", limit, keep); +#else + LOG(ERROR) << "No log truncation support."; +#endif +} + + +// Helper functions for string comparisons. +#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ + string* Check##func##expected##Impl(const char* s1, const char* s2, \ + const char* names) { \ + bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ + if (equal == expected) return NULL; \ + else { \ + strstream ss; \ + if (!s1) s1 = ""; \ + if (!s2) s2 = ""; \ + ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ + return new string(ss.str(), ss.pcount()); \ + } \ + } +DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) +DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) +DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true) +DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false) +#undef DEFINE_CHECK_STROP_IMPL + +int posix_strerror_r(int err, char *buf, size_t len) { + // Sanity check input parameters + if (buf == NULL || len <= 0) { + errno = EINVAL; + return -1; + } + + // Reset buf and errno, and try calling whatever version of strerror_r() + // is implemented by glibc + buf[0] = '\000'; + int old_errno = errno; + errno = 0; + char *rc = reinterpret_cast(strerror_r(err, buf, len)); + + // Both versions set errno on failure + if (errno) { + // Should already be there, but better safe than sorry + buf[0] = '\000'; + return -1; + } + errno = old_errno; + + // POSIX is vague about whether the string will be terminated, although + // is indirectly implies that typically ERANGE will be returned, instead + // of truncating the string. This is different from the GNU implementation. + // We play it safe by always terminating the string explicitly. + buf[len-1] = '\000'; + + // If the function succeeded, we can use its exit code to determine the + // semantics implemented by glibc + if (!rc) { + return 0; + } else { + // GNU semantics detected + if (rc == buf) { + return 0; + } else { + buf[0] = '\000'; +#if defined(OS_MACOSX) || defined(OS_FREEBSD) || defined(OS_OPENBSD) + if (reinterpret_cast(rc) < sys_nerr) { + // This means an error on MacOSX or FreeBSD. + return -1; + } +#endif + strncat(buf, rc, len-1); + return 0; + } + } +} + +LogMessageFatal::LogMessageFatal(const char* file, int line) : + LogMessage(file, line, FATAL) {} + +LogMessageFatal::LogMessageFatal(const char* file, int line, + const CheckOpString& result) : + LogMessage(file, line, result) {} + +LogMessageFatal::~LogMessageFatal() { + Flush(); + LogMessage::Fail(); +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/raw_logging.cc b/extern/libmv/third_party/glog/src/raw_logging.cc new file mode 100644 index 00000000000..b179a1eded4 --- /dev/null +++ b/extern/libmv/third_party/glog/src/raw_logging.cc @@ -0,0 +1,172 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Maxim Lifantsev +// +// logging_unittest.cc covers the functionality herein + +#include "utilities.h" + +#include +#include +#include +#ifdef HAVE_UNISTD_H +# include // for close() and write() +#endif +#include // for open() +#include +#include "config.h" +#include // To pick up flag settings etc. +#include +#include "base/commandlineflags.h" + +#ifdef HAVE_STACKTRACE +# include "stacktrace.h" +#endif + +#if defined(HAVE_SYSCALL_H) +#include // for syscall() +#elif defined(HAVE_SYS_SYSCALL_H) +#include // for syscall() +#endif +#ifdef HAVE_UNISTD_H +# include +#endif + +#if defined(HAVE_SYSCALL_H) || defined(HAVE_SYS_SYSCALL_H) +# define safe_write(fd, s, len) syscall(SYS_write, fd, s, len) +#else + // Not so safe, but what can you do? +# define safe_write(fd, s, len) write(fd, s, len) +#endif + +_START_GOOGLE_NAMESPACE_ + +// Data for RawLog__ below. We simply pick up the latest +// time data created by a normal log message to avoid calling +// localtime_r which can allocate memory. +static struct ::tm last_tm_time_for_raw_log; +static int last_usecs_for_raw_log; + +void RawLog__SetLastTime(const struct ::tm& t, int usecs) { + memcpy(&last_tm_time_for_raw_log, &t, sizeof(last_tm_time_for_raw_log)); + last_usecs_for_raw_log = usecs; +} + +// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths +// that invoke malloc() and getenv() that might acquire some locks. +// If this becomes a problem we should reimplement a subset of vsnprintf +// that does not need locks and malloc. + +// Helper for RawLog__ below. +// *DoRawLog writes to *buf of *size and move them past the written portion. +// It returns true iff there was no overflow or error. +static bool DoRawLog(char** buf, int* size, const char* format, ...) { + va_list ap; + va_start(ap, format); + int n = vsnprintf(*buf, *size, format, ap); + va_end(ap); + if (n < 0 || n > *size) return false; + *size -= n; + *buf += n; + return true; +} + +// Helper for RawLog__ below. +inline static bool VADoRawLog(char** buf, int* size, + const char* format, va_list ap) { + int n = vsnprintf(*buf, *size, format, ap); + if (n < 0 || n > *size) return false; + *size -= n; + *buf += n; + return true; +} + +static const int kLogBufSize = 3000; +static bool crashed = false; +static CrashReason crash_reason; +static char crash_buf[kLogBufSize + 1] = { 0 }; // Will end in '\0' + +void RawLog__(LogSeverity severity, const char* file, int line, + const char* format, ...) { + if (!(FLAGS_logtostderr || severity >= FLAGS_stderrthreshold || + FLAGS_alsologtostderr || !IsGoogleLoggingInitialized())) { + return; // this stderr log message is suppressed + } + // can't call localtime_r here: it can allocate + struct ::tm& t = last_tm_time_for_raw_log; + char buffer[kLogBufSize]; + char* buf = buffer; + int size = sizeof(buffer); + + // NOTE: this format should match the specification in base/logging.h + DoRawLog(&buf, &size, "%c%02d%02d %02d:%02d:%02d.%06d %5u %s:%d] RAW: ", + LogSeverityNames[severity][0], + 1 + t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, + last_usecs_for_raw_log, + static_cast(GetTID()), + const_basename(const_cast(file)), line); + + // Record the position and size of the buffer after the prefix + const char* msg_start = buf; + const int msg_size = size; + + va_list ap; + va_start(ap, format); + bool no_chop = VADoRawLog(&buf, &size, format, ap); + va_end(ap); + if (no_chop) { + DoRawLog(&buf, &size, "\n"); + } else { + DoRawLog(&buf, &size, "RAW_LOG ERROR: The Message was too long!\n"); + } + // We make a raw syscall to write directly to the stderr file descriptor, + // avoiding FILE buffering (to avoid invoking malloc()), and bypassing + // libc (to side-step any libc interception). + // We write just once to avoid races with other invocations of RawLog__. + safe_write(STDERR_FILENO, buffer, strlen(buffer)); + if (severity == FATAL) { + if (!sync_val_compare_and_swap(&crashed, false, true)) { + crash_reason.filename = file; + crash_reason.line_number = line; + memcpy(crash_buf, msg_start, msg_size); // Don't include prefix + crash_reason.message = crash_buf; +#ifdef HAVE_STACKTRACE + crash_reason.depth = + GetStackTrace(crash_reason.stack, ARRAYSIZE(crash_reason.stack), 1); +#else + crash_reason.depth = 0; +#endif + SetCrashReason(&crash_reason); + } + LogMessage::Fail(); // abort() + } +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/signalhandler.cc b/extern/libmv/third_party/glog/src/signalhandler.cc new file mode 100644 index 00000000000..9fc91b3390d --- /dev/null +++ b/extern/libmv/third_party/glog/src/signalhandler.cc @@ -0,0 +1,348 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Satoru Takabayashi +// +// Implementation of InstallFailureSignalHandler(). + +#include "utilities.h" +#include "stacktrace.h" +#include "symbolize.h" +#include "glog/logging.h" + +#include +#include +#ifdef HAVE_UCONTEXT_H +# include +#endif +#ifdef HAVE_SYS_UCONTEXT_H +# include +#endif +#include + +_START_GOOGLE_NAMESPACE_ + +namespace { + +// We'll install the failure signal handler for these signals. We could +// use strsignal() to get signal names, but we don't use it to avoid +// introducing yet another #ifdef complication. +// +// The list should be synced with the comment in signalhandler.h. +const struct { + int number; + const char *name; +} kFailureSignals[] = { + { SIGSEGV, "SIGSEGV" }, + { SIGILL, "SIGILL" }, + { SIGFPE, "SIGFPE" }, + { SIGABRT, "SIGABRT" }, + { SIGBUS, "SIGBUS" }, + { SIGTERM, "SIGTERM" }, +}; + +// Returns the program counter from signal context, NULL if unknown. +void* GetPC(void* ucontext_in_void) { +#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT) + if (ucontext_in_void != NULL) { + ucontext_t *context = reinterpret_cast(ucontext_in_void); + return (void*)context->PC_FROM_UCONTEXT; + } +#endif + return NULL; +} + +// The class is used for formatting error messages. We don't use printf() +// as it's not async signal safe. +class MinimalFormatter { + public: + MinimalFormatter(char *buffer, int size) + : buffer_(buffer), + cursor_(buffer), + end_(buffer + size) { + } + + // Returns the number of bytes written in the buffer. + int num_bytes_written() const { return cursor_ - buffer_; } + + // Appends string from "str" and updates the internal cursor. + void AppendString(const char* str) { + int i = 0; + while (str[i] != '\0' && cursor_ + i < end_) { + cursor_[i] = str[i]; + ++i; + } + cursor_ += i; + } + + // Formats "number" in "radix" and updates the internal cursor. + // Lowercase letters are used for 'a' - 'z'. + void AppendUint64(uint64 number, int radix) { + int i = 0; + while (cursor_ + i < end_) { + const int tmp = number % radix; + number /= radix; + cursor_[i] = (tmp < 10 ? '0' + tmp : 'a' + tmp - 10); + ++i; + if (number == 0) { + break; + } + } + // Reverse the bytes written. + std::reverse(cursor_, cursor_ + i); + cursor_ += i; + } + + // Formats "number" as hexadecimal number, and updates the internal + // cursor. Padding will be added in front if needed. + void AppendHexWithPadding(uint64 number, int width) { + char* start = cursor_; + AppendString("0x"); + AppendUint64(number, 16); + // Move to right and add padding in front if needed. + if (cursor_ < start + width) { + const int64 delta = start + width - cursor_; + std::copy(start, cursor_, start + delta); + std::fill(start, start + delta, ' '); + cursor_ = start + width; + } + } + + private: + char *buffer_; + char *cursor_; + const char * const end_; +}; + +// Writes the given data with the size to the standard error. +void WriteToStderr(const char* data, int size) { + write(STDERR_FILENO, data, size); +} + +// The writer function can be changed by InstallFailureWriter(). +void (*g_failure_writer)(const char* data, int size) = WriteToStderr; + +// Dumps time information. We don't dump human-readable time information +// as localtime() is not guaranteed to be async signal safe. +void DumpTimeInfo() { + time_t time_in_sec = time(NULL); + char buf[256]; // Big enough for time info. + MinimalFormatter formatter(buf, sizeof(buf)); + formatter.AppendString("*** Aborted at "); + formatter.AppendUint64(time_in_sec, 10); + formatter.AppendString(" (unix time)"); + formatter.AppendString(" try \"date -d @"); + formatter.AppendUint64(time_in_sec, 10); + formatter.AppendString("\" if you are using GNU date ***\n"); + g_failure_writer(buf, formatter.num_bytes_written()); +} + +// Dumps information about the signal to STDERR. +void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { + // Get the signal name. + const char* signal_name = NULL; + for (int i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { + if (signal_number == kFailureSignals[i].number) { + signal_name = kFailureSignals[i].name; + } + } + + char buf[256]; // Big enough for signal info. + MinimalFormatter formatter(buf, sizeof(buf)); + + formatter.AppendString("*** "); + if (signal_name) { + formatter.AppendString(signal_name); + } else { + // Use the signal number if the name is unknown. The signal name + // should be known, but just in case. + formatter.AppendString("Signal "); + formatter.AppendUint64(signal_number, 10); + } + formatter.AppendString(" (@0x"); + formatter.AppendUint64(reinterpret_cast(siginfo->si_addr), 16); + formatter.AppendString(")"); + formatter.AppendString(" received by PID "); + formatter.AppendUint64(getpid(), 10); + formatter.AppendString(" (TID 0x"); + // We assume pthread_t is an integral number or a pointer, rather + // than a complex struct. In some environments, pthread_self() + // returns an uint64 but in some other environments pthread_self() + // returns a pointer. Hence we use C-style cast here, rather than + // reinterpret/static_cast, to support both types of environments. + formatter.AppendUint64((uintptr_t)pthread_self(), 16); + formatter.AppendString(") "); + // Only linux has the PID of the signal sender in si_pid. +#ifdef OS_LINUX + formatter.AppendString("from PID "); + formatter.AppendUint64(siginfo->si_pid, 10); + formatter.AppendString("; "); +#endif + formatter.AppendString("stack trace: ***\n"); + g_failure_writer(buf, formatter.num_bytes_written()); +} + +// Dumps information about the stack frame to STDERR. +void DumpStackFrameInfo(const char* prefix, void* pc) { + // Get the symbol name. + const char *symbol = "(unknown)"; + char symbolized[1024]; // Big enough for a sane symbol. + // Symbolizes the previous address of pc because pc may be in the + // next function. + if (Symbolize(reinterpret_cast(pc) - 1, + symbolized, sizeof(symbolized))) { + symbol = symbolized; + } + + char buf[1024]; // Big enough for stack frame info. + MinimalFormatter formatter(buf, sizeof(buf)); + + formatter.AppendString(prefix); + formatter.AppendString("@ "); + const int width = 2 * sizeof(void*) + 2; // + 2 for "0x". + formatter.AppendHexWithPadding(reinterpret_cast(pc), width); + formatter.AppendString(" "); + formatter.AppendString(symbol); + formatter.AppendString("\n"); + g_failure_writer(buf, formatter.num_bytes_written()); +} + +// Invoke the default signal handler. +void InvokeDefaultSignalHandler(int signal_number) { + struct sigaction sig_action; + memset(&sig_action, 0, sizeof(sig_action)); + sigemptyset(&sig_action.sa_mask); + sig_action.sa_handler = SIG_DFL; + sigaction(signal_number, &sig_action, NULL); + kill(getpid(), signal_number); +} + +// This variable is used for protecting FailureSignalHandler() from +// dumping stuff while another thread is doing it. Our policy is to let +// the first thread dump stuff and let other threads wait. +// See also comments in FailureSignalHandler(). +static pthread_t* g_entered_thread_id_pointer = NULL; + +// Dumps signal and stack frame information, and invokes the default +// signal handler once our job is done. +void FailureSignalHandler(int signal_number, + siginfo_t *signal_info, + void *ucontext) { + // First check if we've already entered the function. We use an atomic + // compare and swap operation for platforms that support it. For other + // platforms, we use a naive method that could lead to a subtle race. + + // We assume pthread_self() is async signal safe, though it's not + // officially guaranteed. + pthread_t my_thread_id = pthread_self(); + // NOTE: We could simply use pthread_t rather than pthread_t* for this, + // if pthread_self() is guaranteed to return non-zero value for thread + // ids, but there is no such guarantee. We need to distinguish if the + // old value (value returned from __sync_val_compare_and_swap) is + // different from the original value (in this case NULL). + pthread_t* old_thread_id_pointer = + glog_internal_namespace_::sync_val_compare_and_swap( + &g_entered_thread_id_pointer, + static_cast(NULL), + &my_thread_id); + if (old_thread_id_pointer != NULL) { + // We've already entered the signal handler. What should we do? + if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) { + // It looks the current thread is reentering the signal handler. + // Something must be going wrong (maybe we are reentering by another + // type of signal?). Kill ourself by the default signal handler. + InvokeDefaultSignalHandler(signal_number); + } + // Another thread is dumping stuff. Let's wait until that thread + // finishes the job and kills the process. + while (true) { + sleep(1); + } + } + // This is the first time we enter the signal handler. We are going to + // do some interesting stuff from here. + // TODO(satorux): We might want to set timeout here using alarm(), but + // mixing alarm() and sleep() can be a bad idea. + + // First dump time info. + DumpTimeInfo(); + + // Get the program counter from ucontext. + void *pc = GetPC(ucontext); + DumpStackFrameInfo("PC: ", pc); + +#ifdef HAVE_STACKTRACE + // Get the stack traces. + void *stack[32]; + // +1 to exclude this function. + const int depth = GetStackTrace(stack, ARRAYSIZE(stack), 1); + DumpSignalInfo(signal_number, signal_info); + // Dump the stack traces. + for (int i = 0; i < depth; ++i) { + DumpStackFrameInfo(" ", stack[i]); + } +#endif + + // *** TRANSITION *** + // + // BEFORE this point, all code must be async-termination-safe! + // (See WARNING above.) + // + // AFTER this point, we do unsafe things, like using LOG()! + // The process could be terminated or hung at any time. We try to + // do more useful things first and riskier things later. + + // Flush the logs before we do anything in case 'anything' + // causes problems. + FlushLogFilesUnsafe(0); + + // Kill ourself by the default signal handler. + InvokeDefaultSignalHandler(signal_number); +} + +} // namespace + +void InstallFailureSignalHandler() { + // Build the sigaction struct. + struct sigaction sig_action; + memset(&sig_action, 0, sizeof(sig_action)); + sigemptyset(&sig_action.sa_mask); + sig_action.sa_flags |= SA_SIGINFO; + sig_action.sa_sigaction = &FailureSignalHandler; + + for (int i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { + CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); + } +} + +void InstallFailureWriter(void (*writer)(const char* data, int size)) { + g_failure_writer = writer; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace.h b/extern/libmv/third_party/glog/src/stacktrace.h new file mode 100644 index 00000000000..8c3e8fe8f8d --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace.h @@ -0,0 +1,60 @@ +// Copyright (c) 2000 - 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Routines to extract the current stack trace. These functions are +// thread-safe. + +#ifndef BASE_STACKTRACE_H_ +#define BASE_STACKTRACE_H_ + +#include "config.h" + +_START_GOOGLE_NAMESPACE_ + +// This is similar to the GetStackFrames routine, except that it returns +// the stack trace only, and not the stack frame sizes as well. +// Example: +// main() { foo(); } +// foo() { bar(); } +// bar() { +// void* result[10]; +// int depth = GetStackFrames(result, 10, 1); +// } +// +// This produces: +// result[0] foo +// result[1] main +// .... ... +// +// "result" must not be NULL. +extern int GetStackTrace(void** result, int max_depth, int skip_count); + +_END_GOOGLE_NAMESPACE_ + +#endif // BASE_STACKTRACE_H_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h b/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h new file mode 100644 index 00000000000..fad81d3e3f4 --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace_generic-inl.h @@ -0,0 +1,59 @@ +// Copyright (c) 2000 - 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Portable implementation - just use glibc +// +// Note: The glibc implementation may cause a call to malloc. +// This can cause a deadlock in HeapProfiler. +#include +#include +#include "stacktrace.h" + +_START_GOOGLE_NAMESPACE_ + +// If you change this function, also change GetStackFrames below. +int GetStackTrace(void** result, int max_depth, int skip_count) { + static const int kStackLength = 64; + void * stack[kStackLength]; + int size; + + size = backtrace(stack, kStackLength); + skip_count++; // we want to skip the current frame as well + int result_count = size - skip_count; + if (result_count < 0) + result_count = 0; + if (result_count > max_depth) + result_count = max_depth; + for (int i = 0; i < result_count; i++) + result[i] = stack[i + skip_count]; + + return result_count; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h new file mode 100644 index 00000000000..0dc14c6506e --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h @@ -0,0 +1,87 @@ +// Copyright (c) 2005 - 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Arun Sharma +// +// Produce stack trace using libunwind + +#include "utilities.h" + +extern "C" { +#define UNW_LOCAL_ONLY +#include +} +#include "glog/raw_logging.h" +#include "stacktrace.h" + +_START_GOOGLE_NAMESPACE_ + +// Sometimes, we can try to get a stack trace from within a stack +// trace, because libunwind can call mmap (maybe indirectly via an +// internal mmap based memory allocator), and that mmap gets trapped +// and causes a stack-trace request. If were to try to honor that +// recursive request, we'd end up with infinite recursion or deadlock. +// Luckily, it's safe to ignore those subsequent traces. In such +// cases, we return 0 to indicate the situation. +static bool g_now_entering = false; + +// If you change this function, also change GetStackFrames below. +int GetStackTrace(void** result, int max_depth, int skip_count) { + void *ip; + int n = 0; + unw_cursor_t cursor; + unw_context_t uc; + + if (sync_val_compare_and_swap(&g_now_entering, false, true)) { + return 0; + } + + unw_getcontext(&uc); + RAW_CHECK(unw_init_local(&cursor, &uc) >= 0, "unw_init_local failed"); + skip_count++; // Do not include the "GetStackTrace" frame + + while (n < max_depth) { + int ret = unw_get_reg(&cursor, UNW_REG_IP, (unw_word_t *) &ip); + if (ret < 0) + break; + if (skip_count > 0) { + skip_count--; + } else { + result[n++] = ip; + } + ret = unw_step(&cursor); + if (ret <= 0) + break; + } + + g_now_entering = false; + return n; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h b/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h new file mode 100644 index 00000000000..1090ddedbc7 --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace_powerpc-inl.h @@ -0,0 +1,130 @@ +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Craig Silverstein +// +// Produce stack trace. I'm guessing (hoping!) the code is much like +// for x86. For apple machines, at least, it seems to be; see +// http://developer.apple.com/documentation/mac/runtimehtml/RTArch-59.html +// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK +// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 + +#include +#include // for uintptr_t +#include "stacktrace.h" + +_START_GOOGLE_NAMESPACE_ + +// Given a pointer to a stack frame, locate and return the calling +// stackframe, or return NULL if no stackframe can be found. Perform sanity +// checks (the strictness of which is controlled by the boolean parameter +// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. +template +static void **NextStackFrame(void **old_sp) { + void **new_sp = (void **) *old_sp; + + // Check that the transition from frame pointer old_sp to frame + // pointer new_sp isn't clearly bogus + if (STRICT_UNWINDING) { + // With the stack growing downwards, older stack frame must be + // at a greater address that the current one. + if (new_sp <= old_sp) return NULL; + // Assume stack frames larger than 100,000 bytes are bogus. + if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; + } else { + // In the non-strict mode, allow discontiguous stack frames. + // (alternate-signal-stacks for example). + if (new_sp == old_sp) return NULL; + // And allow frames upto about 1MB. + if ((new_sp > old_sp) + && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; + } + if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; + return new_sp; +} + +// This ensures that GetStackTrace stes up the Link Register properly. +void StacktracePowerPCDummyFunction() __attribute__((noinline)); +void StacktracePowerPCDummyFunction() { __asm__ volatile(""); } + +// If you change this function, also change GetStackFrames below. +int GetStackTrace(void** result, int max_depth, int skip_count) { + void **sp; + // Apple OS X uses an old version of gnu as -- both Darwin 7.9.0 (Panther) + // and Darwin 8.8.1 (Tiger) use as 1.38. This means we have to use a + // different asm syntax. I don't know quite the best way to discriminate + // systems using the old as from the new one; I've gone with __APPLE__. +#ifdef __APPLE__ + __asm__ volatile ("mr %0,r1" : "=r" (sp)); +#else + __asm__ volatile ("mr %0,1" : "=r" (sp)); +#endif + + // On PowerPC, the "Link Register" or "Link Record" (LR), is a stack + // entry that holds the return address of the subroutine call (what + // instruction we run after our function finishes). This is the + // same as the stack-pointer of our parent routine, which is what we + // want here. While the compiler will always(?) set up LR for + // subroutine calls, it may not for leaf functions (such as this one). + // This routine forces the compiler (at least gcc) to push it anyway. + StacktracePowerPCDummyFunction(); + + // The LR save area is used by the callee, so the top entry is bogus. + skip_count++; + + int n = 0; + while (sp && n < max_depth) { + if (skip_count > 0) { + skip_count--; + } else { + // PowerPC has 3 main ABIs, which say where in the stack the + // Link Register is. For DARWIN and AIX (used by apple and + // linux ppc64), it's in sp[2]. For SYSV (used by linux ppc), + // it's in sp[1]. +#if defined(_CALL_AIX) || defined(_CALL_DARWIN) + result[n++] = *(sp+2); +#elif defined(_CALL_SYSV) + result[n++] = *(sp+1); +#elif defined(__APPLE__) || (defined(__linux) && defined(__PPC64__)) + // This check is in case the compiler doesn't define _CALL_AIX/etc. + result[n++] = *(sp+2); +#elif defined(__linux) + // This check is in case the compiler doesn't define _CALL_SYSV. + result[n++] = *(sp+1); +#else +#error Need to specify the PPC ABI for your archiecture. +#endif + } + // Use strict unwinding rules. + sp = NextStackFrame(sp); + } + return n; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h b/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h new file mode 100644 index 00000000000..cfd31f783e3 --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace_x86-inl.h @@ -0,0 +1,139 @@ +// Copyright (c) 2000 - 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Produce stack trace + +#include // for uintptr_t + +#include "utilities.h" // for OS_* macros + +#if !defined(OS_WINDOWS) +#include +#include +#endif + +#include // for NULL +#include "stacktrace.h" + +_START_GOOGLE_NAMESPACE_ + +// Given a pointer to a stack frame, locate and return the calling +// stackframe, or return NULL if no stackframe can be found. Perform sanity +// checks (the strictness of which is controlled by the boolean parameter +// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. +template +static void **NextStackFrame(void **old_sp) { + void **new_sp = (void **) *old_sp; + + // Check that the transition from frame pointer old_sp to frame + // pointer new_sp isn't clearly bogus + if (STRICT_UNWINDING) { + // With the stack growing downwards, older stack frame must be + // at a greater address that the current one. + if (new_sp <= old_sp) return NULL; + // Assume stack frames larger than 100,000 bytes are bogus. + if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; + } else { + // In the non-strict mode, allow discontiguous stack frames. + // (alternate-signal-stacks for example). + if (new_sp == old_sp) return NULL; + // And allow frames upto about 1MB. + if ((new_sp > old_sp) + && ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; + } + if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; +#ifdef __i386__ + // On 64-bit machines, the stack pointer can be very close to + // 0xffffffff, so we explicitly check for a pointer into the + // last two pages in the address space + if ((uintptr_t)new_sp >= 0xffffe000) return NULL; +#endif +#if !defined(OS_WINDOWS) + if (!STRICT_UNWINDING) { + // Lax sanity checks cause a crash in 32-bit tcmalloc/crash_reason_test + // on AMD-based machines with VDSO-enabled kernels. + // Make an extra sanity check to insure new_sp is readable. + // Note: NextStackFrame() is only called while the program + // is already on its last leg, so it's ok to be slow here. + static int page_size = getpagesize(); + void *new_sp_aligned = (void *)((uintptr_t)new_sp & ~(page_size - 1)); + if (msync(new_sp_aligned, page_size, MS_ASYNC) == -1) + return NULL; + } +#endif + return new_sp; +} + +// If you change this function, also change GetStackFrames below. +int GetStackTrace(void** result, int max_depth, int skip_count) { + void **sp; +#ifdef __i386__ + // Stack frame format: + // sp[0] pointer to previous frame + // sp[1] caller address + // sp[2] first argument + // ... + sp = (void **)&result - 2; +#endif + +#ifdef __x86_64__ + // __builtin_frame_address(0) can return the wrong address on gcc-4.1.0-k8 + unsigned long rbp; + // Move the value of the register %rbp into the local variable rbp. + // We need 'volatile' to prevent this instruction from getting moved + // around during optimization to before function prologue is done. + // An alternative way to achieve this + // would be (before this __asm__ instruction) to call Noop() defined as + // static void Noop() __attribute__ ((noinline)); // prevent inlining + // static void Noop() { asm(""); } // prevent optimizing-away + __asm__ volatile ("mov %%rbp, %0" : "=r" (rbp)); + // Arguments are passed in registers on x86-64, so we can't just + // offset from &result + sp = (void **) rbp; +#endif + + int n = 0; + while (sp && n < max_depth) { + if (*(sp+1) == (void *)0) { + // In 64-bit code, we often see a frame that + // points to itself and has a return address of 0. + break; + } + if (skip_count > 0) { + skip_count--; + } else { + result[n++] = *(sp+1); + } + // Use strict unwinding rules. + sp = NextStackFrame(sp); + } + return n; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h b/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h new file mode 100644 index 00000000000..f7d1dca85bc --- /dev/null +++ b/extern/libmv/third_party/glog/src/stacktrace_x86_64-inl.h @@ -0,0 +1,105 @@ +// Copyright (c) 2005 - 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Arun Sharma +// +// Produce stack trace using libgcc + +extern "C" { +#include // for NULL +#include // ABI defined unwinder +} +#include "stacktrace.h" + +_START_GOOGLE_NAMESPACE_ + +typedef struct { + void **result; + int max_depth; + int skip_count; + int count; +} trace_arg_t; + + +// Workaround for the malloc() in _Unwind_Backtrace() issue. +static _Unwind_Reason_Code nop_backtrace(struct _Unwind_Context *uc, void *opq) { + return _URC_NO_REASON; +} + + +// This code is not considered ready to run until +// static initializers run so that we are guaranteed +// that any malloc-related initialization is done. +static bool ready_to_run = false; +class StackTraceInit { + public: + StackTraceInit() { + // Extra call to force initialization + _Unwind_Backtrace(nop_backtrace, NULL); + ready_to_run = true; + } +}; + +static StackTraceInit module_initializer; // Force initialization + +static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) { + trace_arg_t *targ = (trace_arg_t *) opq; + + if (targ->skip_count > 0) { + targ->skip_count--; + } else { + targ->result[targ->count++] = (void *) _Unwind_GetIP(uc); + } + + if (targ->count == targ->max_depth) + return _URC_END_OF_STACK; + + return _URC_NO_REASON; +} + +// If you change this function, also change GetStackFrames below. +int GetStackTrace(void** result, int max_depth, int skip_count) { + if (!ready_to_run) + return 0; + + trace_arg_t targ; + + skip_count += 1; // Do not include the "GetStackTrace" frame + + targ.result = result; + targ.max_depth = max_depth; + targ.skip_count = skip_count; + targ.count = 0; + + _Unwind_Backtrace(GetOneFrame, &targ); + + return targ.count; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/symbolize.cc b/extern/libmv/third_party/glog/src/symbolize.cc new file mode 100644 index 00000000000..3465de6c6fe --- /dev/null +++ b/extern/libmv/third_party/glog/src/symbolize.cc @@ -0,0 +1,681 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Satoru Takabayashi +// Stack-footprint reduction work done by Raksit Ashok +// +// Implementation note: +// +// We don't use heaps but only use stacks. We want to reduce the +// stack consumption so that the symbolizer can run on small stacks. +// +// Here are some numbers collected with GCC 4.1.0 on x86: +// - sizeof(Elf32_Sym) = 16 +// - sizeof(Elf32_Shdr) = 40 +// - sizeof(Elf64_Sym) = 24 +// - sizeof(Elf64_Shdr) = 64 +// +// This implementation is intended to be async-signal-safe but uses +// some functions which are not guaranteed to be so, such as memchr() +// and memmove(). We assume they are async-signal-safe. +// + +#include "utilities.h" + +#if defined(HAVE_SYMBOLIZE) + +#include + +#include "symbolize.h" +#include "demangle.h" + +_START_GOOGLE_NAMESPACE_ + +// We don't use assert() since it's not guaranteed to be +// async-signal-safe. Instead we define a minimal assertion +// macro. So far, we don't need pretty printing for __FILE__, etc. + +// A wrapper for abort() to make it callable in ? :. +static int AssertFail() { + abort(); + return 0; // Should not reach. +} + +#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail()) + +static SymbolizeCallback g_symbolize_callback = NULL; +void InstallSymbolizeCallback(SymbolizeCallback callback) { + g_symbolize_callback = callback; +} + +// This function wraps the Demangle function to provide an interface +// where the input symbol is demangled in-place. +// To keep stack consumption low, we would like this function to not +// get inlined. +static ATTRIBUTE_NOINLINE void DemangleInplace(char *out, int out_size) { + char demangled[256]; // Big enough for sane demangled symbols. + if (Demangle(out, demangled, sizeof(demangled))) { + // Demangling succeeded. Copy to out if the space allows. + int len = strlen(demangled); + if (len + 1 <= out_size) { // +1 for '\0'. + SAFE_ASSERT(len < sizeof(demangled)); + memmove(out, demangled, len + 1); + } + } +} + +_END_GOOGLE_NAMESPACE_ + +#if defined(__ELF__) + +#include +#include +#include +#include +#include +#include // For ElfW() macro. +#include +#include +#include +#include +#include +#include +#include +#include + +#include "symbolize.h" +#include "config.h" +#include "glog/raw_logging.h" + +// Re-runs fn until it doesn't cause EINTR. +#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR) + +_START_GOOGLE_NAMESPACE_ + +// Read up to "count" bytes from file descriptor "fd" into the buffer +// starting at "buf" while handling short reads and EINTR. On +// success, return the number of bytes read. Otherwise, return -1. +static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) { + SAFE_ASSERT(fd >= 0); + SAFE_ASSERT(count >= 0 && count <= std::numeric_limits::max()); + char *buf0 = reinterpret_cast(buf); + ssize_t num_bytes = 0; + while (num_bytes < count) { + ssize_t len; + NO_INTR(len = read(fd, buf0 + num_bytes, count - num_bytes)); + if (len < 0) { // There was an error other than EINTR. + return -1; + } + if (len == 0) { // Reached EOF. + break; + } + num_bytes += len; + } + SAFE_ASSERT(num_bytes <= count); + return num_bytes; +} + +// Read up to "count" bytes from "offset" in the file pointed by file +// descriptor "fd" into the buffer starting at "buf". On success, +// return the number of bytes read. Otherwise, return -1. +static ssize_t ReadFromOffset(const int fd, void *buf, + const size_t count, const off_t offset) { + off_t off = lseek(fd, offset, SEEK_SET); + if (off == (off_t)-1) { + return -1; + } + return ReadPersistent(fd, buf, count); +} + +// Try reading exactly "count" bytes from "offset" bytes in a file +// pointed by "fd" into the buffer starting at "buf" while handling +// short reads and EINTR. On success, return true. Otherwise, return +// false. +static bool ReadFromOffsetExact(const int fd, void *buf, + const size_t count, const off_t offset) { + ssize_t len = ReadFromOffset(fd, buf, count, offset); + return len == count; +} + +// Returns elf_header.e_type if the file pointed by fd is an ELF binary. +static int FileGetElfType(const int fd) { + ElfW(Ehdr) elf_header; + if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { + return -1; + } + if (memcmp(elf_header.e_ident, ELFMAG, SELFMAG) != 0) { + return -1; + } + return elf_header.e_type; +} + +// Read the section headers in the given ELF binary, and if a section +// of the specified type is found, set the output to this section header +// and return true. Otherwise, return false. +// To keep stack consumption low, we would like this function to not get +// inlined. +static ATTRIBUTE_NOINLINE bool +GetSectionHeaderByType(const int fd, ElfW(Half) sh_num, const off_t sh_offset, + ElfW(Word) type, ElfW(Shdr) *out) { + // Read at most 16 section headers at a time to save read calls. + ElfW(Shdr) buf[16]; + for (int i = 0; i < sh_num;) { + const ssize_t num_bytes_left = (sh_num - i) * sizeof(buf[0]); + const ssize_t num_bytes_to_read = + (sizeof(buf) > num_bytes_left) ? num_bytes_left : sizeof(buf); + const ssize_t len = ReadFromOffset(fd, buf, num_bytes_to_read, + sh_offset + i * sizeof(buf[0])); + SAFE_ASSERT(len % sizeof(buf[0]) == 0); + const ssize_t num_headers_in_buf = len / sizeof(buf[0]); + SAFE_ASSERT(num_headers_in_buf <= sizeof(buf) / sizeof(buf[0])); + for (int j = 0; j < num_headers_in_buf; ++j) { + if (buf[j].sh_type == type) { + *out = buf[j]; + return true; + } + } + i += num_headers_in_buf; + } + return false; +} + +// There is no particular reason to limit section name to 63 characters, +// but there has (as yet) been no need for anything longer either. +const int kMaxSectionNameLen = 64; + +// name_len should include terminating '\0'. +bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, + ElfW(Shdr) *out) { + ElfW(Ehdr) elf_header; + if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { + return false; + } + + ElfW(Shdr) shstrtab; + off_t shstrtab_offset = (elf_header.e_shoff + + elf_header.e_shentsize * elf_header.e_shstrndx); + if (!ReadFromOffsetExact(fd, &shstrtab, sizeof(shstrtab), shstrtab_offset)) { + return false; + } + + for (int i = 0; i < elf_header.e_shnum; ++i) { + off_t section_header_offset = (elf_header.e_shoff + + elf_header.e_shentsize * i); + if (!ReadFromOffsetExact(fd, out, sizeof(*out), section_header_offset)) { + return false; + } + char header_name[kMaxSectionNameLen]; + if (sizeof(header_name) < name_len) { + RAW_LOG(WARNING, "Section name '%s' is too long (%"PRIuS"); " + "section will not be found (even if present).", name, name_len); + // No point in even trying. + return false; + } + off_t name_offset = shstrtab.sh_offset + out->sh_name; + ssize_t n_read = ReadFromOffset(fd, &header_name, name_len, name_offset); + if (n_read == -1) { + return false; + } else if (n_read != name_len) { + // Short read -- name could be at end of file. + continue; + } + if (memcmp(header_name, name, name_len) == 0) { + return true; + } + } + return false; +} + +// Read a symbol table and look for the symbol containing the +// pc. Iterate over symbols in a symbol table and look for the symbol +// containing "pc". On success, return true and write the symbol name +// to out. Otherwise, return false. +// To keep stack consumption low, we would like this function to not get +// inlined. +static ATTRIBUTE_NOINLINE bool +FindSymbol(uint64_t pc, const int fd, char *out, int out_size, + uint64_t symbol_offset, const ElfW(Shdr) *strtab, + const ElfW(Shdr) *symtab) { + if (symtab == NULL) { + return false; + } + const int num_symbols = symtab->sh_size / symtab->sh_entsize; + for (int i = 0; i < num_symbols;) { + off_t offset = symtab->sh_offset + i * symtab->sh_entsize; + + // If we are reading Elf64_Sym's, we want to limit this array to + // 32 elements (to keep stack consumption low), otherwise we can + // have a 64 element Elf32_Sym array. +#if __WORDSIZE == 64 +#define NUM_SYMBOLS 32 +#else +#define NUM_SYMBOLS 64 +#endif + + // Read at most NUM_SYMBOLS symbols at once to save read() calls. + ElfW(Sym) buf[NUM_SYMBOLS]; + const ssize_t len = ReadFromOffset(fd, &buf, sizeof(buf), offset); + SAFE_ASSERT(len % sizeof(buf[0]) == 0); + const ssize_t num_symbols_in_buf = len / sizeof(buf[0]); + SAFE_ASSERT(num_symbols_in_buf <= sizeof(buf)/sizeof(buf[0])); + for (int j = 0; j < num_symbols_in_buf; ++j) { + const ElfW(Sym)& symbol = buf[j]; + uint64_t start_address = symbol.st_value; + start_address += symbol_offset; + uint64_t end_address = start_address + symbol.st_size; + if (symbol.st_value != 0 && // Skip null value symbols. + symbol.st_shndx != 0 && // Skip undefined symbols. + start_address <= pc && pc < end_address) { + ssize_t len1 = ReadFromOffset(fd, out, out_size, + strtab->sh_offset + symbol.st_name); + if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) { + return false; + } + return true; // Obtained the symbol name. + } + } + i += num_symbols_in_buf; + } + return false; +} + +// Get the symbol name of "pc" from the file pointed by "fd". Process +// both regular and dynamic symbol tables if necessary. On success, +// write the symbol name to "out" and return true. Otherwise, return +// false. +static bool GetSymbolFromObjectFile(const int fd, uint64_t pc, + char *out, int out_size, + uint64_t map_start_address) { + // Read the ELF header. + ElfW(Ehdr) elf_header; + if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) { + return false; + } + + uint64_t symbol_offset = 0; + if (elf_header.e_type == ET_DYN) { // DSO needs offset adjustment. + symbol_offset = map_start_address; + } + + ElfW(Shdr) symtab, strtab; + + // Consult a regular symbol table first. + if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, + SHT_SYMTAB, &symtab)) { + return false; + } + if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + + symtab.sh_link * sizeof(symtab))) { + return false; + } + if (FindSymbol(pc, fd, out, out_size, symbol_offset, + &strtab, &symtab)) { + return true; // Found the symbol in a regular symbol table. + } + + // If the symbol is not found, then consult a dynamic symbol table. + if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff, + SHT_DYNSYM, &symtab)) { + return false; + } + if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff + + symtab.sh_link * sizeof(symtab))) { + return false; + } + if (FindSymbol(pc, fd, out, out_size, symbol_offset, + &strtab, &symtab)) { + return true; // Found the symbol in a dynamic symbol table. + } + + return false; +} + +namespace { +// Thin wrapper around a file descriptor so that the file descriptor +// gets closed for sure. +struct FileDescriptor { + const int fd_; + explicit FileDescriptor(int fd) : fd_(fd) {} + ~FileDescriptor() { + if (fd_ >= 0) { + NO_INTR(close(fd_)); + } + } + int get() { return fd_; } + + private: + explicit FileDescriptor(const FileDescriptor&); + void operator=(const FileDescriptor&); +}; + +// Helper class for reading lines from file. +// +// Note: we don't use ProcMapsIterator since the object is big (it has +// a 5k array member) and uses async-unsafe functions such as sscanf() +// and snprintf(). +class LineReader { + public: + explicit LineReader(int fd, char *buf, int buf_len) : fd_(fd), + buf_(buf), buf_len_(buf_len), bol_(buf), eol_(buf), eod_(buf) { + } + + // Read '\n'-terminated line from file. On success, modify "bol" + // and "eol", then return true. Otherwise, return false. + // + // Note: if the last line doesn't end with '\n', the line will be + // dropped. It's an intentional behavior to make the code simple. + bool ReadLine(const char **bol, const char **eol) { + if (BufferIsEmpty()) { // First time. + const ssize_t num_bytes = ReadPersistent(fd_, buf_, buf_len_); + if (num_bytes <= 0) { // EOF or error. + return false; + } + eod_ = buf_ + num_bytes; + bol_ = buf_; + } else { + bol_ = eol_ + 1; // Advance to the next line in the buffer. + SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". + if (!HasCompleteLine()) { + const int incomplete_line_length = eod_ - bol_; + // Move the trailing incomplete line to the beginning. + memmove(buf_, bol_, incomplete_line_length); + // Read text from file and append it. + char * const append_pos = buf_ + incomplete_line_length; + const int capacity_left = buf_len_ - incomplete_line_length; + const ssize_t num_bytes = ReadPersistent(fd_, append_pos, + capacity_left); + if (num_bytes <= 0) { // EOF or error. + return false; + } + eod_ = append_pos + num_bytes; + bol_ = buf_; + } + } + eol_ = FindLineFeed(); + if (eol_ == NULL) { // '\n' not found. Malformed line. + return false; + } + *eol_ = '\0'; // Replace '\n' with '\0'. + + *bol = bol_; + *eol = eol_; + return true; + } + + // Beginning of line. + const char *bol() { + return bol_; + } + + // End of line. + const char *eol() { + return eol_; + } + + private: + explicit LineReader(const LineReader&); + void operator=(const LineReader&); + + char *FindLineFeed() { + return reinterpret_cast(memchr(bol_, '\n', eod_ - bol_)); + } + + bool BufferIsEmpty() { + return buf_ == eod_; + } + + bool HasCompleteLine() { + return !BufferIsEmpty() && FindLineFeed() != NULL; + } + + const int fd_; + char * const buf_; + const int buf_len_; + char *bol_; + char *eol_; + const char *eod_; // End of data in "buf_". +}; +} // namespace + +// Place the hex number read from "start" into "*hex". The pointer to +// the first non-hex character or "end" is returned. +static char *GetHex(const char *start, const char *end, uint64_t *hex) { + *hex = 0; + const char *p; + for (p = start; p < end; ++p) { + int ch = *p; + if ((ch >= '0' && ch <= '9') || + (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) { + *hex = (*hex << 4) | (ch < 'A' ? ch - '0' : (ch & 0xF) + 9); + } else { // Encountered the first non-hex character. + break; + } + } + SAFE_ASSERT(p <= end); + return const_cast(p); +} + +// Search for the object file (from /proc/self/maps) that contains +// the specified pc. If found, open this file and return the file handle, +// and also set start_address to the start address of where this object +// file is mapped to in memory. Otherwise, return -1. +static ATTRIBUTE_NOINLINE int +OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc, + uint64_t &start_address) { + int object_fd; + + // Open /proc/self/maps. + int maps_fd; + NO_INTR(maps_fd = open("/proc/self/maps", O_RDONLY)); + FileDescriptor wrapped_maps_fd(maps_fd); + if (wrapped_maps_fd.get() < 0) { + return -1; + } + + // Iterate over maps and look for the map containing the pc. Then + // look into the symbol tables inside. + char buf[1024]; // Big enough for line of sane /proc/self/maps + LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf)); + while (true) { + const char *cursor; + const char *eol; + if (!reader.ReadLine(&cursor, &eol)) { // EOF or malformed line. + return -1; + } + + // Start parsing line in /proc/self/maps. Here is an example: + // + // 08048000-0804c000 r-xp 00000000 08:01 2142121 /bin/cat + // + // We want start address (08048000), end address (0804c000), flags + // (r-xp) and file name (/bin/cat). + + // Read start address. + cursor = GetHex(cursor, eol, &start_address); + if (cursor == eol || *cursor != '-') { + return -1; // Malformed line. + } + ++cursor; // Skip '-'. + + // Read end address. + uint64_t end_address; + cursor = GetHex(cursor, eol, &end_address); + if (cursor == eol || *cursor != ' ') { + return -1; // Malformed line. + } + ++cursor; // Skip ' '. + + // Check start and end addresses. + if (!(start_address <= pc && pc < end_address)) { + continue; // We skip this map. PC isn't in this map. + } + + // Read flags. Skip flags until we encounter a space or eol. + const char * const flags_start = cursor; + while (cursor < eol && *cursor != ' ') { + ++cursor; + } + // We expect at least four letters for flags (ex. "r-xp"). + if (cursor == eol || cursor < flags_start + 4) { + return -1; // Malformed line. + } + + // Check flags. We are only interested in "r-x" maps. + if (memcmp(flags_start, "r-x", 3) != 0) { // Not a "r-x" map. + continue; // We skip this map. + } + ++cursor; // Skip ' '. + + // Skip to file name. "cursor" now points to file offset. We need to + // skip at least three spaces for file offset, dev, and inode. + int num_spaces = 0; + while (cursor < eol) { + if (*cursor == ' ') { + ++num_spaces; + } else if (num_spaces >= 3) { + // The first non-space character after skipping three spaces + // is the beginning of the file name. + break; + } + ++cursor; + } + if (cursor == eol) { + return -1; // Malformed line. + } + + // Finally, "cursor" now points to file name of our interest. + NO_INTR(object_fd = open(cursor, O_RDONLY)); + if (object_fd < 0) { + return -1; + } + return object_fd; + } +} + +// The implementation of our symbolization routine. If it +// successfully finds the symbol containing "pc" and obtains the +// symbol name, returns true and write the symbol name to "out". +// Otherwise, returns false. If Callback function is installed via +// InstallSymbolizeCallback(), the function is also called in this function, +// and "out" is used as its output. +// To keep stack consumption low, we would like this function to not +// get inlined. +static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, + int out_size) { + uint64_t pc0 = reinterpret_cast(pc); + uint64_t start_address = 0; + + int object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, + start_address); + if (object_fd == -1) { + return false; + } + FileDescriptor wrapped_object_fd(object_fd); + int elf_type = FileGetElfType(wrapped_object_fd.get()); + if (elf_type == -1) { + return false; + } + if (g_symbolize_callback) { + // Run the call back if it's installed. + // Note: relocation (and much of the rest of this code) will be + // wrong for prelinked shared libraries and PIE executables. + uint64 relocation = (elf_type == ET_DYN) ? start_address : 0; + int num_bytes_written = g_symbolize_callback(wrapped_object_fd.get(), + pc, out, out_size, + relocation); + if (num_bytes_written > 0) { + out += num_bytes_written; + out_size -= num_bytes_written; + } + } + if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0, + out, out_size, start_address)) { + return false; + } + + // Symbolization succeeded. Now we try to demangle the symbol. + DemangleInplace(out, out_size); + return true; +} + +_END_GOOGLE_NAMESPACE_ + +#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) + +#include +#include + +_START_GOOGLE_NAMESPACE_ + +static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, + int out_size) { + Dl_info info; + if (dladdr(pc, &info)) { + if (strlen(info.dli_sname) < out_size) { + strcpy(out, info.dli_sname); + // Symbolization succeeded. Now we try to demangle the symbol. + DemangleInplace(out, out_size); + return true; + } + } + return false; +} + +_END_GOOGLE_NAMESPACE_ + +#else +# error BUG: HAVE_SYMBOLIZE was wrongly set +#endif + +_START_GOOGLE_NAMESPACE_ + +bool Symbolize(void *pc, char *out, int out_size) { + SAFE_ASSERT(out_size >= 0); + return SymbolizeAndDemangle(pc, out, out_size); +} + +_END_GOOGLE_NAMESPACE_ + +#else /* HAVE_SYMBOLIZE */ + +#include + +#include "config.h" + +_START_GOOGLE_NAMESPACE_ + +// TODO: Support other environments. +bool Symbolize(void *pc, char *out, int out_size) { + assert(0); + return false; +} + +_END_GOOGLE_NAMESPACE_ + +#endif diff --git a/extern/libmv/third_party/glog/src/symbolize.h b/extern/libmv/third_party/glog/src/symbolize.h new file mode 100644 index 00000000000..1ebe4dd94a2 --- /dev/null +++ b/extern/libmv/third_party/glog/src/symbolize.h @@ -0,0 +1,116 @@ +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Satoru Takabayashi +// +// This library provides Symbolize() function that symbolizes program +// counters to their corresponding symbol names on linux platforms. +// This library has a minimal implementation of an ELF symbol table +// reader (i.e. it doesn't depend on libelf, etc.). +// +// The algorithm used in Symbolize() is as follows. +// +// 1. Go through a list of maps in /proc/self/maps and find the map +// containing the program counter. +// +// 2. Open the mapped file and find a regular symbol table inside. +// Iterate over symbols in the symbol table and look for the symbol +// containing the program counter. If such a symbol is found, +// obtain the symbol name, and demangle the symbol if possible. +// If the symbol isn't found in the regular symbol table (binary is +// stripped), try the same thing with a dynamic symbol table. +// +// Note that Symbolize() is originally implemented to be used in +// FailureSignalHandler() in base/google.cc. Hence it doesn't use +// malloc() and other unsafe operations. It should be both +// thread-safe and async-signal-safe. + +#ifndef BASE_SYMBOLIZE_H_ +#define BASE_SYMBOLIZE_H_ + +#include "utilities.h" +#include "config.h" +#include "glog/logging.h" + +#ifdef HAVE_SYMBOLIZE + +#if defined(__ELF__) // defined by gcc on Linux +#include +#include // For ElfW() macro. + +// If there is no ElfW macro, let's define it by ourself. +#ifndef ElfW +# if SIZEOF_VOID_P == 4 +# define ElfW(type) Elf32_##type +# elif SIZEOF_VOID_P == 8 +# define ElfW(type) Elf64_##type +# else +# error "Unknown sizeof(void *)" +# endif +#endif + +_START_GOOGLE_NAMESPACE_ + +// Gets the section header for the given name, if it exists. Returns true on +// success. Otherwise, returns false. +bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, + ElfW(Shdr) *out); + +_END_GOOGLE_NAMESPACE_ + +#endif /* __ELF__ */ + +_START_GOOGLE_NAMESPACE_ + +// Installs a callback function, which will be called right before a symbol name +// is printed. The callback is intended to be used for showing a file name and a +// line number preceding a symbol name. +// "fd" is a file descriptor of the object file containing the program +// counter "pc". The callback function should write output to "out" +// and return the size of the output written. On error, the callback +// function should return -1. +typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size, + uint64 relocation); +void InstallSymbolizeCallback(SymbolizeCallback callback); + +_END_GOOGLE_NAMESPACE_ + +#endif + +_START_GOOGLE_NAMESPACE_ + +// Symbolizes a program counter. On success, returns true and write the +// symbol name to "out". The symbol name is demangled if possible +// (supports symbols generated by GCC 3.x or newer). Otherwise, +// returns false. +bool Symbolize(void *pc, char *out, int out_size); + +_END_GOOGLE_NAMESPACE_ + +#endif // BASE_SYMBOLIZE_H_ diff --git a/extern/libmv/third_party/glog/src/utilities.cc b/extern/libmv/third_party/glog/src/utilities.cc new file mode 100644 index 00000000000..e97d4f237ec --- /dev/null +++ b/extern/libmv/third_party/glog/src/utilities.cc @@ -0,0 +1,335 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Shinichiro Hamaji + +#include "utilities.h" + +#include +#include + +#include +#ifdef HAVE_SYS_TIME_H +# include +#endif +#include +#if defined(HAVE_SYSCALL_H) +#include // for syscall() +#elif defined(HAVE_SYS_SYSCALL_H) +#include // for syscall() +#endif +#ifdef HAVE_SYSLOG_H +# include +#endif + +#include "base/googleinit.h" + +using std::string; + +_START_GOOGLE_NAMESPACE_ + +static const char* g_program_invocation_short_name = NULL; +static pthread_t g_main_thread_id; + +_END_GOOGLE_NAMESPACE_ + +// The following APIs are all internal. +#ifdef HAVE_STACKTRACE + +#include "stacktrace.h" +#include "symbolize.h" +#include "base/commandlineflags.h" + +GLOG_DEFINE_bool(symbolize_stacktrace, true, + "Symbolize the stack trace in the tombstone"); + +_START_GOOGLE_NAMESPACE_ + +typedef void DebugWriter(const char*, void*); + +// The %p field width for printf() functions is two characters per byte. +// For some environments, add two extra bytes for the leading "0x". +static const int kPrintfPointerFieldWidth = 2 + 2 * sizeof(void*); + +static void DebugWriteToStderr(const char* data, void *unused) { + // This one is signal-safe. + write(STDERR_FILENO, data, strlen(data)); +} + +void DebugWriteToString(const char* data, void *arg) { + reinterpret_cast(arg)->append(data); +} + +#ifdef HAVE_SYMBOLIZE +// Print a program counter and its symbol name. +static void DumpPCAndSymbol(DebugWriter *writerfn, void *arg, void *pc, + const char * const prefix) { + char tmp[1024]; + const char *symbol = "(unknown)"; + // Symbolizes the previous address of pc because pc may be in the + // next function. The overrun happens when the function ends with + // a call to a function annotated noreturn (e.g. CHECK). + if (Symbolize(reinterpret_cast(pc) - 1, tmp, sizeof(tmp))) { + symbol = tmp; + } + char buf[1024]; + snprintf(buf, sizeof(buf), "%s@ %*p %s\n", + prefix, kPrintfPointerFieldWidth, pc, symbol); + writerfn(buf, arg); +} +#endif + +static void DumpPC(DebugWriter *writerfn, void *arg, void *pc, + const char * const prefix) { + char buf[100]; + snprintf(buf, sizeof(buf), "%s@ %*p\n", + prefix, kPrintfPointerFieldWidth, pc); + writerfn(buf, arg); +} + +// Dump current stack trace as directed by writerfn +static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { + // Print stack trace + void* stack[32]; + int depth = GetStackTrace(stack, ARRAYSIZE(stack), skip_count+1); + for (int i = 0; i < depth; i++) { +#if defined(HAVE_SYMBOLIZE) + if (FLAGS_symbolize_stacktrace) { + DumpPCAndSymbol(writerfn, arg, stack[i], " "); + } else { + DumpPC(writerfn, arg, stack[i], " "); + } +#else + DumpPC(writerfn, arg, stack[i], " "); +#endif + } +} + +static void DumpStackTraceAndExit() { + DumpStackTrace(1, DebugWriteToStderr, NULL); + + // Set the default signal handler for SIGABRT, to avoid invoking our + // own signal handler installed by InstallFailedSignalHandler(). + struct sigaction sig_action; + memset(&sig_action, 0, sizeof(sig_action)); + sigemptyset(&sig_action.sa_mask); + sig_action.sa_handler = SIG_DFL; + sigaction(SIGABRT, &sig_action, NULL); + + abort(); +} + +_END_GOOGLE_NAMESPACE_ + +#endif // HAVE_STACKTRACE + +_START_GOOGLE_NAMESPACE_ + +namespace glog_internal_namespace_ { + +const char* ProgramInvocationShortName() { + if (g_program_invocation_short_name != NULL) { + return g_program_invocation_short_name; + } else { + // TODO(hamaji): Use /proc/self/cmdline and so? + return "UNKNOWN"; + } +} + +bool IsGoogleLoggingInitialized() { + return g_program_invocation_short_name != NULL; +} + +bool is_default_thread() { + if (g_program_invocation_short_name == NULL) { + // InitGoogleLogging() not yet called, so unlikely to be in a different + // thread + return true; + } else { + return pthread_equal(pthread_self(), g_main_thread_id); + } +} + +#ifdef OS_WINDOWS +struct timeval { + long tv_sec, tv_usec; +}; + +// Based on: http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd +// See COPYING for copyright information. +static int gettimeofday(struct timeval *tv, void* tz) { +#define EPOCHFILETIME (116444736000000000ULL) + FILETIME ft; + LARGE_INTEGER li; + uint64 tt; + + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + tt = (li.QuadPart - EPOCHFILETIME) / 10; + tv->tv_sec = tt / 1000000; + tv->tv_usec = tt % 1000000; + + return 0; +} +#endif + +int64 CycleClock_Now() { + // TODO(hamaji): temporary impementation - it might be too slow. + struct timeval tv; + gettimeofday(&tv, NULL); + return static_cast(tv.tv_sec) * 1000000 + tv.tv_usec; +} + +int64 UsecToCycles(int64 usec) { + return usec; +} + +WallTime WallTime_Now() { + // Now, cycle clock is retuning microseconds since the epoch. + return CycleClock_Now() * 0.000001; +} + +static int32 g_main_thread_pid = getpid(); +int32 GetMainThreadPid() { + return g_main_thread_pid; +} + +pid_t GetTID() { + // On Linux and FreeBSD, we try to use gettid(). +#if defined OS_LINUX || defined OS_FREEBSD || defined OS_MACOSX +#ifndef __NR_gettid +#ifdef OS_MACOSX +#define __NR_gettid SYS_gettid +#elif ! defined __i386__ +#error "Must define __NR_gettid for non-x86 platforms" +#else +#define __NR_gettid 224 +#endif +#endif + static bool lacks_gettid = false; + if (!lacks_gettid) { + pid_t tid = syscall(__NR_gettid); + if (tid != -1) { + return tid; + } + // Technically, this variable has to be volatile, but there is a small + // performance penalty in accessing volatile variables and there should + // not be any serious adverse effect if a thread does not immediately see + // the value change to "true". + lacks_gettid = true; + } +#endif // OS_LINUX || OS_FREEBSD + + // If gettid() could not be used, we use one of the following. +#if defined OS_LINUX + return getpid(); // Linux: getpid returns thread ID when gettid is absent +#elif defined OS_WINDOWS || defined OS_CYGWIN + return GetCurrentThreadId(); +#else + // If none of the techniques above worked, we use pthread_self(). + return (pid_t)(uintptr_t)pthread_self(); +#endif +} + +const char* const_basename(const char* filepath) { + const char* base = strrchr(filepath, '/'); +#ifdef OS_WINDOWS // Look for either path separator in Windows + if (!base) + base = strrchr(filepath, '\\'); +#endif + return base ? (base+1) : filepath; +} + +static string g_my_user_name; +const string& MyUserName() { + return g_my_user_name; +} +static void MyUserNameInitializer() { + // TODO(hamaji): Probably this is not portable. +#if defined(OS_WINDOWS) + const char* user = getenv("USERNAME"); +#else + const char* user = getenv("USER"); +#endif + if (user != NULL) { + g_my_user_name = user; + } else { + g_my_user_name = "invalid-user"; + } +} +REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()); + +#ifdef HAVE_STACKTRACE +void DumpStackTraceToString(string* stacktrace) { + DumpStackTrace(1, DebugWriteToString, stacktrace); +} +#endif + +// We use an atomic operation to prevent problems with calling CrashReason +// from inside the Mutex implementation (potentially through RAW_CHECK). +static const CrashReason* g_reason = 0; + +void SetCrashReason(const CrashReason* r) { + sync_val_compare_and_swap(&g_reason, + reinterpret_cast(0), + r); +} + +} // namespace glog_internal_namespace_ + +void InitGoogleLogging(const char* argv0) { + CHECK(!IsGoogleLoggingInitialized()) + << "You called InitGoogleLogging() twice!"; + const char* slash = strrchr(argv0, '/'); +#ifdef OS_WINDOWS + if (!slash) slash = strrchr(argv0, '\\'); +#endif + g_program_invocation_short_name = slash ? slash + 1 : argv0; + g_main_thread_id = pthread_self(); + +#ifdef HAVE_STACKTRACE + InstallFailureFunction(&DumpStackTraceAndExit); +#endif +} + +void ShutdownGoogleLogging() { + CHECK(IsGoogleLoggingInitialized()) + << "You called ShutdownGoogleLogging() without InitGoogleLogging() first!"; +#ifdef HAVE_SYSLOG_H + closelog(); +#endif +} + +_END_GOOGLE_NAMESPACE_ + +// Make an implementation of stacktrace compiled. +#ifdef STACKTRACE_H +# include STACKTRACE_H +#endif diff --git a/extern/libmv/third_party/glog/src/utilities.h b/extern/libmv/third_party/glog/src/utilities.h new file mode 100644 index 00000000000..2d4e99e595e --- /dev/null +++ b/extern/libmv/third_party/glog/src/utilities.h @@ -0,0 +1,222 @@ +// Copyright (c) 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Shinichiro Hamaji +// +// Define utilties for glog internal usage. + +#ifndef UTILITIES_H__ +#define UTILITIES_H__ + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# define OS_WINDOWS +#elif defined(__CYGWIN__) || defined(__CYGWIN32__) +# define OS_CYGWIN +#elif defined(linux) || defined(__linux) || defined(__linux__) +# define OS_LINUX +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +# define OS_MACOSX +#elif defined(__FreeBSD__) +# define OS_FREEBSD +#elif defined(__NetBSD__) +# define OS_NETBSD +#elif defined(__OpenBSD__) +# define OS_OPENBSD +#else +// TODO(hamaji): Add other platforms. +#endif + +// printf macros for size_t, in the style of inttypes.h +#ifdef _LP64 +#define __PRIS_PREFIX "z" +#else +#define __PRIS_PREFIX +#endif + +// Use these macros after a % in a printf format string +// to get correct 32/64 bit behavior, like this: +// size_t size = records.size(); +// printf("%"PRIuS"\n", size); + +#define PRIdS __PRIS_PREFIX "d" +#define PRIxS __PRIS_PREFIX "x" +#define PRIuS __PRIS_PREFIX "u" +#define PRIXS __PRIS_PREFIX "X" +#define PRIoS __PRIS_PREFIX "o" + +#include "base/mutex.h" // This must go first so we get _XOPEN_SOURCE + +#include + +#if defined(OS_WINDOWS) +# include "port.h" +#endif + +#include "config.h" +#include + +// There are three different ways we can try to get the stack trace: +// +// 1) The libunwind library. This is still in development, and as a +// separate library adds a new dependency, but doesn't need a frame +// pointer. It also doesn't call malloc. +// +// 2) Our hand-coded stack-unwinder. This depends on a certain stack +// layout, which is used by gcc (and those systems using a +// gcc-compatible ABI) on x86 systems, at least since gcc 2.95. +// It uses the frame pointer to do its work. +// +// 3) The gdb unwinder -- also the one used by the c++ exception code. +// It's obviously well-tested, but has a fatal flaw: it can call +// malloc() from the unwinder. This is a problem because we're +// trying to use the unwinder to instrument malloc(). +// +// Note: if you add a new implementation here, make sure it works +// correctly when GetStackTrace() is called with max_depth == 0. +// Some code may do that. + +#if defined(HAVE_LIB_UNWIND) +# define STACKTRACE_H "stacktrace_libunwind-inl.h" +#elif !defined(NO_FRAME_POINTER) +# if defined(__i386__) && __GNUC__ >= 2 +# define STACKTRACE_H "stacktrace_x86-inl.h" +# elif defined(__x86_64__) && __GNUC__ >= 2 +# define STACKTRACE_H "stacktrace_x86_64-inl.h" +# elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 +# define STACKTRACE_H "stacktrace_powerpc-inl.h" +# endif +#endif + +#if !defined(STACKTRACE_H) && defined(HAVE_EXECINFO_H) +# define STACKTRACE_H "stacktrace_generic-inl.h" +#endif + +#if defined(STACKTRACE_H) +# define HAVE_STACKTRACE +#endif + +// defined by gcc +#if defined(__ELF__) && defined(OS_LINUX) +# define HAVE_SYMBOLIZE +#elif defined(OS_MACOSX) && defined(HAVE_DLADDR) +// Use dladdr to symbolize. +# define HAVE_SYMBOLIZE +#endif + +#ifndef ARRAYSIZE +// There is a better way, but this is good enough for our purpose. +# define ARRAYSIZE(a) (sizeof(a) / sizeof(*(a))) +#endif + +_START_GOOGLE_NAMESPACE_ + +namespace glog_internal_namespace_ { + +#ifdef HAVE___ATTRIBUTE__ +# define ATTRIBUTE_NOINLINE __attribute__ ((noinline)) +# define HAVE_ATTRIBUTE_NOINLINE +#else +# define ATTRIBUTE_NOINLINE +#endif + +const char* ProgramInvocationShortName(); + +bool IsGoogleLoggingInitialized(); + +bool is_default_thread(); + +int64 CycleClock_Now(); + +int64 UsecToCycles(int64 usec); + +typedef double WallTime; +WallTime WallTime_Now(); + +int32 GetMainThreadPid(); + +pid_t GetTID(); + +const std::string& MyUserName(); + +// Get the part of filepath after the last path separator. +// (Doesn't modify filepath, contrary to basename() in libgen.h.) +const char* const_basename(const char* filepath); + +// Wrapper of __sync_val_compare_and_swap. If the GCC extension isn't +// defined, we try the CPU specific logics (we only support x86 and +// x86_64 for now) first, then use a naive implementation, which has a +// race condition. +template +inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) { +#if defined(HAVE___SYNC_VAL_COMPARE_AND_SWAP) + return __sync_val_compare_and_swap(ptr, oldval, newval); +#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + T ret; + __asm__ __volatile__("lock; cmpxchg %1, (%2);" + :"=a"(ret) + // GCC may produces %sil or %dil for + // constraint "r", but some of apple's gas + // dosn't know the 8 bit registers. + // We use "q" to avoid these registers. + :"q"(newval), "q"(ptr), "a"(oldval) + :"memory", "cc"); + return ret; +#else + T ret = *ptr; + if (ret == oldval) { + *ptr = newval; + } + return ret; +#endif +} + +void DumpStackTraceToString(std::string* stacktrace); + +struct CrashReason { + CrashReason() : filename(0), line_number(0), message(0), depth(0) {} + + const char* filename; + int line_number; + const char* message; + + // We'll also store a bit of stack trace context at the time of crash as + // it may not be available later on. + void* stack[32]; + int depth; +}; + +void SetCrashReason(const CrashReason* r); + +} // namespace glog_internal_namespace_ + +_END_GOOGLE_NAMESPACE_ + +using namespace GOOGLE_NAMESPACE::glog_internal_namespace_; + +#endif // UTILITIES_H__ diff --git a/extern/libmv/third_party/glog/src/vlog_is_on.cc b/extern/libmv/third_party/glog/src/vlog_is_on.cc new file mode 100644 index 00000000000..ed88514dce5 --- /dev/null +++ b/extern/libmv/third_party/glog/src/vlog_is_on.cc @@ -0,0 +1,249 @@ +// Copyright (c) 1999, 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Ray Sidney and many others +// +// Broken out from logging.cc by Soren Lassen +// logging_unittest.cc covers the functionality herein + +#include "utilities.h" + +#include +#include +#include +#include +#include +#include "base/commandlineflags.h" +#include +#include +#include "base/googleinit.h" + +// glog doesn't have annotation +#define ANNOTATE_BENIGN_RACE(address, description) + +using std::string; + +GLOG_DEFINE_int32(v, 0, "Show all VLOG(m) messages for m <= this." +" Overridable by --vmodule."); + +GLOG_DEFINE_string(vmodule, "", "per-module verbose level." +" Argument is a comma-separated list of =." +" is a glob pattern, matched against the filename base" +" (that is, name ignoring .cc/.h./-inl.h)." +" overrides any value given by --v."); + +_START_GOOGLE_NAMESPACE_ + +namespace glog_internal_namespace_ { + +// Implementation of fnmatch that does not need 0-termination +// of arguments and does not allocate any memory, +// but we only support "*" and "?" wildcards, not the "[...]" patterns. +// It's not a static function for the unittest. +GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, + size_t patt_len, + const char* str, + size_t str_len) { + int p = 0; + int s = 0; + while (1) { + if (p == patt_len && s == str_len) return true; + if (p == patt_len) return false; + if (s == str_len) return p+1 == patt_len && pattern[p] == '*'; + if (pattern[p] == str[s] || pattern[p] == '?') { + p += 1; + s += 1; + continue; + } + if (pattern[p] == '*') { + if (p+1 == patt_len) return true; + do { + if (SafeFNMatch_(pattern+(p+1), patt_len-(p+1), str+s, str_len-s)) { + return true; + } + s += 1; + } while (s != str_len); + return false; + } + return false; + } +} + +} // namespace glog_internal_namespace_ + +using glog_internal_namespace_::SafeFNMatch_; + +int32 kLogSiteUninitialized = 1000; + +// List of per-module log levels from FLAGS_vmodule. +// Once created each element is never deleted/modified +// except for the vlog_level: other threads will read VModuleInfo blobs +// w/o locks and we'll store pointers to vlog_level at VLOG locations +// that will never go away. +// We can't use an STL struct here as we wouldn't know +// when it's safe to delete/update it: other threads need to use it w/o locks. +struct VModuleInfo { + string module_pattern; + mutable int32 vlog_level; // Conceptually this is an AtomicWord, but it's + // too much work to use AtomicWord type here + // w/o much actual benefit. + const VModuleInfo* next; +}; + +// This protects the following global variables. +static Mutex vmodule_lock; +// Pointer to head of the VModuleInfo list. +// It's a map from module pattern to logging level for those module(s). +static VModuleInfo* vmodule_list = 0; +// Boolean initialization flag. +static bool inited_vmodule = false; + +// L >= vmodule_lock. +static void VLOG2Initializer() { + vmodule_lock.AssertHeld(); + // Can now parse --vmodule flag and initialize mapping of module-specific + // logging levels. + inited_vmodule = false; + const char* vmodule = FLAGS_vmodule.c_str(); + const char* sep; + VModuleInfo* head = NULL; + VModuleInfo* tail = NULL; + while ((sep = strchr(vmodule, '=')) != NULL) { + string pattern(vmodule, sep - vmodule); + int module_level; + if (sscanf(sep, "=%d", &module_level) == 1) { + VModuleInfo* info = new VModuleInfo; + info->module_pattern = pattern; + info->vlog_level = module_level; + if (head) tail->next = info; + else head = info; + tail = info; + } + // Skip past this entry + vmodule = strchr(sep, ','); + if (vmodule == NULL) break; + vmodule++; // Skip past "," + } + if (head) { // Put them into the list at the head: + tail->next = vmodule_list; + vmodule_list = head; + } + inited_vmodule = true; +} + +// This can be called very early, so we use SpinLock and RAW_VLOG here. +int SetVLOGLevel(const char* module_pattern, int log_level) { + int result = FLAGS_v; + int const pattern_len = strlen(module_pattern); + bool found = false; + MutexLock l(&vmodule_lock); // protect whole read-modify-write + for (const VModuleInfo* info = vmodule_list; + info != NULL; info = info->next) { + if (info->module_pattern == module_pattern) { + if (!found) { + result = info->vlog_level; + found = true; + } + info->vlog_level = log_level; + } else if (!found && + SafeFNMatch_(info->module_pattern.c_str(), + info->module_pattern.size(), + module_pattern, pattern_len)) { + result = info->vlog_level; + found = true; + } + } + if (!found) { + VModuleInfo* info = new VModuleInfo; + info->module_pattern = module_pattern; + info->vlog_level = log_level; + info->next = vmodule_list; + vmodule_list = info; + } + RAW_VLOG(1, "Set VLOG level for \"%s\" to %d", module_pattern, log_level); + return result; +} + +// NOTE: Individual VLOG statements cache the integer log level pointers. +// NOTE: This function must not allocate memory or require any locks. +bool InitVLOG3__(int32** site_flag, int32* site_default, + const char* fname, int32 verbose_level) { + MutexLock l(&vmodule_lock); + bool read_vmodule_flag = inited_vmodule; + if (!read_vmodule_flag) { + VLOG2Initializer(); + } + + // protect the errno global in case someone writes: + // VLOG(..) << "The last error was " << strerror(errno) + int old_errno = errno; + + // site_default normally points to FLAGS_v + int32* site_flag_value = site_default; + + // Get basename for file + const char* base = strrchr(fname, '/'); + base = base ? (base+1) : fname; + const char* base_end = strchr(base, '.'); + size_t base_length = base_end ? (base_end - base) : strlen(base); + + // Trim out trailing "-inl" if any + if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) { + base_length -= 4; + } + + // TODO: Trim out _unittest suffix? Perhaps it is better to have + // the extra control and just leave it there. + + // find target in vector of modules, replace site_flag_value with + // a module-specific verbose level, if any. + for (const VModuleInfo* info = vmodule_list; + info != NULL; info = info->next) { + if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(), + base, base_length)) { + site_flag_value = &info->vlog_level; + // value at info->vlog_level is now what controls + // the VLOG at the caller site forever + break; + } + } + + // Cache the vlog value pointer if --vmodule flag has been parsed. + ANNOTATE_BENIGN_RACE(site_flag, + "*site_flag may be written by several threads," + " but the value will be the same"); + if (read_vmodule_flag) *site_flag = site_flag_value; + + // restore the errno in case something recoverable went wrong during + // the initialization of the VLOG mechanism (see above note "protect the..") + errno = old_errno; + return *site_flag_value >= verbose_level; +} + +_END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/windows/config.h b/extern/libmv/third_party/glog/src/windows/config.h new file mode 100644 index 00000000000..682a1b9309d --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/config.h @@ -0,0 +1,136 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google + +/* Define if you have the `dladdr' function */ +#undef HAVE_DLADDR + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_EXECINFO_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBUNWIND_H + +/* define if you have google gflags library */ +#define HAVE_LIB_GFLAGS 1 + +/* define if you have libunwind */ +#undef HAVE_LIB_UNWIND + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* define if the compiler implements namespaces */ +#undef HAVE_NAMESPACES + +/* Define if you have POSIX threads libraries and header files. */ +#undef HAVE_PTHREAD + +/* define if the compiler implements pthread_rwlock_* */ +#undef HAVE_RWLOCK + +/* Define if you have the `sigaltstack' function */ +#undef HAVE_SIGALTSTACK + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSCALL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SYSCALL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UCONTEXT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* define if the compiler supports using expression for operator */ +#undef HAVE_USING_OPERATOR + +/* define if your compiler has __attribute__ */ +#undef HAVE___ATTRIBUTE__ + +/* define if your compiler has __builtin_expect */ +#undef HAVE___BUILTIN_EXPECT + +/* define if your compiler has __sync_val_compare_and_swap */ +#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* How to access the PC from a struct ucontext */ +#undef PC_FROM_UCONTEXT + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#undef PTHREAD_CREATE_JOINABLE + +/* The size of `void *', as computed by sizeof. */ +#undef SIZEOF_VOID_P + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* the namespace where STL code like vector<> is defined */ +#undef STL_NAMESPACE + +/* Version number of package */ +#undef VERSION + +/* Stops putting the code inside the Google namespace */ +#define _END_GOOGLE_NAMESPACE_ } + +/* Puts following code inside the Google namespace */ +#define _START_GOOGLE_NAMESPACE_ namespace google { + +/* Always the empty-string on non-windows systems. On windows, should be + "__declspec(dllexport)". This way, when we compile the dll, we export our + functions/classes. It's safe to define this here because config.h is only + used internally, to compile the DLL, and every DLL source file #includes + "config.h" before anything else. */ +#ifndef GOOGLE_GLOG_DLL_DECL +# define GOOGLE_GLOG_IS_A_DLL 1 /* not set if you're statically linking */ +# define GOOGLE_GLOG_DLL_DECL __declspec(dllexport) +# define GOOGLE_GLOG_DLL_DECL_FOR_UNITTESTS __declspec(dllimport) +#endif diff --git a/extern/libmv/third_party/glog/src/windows/glog/log_severity.h b/extern/libmv/third_party/glog/src/windows/glog/log_severity.h new file mode 100644 index 00000000000..5e7d09effb2 --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/glog/log_severity.h @@ -0,0 +1,88 @@ +// This file is automatically generated from src/glog/log_severity.h +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright (c) 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef BASE_LOG_SEVERITY_H__ +#define BASE_LOG_SEVERITY_H__ + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// Variables of type LogSeverity are widely taken to lie in the range +// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if +// you ever need to change their values or add a new severity. +typedef int LogSeverity; + +const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; + +// DFATAL is FATAL in debug mode, ERROR in normal mode +#ifdef NDEBUG +#define DFATAL_LEVEL ERROR +#else +#define DFATAL_LEVEL FATAL +#endif + +extern GOOGLE_GLOG_DLL_DECL const char* const LogSeverityNames[NUM_SEVERITIES]; + +// NDEBUG usage helpers related to (RAW_)DCHECK: +// +// DEBUG_MODE is for small !NDEBUG uses like +// if (DEBUG_MODE) foo.CheckThatFoo(); +// instead of substantially more verbose +// #ifndef NDEBUG +// foo.CheckThatFoo(); +// #endif +// +// IF_DEBUG_MODE is for small !NDEBUG uses like +// IF_DEBUG_MODE( string error; ) +// DCHECK(Foo(&error)) << error; +// instead of substantially more verbose +// #ifndef NDEBUG +// string error; +// DCHECK(Foo(&error)) << error; +// #endif +// +#ifdef NDEBUG +enum { DEBUG_MODE = 0 }; +#define IF_DEBUG_MODE(x) +#else +enum { DEBUG_MODE = 1 }; +#define IF_DEBUG_MODE(x) x +#endif + +#endif // BASE_LOG_SEVERITY_H__ diff --git a/extern/libmv/third_party/glog/src/windows/glog/logging.h b/extern/libmv/third_party/glog/src/windows/glog/logging.h new file mode 100644 index 00000000000..de51586f8e3 --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/glog/logging.h @@ -0,0 +1,1510 @@ +// This file is automatically generated from src/glog/logging.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright (c) 1999, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Ray Sidney +// +// This file contains #include information about logging-related stuff. +// Pretty much everybody needs to #include this file so that they can +// log various happenings. +// +#ifndef _LOGGING_H_ +#define _LOGGING_H_ + +#include +#include +#include +#include +#if 0 +# include +#endif +#ifdef __DEPRECATED +// Make GCC quiet. +# undef __DEPRECATED +# include +# define __DEPRECATED +#else +# include +#endif +#include + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// We care a lot about number of bits things take up. Unfortunately, +// systems define their bit-specific ints in a lot of different ways. +// We use our own way, and have a typedef to get there. +// Note: these commands below may look like "#if 1" or "#if 0", but +// that's because they were constructed that way at ./configure time. +// Look at logging.h.in to see how they're calculated (based on your config). +#if 0 +#include // the normal place uint16_t is defined +#endif +#if 0 +#include // the normal place u_int16_t is defined +#endif +#if 0 +#include // a third place for uint16_t or u_int16_t +#endif + +#if 1 +#include "third_party/gflags/gflags.h" +#endif + +namespace google { + +#if 0 // the C99 format +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +#elif 0 // the BSD format +typedef int32_t int32; +typedef u_int32_t uint32; +typedef int64_t int64; +typedef u_int64_t uint64; +#elif 1 // the windows (vc7) format +typedef __int32 int32; +typedef unsigned __int32 uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; +#else +#error Do not know how to define a 32-bit integer quantity on your system +#endif + +} + +// The global value of GOOGLE_STRIP_LOG. All the messages logged to +// LOG(XXX) with severity less than GOOGLE_STRIP_LOG will not be displayed. +// If it can be determined at compile time that the message will not be +// printed, the statement will be compiled out. +// +// Example: to strip out all INFO and WARNING messages, use the value +// of 2 below. To make an exception for WARNING messages from a single +// file, add "#define GOOGLE_STRIP_LOG 1" to that file _before_ including +// base/logging.h +#ifndef GOOGLE_STRIP_LOG +#define GOOGLE_STRIP_LOG 0 +#endif + +// GCC can be told that a certain branch is not likely to be taken (for +// instance, a CHECK failure), and use that information in static analysis. +// Giving it this information can help it optimize for the common case in +// the absence of better information (ie. -fprofile-arcs). +// +#ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN +#if 0 +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) +#else +#define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x +#endif +#endif + +// Make a bunch of macros for logging. The way to log things is to stream +// things to LOG(). E.g., +// +// LOG(INFO) << "Found " << num_cookies << " cookies"; +// +// You can capture log messages in a string, rather than reporting them +// immediately: +// +// vector errors; +// LOG_STRING(ERROR, &errors) << "Couldn't parse cookie #" << cookie_num; +// +// This pushes back the new error onto 'errors'; if given a NULL pointer, +// it reports the error via LOG(ERROR). +// +// You can also do conditional logging: +// +// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// You can also do occasional logging (log every n'th occurrence of an +// event): +// +// LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// The above will cause log messages to be output on the 1st, 11th, 21st, ... +// times it is executed. Note that the special COUNTER value is used to +// identify which repetition is happening. +// +// You can also do occasional conditional logging (log every n'th +// occurrence of an event, when condition is satisfied): +// +// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER +// << "th big cookie"; +// +// You can log messages the first N times your code executes a line. E.g. +// +// LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie"; +// +// Outputs log messages for the first 20 times it is executed. +// +// Analogous SYSLOG, SYSLOG_IF, and SYSLOG_EVERY_N macros are available. +// These log to syslog as well as to the normal logs. If you use these at +// all, you need to be aware that syslog can drastically reduce performance, +// especially if it is configured for remote logging! Don't use these +// unless you fully understand this and have a concrete need to use them. +// Even then, try to minimize your use of them. +// +// There are also "debug mode" logging macros like the ones above: +// +// DLOG(INFO) << "Found cookies"; +// +// DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; +// +// DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie"; +// +// All "debug mode" logging is compiled away to nothing for non-debug mode +// compiles. +// +// We also have +// +// LOG_ASSERT(assertion); +// DLOG_ASSERT(assertion); +// +// which is syntactic sugar for {,D}LOG_IF(FATAL, assert fails) << assertion; +// +// There are "verbose level" logging macros. They look like +// +// VLOG(1) << "I'm printed when you run the program with --v=1 or more"; +// VLOG(2) << "I'm printed when you run the program with --v=2 or more"; +// +// These always log at the INFO log level (when they log at all). +// The verbose logging can also be turned on module-by-module. For instance, +// --vmodule=mapreduce=2,file=1,gfs*=3 --v=0 +// will cause: +// a. VLOG(2) and lower messages to be printed from mapreduce.{h,cc} +// b. VLOG(1) and lower messages to be printed from file.{h,cc} +// c. VLOG(3) and lower messages to be printed from files prefixed with "gfs" +// d. VLOG(0) and lower messages to be printed from elsewhere +// +// The wildcarding functionality shown by (c) supports both '*' (match +// 0 or more characters) and '?' (match any single character) wildcards. +// +// There's also VLOG_IS_ON(n) "verbose level" condition macro. To be used as +// +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished with just VLOG(2) << ...; +// } +// +// There are also VLOG_IF, VLOG_EVERY_N and VLOG_IF_EVERY_N "verbose level" +// condition macros for sample cases, when some extra computation and +// preparation for logs is not needed. +// VLOG_IF(1, (size > 1024)) +// << "I'm printed when size is more than 1024 and when you run the " +// "program with --v=1 or more"; +// VLOG_EVERY_N(1, 10) +// << "I'm printed every 10th occurrence, and when you run the program " +// "with --v=1 or more. Present occurence is " << COUNTER; +// VLOG_IF_EVERY_N(1, (size > 1024), 10) +// << "I'm printed on every 10th occurence of case when size is more " +// " than 1024, when you run the program with --v=1 or more. "; +// "Present occurence is " << COUNTER; +// +// The supported severity levels for macros that allow you to specify one +// are (in increasing order of severity) INFO, WARNING, ERROR, and FATAL. +// Note that messages of a given severity are logged not only in the +// logfile for that severity, but also in all logfiles of lower severity. +// E.g., a message of severity FATAL will be logged to the logfiles of +// severity FATAL, ERROR, WARNING, and INFO. +// +// There is also the special severity of DFATAL, which logs FATAL in +// debug mode, ERROR in normal mode. +// +// Very important: logging a message at the FATAL severity level causes +// the program to terminate (after the message is logged). +// +// Unless otherwise specified, logs will be written to the filename +// "...log..", followed +// by the date, time, and pid (you can't prevent the date, time, and pid +// from being in the filename). +// +// The logging code takes two flags: +// --v=# set the verbose level +// --logtostderr log all the messages to stderr instead of to logfiles + +// LOG LINE PREFIX FORMAT +// +// Log lines have this form: +// +// Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg... +// +// where the fields are defined as follows: +// +// L A single character, representing the log level +// (eg 'I' for INFO) +// mm The month (zero padded; ie May is '05') +// dd The day (zero padded) +// hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds +// threadid The space-padded thread ID as returned by GetTID() +// (this matches the PID on Linux) +// file The file name +// line The line number +// msg The user-supplied message +// +// Example: +// +// I1103 11:57:31.739339 24395 google.cc:2341] Command line: ./some_prog +// I1103 11:57:31.739403 24395 google.cc:2342] Process id 24395 +// +// NOTE: although the microseconds are useful for comparing events on +// a single machine, clocks on different machines may not be well +// synchronized. Hence, use caution when comparing the low bits of +// timestamps from different machines. + +#ifndef DECLARE_VARIABLE +#define MUST_UNDEF_GFLAGS_DECLARE_MACROS +#define DECLARE_VARIABLE(type, name, tn) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name + +// bool specialization +#define DECLARE_bool(name) \ + DECLARE_VARIABLE(bool, name, bool) + +// int32 specialization +#define DECLARE_int32(name) \ + DECLARE_VARIABLE(google::int32, name, int32) + +// Special case for string, because we have to specify the namespace +// std::string, which doesn't play nicely with our FLAG__namespace hackery. +#define DECLARE_string(name) \ + namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ + extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ + } \ + using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#endif + +// Set whether log messages go to stderr instead of logfiles +DECLARE_bool(logtostderr); + +// Set whether log messages go to stderr in addition to logfiles. +DECLARE_bool(alsologtostderr); + +// Log messages at a level >= this flag are automatically sent to +// stderr in addition to log files. +DECLARE_int32(stderrthreshold); + +// Set whether the log prefix should be prepended to each line of output. +DECLARE_bool(log_prefix); + +// Log messages at a level <= this flag are buffered. +// Log messages at a higher level are flushed immediately. +DECLARE_int32(logbuflevel); + +// Sets the maximum number of seconds which logs may be buffered for. +DECLARE_int32(logbufsecs); + +// Log suppression level: messages logged at a lower level than this +// are suppressed. +DECLARE_int32(minloglevel); + +// If specified, logfiles are written into this directory instead of the +// default logging directory. +DECLARE_string(log_dir); + +// Sets the path of the directory into which to put additional links +// to the log files. +DECLARE_string(log_link); + +DECLARE_int32(v); // in vlog_is_on.cc + +// Sets the maximum log file size (in MB). +DECLARE_int32(max_log_size); + +// Sets whether to avoid logging to the disk if the disk is full. +DECLARE_bool(stop_logging_if_full_disk); + +#ifdef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef MUST_UNDEF_GFLAGS_DECLARE_MACROS +#undef DECLARE_VARIABLE +#undef DECLARE_bool +#undef DECLARE_int32 +#undef DECLARE_string +#endif + +// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for +// security reasons. See LOG(severtiy) below. + +// A few definitions of macros that don't generate much code. Since +// LOG(INFO) and its ilk are used all over our code, it's +// better to have compact code for these operations. + +#if GOOGLE_STRIP_LOG == 0 +#define COMPACT_GOOGLE_LOG_INFO google::LogMessage( \ + __FILE__, __LINE__) +#define LOG_TO_STRING_INFO(message) google::LogMessage( \ + __FILE__, __LINE__, google::INFO, message) +#else +#define COMPACT_GOOGLE_LOG_INFO google::NullStream() +#define LOG_TO_STRING_INFO(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 1 +#define COMPACT_GOOGLE_LOG_WARNING google::LogMessage( \ + __FILE__, __LINE__, google::WARNING) +#define LOG_TO_STRING_WARNING(message) google::LogMessage( \ + __FILE__, __LINE__, google::WARNING, message) +#else +#define COMPACT_GOOGLE_LOG_WARNING google::NullStream() +#define LOG_TO_STRING_WARNING(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 2 +#define COMPACT_GOOGLE_LOG_ERROR google::LogMessage( \ + __FILE__, __LINE__, google::ERROR) +#define LOG_TO_STRING_ERROR(message) google::LogMessage( \ + __FILE__, __LINE__, google::ERROR, message) +#else +#define COMPACT_GOOGLE_LOG_ERROR google::NullStream() +#define LOG_TO_STRING_ERROR(message) google::NullStream() +#endif + +#if GOOGLE_STRIP_LOG <= 3 +#define COMPACT_GOOGLE_LOG_FATAL google::LogMessageFatal( \ + __FILE__, __LINE__) +#define LOG_TO_STRING_FATAL(message) google::LogMessage( \ + __FILE__, __LINE__, google::FATAL, message) +#else +#define COMPACT_GOOGLE_LOG_FATAL google::NullStreamFatal() +#define LOG_TO_STRING_FATAL(message) google::NullStreamFatal() +#endif + +// For DFATAL, we want to use LogMessage (as opposed to +// LogMessageFatal), to be consistent with the original behavior. +#ifdef NDEBUG +#define COMPACT_GOOGLE_LOG_DFATAL COMPACT_GOOGLE_LOG_ERROR +#elif GOOGLE_STRIP_LOG <= 3 +#define COMPACT_GOOGLE_LOG_DFATAL google::LogMessage( \ + __FILE__, __LINE__, google::FATAL) +#else +#define COMPACT_GOOGLE_LOG_DFATAL google::NullStreamFatal() +#endif + +#define GOOGLE_LOG_INFO(counter) google::LogMessage(__FILE__, __LINE__, google::INFO, counter, &google::LogMessage::SendToLog) +#define SYSLOG_INFO(counter) \ + google::LogMessage(__FILE__, __LINE__, google::INFO, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_WARNING(counter) \ + google::LogMessage(__FILE__, __LINE__, google::WARNING, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_ERROR(counter) \ + google::LogMessage(__FILE__, __LINE__, google::ERROR, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_FATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::FATAL, counter, \ + &google::LogMessage::SendToSyslogAndLog) +#define GOOGLE_LOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToLog) +#define SYSLOG_DFATAL(counter) \ + google::LogMessage(__FILE__, __LINE__, google::DFATAL_LEVEL, counter, \ + &google::LogMessage::SendToSyslogAndLog) + +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) +// A very useful logging macro to log windows errors: +#define LOG_SYSRESULT(result) \ + if (FAILED(result)) { \ + LPTSTR message = NULL; \ + LPTSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + FORMAT_MESSAGE_FROM_SYSTEM, \ + 0, result, 0, msg, 100, NULL); \ + if (message_length > 0) { \ + google::LogMessage(__FILE__, __LINE__, ERROR, 0, \ + &google::LogMessage::SendToLog).stream() << message; \ + LocalFree(message); \ + } \ + } +#endif + +// We use the preprocessor's merging operator, "##", so that, e.g., +// LOG(INFO) becomes the token GOOGLE_LOG_INFO. There's some funny +// subtle difference between ostream member streaming functions (e.g., +// ostream::operator<<(int) and ostream non-member streaming functions +// (e.g., ::operator<<(ostream&, string&): it turns out that it's +// impossible to stream something like a string directly to an unnamed +// ostream. We employ a neat hack by calling the stream() member +// function of LogMessage which seems to avoid the problem. +#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream() +#define SYSLOG(severity) SYSLOG_ ## severity(0).stream() + +namespace google { + +// They need the definitions of integer types. +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Initialize google's logging library. You will see the program name +// specified by argv0 in log outputs. +GOOGLE_GLOG_DLL_DECL void InitGoogleLogging(const char* argv0); + +// Shutdown google's logging library. +GOOGLE_GLOG_DLL_DECL void ShutdownGoogleLogging(); + +// Install a function which will be called after LOG(FATAL). +GOOGLE_GLOG_DLL_DECL void InstallFailureFunction(void (*fail_func)()); + +class LogSink; // defined below + +// If a non-NULL sink pointer is given, we push this message to that sink. +// For LOG_TO_SINK we then do normal LOG(severity) logging as well. +// This is useful for capturing messages and passing/storing them +// somewhere more specific than the global log of the process. +// Argument types: +// LogSink* sink; +// LogSeverity severity; +// The cast is to disambiguate NULL arguments. +#define LOG_TO_SINK(sink, severity) \ + google::LogMessage( \ + __FILE__, __LINE__, \ + google::severity, \ + static_cast(sink), true).stream() +#define LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity) \ + google::LogMessage( \ + __FILE__, __LINE__, \ + google::severity, \ + static_cast(sink), false).stream() + +// If a non-NULL string pointer is given, we write this message to that string. +// We then do normal LOG(severity) logging as well. +// This is useful for capturing messages and storing them somewhere more +// specific than the global log of the process. +// Argument types: +// string* message; +// LogSeverity severity; +// The cast is to disambiguate NULL arguments. +// NOTE: LOG(severity) expands to LogMessage().stream() for the specified +// severity. +#define LOG_TO_STRING(severity, message) \ + LOG_TO_STRING_##severity(static_cast(message)).stream() + +// If a non-NULL pointer is given, we push the message onto the end +// of a vector of strings; otherwise, we report it with LOG(severity). +// This is handy for capturing messages and perhaps passing them back +// to the caller, rather than reporting them immediately. +// Argument types: +// LogSeverity severity; +// vector *outvec; +// The cast is to disambiguate NULL arguments. +#define LOG_STRING(severity, outvec) \ + LOG_TO_STRING_##severity(static_cast*>(outvec)).stream() + +#define LOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) +#define SYSLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & SYSLOG(severity) + +#define LOG_ASSERT(condition) \ + LOG_IF(FATAL, !(condition)) << "Assert failed: " #condition +#define SYSLOG_ASSERT(condition) \ + SYSLOG_IF(FATAL, !(condition)) << "Assert failed: " #condition + +// CHECK dies with a fatal error if condition is not true. It is *not* +// controlled by NDEBUG, so the check will be executed regardless of +// compilation mode. Therefore, it is safe to do things like: +// CHECK(fp->Write(x) == 4) +#define CHECK(condition) \ + LOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A container for a string pointer which can be evaluated to a bool - +// true iff the pointer is NULL. +struct CheckOpString { + CheckOpString(std::string* str) : str_(str) { } + // No destructor: if str_ is non-NULL, we're about to LOG(FATAL), + // so there's no point in cleaning up str_. + operator bool() const { + return GOOGLE_PREDICT_BRANCH_NOT_TAKEN(str_ != NULL); + } + std::string* str_; +}; + +// Function is overloaded for integral types to allow static const +// integrals declared in classes and not defined to be used as arguments to +// CHECK* macros. It's not encouraged though. +template +inline const T& GetReferenceableValue(const T& t) { return t; } +inline char GetReferenceableValue(char t) { return t; } +inline unsigned char GetReferenceableValue(unsigned char t) { return t; } +inline signed char GetReferenceableValue(signed char t) { return t; } +inline short GetReferenceableValue(short t) { return t; } +inline unsigned short GetReferenceableValue(unsigned short t) { return t; } +inline int GetReferenceableValue(int t) { return t; } +inline unsigned int GetReferenceableValue(unsigned int t) { return t; } +inline long GetReferenceableValue(long t) { return t; } +inline unsigned long GetReferenceableValue(unsigned long t) { return t; } +inline long long GetReferenceableValue(long long t) { return t; } +inline unsigned long long GetReferenceableValue(unsigned long long t) { + return t; +} + +// This is a dummy class to define the following operator. +struct DummyClassToDefineOperator {}; + +} + +// Define global operator<< to declare using ::operator<<. +// This declaration will allow use to use CHECK macros for user +// defined classes which have operator<< (e.g., stl_logging.h). +inline std::ostream& operator<<( + std::ostream& out, const google::DummyClassToDefineOperator&) { + return out; +} + +namespace google { + +// Build the error message string. +template +std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { + // It means that we cannot use stl_logging if compiler doesn't + // support using expression for operator. + // TODO(hamaji): Figure out a way to fix. +#if 1 + using ::operator<<; +#endif + std::strstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + return new std::string(ss.str(), ss.pcount()); +} + +// Helper functions for CHECK_OP macro. +// The (int, int) specialization works around the issue that the compiler +// will not instantiate the template version of the function on values of +// unnamed enum type - see comment below. +#define DEFINE_CHECK_OP_IMPL(name, op) \ + template \ + inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ + const char* names) { \ + if (v1 op v2) return NULL; \ + else return MakeCheckOpString(v1, v2, names); \ + } \ + inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ + return Check##name##Impl(v1, v2, names); \ + } + +// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h +// provides its own #defines for the simpler names EQ, NE, LE, etc. +// This happens if, for example, those are used as token names in a +// yacc grammar. +DEFINE_CHECK_OP_IMPL(_EQ, ==) +DEFINE_CHECK_OP_IMPL(_NE, !=) +DEFINE_CHECK_OP_IMPL(_LE, <=) +DEFINE_CHECK_OP_IMPL(_LT, < ) +DEFINE_CHECK_OP_IMPL(_GE, >=) +DEFINE_CHECK_OP_IMPL(_GT, > ) +#undef DEFINE_CHECK_OP_IMPL + +// Helper macro for binary operators. +// Don't use this macro directly in your code, use CHECK_EQ et al below. + +#if defined(STATIC_ANALYSIS) +// Only for static analysis tool to know that it is equivalent to assert +#define CHECK_OP_LOG(name, op, val1, val2, log) CHECK((val1) op (val2)) +#elif !defined(NDEBUG) +// In debug mode, avoid constructing CheckOpStrings if possible, +// to reduce the overhead of CHECK statments by 2x. +// Real DCHECK-heavy tests have seen 1.5x speedups. + +// The meaning of "string" might be different between now and +// when this macro gets invoked (e.g., if someone is experimenting +// with other string implementations that get defined after this +// file is included). Save the current meaning now and use it +// in the macro. +typedef std::string _Check_string; +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::_Check_string* _result = \ + google::Check##name##Impl( \ + google::GetReferenceableValue(val1), \ + google::GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, \ + google::CheckOpString(_result)).stream() +#else +// In optimized mode, use CheckOpString to hint to compiler that +// the while condition is unlikely. +#define CHECK_OP_LOG(name, op, val1, val2, log) \ + while (google::CheckOpString _result = \ + google::Check##name##Impl( \ + google::GetReferenceableValue(val1), \ + google::GetReferenceableValue(val2), \ + #val1 " " #op " " #val2)) \ + log(__FILE__, __LINE__, _result).stream() +#endif // STATIC_ANALYSIS, !NDEBUG + +#if GOOGLE_STRIP_LOG <= 3 +#define CHECK_OP(name, op, val1, val2) \ + CHECK_OP_LOG(name, op, val1, val2, google::LogMessageFatal) +#else +#define CHECK_OP(name, op, val1, val2) \ + CHECK_OP_LOG(name, op, val1, val2, google::NullStreamFatal) +#endif // STRIP_LOG <= 3 + +// Equality/Inequality checks - compare two values, and log a FATAL message +// including the two values when the result is not as expected. The values +// must have operator<<(ostream, ...) defined. +// +// You may append to the error message like so: +// CHECK_NE(1, 2) << ": The world must be ending!"; +// +// We are very careful to ensure that each argument is evaluated exactly +// once, and that anything which is legal to pass as a function argument is +// legal here. In particular, the arguments may be temporary expressions +// which will end up being destroyed at the end of the apparent statement, +// for example: +// CHECK_EQ(string("abc")[1], 'b'); +// +// WARNING: These don't compile correctly if one of the arguments is a pointer +// and the other is NULL. To work around this, simply static_cast NULL to the +// type of the desired pointer. + +#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==, val1, val2) +#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=, val1, val2) +#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=, val1, val2) +#define CHECK_LT(val1, val2) CHECK_OP(_LT, < , val1, val2) +#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=, val1, val2) +#define CHECK_GT(val1, val2) CHECK_OP(_GT, > , val1, val2) + +// Check that the input is non NULL. This very useful in constructor +// initializer lists. + +#define CHECK_NOTNULL(val) \ + google::CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) + +// Helper functions for string comparisons. +// To avoid bloat, the definitions are in logging.cc. +#define DECLARE_CHECK_STROP_IMPL(func, expected) \ + GOOGLE_GLOG_DLL_DECL std::string* Check##func##expected##Impl( \ + const char* s1, const char* s2, const char* names); +DECLARE_CHECK_STROP_IMPL(strcmp, true) +DECLARE_CHECK_STROP_IMPL(strcmp, false) +DECLARE_CHECK_STROP_IMPL(strcasecmp, true) +DECLARE_CHECK_STROP_IMPL(strcasecmp, false) +#undef DECLARE_CHECK_STROP_IMPL + +// Helper macro for string comparisons. +// Don't use this macro directly in your code, use CHECK_STREQ et al below. +#define CHECK_STROP(func, op, expected, s1, s2) \ + while (google::CheckOpString _result = \ + google::Check##func##expected##Impl((s1), (s2), \ + #s1 " " #op " " #s2)) \ + LOG(FATAL) << *_result.str_ + + +// String (char*) equality/inequality checks. +// CASE versions are case-insensitive. +// +// Note that "s1" and "s2" may be temporary strings which are destroyed +// by the compiler at the end of the current "full expression" +// (e.g. CHECK_STREQ(Foo().c_str(), Bar().c_str())). + +#define CHECK_STREQ(s1, s2) CHECK_STROP(strcmp, ==, true, s1, s2) +#define CHECK_STRNE(s1, s2) CHECK_STROP(strcmp, !=, false, s1, s2) +#define CHECK_STRCASEEQ(s1, s2) CHECK_STROP(strcasecmp, ==, true, s1, s2) +#define CHECK_STRCASENE(s1, s2) CHECK_STROP(strcasecmp, !=, false, s1, s2) + +#define CHECK_INDEX(I,A) CHECK(I < (sizeof(A)/sizeof(A[0]))) +#define CHECK_BOUND(B,A) CHECK(B <= (sizeof(A)/sizeof(A[0]))) + +#define CHECK_DOUBLE_EQ(val1, val2) \ + do { \ + CHECK_LE((val1), (val2)+0.000000000000001L); \ + CHECK_GE((val1), (val2)-0.000000000000001L); \ + } while (0) + +#define CHECK_NEAR(val1, val2, margin) \ + do { \ + CHECK_LE((val1), (val2)+(margin)); \ + CHECK_GE((val1), (val2)-(margin)); \ + } while (0) + +// perror()..googly style! +// +// PLOG() and PLOG_IF() and PCHECK() behave exactly like their LOG* and +// CHECK equivalents with the addition that they postpend a description +// of the current state of errno to their output lines. + +#define PLOG(severity) GOOGLE_PLOG(severity, 0).stream() + +#define GOOGLE_PLOG(severity, counter) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, counter, \ + &google::LogMessage::SendToLog) + +#define PLOG_IF(severity, condition) \ + !(condition) ? (void) 0 : google::LogMessageVoidify() & PLOG(severity) + +// A CHECK() macro that postpends errno if the condition is false. E.g. +// +// if (poll(fds, nfds, timeout) == -1) { PCHECK(errno == EINTR); ... } +#define PCHECK(condition) \ + PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN(!(condition))) \ + << "Check failed: " #condition " " + +// A CHECK() macro that lets you assert the success of a function that +// returns -1 and sets errno in case of an error. E.g. +// +// CHECK_ERR(mkdir(path, 0700)); +// +// or +// +// int fd = open(filename, flags); CHECK_ERR(fd) << ": open " << filename; +#define CHECK_ERR(invocation) \ +PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \ + << #invocation + +// Use macro expansion to create, for each use of LOG_EVERY_N(), static +// variables with the __LINE__ expansion as part of the variable name. +#define LOG_EVERY_N_VARNAME(base, line) LOG_EVERY_N_VARNAME_CONCAT(base, line) +#define LOG_EVERY_N_VARNAME_CONCAT(base, line) base ## line + +#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) +#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) + +#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (condition && \ + ((LOG_OCCURRENCES_MOD_N=(LOG_OCCURRENCES_MOD_N + 1) % n) == (1 % n))) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + if (LOG_OCCURRENCES_MOD_N == 1) \ + google::ErrnoLogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \ + static int LOG_OCCURRENCES = 0; \ + if (LOG_OCCURRENCES <= n) \ + ++LOG_OCCURRENCES; \ + if (LOG_OCCURRENCES <= n) \ + google::LogMessage( \ + __FILE__, __LINE__, google::severity, LOG_OCCURRENCES, \ + &what_to_do).stream() + +namespace glog_internal_namespace_ { +template +struct CompileAssert { +}; +struct CrashReason; +} // namespace glog_internal_namespace_ + +#define GOOGLE_GLOG_COMPILE_ASSERT(expr, msg) \ + typedef google::glog_internal_namespace_::CompileAssert<(bool(expr))> msg[bool(expr) ? 1 : -1] + +#define LOG_EVERY_N(severity, n) \ + GOOGLE_GLOG_COMPILE_ASSERT(google::severity < \ + google::NUM_SEVERITIES, \ + INVALID_REQUESTED_LOG_SEVERITY); \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define SYSLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_LOG_EVERY_N(severity, (n), google::LogMessage::SendToSyslogAndLog) + +#define PLOG_EVERY_N(severity, n) \ + SOME_KIND_OF_PLOG_EVERY_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_FIRST_N(severity, n) \ + SOME_KIND_OF_LOG_FIRST_N(severity, (n), google::LogMessage::SendToLog) + +#define LOG_IF_EVERY_N(severity, condition, n) \ + SOME_KIND_OF_LOG_IF_EVERY_N(severity, (condition), (n), google::LogMessage::SendToLog) + +// We want the special COUNTER value available for LOG_EVERY_X()'ed messages +enum PRIVATE_Counter {COUNTER}; + + +// Plus some debug-logging macros that get compiled to nothing for production + +#ifndef NDEBUG + +#define DLOG(severity) LOG(severity) +#define DVLOG(verboselevel) VLOG(verboselevel) +#define DLOG_IF(severity, condition) LOG_IF(severity, condition) +#define DLOG_EVERY_N(severity, n) LOG_EVERY_N(severity, n) +#define DLOG_IF_EVERY_N(severity, condition, n) \ + LOG_IF_EVERY_N(severity, condition, n) +#define DLOG_ASSERT(condition) LOG_ASSERT(condition) + +// debug-only checking. not executed in NDEBUG mode. +#define DCHECK(condition) CHECK(condition) +#define DCHECK_EQ(val1, val2) CHECK_EQ(val1, val2) +#define DCHECK_NE(val1, val2) CHECK_NE(val1, val2) +#define DCHECK_LE(val1, val2) CHECK_LE(val1, val2) +#define DCHECK_LT(val1, val2) CHECK_LT(val1, val2) +#define DCHECK_GE(val1, val2) CHECK_GE(val1, val2) +#define DCHECK_GT(val1, val2) CHECK_GT(val1, val2) +#define DCHECK_NOTNULL(val) CHECK_NOTNULL(val) +#define DCHECK_STREQ(str1, str2) CHECK_STREQ(str1, str2) +#define DCHECK_STRCASEEQ(str1, str2) CHECK_STRCASEEQ(str1, str2) +#define DCHECK_STRNE(str1, str2) CHECK_STRNE(str1, str2) +#define DCHECK_STRCASENE(str1, str2) CHECK_STRCASENE(str1, str2) + +#else // NDEBUG + +#define DLOG(severity) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DVLOG(verboselevel) \ + (true || !VLOG_IS_ON(verboselevel)) ?\ + (void) 0 : google::LogMessageVoidify() & LOG(INFO) + +#define DLOG_IF(severity, condition) \ + (true || !(condition)) ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_EVERY_N(severity, n) \ + true ? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_IF_EVERY_N(severity, condition, n) \ + (true || !(condition))? (void) 0 : google::LogMessageVoidify() & LOG(severity) + +#define DLOG_ASSERT(condition) \ + true ? (void) 0 : LOG_ASSERT(condition) + +#define DCHECK(condition) \ + while (false) \ + CHECK(condition) + +#define DCHECK_EQ(val1, val2) \ + while (false) \ + CHECK_EQ(val1, val2) + +#define DCHECK_NE(val1, val2) \ + while (false) \ + CHECK_NE(val1, val2) + +#define DCHECK_LE(val1, val2) \ + while (false) \ + CHECK_LE(val1, val2) + +#define DCHECK_LT(val1, val2) \ + while (false) \ + CHECK_LT(val1, val2) + +#define DCHECK_GE(val1, val2) \ + while (false) \ + CHECK_GE(val1, val2) + +#define DCHECK_GT(val1, val2) \ + while (false) \ + CHECK_GT(val1, val2) + +#define DCHECK_NOTNULL(val) (val) + +#define DCHECK_STREQ(str1, str2) \ + while (false) \ + CHECK_STREQ(str1, str2) + +#define DCHECK_STRCASEEQ(str1, str2) \ + while (false) \ + CHECK_STRCASEEQ(str1, str2) + +#define DCHECK_STRNE(str1, str2) \ + while (false) \ + CHECK_STRNE(str1, str2) + +#define DCHECK_STRCASENE(str1, str2) \ + while (false) \ + CHECK_STRCASENE(str1, str2) + + +#endif // NDEBUG + +// Log only in verbose mode. + +#define VLOG(verboselevel) LOG_IF(INFO, VLOG_IS_ON(verboselevel)) + +#define VLOG_IF(verboselevel, condition) \ + LOG_IF(INFO, (condition) && VLOG_IS_ON(verboselevel)) + +#define VLOG_EVERY_N(verboselevel, n) \ + LOG_IF_EVERY_N(INFO, VLOG_IS_ON(verboselevel), n) + +#define VLOG_IF_EVERY_N(verboselevel, condition, n) \ + LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) + +// +// This class more or less represents a particular log message. You +// create an instance of LogMessage and then stream stuff to it. +// When you finish streaming to it, ~LogMessage is called and the +// full message gets streamed to the appropriate destination. +// +// You shouldn't actually use LogMessage's constructor to log things, +// though. You should use the LOG() macro (and variants thereof) +// above. +class GOOGLE_GLOG_DLL_DECL LogMessage { +public: + enum { + // Passing kNoLogPrefix for the line number disables the + // log-message prefix. Useful for using the LogMessage + // infrastructure as a printing utility. See also the --log_prefix + // flag for controlling the log-message prefix on an + // application-wide basis. + kNoLogPrefix = -1 + }; + + // LogStream inherit from non-DLL-exported class (std::ostrstream) + // and VC++ produces a warning for this situation. + // However, MSDN says "C4275 can be ignored in Microsoft Visual C++ + // 2005 if you are deriving from a type in the Standard C++ Library" + // http://msdn.microsoft.com/en-us/library/3tdb471s(VS.80).aspx + // Let's just ignore the warning. +#ifdef _MSC_VER +# pragma warning(disable: 4275) +#endif + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { +#ifdef _MSC_VER +# pragma warning(default: 4275) +#endif + public: + LogStream(char *buf, int len, int ctr) + : ostrstream(buf, len), + ctr_(ctr) { + self_ = this; + } + + int ctr() const { return ctr_; } + void set_ctr(int ctr) { ctr_ = ctr; } + LogStream* self() const { return self_; } + + private: + int ctr_; // Counter hack (for the LOG_EVERY_X() macro) + LogStream *self_; // Consistency check hack + }; + +public: + // icc 8 requires this typedef to avoid an internal compiler error. + typedef void (LogMessage::*SendMethod)(); + + LogMessage(const char* file, int line, LogSeverity severity, int ctr, + SendMethod send_method); + + // Two special constructors that generate reduced amounts of code at + // LOG call sites for common cases. + + // Used for LOG(INFO): Implied are: + // severity = INFO, ctr = 0, send_method = &LogMessage::SendToLog. + // + // Using this constructor instead of the more complex constructor above + // saves 19 bytes per call site. + LogMessage(const char* file, int line); + + // Used for LOG(severity) where severity != INFO. Implied + // are: ctr = 0, send_method = &LogMessage::SendToLog + // + // Using this constructor instead of the more complex constructor above + // saves 17 bytes per call site. + LogMessage(const char* file, int line, LogSeverity severity); + + // Constructor to log this message to a specified sink (if not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SendToSinkAndLog if + // also_send_to_log is true, send_method = &LogMessage::SendToSink otherwise. + LogMessage(const char* file, int line, LogSeverity severity, LogSink* sink, + bool also_send_to_log); + + // Constructor where we also give a vector pointer + // for storing the messages (if the pointer is not NULL). + // Implied are: ctr = 0, send_method = &LogMessage::SaveOrSendToLog. + LogMessage(const char* file, int line, LogSeverity severity, + std::vector* outvec); + + // Constructor where we also give a string pointer for storing the + // message (if the pointer is not NULL). Implied are: ctr = 0, + // send_method = &LogMessage::WriteToStringAndLog. + LogMessage(const char* file, int line, LogSeverity severity, + std::string* message); + + // A special constructor used for check failures + LogMessage(const char* file, int line, const CheckOpString& result); + + ~LogMessage(); + + // Flush a buffered message to the sink set in the constructor. Always + // called by the destructor, it may also be called from elsewhere if + // needed. Only the first call is actioned; any later ones are ignored. + void Flush(); + + // An arbitrary limit on the length of a single log message. This + // is so that streaming can be done more efficiently. + static const size_t kMaxLogMessageLen; + + // Theses should not be called directly outside of logging.*, + // only passed as SendMethod arguments to other LogMessage methods: + void SendToLog(); // Actually dispatch to the logs + void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs + + // Call abort() or similar to perform LOG(FATAL) crash. + static void Fail() ; + + std::ostream& stream() { return *(data_->stream_); } + + int preserved_errno() const { return data_->preserved_errno_; } + + // Must be called without the log_mutex held. (L < log_mutex) + static int64 num_messages(int severity); + +private: + // Fully internal SendMethod cases: + void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs + void SendToSink(); // Send to sink if provided, do nothing otherwise. + + // Write to string if provided and dispatch to the logs. + void WriteToStringAndLog(); + + void SaveOrSendToLog(); // Save to stringvec if provided, else to logs + + void Init(const char* file, int line, LogSeverity severity, + void (LogMessage::*send_method)()); + + // Used to fill in crash information during LOG(FATAL) failures. + void RecordCrashReason(glog_internal_namespace_::CrashReason* reason); + + // Counts of messages sent at each priority: + static int64 num_messages_[NUM_SEVERITIES]; // under log_mutex + + // We keep the data in a separate struct so that each instance of + // LogMessage uses less stack space. + struct GOOGLE_GLOG_DLL_DECL LogMessageData { + LogMessageData() {}; + + int preserved_errno_; // preserved errno + char* buf_; + char* message_text_; // Complete message text (points to selected buffer) + LogStream* stream_alloc_; + LogStream* stream_; + char severity_; // What level is this LogMessage logged at? + int line_; // line number where logging call is. + void (LogMessage::*send_method_)(); // Call this in destructor to send + union { // At most one of these is used: union to keep the size low. + LogSink* sink_; // NULL or sink to send message to + std::vector* outvec_; // NULL or vector to push message onto + std::string* message_; // NULL or string to write message into + }; + time_t timestamp_; // Time of creation of LogMessage + struct ::tm tm_time_; // Time of creation of LogMessage + size_t num_prefix_chars_; // # of chars of prefix in this message + size_t num_chars_to_log_; // # of chars of msg to send to log + size_t num_chars_to_syslog_; // # of chars of msg to send to syslog + const char* basename_; // basename of file that called LOG + const char* fullname_; // fullname of file that called LOG + bool has_been_flushed_; // false => data has not been flushed + bool first_fatal_; // true => this was first fatal msg + + ~LogMessageData(); + private: + LogMessageData(const LogMessageData&); + void operator=(const LogMessageData&); + }; + + static LogMessageData fatal_msg_data_exclusive_; + static LogMessageData fatal_msg_data_shared_; + + LogMessageData* allocated_; + LogMessageData* data_; + + friend class LogDestination; + + LogMessage(const LogMessage&); + void operator=(const LogMessage&); +}; + +// This class happens to be thread-hostile because all instances share +// a single data buffer, but since it can only be created just before +// the process dies, we don't worry so much. +class GOOGLE_GLOG_DLL_DECL LogMessageFatal : public LogMessage { + public: + LogMessageFatal(const char* file, int line); + LogMessageFatal(const char* file, int line, const CheckOpString& result); + ~LogMessageFatal() ; +}; + +// A non-macro interface to the log facility; (useful +// when the logging level is not a compile-time constant). +inline void LogAtLevel(int const severity, std::string const &msg) { + LogMessage(__FILE__, __LINE__, severity).stream() << msg; +} + +// A macro alternative of LogAtLevel. New code may want to use this +// version since there are two advantages: 1. this version outputs the +// file name and the line number where this macro is put like other +// LOG macros, 2. this macro can be used as C++ stream. +#define LOG_AT_LEVEL(severity) google::LogMessage(__FILE__, __LINE__, severity).stream() + +// A small helper for CHECK_NOTNULL(). +template +T* CheckNotNull(const char *file, int line, const char *names, T* t) { + if (t == NULL) { + LogMessageFatal(file, line, new std::string(names)); + } + return t; +} + +// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This +// only works if ostream is a LogStream. If the ostream is not a +// LogStream you'll get an assert saying as much at runtime. +GOOGLE_GLOG_DLL_DECL std::ostream& operator<<(std::ostream &os, + const PRIVATE_Counter&); + + +// Derived class for PLOG*() above. +class GOOGLE_GLOG_DLL_DECL ErrnoLogMessage : public LogMessage { + public: + + ErrnoLogMessage(const char* file, int line, LogSeverity severity, int ctr, + void (LogMessage::*send_method)()); + + // Postpends ": strerror(errno) [errno]". + ~ErrnoLogMessage(); + + private: + ErrnoLogMessage(const ErrnoLogMessage&); + void operator=(const ErrnoLogMessage&); +}; + + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". + +class GOOGLE_GLOG_DLL_DECL LogMessageVoidify { + public: + LogMessageVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(std::ostream&) { } +}; + + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-safe. +GOOGLE_GLOG_DLL_DECL void FlushLogFiles(LogSeverity min_severity); + +// Flushes all log files that contains messages that are at least of +// the specified severity level. Thread-hostile because it ignores +// locking -- used for catastrophic failures. +GOOGLE_GLOG_DLL_DECL void FlushLogFilesUnsafe(LogSeverity min_severity); + +// +// Set the destination to which a particular severity level of log +// messages is sent. If base_filename is "", it means "don't log this +// severity". Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogDestination(LogSeverity severity, + const char* base_filename); + +// +// Set the basename of the symlink to the latest log file at a given +// severity. If symlink_basename is empty, do not make a symlink. If +// you don't call this function, the symlink basename is the +// invocation name of the program. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogSymlink(LogSeverity severity, + const char* symlink_basename); + +// +// Used to send logs to some other kind of destination +// Users should subclass LogSink and override send to do whatever they want. +// Implementations must be thread-safe because a shared instance will +// be called from whichever thread ran the LOG(XXX) line. +class GOOGLE_GLOG_DLL_DECL LogSink { + public: + virtual ~LogSink(); + + // Sink's logging logic (message_len is such as to exclude '\n' at the end). + // This method can't use LOG() or CHECK() as logging system mutex(s) are held + // during this call. + virtual void send(LogSeverity severity, const char* full_filename, + const char* base_filename, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len) = 0; + + // Redefine this to implement waiting for + // the sink's logging logic to complete. + // It will be called after each send() returns, + // but before that LogMessage exits or crashes. + // By default this function does nothing. + // Using this function one can implement complex logic for send() + // that itself involves logging; and do all this w/o causing deadlocks and + // inconsistent rearrangement of log messages. + // E.g. if a LogSink has thread-specific actions, the send() method + // can simply add the message to a queue and wake up another thread that + // handles real logging while itself making some LOG() calls; + // WaitTillSent() can be implemented to wait for that logic to complete. + // See our unittest for an example. + virtual void WaitTillSent(); + + // Returns the normal text output of the log message. + // Can be useful to implement send(). + static std::string ToString(LogSeverity severity, const char* file, int line, + const struct ::tm* tm_time, + const char* message, size_t message_len); +}; + +// Add or remove a LogSink as a consumer of logging data. Thread-safe. +GOOGLE_GLOG_DLL_DECL void AddLogSink(LogSink *destination); +GOOGLE_GLOG_DLL_DECL void RemoveLogSink(LogSink *destination); + +// +// Specify an "extension" added to the filename specified via +// SetLogDestination. This applies to all severity levels. It's +// often used to append the port we're listening on to the logfile +// name. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetLogFilenameExtension( + const char* filename_extension); + +// +// Make it so that all log messages of at least a particular severity +// are logged to stderr (in addition to logging to the usual log +// file(s)). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetStderrLogging(LogSeverity min_severity); + +// +// Make it so that all log messages go only to stderr. Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void LogToStderr(); + +// +// Make it so that all log messages of at least a particular severity are +// logged via email to a list of addresses (in addition to logging to the +// usual log file(s)). The list of addresses is just a string containing +// the email addresses to send to (separated by spaces, say). Thread-safe. +// +GOOGLE_GLOG_DLL_DECL void SetEmailLogging(LogSeverity min_severity, + const char* addresses); + +// A simple function that sends email. dest is a commma-separated +// list of addressess. Thread-safe. +GOOGLE_GLOG_DLL_DECL bool SendEmail(const char *dest, + const char *subject, const char *body); + +GOOGLE_GLOG_DLL_DECL const std::vector& GetLoggingDirectories(); + +// For tests only: Clear the internal [cached] list of logging directories to +// force a refresh the next time GetLoggingDirectories is called. +// Thread-hostile. +void TestOnly_ClearLoggingDirectoriesList(); + +// Returns a set of existing temporary directories, which will be a +// subset of the directories returned by GetLogginDirectories(). +// Thread-safe. +GOOGLE_GLOG_DLL_DECL void GetExistingTempDirectories( + std::vector* list); + +// Print any fatal message again -- useful to call from signal handler +// so that the last thing in the output is the fatal message. +// Thread-hostile, but a race is unlikely. +GOOGLE_GLOG_DLL_DECL void ReprintFatalMessage(); + +// Truncate a log file that may be the append-only output of multiple +// processes and hence can't simply be renamed/reopened (typically a +// stdout/stderr). If the file "path" is > "limit" bytes, copy the +// last "keep" bytes to offset 0 and truncate the rest. Since we could +// be racing with other writers, this approach has the potential to +// lose very small amounts of data. For security, only follow symlinks +// if the path is /proc/self/fd/* +GOOGLE_GLOG_DLL_DECL void TruncateLogFile(const char *path, + int64 limit, int64 keep); + +// Truncate stdout and stderr if they are over the value specified by +// --max_log_size; keep the final 1MB. This function has the same +// race condition as TruncateLogFile. +GOOGLE_GLOG_DLL_DECL void TruncateStdoutStderr(); + +// Return the string representation of the provided LogSeverity level. +// Thread-safe. +GOOGLE_GLOG_DLL_DECL const char* GetLogSeverityName(LogSeverity severity); + +// --------------------------------------------------------------------- +// Implementation details that are not useful to most clients +// --------------------------------------------------------------------- + +// A Logger is the interface used by logging modules to emit entries +// to a log. A typical implementation will dump formatted data to a +// sequence of files. We also provide interfaces that will forward +// the data to another thread so that the invoker never blocks. +// Implementations should be thread-safe since the logging system +// will write to them from multiple threads. + +namespace base { + +class GOOGLE_GLOG_DLL_DECL Logger { + public: + virtual ~Logger(); + + // Writes "message[0,message_len-1]" corresponding to an event that + // occurred at "timestamp". If "force_flush" is true, the log file + // is flushed immediately. + // + // The input message has already been formatted as deemed + // appropriate by the higher level logging facility. For example, + // textual log messages already contain timestamps, and the + // file:linenumber header. + virtual void Write(bool force_flush, + time_t timestamp, + const char* message, + int message_len) = 0; + + // Flush any buffered messages + virtual void Flush() = 0; + + // Get the current LOG file size. + // The returned value is approximate since some + // logged data may not have been flushed to disk yet. + virtual uint32 LogSize() = 0; +}; + +// Get the logger for the specified severity level. The logger +// remains the property of the logging module and should not be +// deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL Logger* GetLogger(LogSeverity level); + +// Set the logger for the specified severity level. The logger +// becomes the property of the logging module and should not +// be deleted by the caller. Thread-safe. +extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); + +} + +// glibc has traditionally implemented two incompatible versions of +// strerror_r(). There is a poorly defined convention for picking the +// version that we want, but it is not clear whether it even works with +// all versions of glibc. +// So, instead, we provide this wrapper that automatically detects the +// version that is in use, and then implements POSIX semantics. +// N.B. In addition to what POSIX says, we also guarantee that "buf" will +// be set to an empty string, if this function failed. This means, in most +// cases, you do not need to check the error code and you can directly +// use the value of "buf". It will never have an undefined value. +GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); + + +// A class for which we define operator<<, which does nothing. +class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { + public: + // Initialize the LogStream so the messages can be written somewhere + // (they'll never be actually displayed). This will be needed if a + // NullStream& is implicitly converted to LogStream&, in which case + // the overloaded NullStream::operator<< will not be invoked. + NullStream() : LogMessage::LogStream(message_buffer_, 1, 0) { } + NullStream(const char* /*file*/, int /*line*/, + const CheckOpString& /*result*/) : + LogMessage::LogStream(message_buffer_, 1, 0) { } + NullStream &stream() { return *this; } + private: + // A very short buffer for messages (which we discard anyway). This + // will be needed if NullStream& converted to LogStream& (e.g. as a + // result of a conditional expression). + char message_buffer_[2]; +}; + +// Do nothing. This operator is inline, allowing the message to be +// compiled away. The message will not be compiled away if we do +// something like (flag ? LOG(INFO) : LOG(ERROR)) << message; when +// SKIP_LOG=WARNING. In those cases, NullStream will be implicitly +// converted to LogStream and the message will be computed and then +// quietly discarded. +template +inline NullStream& operator<<(NullStream &str, const T &value) { return str; } + +// Similar to NullStream, but aborts the program (without stack +// trace), like LogMessageFatal. +class GOOGLE_GLOG_DLL_DECL NullStreamFatal : public NullStream { + public: + NullStreamFatal() { } + NullStreamFatal(const char* file, int line, const CheckOpString& result) : + NullStream(file, line, result) { } + ~NullStreamFatal() { _exit(1); } +}; + +// Install a signal handler that will dump signal information and a stack +// trace when the program crashes on certain signals. We'll install the +// signal handler for the following signals. +// +// SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, and SIGTERM. +// +// By default, the signal handler will write the failure dump to the +// standard error. You can customize the destination by installing your +// own writer function by InstallFailureWriter() below. +// +// Note on threading: +// +// The function should be called before threads are created, if you want +// to use the failure signal handler for all threads. The stack trace +// will be shown only for the thread that receives the signal. In other +// words, stack traces of other threads won't be shown. +GOOGLE_GLOG_DLL_DECL void InstallFailureSignalHandler(); + +// Installs a function that is used for writing the failure dump. "data" +// is the pointer to the beginning of a message to be written, and "size" +// is the size of the message. You should not expect the data is +// terminated with '\0'. +GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( + void (*writer)(const char* data, int size)); + +} + +#endif // _LOGGING_H_ diff --git a/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h b/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h new file mode 100644 index 00000000000..c81e67bf99c --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/glog/raw_logging.h @@ -0,0 +1,189 @@ +// This file is automatically generated from src/glog/raw_logging.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright (c) 2006, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Maxim Lifantsev +// +// Thread-safe logging routines that do not allocate any memory or +// acquire any locks, and can therefore be used by low-level memory +// allocation and synchronization code. + +#ifndef BASE_RAW_LOGGING_H_ +#define BASE_RAW_LOGGING_H_ + +#include + +namespace google { + +#include "glog/log_severity.h" +#include "glog/vlog_is_on.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +// This is similar to LOG(severity) << format... and VLOG(level) << format.., +// but +// * it is to be used ONLY by low-level modules that can't use normal LOG() +// * it is desiged to be a low-level logger that does not allocate any +// memory and does not need any locks, hence: +// * it logs straight and ONLY to STDERR w/o buffering +// * it uses an explicit format and arguments list +// * it will silently chop off really long message strings +// Usage example: +// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); +// RAW_VLOG(3, "status is %i", status); +// These will print an almost standard log lines like this to stderr only: +// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file +// I0821 211317 file.cc:142] RAW: status is 20 +#define RAW_LOG(severity, ...) \ + do { \ + switch (google::severity) { \ + case 0: \ + RAW_LOG_INFO(__VA_ARGS__); \ + break; \ + case 1: \ + RAW_LOG_WARNING(__VA_ARGS__); \ + break; \ + case 2: \ + RAW_LOG_ERROR(__VA_ARGS__); \ + break; \ + case 3: \ + RAW_LOG_FATAL(__VA_ARGS__); \ + break; \ + default: \ + break; \ + } \ + } while (0) + +// The following STRIP_LOG testing is performed in the header file so that it's +// possible to completely compile out the logging code and the log messages. +#if STRIP_LOG == 0 +#define RAW_VLOG(verboselevel, ...) \ + do { \ + if (VLOG_IS_ON(verboselevel)) { \ + RAW_LOG_INFO(__VA_ARGS__); \ + } \ + } while (0) +#else +#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG == 0 + +#if STRIP_LOG == 0 +#define RAW_LOG_INFO(...) google::RawLog__(google::INFO, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG == 0 + +#if STRIP_LOG <= 1 +#define RAW_LOG_WARNING(...) google::RawLog__(google::WARNING, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG <= 1 + +#if STRIP_LOG <= 2 +#define RAW_LOG_ERROR(...) google::RawLog__(google::ERROR, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__) +#endif // STRIP_LOG <= 2 + +#if STRIP_LOG <= 3 +#define RAW_LOG_FATAL(...) google::RawLog__(google::FATAL, \ + __FILE__, __LINE__, __VA_ARGS__) +#else +#define RAW_LOG_FATAL(...) \ + do { \ + google::RawLogStub__(0, __VA_ARGS__); \ + exit(1); \ + } while (0) +#endif // STRIP_LOG <= 3 + +// Similar to CHECK(condition) << message, +// but for low-level modules: we use only RAW_LOG that does not allocate memory. +// We do not want to provide args list here to encourage this usage: +// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args); +// so that the args are not computed when not needed. +#define RAW_CHECK(condition, message) \ + do { \ + if (!(condition)) { \ + RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ + } \ + } while (0) + +// Debug versions of RAW_LOG and RAW_CHECK +#ifndef NDEBUG + +#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message) + +#else // NDEBUG + +#define RAW_DLOG(severity, ...) \ + while (false) \ + RAW_LOG(severity, __VA_ARGS__) +#define RAW_DCHECK(condition, message) \ + while (false) \ + RAW_CHECK(condition, message) + +#endif // NDEBUG + +// Stub log function used to work around for unused variable warnings when +// building with STRIP_LOG > 0. +static inline void RawLogStub__(int ignored, ...) { +} + +// Helper function to implement RAW_LOG and RAW_VLOG +// Logs format... at "severity" level, reporting it +// as called from file:line. +// This does not allocate memory or acquire locks. +GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity, + const char* file, + int line, + const char* format, ...) + ; + +// Hack to propagate time information into this module so that +// this module does not have to directly call localtime_r(), +// which could allocate memory. +GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs); + +} + +#endif // BASE_RAW_LOGGING_H_ diff --git a/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h b/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h new file mode 100644 index 00000000000..409a4011b38 --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/glog/vlog_is_on.h @@ -0,0 +1,133 @@ +// This file is automatically generated from src/glog/vlog_is_on.h.in +// using src/windows/preprocess.sh. +// DO NOT EDIT! + +// Copyright (c) 1999, 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: Ray Sidney and many others +// +// Defines the VLOG_IS_ON macro that controls the variable-verbosity +// conditional logging. +// +// It's used by VLOG and VLOG_IF in logging.h +// and by RAW_VLOG in raw_logging.h to trigger the logging. +// +// It can also be used directly e.g. like this: +// if (VLOG_IS_ON(2)) { +// // do some logging preparation and logging +// // that can't be accomplished e.g. via just VLOG(2) << ...; +// } +// +// The truth value that VLOG_IS_ON(level) returns is determined by +// the three verbosity level flags: +// --v= Gives the default maximal active V-logging level; +// 0 is the default. +// Normally positive values are used for V-logging levels. +// --vmodule= Gives the per-module maximal V-logging levels to override +// the value given by --v. +// E.g. "my_module=2,foo*=3" would change the logging level +// for all code in source files "my_module.*" and "foo*.*" +// ("-inl" suffixes are also disregarded for this matching). +// +// SetVLOGLevel helper function is provided to do limited dynamic control over +// V-logging by overriding the per-module settings given via --vmodule flag. +// +// CAVEAT: --vmodule functionality is not available in non gcc compilers. +// + +#ifndef BASE_VLOG_IS_ON_H_ +#define BASE_VLOG_IS_ON_H_ + +#include "glog/log_severity.h" + +// Annoying stuff for windows -- makes sure clients can import these functions +#ifndef GOOGLE_GLOG_DLL_DECL +# if defined(_WIN32) && !defined(__CYGWIN__) +# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) +# else +# define GOOGLE_GLOG_DLL_DECL +# endif +#endif + +#if defined(__GNUC__) +// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. +// (Normally) the first time every VLOG_IS_ON(n) site is hit, +// we determine what variable will dynamically control logging at this site: +// it's either FLAGS_v or an appropriate internal variable +// matching the current source file that represents results of +// parsing of --vmodule flag and/or SetVLOGLevel calls. +#define VLOG_IS_ON(verboselevel) \ + __extension__ \ + ({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \ + google::int32 verbose_level__ = (verboselevel); \ + (*vlocal__ >= verbose_level__) && \ + ((vlocal__ != &google::kLogSiteUninitialized) || \ + (google::InitVLOG3__(&vlocal__, &FLAGS_v, \ + __FILE__, verbose_level__))); }) +#else +// GNU extensions not available, so we do not support --vmodule. +// Dynamic value of FLAGS_v always controls the logging level. +#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel)) +#endif + +// Set VLOG(_IS_ON) level for module_pattern to log_level. +// This lets us dynamically control what is normally set by the --vmodule flag. +// Returns the level that previously applied to module_pattern. +// NOTE: To change the log level for VLOG(_IS_ON) sites +// that have already executed after/during InitGoogleLogging, +// one needs to supply the exact --vmodule pattern that applied to them. +// (If no --vmodule pattern applied to them +// the value of FLAGS_v will continue to control them.) +extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern, + int log_level); + +// Various declarations needed for VLOG_IS_ON above: ========================= + +// Special value used to indicate that a VLOG_IS_ON site has not been +// initialized. We make this a large value, so the common-case check +// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition +// passes in such cases and InitVLOG3__ is then triggered. +extern google::int32 kLogSiteUninitialized; + +// Helper routine which determines the logging info for a particalur VLOG site. +// site_flag is the address of the site-local pointer to the controlling +// verbosity level +// site_default is the default to use for *site_flag +// fname is the current source file name +// verbose_level is the argument to VLOG_IS_ON +// We will return the return value for VLOG_IS_ON +// and if possible set *site_flag appropriately. +extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__( + google::int32** site_flag, + google::int32* site_default, + const char* fname, + google::int32 verbose_level); + +#endif // BASE_VLOG_IS_ON_H_ diff --git a/extern/libmv/third_party/glog/src/windows/port.cc b/extern/libmv/third_party/glog/src/windows/port.cc new file mode 100644 index 00000000000..bfa6e70afbb --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/port.cc @@ -0,0 +1,64 @@ +/* Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Craig Silverstein + * Copied from google-perftools and modified by Shinichiro Hamaji + */ + +#ifndef _WIN32 +# error You should only be including windows/port.cc in a windows environment! +#endif + +#include "config.h" +#include // for va_list, va_start, va_end +#include // for strstr() +#include +#include +#include +#include "port.h" + +using std::string; +using std::vector; + +// These call the windows _vsnprintf, but always NUL-terminate. +int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { + if (size == 0) // not even room for a \0? + return -1; // not what C99 says to do, but what windows does + str[size-1] = '\0'; + return _vsnprintf(str, size-1, format, ap); +} + +int snprintf(char *str, size_t size, const char *format, ...) { + va_list ap; + va_start(ap, format); + const int r = vsnprintf(str, size, format, ap); + va_end(ap); + return r; +} diff --git a/extern/libmv/third_party/glog/src/windows/port.h b/extern/libmv/third_party/glog/src/windows/port.h new file mode 100644 index 00000000000..d093bf5d34c --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/port.h @@ -0,0 +1,149 @@ +/* Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * --- + * Author: Craig Silverstein + * Copied from google-perftools and modified by Shinichiro Hamaji + * + * These are some portability typedefs and defines to make it a bit + * easier to compile this code under VC++. + * + * Several of these are taken from glib: + * http://developer.gnome.org/doc/API/glib/glib-windows-compatability-functions.html + */ + +#ifndef CTEMPLATE_WINDOWS_PORT_H_ +#define CTEMPLATE_WINDOWS_PORT_H_ + +#include "config.h" + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ +#include +#include /* for gethostname */ +#include /* because we so often use open/close/etc */ +#include /* for _getcwd() */ +#include /* for _getpid() */ +#include /* read in vsnprintf decl. before redifining it */ +#include /* template_dictionary.cc uses va_copy */ +#include /* for _strnicmp(), strerror_s() */ +#include /* for localtime_s() */ +/* Note: the C++ #includes are all together at the bottom. This file is + * used by both C and C++ code, so we put all the C++ together. + */ + +/* 4244: otherwise we get problems when substracting two size_t's to an int + * 4251: it's complaining about a private struct I've chosen not to dllexport + * 4355: we use this in a constructor, but we do it safely + * 4715: for some reason VC++ stopped realizing you can't return after abort() + * 4800: we know we're casting ints/char*'s to bools, and we're ok with that + * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() + */ +#pragma warning(disable:4244 4251 4355 4715 4800 4996) + +/* file I/O */ +#define PATH_MAX 1024 +#define access _access +#define getcwd _getcwd +#define open _open +#define read _read +#define write _write +#define lseek _lseek +#define close _close +#define popen _popen +#define pclose _pclose +#define R_OK 04 /* read-only (for access()) */ +#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR) +#ifndef __MINGW32__ +enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; +#endif +#define S_IRUSR S_IREAD +#define S_IWUSR S_IWRITE + +/* Not quite as lightweight as a hard-link, but more than good enough for us. */ +#define link(oldpath, newpath) CopyFileA(oldpath, newpath, false) + +#define strcasecmp _stricmp +#define strncasecmp _strnicmp + +/* In windows-land, hash<> is called hash_compare<> (from xhash.h) */ +#define hash hash_compare + +/* Sleep is in ms, on windows */ +#define sleep(secs) Sleep((secs) * 1000) + +/* We can't just use _vsnprintf and _snprintf as drop-in-replacements, + * because they don't always NUL-terminate. :-( We also can't use the + * name vsnprintf, since windows defines that (but not snprintf (!)). + */ +extern int snprintf(char *str, size_t size, + const char *format, ...); +extern int safe_vsnprintf(char *str, size_t size, + const char *format, va_list ap); +#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) +#define va_copy(dst, src) (dst) = (src) + +/* Windows doesn't support specifying the number of buckets as a + * hash_map constructor arg, so we leave this blank. + */ +#define CTEMPLATE_SMALL_HASHTABLE + +#define DEFAULT_TEMPLATE_ROOTDIR ".." + +// ----------------------------------- SYSTEM/PROCESS +typedef int pid_t; +#define getpid _getpid + +// ----------------------------------- THREADS +typedef DWORD pthread_t; +typedef DWORD pthread_key_t; +typedef LONG pthread_once_t; +enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock +#define pthread_self GetCurrentThreadId +#define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) + +inline struct tm* localtime_r(const time_t* timep, struct tm* result) { + localtime_s(result, timep); + return result; +} + +inline char* strerror_r(int errnum, char* buf, size_t buflen) { + strerror_s(buf, buflen, errnum); + return buf; +} + +#ifndef __cplusplus +/* I don't see how to get inlining for C code in MSVC. Ah well. */ +#define inline +#endif + +#endif /* _WIN32 */ + +#endif /* CTEMPLATE_WINDOWS_PORT_H_ */ diff --git a/extern/libmv/third_party/glog/src/windows/preprocess.sh b/extern/libmv/third_party/glog/src/windows/preprocess.sh new file mode 100755 index 00000000000..ea4352e8e3a --- /dev/null +++ b/extern/libmv/third_party/glog/src/windows/preprocess.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# Copyright (c) 2008, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# --- +# Author: Craig Silverstein +# Copied from google-perftools and modified by Shinichiro Hamaji +# +# This script is meant to be run at distribution-generation time, for +# instance by autogen.sh. It does some of the work configure would +# normally do, for windows systems. In particular, it expands all the +# @...@ variables found in .in files, and puts them here, in the windows +# directory. +# +# This script should be run before any new release. + +if [ -z "$1" ]; then + echo "USAGE: $0 " + exit 1 +fi + +DLLDEF_MACRO_NAME="GLOG_DLL_DECL" + +# The text we put in every .h files we create. As a courtesy, we'll +# include a helpful comment for windows users as to how to use +# GLOG_DLL_DECL. Apparently sed expands \n into a newline. Good! +DLLDEF_DEFINES="\ +// NOTE: if you are statically linking the template library into your binary\n\ +// (rather than using the template .dll), set '/D $DLLDEF_MACRO_NAME='\n\ +// as a compiler flag in your project file to turn off the dllimports.\n\ +#ifndef $DLLDEF_MACRO_NAME\n\ +# define $DLLDEF_MACRO_NAME __declspec(dllimport)\n\ +#endif" + +# Read all the windows config info into variables +# In order for the 'set' to take, this requires putting all in a subshell. +( + while read define varname value; do + [ "$define" != "#define" ] && continue + eval "$varname='$value'" + done + + # Process all the .in files in the "glog" subdirectory + mkdir -p "$1/windows/glog" + for file in `echo "$1"/glog/*.in`; do + echo "Processing $file" + outfile="$1/windows/glog/`basename $file .in`" + + echo "\ +// This file is automatically generated from $file +// using src/windows/preprocess.sh. +// DO NOT EDIT! +" > "$outfile" + # Besides replacing @...@, we also need to turn on dllimport + # We also need to replace hash by hash_compare (annoying we hard-code :-( ) + sed -e "s!@ac_windows_dllexport@!$DLLDEF_MACRO_NAME!g" \ + -e "s!@ac_windows_dllexport_defines@!$DLLDEF_DEFINES!g" \ + -e "s!@ac_cv_cxx_hash_map@!$HASH_MAP_H!g" \ + -e "s!@ac_cv_cxx_hash_namespace@!$HASH_NAMESPACE!g" \ + -e "s!@ac_cv_cxx_hash_set@!$HASH_SET_H!g" \ + -e "s!@ac_cv_have_stdint_h@!0!g" \ + -e "s!@ac_cv_have_systypes_h@!0!g" \ + -e "s!@ac_cv_have_inttypes_h@!0!g" \ + -e "s!@ac_cv_have_unistd_h@!0!g" \ + -e "s!@ac_cv_have_uint16_t@!0!g" \ + -e "s!@ac_cv_have_u_int16_t@!0!g" \ + -e "s!@ac_cv_have___uint16@!1!g" \ + -e "s!@ac_cv_have_libgflags@!0!g" \ + -e "s!@ac_cv_have___builtin_expect@!0!g" \ + -e "s!@ac_cv_cxx_using_operator@!1!g" \ + -e "s!@ac_cv___attribute___noreturn@!!g" \ + -e "s!@ac_cv___attribute___printf_4_5@!!g" \ + -e "s!@ac_google_attribute@!${HAVE___ATTRIBUTE__:-0}!g" \ + -e "s!@ac_google_end_namespace@!$_END_GOOGLE_NAMESPACE_!g" \ + -e "s!@ac_google_namespace@!$GOOGLE_NAMESPACE!g" \ + -e "s!@ac_google_start_namespace@!$_START_GOOGLE_NAMESPACE_!g" \ + -e "s!@ac_htmlparser_namespace@!$HTMLPARSER_NAMESPACE!g" \ + -e "s!\\bhash\\b!hash_compare!g" \ + "$file" >> "$outfile" + done +) < "$1/windows/config.h" + +# log_severity.h isn't a .in file. +echo "\ +// This file is automatically generated from $1/glog/log_severity.h +// using src/windows/preprocess.sh. +// DO NOT EDIT! +" > "$1/windows/glog/log_severity.h" +cat "$1/glog/log_severity.h" >> "$1/windows/glog/log_severity.h" + +echo "DONE" diff --git a/extern/libmv/third_party/ldl/CMakeLists.txt b/extern/libmv/third_party/ldl/CMakeLists.txt new file mode 100644 index 00000000000..db2d40e2612 --- /dev/null +++ b/extern/libmv/third_party/ldl/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(../ufconfig) +include_directories(Include) +add_library(ldl Source/ldl.c) + +LIBMV_INSTALL_THIRD_PARTY_LIB(ldl) diff --git a/extern/libmv/third_party/ldl/Doc/ChangeLog b/extern/libmv/third_party/ldl/Doc/ChangeLog new file mode 100644 index 00000000000..48c322d3e77 --- /dev/null +++ b/extern/libmv/third_party/ldl/Doc/ChangeLog @@ -0,0 +1,39 @@ +May 31, 2007: version 2.0.0 + + * C-callable 64-bit version added + + * ported to 64-bit MATLAB + + * subdirectories added (Source/, Include/, Lib/, Demo/, Doc/, MATLAB/) + +Dec 12, 2006: version 1.3.4 + + * minor MATLAB cleanup + +Sept 11, 2006: version 1.3.1 + + * The ldl m-file renamed to ldlsparse, to avoid name conflict with the + new MATLAB ldl function (in MATLAB 7.3). + +Apr 30, 2006: version 1.3 + + * requires AMD v2.0. ldlmain.c demo program modified, since AMD can now + handle jumbled matrices. Minor change to Makefile. + +Aug 30, 2005: + + * Makefile changed to use ../UFconfig/UFconfig.mk. License changed to + GNU LGPL. + +July 4, 2005: + + * user guide added. Since no changes to the code were made, + the version number (1.1) and code release date (Apr 22, 2005) + were left unchanged. + +Apr. 22, 2005: LDL v1.1 released. + + * No real changes were made. The code was revised so + that each routine fits on a single page in the documentation. + +Dec 31, 2003: LDL v1.0 released. diff --git a/extern/libmv/third_party/ldl/Doc/lesser.txt b/extern/libmv/third_party/ldl/Doc/lesser.txt new file mode 100644 index 00000000000..8add30ad590 --- /dev/null +++ b/extern/libmv/third_party/ldl/Doc/lesser.txt @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/extern/libmv/third_party/ldl/Include/ldl.h b/extern/libmv/third_party/ldl/Include/ldl.h new file mode 100644 index 00000000000..5840be322f7 --- /dev/null +++ b/extern/libmv/third_party/ldl/Include/ldl.h @@ -0,0 +1,104 @@ +/* ========================================================================== */ +/* === ldl.h: include file for the LDL package ============================= */ +/* ========================================================================== */ + +/* LDL Copyright (c) Timothy A Davis, + * University of Florida. All Rights Reserved. See README for the License. + */ + +#include "UFconfig.h" + +#ifdef LDL_LONG +#define LDL_int UF_long +#define LDL_ID UF_long_id + +#define LDL_symbolic ldl_l_symbolic +#define LDL_numeric ldl_l_numeric +#define LDL_lsolve ldl_l_lsolve +#define LDL_dsolve ldl_l_dsolve +#define LDL_ltsolve ldl_l_ltsolve +#define LDL_perm ldl_l_perm +#define LDL_permt ldl_l_permt +#define LDL_valid_perm ldl_l_valid_perm +#define LDL_valid_matrix ldl_l_valid_matrix + +#else +#define LDL_int int +#define LDL_ID "%d" + +#define LDL_symbolic ldl_symbolic +#define LDL_numeric ldl_numeric +#define LDL_lsolve ldl_lsolve +#define LDL_dsolve ldl_dsolve +#define LDL_ltsolve ldl_ltsolve +#define LDL_perm ldl_perm +#define LDL_permt ldl_permt +#define LDL_valid_perm ldl_valid_perm +#define LDL_valid_matrix ldl_valid_matrix + +#endif + +/* ========================================================================== */ +/* === int version ========================================================== */ +/* ========================================================================== */ + +void ldl_symbolic (int n, int Ap [ ], int Ai [ ], int Lp [ ], + int Parent [ ], int Lnz [ ], int Flag [ ], int P [ ], int Pinv [ ]) ; + +int ldl_numeric (int n, int Ap [ ], int Ai [ ], double Ax [ ], + int Lp [ ], int Parent [ ], int Lnz [ ], int Li [ ], double Lx [ ], + double D [ ], double Y [ ], int Pattern [ ], int Flag [ ], + int P [ ], int Pinv [ ]) ; + +void ldl_lsolve (int n, double X [ ], int Lp [ ], int Li [ ], + double Lx [ ]) ; + +void ldl_dsolve (int n, double X [ ], double D [ ]) ; + +void ldl_ltsolve (int n, double X [ ], int Lp [ ], int Li [ ], + double Lx [ ]) ; + +void ldl_perm (int n, double X [ ], double B [ ], int P [ ]) ; +void ldl_permt (int n, double X [ ], double B [ ], int P [ ]) ; + +int ldl_valid_perm (int n, int P [ ], int Flag [ ]) ; +int ldl_valid_matrix ( int n, int Ap [ ], int Ai [ ]) ; + +/* ========================================================================== */ +/* === long version ========================================================= */ +/* ========================================================================== */ + +void ldl_l_symbolic (UF_long n, UF_long Ap [ ], UF_long Ai [ ], UF_long Lp [ ], + UF_long Parent [ ], UF_long Lnz [ ], UF_long Flag [ ], UF_long P [ ], + UF_long Pinv [ ]) ; + +UF_long ldl_l_numeric (UF_long n, UF_long Ap [ ], UF_long Ai [ ], double Ax [ ], + UF_long Lp [ ], UF_long Parent [ ], UF_long Lnz [ ], UF_long Li [ ], + double Lx [ ], double D [ ], double Y [ ], UF_long Pattern [ ], + UF_long Flag [ ], UF_long P [ ], UF_long Pinv [ ]) ; + +void ldl_l_lsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ], + double Lx [ ]) ; + +void ldl_l_dsolve (UF_long n, double X [ ], double D [ ]) ; + +void ldl_l_ltsolve (UF_long n, double X [ ], UF_long Lp [ ], UF_long Li [ ], + double Lx [ ]) ; + +void ldl_l_perm (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ; +void ldl_l_permt (UF_long n, double X [ ], double B [ ], UF_long P [ ]) ; + +UF_long ldl_l_valid_perm (UF_long n, UF_long P [ ], UF_long Flag [ ]) ; +UF_long ldl_l_valid_matrix ( UF_long n, UF_long Ap [ ], UF_long Ai [ ]) ; + +/* ========================================================================== */ +/* === LDL version ========================================================== */ +/* ========================================================================== */ + +#define LDL_DATE "Nov 1, 2007" +#define LDL_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define LDL_MAIN_VERSION 2 +#define LDL_SUB_VERSION 0 +#define LDL_SUBSUB_VERSION 1 +#define LDL_VERSION LDL_VERSION_CODE(LDL_MAIN_VERSION,LDL_SUB_VERSION) + diff --git a/extern/libmv/third_party/ldl/README.libmv b/extern/libmv/third_party/ldl/README.libmv new file mode 100644 index 00000000000..64ece48a390 --- /dev/null +++ b/extern/libmv/third_party/ldl/README.libmv @@ -0,0 +1,10 @@ +Project: LDL +URL: http://www.cise.ufl.edu/research/sparse/ldl/ +License: LGPL2.1 +Upstream version: 2.0.1 (despite the ChangeLog saying 2.0.0) + +Local modifications: + + * Deleted everything except ldl.c, ldl.h, the license, the ChangeLog, and the + README. + diff --git a/extern/libmv/third_party/ldl/README.txt b/extern/libmv/third_party/ldl/README.txt new file mode 100644 index 00000000000..7be8dd1f001 --- /dev/null +++ b/extern/libmv/third_party/ldl/README.txt @@ -0,0 +1,136 @@ +LDL Version 2.0: a sparse LDL' factorization and solve package. + Written in C, with both a C and MATLAB mexFunction interface. + +These routines are not terrifically fast (they do not use dense matrix kernels), +but the code is very short and concise. The purpose is to illustrate the +algorithms in a very concise and readable manner, primarily for educational +purposes. Although the code is very concise, this package is slightly faster +than the built-in sparse Cholesky factorization in MATLAB 6.5 (chol), when +using the same input permutation. + +Requires UFconfig, in the ../UFconfig directory relative to this directory. + +Quick start (Unix, or Windows with Cygwin): + + To compile, test, and install LDL, you may wish to first obtain a copy of + AMD v2.0 from http://www.cise.ufl.edu/research/sparse, and place it in the + ../AMD directory, relative to this directory. Next, type "make", which + will compile the LDL library and three demo main programs (one of which + requires AMD). It will also compile the LDL MATLAB mexFunction (if you + have MATLAB). Typing "make clean" will remove non-essential files. + AMD v2.0 or later is required. Its use is optional. + +Quick start (for MATLAB users); + + To compile, test, and install the LDL mexFunctions (ldlsparse and + ldlsymbol), start MATLAB in this directory and type ldl_install. + This works on any system supported by MATLAB. + +-------------------------------------------------------------------------------- + +LDL Copyright (c) 2005 by Timothy A. Davis. All Rights Reserved. + +LDL License: + + Your use or distribution of LDL or any modified version of + LDL implies that you agree to this License. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + USA + + Permission is hereby granted to use or copy this program under the + terms of the GNU LGPL, provided that the Copyright, this License, + and the Availability of the original version is retained on all copies. + User documentation of any code that uses this code or any modified + version of this code must cite the Copyright, this License, the + Availability note, and "Used by permission." Permission to modify + the code and to distribute modified code is granted, provided the + Copyright, this License, and the Availability note are retained, + and a notice that the code was modified is included. + +Availability: + + http://www.cise.ufl.edu/research/sparse/ldl + +Acknowledgements: + + This work was supported by the National Science Foundation, under + grant CCR-0203270. + + Portions of this work were done while on sabbatical at Stanford University + and Lawrence Berkeley National Laboratory (with funding from the SciDAC + program). I would like to thank Gene Golub, Esmond Ng, and Horst Simon + for making this sabbatical possible. I would like to thank Pete Stewart + for his comments on a draft of this software and paper. + +-------------------------------------------------------------------------------- +Files and directories in this distribution: +-------------------------------------------------------------------------------- + + Documentation, and compiling: + + README.txt this file + Makefile for compiling LDL + ChangeLog changes since V1.0 (Dec 31, 2003) + License license + lesser.txt the GNU LGPL license + + ldl_userguide.pdf user guide in PDF + ldl_userguide.ps user guide in postscript + ldl_userguide.tex user guide in Latex + ldl.bib bibliography for user guide + + The LDL library itself: + + ldl.c the C-callable routines + ldl.h include file for any code that calls LDL + + A simple C main program that demonstrates how to use LDL: + + ldlsimple.c a stand-alone C program, uses the basic features of LDL + ldlsimple.out output of ldlsimple + + ldllsimple.c long integer version of ldlsimple.c + + Demo C program, for testing LDL and providing an example of its use + + ldlmain.c a stand-alone C main program that uses and tests LDL + Matrix a directory containing matrices used by ldlmain.c + ldlmain.out output of ldlmain + ldlamd.out output of ldlamd (ldlmain.c compiled with AMD) + ldllamd.out output of ldllamd (ldlmain.c compiled with AMD, long) + + MATLAB-related, not required for use in a regular C program + + Contents.m a list of the MATLAB-callable routines + ldl.m MATLAB help file for the LDL mexFunction + ldldemo.m MATLAB demo of how to use the LDL mexFunction + ldldemo.out diary output of ldldemo + ldltest.m to test the LDL mexFunction + ldltest.out diary output of ldltest + ldlmex.c the LDL mexFunction for MATLAB + ldlrow.m the numerical algorithm that LDL is based on + ldlmain2.m compiles and runs ldlmain.c as a MATLAB mexFunction + ldlmain2.out output of ldlmain2.m + ldlsymbolmex.c symbolic factorization using LDL (see SYMBFACT, ETREE) + ldlsymbol.m help file for the LDLSYMBOL mexFunction + + ldl_install.m compile, install, and test LDL functions + ldl_make.m compile LDL (ldlsparse and ldlsymbol) + + ldlsparse.m help for ldlsparse + +See ldl.c for a description of how to use the code from a C program. Type +"help ldl" in MATLAB for information on how to use LDL in a MATLAB program. diff --git a/extern/libmv/third_party/ldl/Source/ldl.c b/extern/libmv/third_party/ldl/Source/ldl.c new file mode 100644 index 00000000000..a9b35c846ef --- /dev/null +++ b/extern/libmv/third_party/ldl/Source/ldl.c @@ -0,0 +1,507 @@ +/* ========================================================================== */ +/* === ldl.c: sparse LDL' factorization and solve package =================== */ +/* ========================================================================== */ + +/* LDL: a simple set of routines for sparse LDL' factorization. These routines + * are not terrifically fast (they do not use dense matrix kernels), but the + * code is very short. The purpose is to illustrate the algorithms in a very + * concise manner, primarily for educational purposes. Although the code is + * very concise, this package is slightly faster than the built-in sparse + * Cholesky factorization in MATLAB 7.0 (chol), when using the same input + * permutation. + * + * The routines compute the LDL' factorization of a real sparse symmetric + * matrix A (or PAP' if a permutation P is supplied), and solve upper + * and lower triangular systems with the resulting L and D factors. If A is + * positive definite then the factorization will be accurate. A can be + * indefinite (with negative values on the diagonal D), but in this case no + * guarantee of accuracy is provided, since no numeric pivoting is performed. + * + * The n-by-n sparse matrix A is in compressed-column form. The nonzero values + * in column j are stored in Ax [Ap [j] ... Ap [j+1]-1], with corresponding row + * indices in Ai [Ap [j] ... Ap [j+1]-1]. Ap [0] = 0 is required, and thus + * nz = Ap [n] is the number of nonzeros in A. Ap is an int array of size n+1. + * The int array Ai and the double array Ax are of size nz. This data structure + * is identical to the one used by MATLAB, except for the following + * generalizations. The row indices in each column of A need not be in any + * particular order, although they must be in the range 0 to n-1. Duplicate + * entries can be present; any duplicates are summed. That is, if row index i + * appears twice in a column j, then the value of A (i,j) is the sum of the two + * entries. The data structure used here for the input matrix A is more + * flexible than MATLAB's, which requires sorted columns with no duplicate + * entries. + * + * Only the diagonal and upper triangular part of A (or PAP' if a permutation + * P is provided) is accessed. The lower triangular parts of the matrix A or + * PAP' can be present, but they are ignored. + * + * The optional input permutation is provided as an array P of length n. If + * P [k] = j, the row and column j of A is the kth row and column of PAP'. + * If P is present then the factorization is LDL' = PAP' or L*D*L' = A(P,P) in + * 0-based MATLAB notation. If P is not present (a null pointer) then no + * permutation is performed, and the factorization is LDL' = A. + * + * The lower triangular matrix L is stored in the same compressed-column + * form (an int Lp array of size n+1, an int Li array of size Lp [n], and a + * double array Lx of the same size as Li). It has a unit diagonal, which is + * not stored. The row indices in each column of L are always returned in + * ascending order, with no duplicate entries. This format is compatible with + * MATLAB, except that it would be more convenient for MATLAB to include the + * unit diagonal of L. Doing so here would add additional complexity to the + * code, and is thus omitted in the interest of keeping this code short and + * readable. + * + * The elimination tree is held in the Parent [0..n-1] array. It is normally + * not required by the user, but it is required by ldl_numeric. The diagonal + * matrix D is held as an array D [0..n-1] of size n. + * + * -------------------- + * C-callable routines: + * -------------------- + * + * ldl_symbolic: Given the pattern of A, computes the Lp and Parent arrays + * required by ldl_numeric. Takes time proportional to the number of + * nonzeros in L. Computes the inverse Pinv of P if P is provided. + * Also returns Lnz, the count of nonzeros in each column of L below + * the diagonal (this is not required by ldl_numeric). + * ldl_numeric: Given the pattern and numerical values of A, the Lp array, + * the Parent array, and P and Pinv if applicable, computes the + * pattern and numerical values of L and D. + * ldl_lsolve: Solves Lx=b for a dense vector b. + * ldl_dsolve: Solves Dx=b for a dense vector b. + * ldl_ltsolve: Solves L'x=b for a dense vector b. + * ldl_perm: Computes x=Pb for a dense vector b. + * ldl_permt: Computes x=P'b for a dense vector b. + * ldl_valid_perm: checks the validity of a permutation vector + * ldl_valid_matrix: checks the validity of the sparse matrix A + * + * ---------------------------- + * Limitations of this package: + * ---------------------------- + * + * In the interest of keeping this code simple and readable, ldl_symbolic and + * ldl_numeric assume their inputs are valid. You can check your own inputs + * prior to calling these routines with the ldl_valid_perm and ldl_valid_matrix + * routines. Except for the two ldl_valid_* routines, no routine checks to see + * if the array arguments are present (non-NULL). Like all C routines, no + * routine can determine if the arrays are long enough and don't overlap. + * + * The ldl_numeric does check the numerical factorization, however. It returns + * n if the factorization is successful. If D (k,k) is zero, then k is + * returned, and L is only partially computed. + * + * No pivoting to control fill-in is performed, which is often critical for + * obtaining good performance. I recommend that you compute the permutation P + * using AMD or SYMAMD (approximate minimum degree ordering routines), or an + * appropriate graph-partitioning based ordering. See the ldldemo.m routine for + * an example in MATLAB, and the ldlmain.c stand-alone C program for examples of + * how to find P. Routines for manipulating compressed-column matrices are + * available in UMFPACK. AMD, SYMAMD, UMFPACK, and this LDL package are all + * available at http://www.cise.ufl.edu/research/sparse. + * + * ------------------------- + * Possible simplifications: + * ------------------------- + * + * These routines could be made even simpler with a few additional assumptions. + * If no input permutation were performed, the caller would have to permute the + * matrix first, but the computation of Pinv, and the use of P and Pinv could be + * removed. If only the diagonal and upper triangular part of A or PAP' are + * present, then the tests in the "if (i < k)" statement in ldl_symbolic and + * "if (i <= k)" in ldl_numeric, are always true, and could be removed (i can + * equal k in ldl_symbolic, but then the body of the if statement would + * correctly do no work since Flag [k] == k). If we could assume that no + * duplicate entries are present, then the statement Y [i] += Ax [p] could be + * replaced with Y [i] = Ax [p] in ldl_numeric. + * + * -------------------------- + * Description of the method: + * -------------------------- + * + * LDL computes the symbolic factorization by finding the pattern of L one row + * at a time. It does this based on the following theory. Consider a sparse + * system Lx=b, where L, x, and b, are all sparse, and where L comes from a + * Cholesky (or LDL') factorization. The elimination tree (etree) of L is + * defined as follows. The parent of node j is the smallest k > j such that + * L (k,j) is nonzero. Node j has no parent if column j of L is completely zero + * below the diagonal (j is a root of the etree in this case). The nonzero + * pattern of x is the union of the paths from each node i to the root, for + * each nonzero b (i). To compute the numerical solution to Lx=b, we can + * traverse the columns of L corresponding to nonzero values of x. This + * traversal does not need to be done in the order 0 to n-1. It can be done in + * any "topological" order, such that x (i) is computed before x (j) if i is a + * descendant of j in the elimination tree. + * + * The row-form of the LDL' factorization is shown in the MATLAB function + * ldlrow.m in this LDL package. Note that row k of L is found via a sparse + * triangular solve of L (1:k-1, 1:k-1) \ A (1:k-1, k), to use 1-based MATLAB + * notation. Thus, we can start with the nonzero pattern of the kth column of + * A (above the diagonal), follow the paths up to the root of the etree of the + * (k-1)-by-(k-1) leading submatrix of L, and obtain the pattern of the kth row + * of L. Note that we only need the leading (k-1)-by-(k-1) submatrix of L to + * do this. The elimination tree can be constructed as we go. + * + * The symbolic factorization does the same thing, except that it discards the + * pattern of L as it is computed. It simply counts the number of nonzeros in + * each column of L and then constructs the Lp index array when it's done. The + * symbolic factorization does not need to do this in topological order. + * Compare ldl_symbolic with the first part of ldl_numeric, and note that the + * while (len > 0) loop is not present in ldl_symbolic. + * + * LDL Version 1.3, Copyright (c) 2006 by Timothy A Davis, + * University of Florida. All Rights Reserved. Developed while on sabbatical + * at Stanford University and Lawrence Berkeley National Laboratory. Refer to + * the README file for the License. Available at + * http://www.cise.ufl.edu/research/sparse. + */ + +#include "ldl.h" + +/* ========================================================================== */ +/* === ldl_symbolic ========================================================= */ +/* ========================================================================== */ + +/* The input to this routine is a sparse matrix A, stored in column form, and + * an optional permutation P. The output is the elimination tree + * and the number of nonzeros in each column of L. Parent [i] = k if k is the + * parent of i in the tree. The Parent array is required by ldl_numeric. + * Lnz [k] gives the number of nonzeros in the kth column of L, excluding the + * diagonal. + * + * One workspace vector (Flag) of size n is required. + * + * If P is NULL, then it is ignored. The factorization will be LDL' = A. + * Pinv is not computed. In this case, neither P nor Pinv are required by + * ldl_numeric. + * + * If P is not NULL, then it is assumed to be a valid permutation. If + * row and column j of A is the kth pivot, the P [k] = j. The factorization + * will be LDL' = PAP', or A (p,p) in MATLAB notation. The inverse permutation + * Pinv is computed, where Pinv [j] = k if P [k] = j. In this case, both P + * and Pinv are required as inputs to ldl_numeric. + * + * The floating-point operation count of the subsequent call to ldl_numeric + * is not returned, but could be computed after ldl_symbolic is done. It is + * the sum of (Lnz [k]) * (Lnz [k] + 2) for k = 0 to n-1. + */ + +void LDL_symbolic +( + LDL_int n, /* A and L are n-by-n, where n >= 0 */ + LDL_int Ap [ ], /* input of size n+1, not modified */ + LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */ + LDL_int Lp [ ], /* output of size n+1, not defined on input */ + LDL_int Parent [ ], /* output of size n, not defined on input */ + LDL_int Lnz [ ], /* output of size n, not defined on input */ + LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */ + LDL_int P [ ], /* optional input of size n */ + LDL_int Pinv [ ] /* optional output of size n (used if P is not NULL) */ +) +{ + LDL_int i, k, p, kk, p2 ; + if (P) + { + /* If P is present then compute Pinv, the inverse of P */ + for (k = 0 ; k < n ; k++) + { + Pinv [P [k]] = k ; + } + } + for (k = 0 ; k < n ; k++) + { + /* L(k,:) pattern: all nodes reachable in etree from nz in A(0:k-1,k) */ + Parent [k] = -1 ; /* parent of k is not yet known */ + Flag [k] = k ; /* mark node k as visited */ + Lnz [k] = 0 ; /* count of nonzeros in column k of L */ + kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */ + p2 = Ap [kk+1] ; + for (p = Ap [kk] ; p < p2 ; p++) + { + /* A (i,k) is nonzero (original or permuted A) */ + i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ; + if (i < k) + { + /* follow path from i to root of etree, stop at flagged node */ + for ( ; Flag [i] != k ; i = Parent [i]) + { + /* find parent of i if not yet determined */ + if (Parent [i] == -1) Parent [i] = k ; + Lnz [i]++ ; /* L (k,i) is nonzero */ + Flag [i] = k ; /* mark i as visited */ + } + } + } + } + /* construct Lp index array from Lnz column counts */ + Lp [0] = 0 ; + for (k = 0 ; k < n ; k++) + { + Lp [k+1] = Lp [k] + Lnz [k] ; + } +} + + +/* ========================================================================== */ +/* === ldl_numeric ========================================================== */ +/* ========================================================================== */ + +/* Given a sparse matrix A (the arguments n, Ap, Ai, and Ax) and its symbolic + * analysis (Lp and Parent, and optionally P and Pinv), compute the numeric LDL' + * factorization of A or PAP'. The outputs of this routine are arguments Li, + * Lx, and D. It also requires three size-n workspaces (Y, Pattern, and Flag). + */ + +LDL_int LDL_numeric /* returns n if successful, k if D (k,k) is zero */ +( + LDL_int n, /* A and L are n-by-n, where n >= 0 */ + LDL_int Ap [ ], /* input of size n+1, not modified */ + LDL_int Ai [ ], /* input of size nz=Ap[n], not modified */ + double Ax [ ], /* input of size nz=Ap[n], not modified */ + LDL_int Lp [ ], /* input of size n+1, not modified */ + LDL_int Parent [ ], /* input of size n, not modified */ + LDL_int Lnz [ ], /* output of size n, not defn. on input */ + LDL_int Li [ ], /* output of size lnz=Lp[n], not defined on input */ + double Lx [ ], /* output of size lnz=Lp[n], not defined on input */ + double D [ ], /* output of size n, not defined on input */ + double Y [ ], /* workspace of size n, not defn. on input or output */ + LDL_int Pattern [ ],/* workspace of size n, not defn. on input or output */ + LDL_int Flag [ ], /* workspace of size n, not defn. on input or output */ + LDL_int P [ ], /* optional input of size n */ + LDL_int Pinv [ ] /* optional input of size n */ +) +{ + double yi, l_ki ; + LDL_int i, k, p, kk, p2, len, top ; + for (k = 0 ; k < n ; k++) + { + /* compute nonzero Pattern of kth row of L, in topological order */ + Y [k] = 0.0 ; /* Y(0:k) is now all zero */ + top = n ; /* stack for pattern is empty */ + Flag [k] = k ; /* mark node k as visited */ + Lnz [k] = 0 ; /* count of nonzeros in column k of L */ + kk = (P) ? (P [k]) : (k) ; /* kth original, or permuted, column */ + p2 = Ap [kk+1] ; + for (p = Ap [kk] ; p < p2 ; p++) + { + i = (Pinv) ? (Pinv [Ai [p]]) : (Ai [p]) ; /* get A(i,k) */ + if (i <= k) + { + Y [i] += Ax [p] ; /* scatter A(i,k) into Y (sum duplicates) */ + for (len = 0 ; Flag [i] != k ; i = Parent [i]) + { + Pattern [len++] = i ; /* L(k,i) is nonzero */ + Flag [i] = k ; /* mark i as visited */ + } + while (len > 0) Pattern [--top] = Pattern [--len] ; + } + } + /* compute numerical values kth row of L (a sparse triangular solve) */ + D [k] = Y [k] ; /* get D(k,k) and clear Y(k) */ + Y [k] = 0.0 ; + for ( ; top < n ; top++) + { + i = Pattern [top] ; /* Pattern [top:n-1] is pattern of L(:,k) */ + yi = Y [i] ; /* get and clear Y(i) */ + Y [i] = 0.0 ; + p2 = Lp [i] + Lnz [i] ; + for (p = Lp [i] ; p < p2 ; p++) + { + Y [Li [p]] -= Lx [p] * yi ; + } + l_ki = yi / D [i] ; /* the nonzero entry L(k,i) */ + D [k] -= l_ki * yi ; + Li [p] = k ; /* store L(k,i) in column form of L */ + Lx [p] = l_ki ; + Lnz [i]++ ; /* increment count of nonzeros in col i */ + } + if (D [k] == 0.0) return (k) ; /* failure, D(k,k) is zero */ + } + return (n) ; /* success, diagonal of D is all nonzero */ +} + + +/* ========================================================================== */ +/* === ldl_lsolve: solve Lx=b ============================================== */ +/* ========================================================================== */ + +void LDL_lsolve +( + LDL_int n, /* L is n-by-n, where n >= 0 */ + double X [ ], /* size n. right-hand-side on input, soln. on output */ + LDL_int Lp [ ], /* input of size n+1, not modified */ + LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */ + double Lx [ ] /* input of size lnz=Lp[n], not modified */ +) +{ + LDL_int j, p, p2 ; + for (j = 0 ; j < n ; j++) + { + p2 = Lp [j+1] ; + for (p = Lp [j] ; p < p2 ; p++) + { + X [Li [p]] -= Lx [p] * X [j] ; + } + } +} + + +/* ========================================================================== */ +/* === ldl_dsolve: solve Dx=b ============================================== */ +/* ========================================================================== */ + +void LDL_dsolve +( + LDL_int n, /* D is n-by-n, where n >= 0 */ + double X [ ], /* size n. right-hand-side on input, soln. on output */ + double D [ ] /* input of size n, not modified */ +) +{ + LDL_int j ; + for (j = 0 ; j < n ; j++) + { + X [j] /= D [j] ; + } +} + + +/* ========================================================================== */ +/* === ldl_ltsolve: solve L'x=b ============================================ */ +/* ========================================================================== */ + +void LDL_ltsolve +( + LDL_int n, /* L is n-by-n, where n >= 0 */ + double X [ ], /* size n. right-hand-side on input, soln. on output */ + LDL_int Lp [ ], /* input of size n+1, not modified */ + LDL_int Li [ ], /* input of size lnz=Lp[n], not modified */ + double Lx [ ] /* input of size lnz=Lp[n], not modified */ +) +{ + int j, p, p2 ; + for (j = n-1 ; j >= 0 ; j--) + { + p2 = Lp [j+1] ; + for (p = Lp [j] ; p < p2 ; p++) + { + X [j] -= Lx [p] * X [Li [p]] ; + } + } +} + + +/* ========================================================================== */ +/* === ldl_perm: permute a vector, x=Pb ===================================== */ +/* ========================================================================== */ + +void LDL_perm +( + LDL_int n, /* size of X, B, and P */ + double X [ ], /* output of size n. */ + double B [ ], /* input of size n. */ + LDL_int P [ ] /* input permutation array of size n. */ +) +{ + LDL_int j ; + for (j = 0 ; j < n ; j++) + { + X [j] = B [P [j]] ; + } +} + + +/* ========================================================================== */ +/* === ldl_permt: permute a vector, x=P'b =================================== */ +/* ========================================================================== */ + +void LDL_permt +( + LDL_int n, /* size of X, B, and P */ + double X [ ], /* output of size n. */ + double B [ ], /* input of size n. */ + LDL_int P [ ] /* input permutation array of size n. */ +) +{ + LDL_int j ; + for (j = 0 ; j < n ; j++) + { + X [P [j]] = B [j] ; + } +} + + +/* ========================================================================== */ +/* === ldl_valid_perm: check if a permutation vector is valid =============== */ +/* ========================================================================== */ + +LDL_int LDL_valid_perm /* returns 1 if valid, 0 otherwise */ +( + LDL_int n, + LDL_int P [ ], /* input of size n, a permutation of 0:n-1 */ + LDL_int Flag [ ] /* workspace of size n */ +) +{ + LDL_int j, k ; + if (n < 0 || !Flag) + { + return (0) ; /* n must be >= 0, and Flag must be present */ + } + if (!P) + { + return (1) ; /* If NULL, P is assumed to be the identity perm. */ + } + for (j = 0 ; j < n ; j++) + { + Flag [j] = 0 ; /* clear the Flag array */ + } + for (k = 0 ; k < n ; k++) + { + j = P [k] ; + if (j < 0 || j >= n || Flag [j] != 0) + { + return (0) ; /* P is not valid */ + } + Flag [j] = 1 ; + } + return (1) ; /* P is valid */ +} + + +/* ========================================================================== */ +/* === ldl_valid_matrix: check if a sparse matrix is valid ================== */ +/* ========================================================================== */ + +/* This routine checks to see if a sparse matrix A is valid for input to + * ldl_symbolic and ldl_numeric. It returns 1 if the matrix is valid, 0 + * otherwise. A is in sparse column form. The numerical values in column j + * are stored in Ax [Ap [j] ... Ap [j+1]-1], with row indices in + * Ai [Ap [j] ... Ap [j+1]-1]. The Ax array is not checked. + */ + +LDL_int LDL_valid_matrix +( + LDL_int n, + LDL_int Ap [ ], + LDL_int Ai [ ] +) +{ + LDL_int j, p ; + if (n < 0 || !Ap || !Ai || Ap [0] != 0) + { + return (0) ; /* n must be >= 0, and Ap and Ai must be present */ + } + for (j = 0 ; j < n ; j++) + { + if (Ap [j] > Ap [j+1]) + { + return (0) ; /* Ap must be monotonically nondecreasing */ + } + } + for (p = 0 ; p < Ap [n] ; p++) + { + if (Ai [p] < 0 || Ai [p] >= n) + { + return (0) ; /* row indices must be in the range 0 to n-1 */ + } + } + return (1) ; /* matrix is valid */ +} diff --git a/extern/libmv/third_party/msinttypes/README.libmv b/extern/libmv/third_party/msinttypes/README.libmv new file mode 100644 index 00000000000..423f599b4ad --- /dev/null +++ b/extern/libmv/third_party/msinttypes/README.libmv @@ -0,0 +1,5 @@ +Project: msinttypes +URL: http://code.google.com/p/msinttypes/ +License: New BSD License +Upstream version: r24 +Local modifications: None. diff --git a/extern/libmv/third_party/msinttypes/inttypes.h b/extern/libmv/third_party/msinttypes/inttypes.h new file mode 100644 index 00000000000..0e8af69cb07 --- /dev/null +++ b/extern/libmv/third_party/msinttypes/inttypes.h @@ -0,0 +1,305 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/extern/libmv/third_party/msinttypes/stdint.h b/extern/libmv/third_party/msinttypes/stdint.h new file mode 100644 index 00000000000..e236bb00015 --- /dev/null +++ b/extern/libmv/third_party/msinttypes/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef char int8_t; + typedef short int16_t; + typedef int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef __int8 int8_t; + typedef __int16 int16_t; + typedef __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/extern/libmv/third_party/ssba/COPYING.TXT b/extern/libmv/third_party/ssba/COPYING.TXT new file mode 100644 index 00000000000..fc8a5de7edf --- /dev/null +++ b/extern/libmv/third_party/ssba/COPYING.TXT @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h b/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h new file mode 100644 index 00000000000..448ae9714e5 --- /dev/null +++ b/extern/libmv/third_party/ssba/Geometry/v3d_cameramatrix.h @@ -0,0 +1,204 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_CAMERA_MATRIX_H +#define V3D_CAMERA_MATRIX_H + +#include "Math/v3d_linear.h" +#include "Geometry/v3d_distortion.h" + +namespace V3D +{ + + struct CameraMatrix + { + CameraMatrix() + { + makeIdentityMatrix(_K); + makeIdentityMatrix(_R); + makeZeroVector(_T); + this->updateCachedValues(true, true); + } + + CameraMatrix(double f, double cx, double cy) + { + makeIdentityMatrix(_K); + _K[0][0] = f; + _K[1][1] = f; + _K[0][2] = cx; + _K[1][2] = cy; + makeIdentityMatrix(_R); + makeZeroVector(_T); + this->updateCachedValues(true, true); + } + + CameraMatrix(Matrix3x3d const& K, + Matrix3x3d const& R, + Vector3d const& T) + : _K(K), _R(R), _T(T) + { + this->updateCachedValues(true, true); + } + + void setIntrinsic(Matrix3x3d const& K) { _K = K; this->updateCachedValues(true, false); } + void setRotation(Matrix3x3d const& R) { _R = R; this->updateCachedValues(false, true); } + void setTranslation(Vector3d const& T) { _T = T; this->updateCachedValues(false, true); } + + template + void setOrientation(Mat const& RT) + { + _R[0][0] = RT[0][0]; _R[0][1] = RT[0][1]; _R[0][2] = RT[0][2]; + _R[1][0] = RT[1][0]; _R[1][1] = RT[1][1]; _R[1][2] = RT[1][2]; + _R[2][0] = RT[2][0]; _R[2][1] = RT[2][1]; _R[2][2] = RT[2][2]; + _T[0] = RT[0][3]; _T[1] = RT[1][3]; _T[2] = RT[2][3]; + this->updateCachedValues(false, true); + } + + Matrix3x3d const& getIntrinsic() const { return _K; } + Matrix3x3d const& getRotation() const { return _R; } + Vector3d const& getTranslation() const { return _T; } + + Matrix3x4d getOrientation() const + { + Matrix3x4d RT; + RT[0][0] = _R[0][0]; RT[0][1] = _R[0][1]; RT[0][2] = _R[0][2]; + RT[1][0] = _R[1][0]; RT[1][1] = _R[1][1]; RT[1][2] = _R[1][2]; + RT[2][0] = _R[2][0]; RT[2][1] = _R[2][1]; RT[2][2] = _R[2][2]; + RT[0][3] = _T[0]; RT[1][3] = _T[1]; RT[2][3] = _T[2]; + return RT; + } + + Matrix3x4d getProjection() const + { + Matrix3x4d const RT = this->getOrientation(); + return _K * RT; + } + + double getFocalLength() const { return _K[0][0]; } + double getAspectRatio() const { return _K[1][1] / _K[0][0]; } + + Vector2d getPrincipalPoint() const + { + Vector2d pp; + pp[0] = _K[0][2]; + pp[1] = _K[1][2]; + return pp; + } + + Vector2d projectPoint(Vector3d const& X) const + { + Vector3d q = _K*(_R*X + _T); + Vector2d res; + res[0] = q[0]/q[2]; res[1] = q[1]/q[2]; + return res; + } + + template + Vector2d projectPoint(Distortion const& distortion, Vector3d const& X) const + { + Vector3d XX = _R*X + _T; + Vector2d p; + p[0] = XX[0] / XX[2]; + p[1] = XX[1] / XX[2]; + p = distortion(p); + + Vector2d res; + res[0] = _K[0][0] * p[0] + _K[0][1] * p[1] + _K[0][2]; + res[1] = _K[1][1] * p[1] + _K[1][2]; + return res; + } + + Vector3d unprojectPixel(Vector2d const &p, double depth = 1) const + { + Vector3d pp; + pp[0] = p[0]; pp[1] = p[1]; pp[2] = 1.0; + Vector3d ray = _invK * pp; + ray[0] *= depth/ray[2]; + ray[1] *= depth/ray[2]; + ray[2] = depth; + ray = _Rt * ray; + return _center + ray; + } + + Vector3d transformPointIntoCameraSpace(Vector3d const& p) const + { + return _R*p + _T; + } + + Vector3d transformPointFromCameraSpace(Vector3d const& p) const + { + return _Rt*(p-_T); + } + + Vector3d transformDirectionFromCameraSpace(Vector3d const& dir) const + { + return _Rt*dir; + } + + Vector3d const& cameraCenter() const + { + return _center; + } + + Vector3d opticalAxis() const + { + return this->transformDirectionFromCameraSpace(makeVector3(0.0, 0.0, 1.0)); + } + + Vector3d upVector() const + { + return this->transformDirectionFromCameraSpace(makeVector3(0.0, 1.0, 0.0)); + } + + Vector3d rightVector() const + { + return this->transformDirectionFromCameraSpace(makeVector3(1.0, 0.0, 0.0)); + } + + Vector3d getRay(Vector2d const& p) const + { + Vector3d pp = makeVector3(p[0], p[1], 1.0); + Vector3d ray = _invK * pp; + ray = _Rt * ray; + normalizeVector(ray); + return ray; + } + + protected: + void updateCachedValues(bool intrinsic, bool orientation) + { + if (intrinsic) _invK = invertedMatrix(_K); + + if (orientation) + { + makeTransposedMatrix(_R, _Rt); + _center = _Rt * (-1.0 * _T); + } + } + + Matrix3x3d _K, _R; + Vector3d _T; + Matrix3x3d _invK, _Rt; + Vector3d _center; + }; // end struct CameraMatrix + +} // end namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h b/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h new file mode 100644 index 00000000000..d0816558314 --- /dev/null +++ b/extern/libmv/third_party/ssba/Geometry/v3d_distortion.h @@ -0,0 +1,97 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_DISTORTION_H +#define V3D_DISTORTION_H + +#include "Math/v3d_linear.h" +#include "Math/v3d_linear_utils.h" + +namespace V3D +{ + + struct StdDistortionFunction + { + double k1, k2, p1, p2; + + StdDistortionFunction() + : k1(0), k2(0), p1(0), p2(0) + { } + + Vector2d operator()(Vector2d const& xu) const + { + double const r2 = xu[0]*xu[0] + xu[1]*xu[1]; + double const r4 = r2*r2; + double const kr = 1 + k1*r2 + k2*r4; + + Vector2d xd; + xd[0] = kr * xu[0] + 2*p1*xu[0]*xu[1] + p2*(r2 + 2*xu[0]*xu[0]); + xd[1] = kr * xu[1] + 2*p2*xu[0]*xu[1] + p1*(r2 + 2*xu[1]*xu[1]); + return xd; + } + + Matrix2x2d derivativeWrtRadialParameters(Vector2d const& xu) const + { + double const r2 = xu[0]*xu[0] + xu[1]*xu[1]; + double const r4 = r2*r2; + //double const kr = 1 + k1*r2 + k2*r4; + + Matrix2x2d deriv; + + deriv[0][0] = xu[0] * r2; // d xd/d k1 + deriv[0][1] = xu[0] * r4; // d xd/d k2 + deriv[1][0] = xu[1] * r2; // d yd/d k1 + deriv[1][1] = xu[1] * r4; // d yd/d k2 + return deriv; + } + + Matrix2x2d derivativeWrtTangentialParameters(Vector2d const& xu) const + { + double const r2 = xu[0]*xu[0] + xu[1]*xu[1]; + //double const r4 = r2*r2; + //double const kr = 1 + k1*r2 + k2*r4; + + Matrix2x2d deriv; + deriv[0][0] = 2*xu[0]*xu[1]; // d xd/d p1 + deriv[0][1] = r2 + 2*xu[0]*xu[0]; // d xd/d p2 + deriv[1][0] = r2 + 2*xu[1]*xu[1]; // d yd/d p1 + deriv[1][1] = deriv[0][0]; // d yd/d p2 + return deriv; + } + + Matrix2x2d derivativeWrtUndistortedPoint(Vector2d const& xu) const + { + double const r2 = xu[0]*xu[0] + xu[1]*xu[1]; + double const r4 = r2*r2; + double const kr = 1 + k1*r2 + k2*r4; + double const dkr = 2*k1 + 4*k2*r2; + + Matrix2x2d deriv; + deriv[0][0] = kr + xu[0] * xu[0] * dkr + 2*p1*xu[1] + 6*p2*xu[0]; // d xd/d xu + deriv[0][1] = xu[0] * xu[1] * dkr + 2*p1*xu[0] + 2*p2*xu[1]; // d xd/d yu + deriv[1][0] = deriv[0][1]; // d yd/d xu + deriv[1][1] = kr + xu[1] * xu[1] * dkr + 6*p1*xu[1] + 2*p2*xu[0]; // d yd/d yu + return deriv; + } + }; // end struct StdDistortionFunction + +} // end namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp new file mode 100644 index 00000000000..1c1f0cb2627 --- /dev/null +++ b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.cpp @@ -0,0 +1,365 @@ +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#include "Geometry/v3d_metricbundle.h" + +#if defined(V3DLIB_ENABLE_SUITESPARSE) + +namespace +{ + + typedef V3D::InlineMatrix Matrix2x4d; + typedef V3D::InlineMatrix Matrix4x2d; + typedef V3D::InlineMatrix Matrix2x6d; + +} // end namespace <> + +namespace V3D +{ + + void + MetricBundleOptimizerBase::updateParametersA(VectorArray const& deltaAi) + { + Vector3d T, omega; + Matrix3x3d R0, dR; + + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + { + T = _cams[i].getTranslation(); + T[0] += deltaAi[i][0]; + T[1] += deltaAi[i][1]; + T[2] += deltaAi[i][2]; + _cams[i].setTranslation(T); + + // Create incremental rotation using Rodriguez formula. + R0 = _cams[i].getRotation(); + omega[0] = deltaAi[i][3]; + omega[1] = deltaAi[i][4]; + omega[2] = deltaAi[i][5]; + createRotationMatrixRodriguez(omega, dR); + _cams[i].setRotation(dR * R0); + } // end for (i) + } // end MetricBundleOptimizerBase::updateParametersA() + + void + MetricBundleOptimizerBase::updateParametersB(VectorArray const& deltaBj) + { + for (int j = _nNonvaryingB; j < _nParametersB; ++j) + { + _Xs[j][0] += deltaBj[j][0]; + _Xs[j][1] += deltaBj[j][1]; + _Xs[j][2] += deltaBj[j][2]; + } + } // end MetricBundleOptimizerBase::updateParametersB() + + void + MetricBundleOptimizerBase::poseDerivatives(int i, int j, Vector3d& XX, + Matrix3x6d& d_dRT, Matrix3x3d& d_dX) const + { + XX = _cams[i].transformPointIntoCameraSpace(_Xs[j]); + + // See Frank Dellaerts bundle adjustment tutorial. + // d(dR * R0 * X + t)/d omega = -[R0 * X]_x + Matrix3x3d J; + makeCrossProductMatrix(XX - _cams[i].getTranslation(), J); + scaleMatrixIP(-1.0, J); + + // Now the transformation from world coords into camera space is xx = Rx + T + // Hence the derivative of x wrt. T is just the identity matrix. + makeIdentityMatrix(d_dRT); + copyMatrixSlice(J, 0, 0, 3, 3, d_dRT, 0, 3); + + // The derivative of Rx+T wrt x is just R. + copyMatrix(_cams[i].getRotation(), d_dX); + } // end MetricBundleOptimizerBase::poseDerivatives() + + +//---------------------------------------------------------------------- + + void + StdMetricBundleOptimizer::fillJacobians(Matrix& Ak, + Matrix& Bk, + Matrix& Ck, + int i, int j, int k) + { + Vector3d XX; + Matrix3x6d d_dRT; + Matrix3x3d d_dX; + this->poseDerivatives(i, j, XX, d_dRT, d_dX); + + double const f = _cams[i].getFocalLength(); + double const ar = _cams[i].getAspectRatio(); + + Matrix2x3d dp_dX; + double const bx = f / (XX[2] * XX[2]); + double const by = ar * bx; + dp_dX[0][0] = bx * XX[2]; dp_dX[0][1] = 0; dp_dX[0][2] = -bx * XX[0]; + dp_dX[1][0] = 0; dp_dX[1][1] = by * XX[2]; dp_dX[1][2] = -by * XX[1]; + + multiply_A_B(dp_dX, d_dRT, Ak); + multiply_A_B(dp_dX, d_dX, Bk); + } // end StdMetricBundleOptimizer::fillJacobians() + + //---------------------------------------------------------------------- + + void + CommonInternalsMetricBundleOptimizer::fillJacobians(Matrix& Ak, + Matrix& Bk, + Matrix& Ck, + int i, int j, int k) + { + double const focalLength = _K[0][0]; + + Vector3d XX; + Matrix3x6d dXX_dRT; + Matrix3x3d dXX_dX; + this->poseDerivatives(i, j, XX, dXX_dRT, dXX_dX); + + Vector2d xu; // undistorted image point + xu[0] = XX[0] / XX[2]; + xu[1] = XX[1] / XX[2]; + + Vector2d const xd = _distortion(xu); // distorted image point + + Matrix2x2d dp_dxd; + dp_dxd[0][0] = focalLength; dp_dxd[0][1] = 0; + dp_dxd[1][0] = 0; dp_dxd[1][1] = _cachedAspectRatio * focalLength; + + { + // First, lets do the derivative wrt the structure and motion parameters. + Matrix2x3d dxu_dXX; + dxu_dXX[0][0] = 1.0f / XX[2]; dxu_dXX[0][1] = 0; dxu_dXX[0][2] = -XX[0]/(XX[2]*XX[2]); + dxu_dXX[1][0] = 0; dxu_dXX[1][1] = 1.0f / XX[2]; dxu_dXX[1][2] = -XX[1]/(XX[2]*XX[2]); + + Matrix2x2d dxd_dxu = _distortion.derivativeWrtUndistortedPoint(xu); + + Matrix2x2d dp_dxu = dp_dxd * dxd_dxu; + Matrix2x3d dp_dXX = dp_dxu * dxu_dXX; + + multiply_A_B(dp_dXX, dXX_dRT, Ak); + multiply_A_B(dp_dXX, dXX_dX, Bk); + } // end scope + + switch (_mode) + { + case FULL_BUNDLE_RADIAL_TANGENTIAL: + { + Matrix2x2d dxd_dp1p2 = _distortion.derivativeWrtTangentialParameters(xu); + Matrix2x2d d_dp1p2 = dp_dxd * dxd_dp1p2; + copyMatrixSlice(d_dp1p2, 0, 0, 2, 2, Ck, 0, 5); + // No break here! + } + case FULL_BUNDLE_RADIAL: + { + Matrix2x2d dxd_dk1k2 = _distortion.derivativeWrtRadialParameters(xu); + Matrix2x2d d_dk1k2 = dp_dxd * dxd_dk1k2; + copyMatrixSlice(d_dk1k2, 0, 0, 2, 2, Ck, 0, 3); + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH_PP: + { + Ck[0][1] = 1; Ck[0][2] = 0; + Ck[1][1] = 0; Ck[1][2] = 1; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH: + { + Ck[0][0] = xd[0]; + Ck[1][0] = xd[1]; + } + case FULL_BUNDLE_METRIC: + { + } + } // end switch + } // end CommonInternalsMetricBundleOptimizer::fillJacobians() + + void + CommonInternalsMetricBundleOptimizer::updateParametersC(Vector const& deltaC) + { + switch (_mode) + { + case FULL_BUNDLE_RADIAL_TANGENTIAL: + { + _distortion.p1 += deltaC[5]; + _distortion.p2 += deltaC[6]; + // No break here! + } + case FULL_BUNDLE_RADIAL: + { + _distortion.k1 += deltaC[3]; + _distortion.k2 += deltaC[4]; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH_PP: + { + _K[0][2] += deltaC[1]; + _K[1][2] += deltaC[2]; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH: + { + _K[0][0] += deltaC[0]; + _K[1][1] = _cachedAspectRatio * _K[0][0]; + } + case FULL_BUNDLE_METRIC: + { + } + } // end switch + } // end CommonInternalsMetricBundleOptimizer::updateParametersC() + + //---------------------------------------------------------------------- + + void + VaryingInternalsMetricBundleOptimizer::fillJacobians(Matrix& Ak, + Matrix& Bk, + Matrix& Ck, + int i, int j, int k) + { + Vector3d XX; + Matrix3x6d dXX_dRT; + Matrix3x3d dXX_dX; + this->poseDerivatives(i, j, XX, dXX_dRT, dXX_dX); + + Vector2d xu; // undistorted image point + xu[0] = XX[0] / XX[2]; + xu[1] = XX[1] / XX[2]; + + Vector2d const xd = _distortions[i](xu); // distorted image point + + double const focalLength = _cams[i].getFocalLength(); + double const aspectRatio = _cams[i].getAspectRatio(); + + Matrix2x2d dp_dxd; + dp_dxd[0][0] = focalLength; dp_dxd[0][1] = 0; + dp_dxd[1][0] = 0; dp_dxd[1][1] = aspectRatio * focalLength; + + { + // First, lets do the derivative wrt the structure and motion parameters. + Matrix2x3d dxu_dXX; + dxu_dXX[0][0] = 1.0f / XX[2]; dxu_dXX[0][1] = 0; dxu_dXX[0][2] = -XX[0]/(XX[2]*XX[2]); + dxu_dXX[1][0] = 0; dxu_dXX[1][1] = 1.0f / XX[2]; dxu_dXX[1][2] = -XX[1]/(XX[2]*XX[2]); + + Matrix2x2d dxd_dxu = _distortions[i].derivativeWrtUndistortedPoint(xu); + + Matrix2x2d dp_dxu = dp_dxd * dxd_dxu; + Matrix2x3d dp_dXX = dp_dxu * dxu_dXX; + + Matrix2x6d dp_dRT; + + multiply_A_B(dp_dXX, dXX_dRT, dp_dRT); + copyMatrixSlice(dp_dRT, 0, 0, 2, 6, Ak, 0, 0); + multiply_A_B(dp_dXX, dXX_dX, Bk); + } // end scope + + switch (_mode) + { + case FULL_BUNDLE_RADIAL_TANGENTIAL: + { + Matrix2x2d dxd_dp1p2 = _distortions[i].derivativeWrtTangentialParameters(xu); + Matrix2x2d d_dp1p2 = dp_dxd * dxd_dp1p2; + copyMatrixSlice(d_dp1p2, 0, 0, 2, 2, Ak, 0, 11); + // No break here! + } + case FULL_BUNDLE_RADIAL: + { + Matrix2x2d dxd_dk1k2 = _distortions[i].derivativeWrtRadialParameters(xu); + Matrix2x2d d_dk1k2 = dp_dxd * dxd_dk1k2; + copyMatrixSlice(d_dk1k2, 0, 0, 2, 2, Ak, 0, 9); + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH_PP: + { + Ak[0][7] = 1; Ak[0][8] = 0; + Ak[1][7] = 0; Ak[1][8] = 1; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH: + { + Ak[0][6] = xd[0]; + Ak[1][6] = xd[1]; + } + case FULL_BUNDLE_METRIC: + { + } + } // end switch + } // end VaryingInternalsMetricBundleOptimizer::fillJacobians() + + void + VaryingInternalsMetricBundleOptimizer::updateParametersA(VectorArray const& deltaAi) + { + Vector3d T, omega; + Matrix3x3d R0, dR, K; + + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + { + Vector const& deltaA = deltaAi[i]; + + T = _cams[i].getTranslation(); + T[0] += deltaA[0]; + T[1] += deltaA[1]; + T[2] += deltaA[2]; + _cams[i].setTranslation(T); + + // Create incremental rotation using Rodriguez formula. + R0 = _cams[i].getRotation(); + omega[0] = deltaA[3]; + omega[1] = deltaA[4]; + omega[2] = deltaA[5]; + createRotationMatrixRodriguez(omega, dR); + _cams[i].setRotation(dR * R0); + + K = _cams[i].getIntrinsic(); + + switch (_mode) + { + case FULL_BUNDLE_RADIAL_TANGENTIAL: + { + _distortions[i].p1 += deltaA[11]; + _distortions[i].p2 += deltaA[12]; + // No break here! + } + case FULL_BUNDLE_RADIAL: + { + _distortions[i].k1 += deltaA[9]; + _distortions[i].k2 += deltaA[10]; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH_PP: + { + K[0][2] += deltaA[7]; + K[1][2] += deltaA[8]; + // No break here! + } + case FULL_BUNDLE_FOCAL_LENGTH: + { + double const ar = K[1][1] / K[0][0]; + K[0][0] += deltaA[6]; + K[1][1] = ar * K[0][0]; + } + case FULL_BUNDLE_METRIC: + { + } + } // end switch + _cams[i].setIntrinsic(K); + } // end for (i) + } // end VaryingInternalsMetricBundleOptimizer::updateParametersC() + +} // end namespace V3D + +#endif // defined(V3DLIB_ENABLE_SUITESPARSE) diff --git a/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h new file mode 100644 index 00000000000..076a9e64346 --- /dev/null +++ b/extern/libmv/third_party/ssba/Geometry/v3d_metricbundle.h @@ -0,0 +1,346 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_METRICBUNDLE_H +#define V3D_METRICBUNDLE_H + +# if defined(V3DLIB_ENABLE_SUITESPARSE) + +#include "Math/v3d_optimization.h" +#include "Math/v3d_linear.h" +#include "Math/v3d_linear_utils.h" +#include "Geometry/v3d_cameramatrix.h" +#include "Geometry/v3d_distortion.h" + +namespace V3D +{ + + // This structure provides some helper functions common to all metric BAs + struct MetricBundleOptimizerBase : public SparseLevenbergOptimizer + { + typedef SparseLevenbergOptimizer Base; + + MetricBundleOptimizerBase(double inlierThreshold, + vector& cams, + vector& Xs, + vector const& measurements, + vector const& corrspondingView, + vector const& corrspondingPoint, + int nAddParamsA, int nParamsC) + : SparseLevenbergOptimizer(2, cams.size(), 6+nAddParamsA, Xs.size(), 3, nParamsC, + corrspondingView, corrspondingPoint), + _cams(cams), _Xs(Xs), _measurements(measurements), + _savedTranslations(cams.size()), _savedRotations(cams.size()), + _savedXs(Xs.size()), + _inlierThreshold(inlierThreshold), _cachedParamLength(0.0) + { + // Since we assume that BA does not alter the inputs too much, + // we compute the overall length of the parameter vector in advance + // and return that value as the result of getParameterLength(). + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + { + _cachedParamLength += sqrNorm_L2(_cams[i].getTranslation()); + _cachedParamLength += 3.0; // Assume eye(3) for R. + } + for (int j = _nNonvaryingB; j < _nParametersB; ++j) + _cachedParamLength += sqrNorm_L2(_Xs[j]); + + _cachedParamLength = sqrt(_cachedParamLength); + } + + // Huber robust cost function. + virtual void fillWeights(VectorArray const& residual, Vector& w) + { + for (unsigned int k = 0; k < w.size(); ++k) + { + Vector const& r = residual[k]; + double const e = norm_L2(r); + w[k] = (e < _inlierThreshold) ? 1.0 : sqrt(_inlierThreshold / e); + } // end for (k) + } + + virtual double getParameterLength() const + { + return _cachedParamLength; + } + + virtual void updateParametersA(VectorArray const& deltaAi); + virtual void updateParametersB(VectorArray const& deltaBj); + virtual void updateParametersC(Vector const& deltaC) + { + (void)deltaC; + } + + virtual void saveAllParameters() + { + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + { + _savedTranslations[i] = _cams[i].getTranslation(); + _savedRotations[i] = _cams[i].getRotation(); + } + _savedXs = _Xs; + } + + virtual void restoreAllParameters() + { + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + { + _cams[i].setTranslation(_savedTranslations[i]); + _cams[i].setRotation(_savedRotations[i]); + } + _Xs = _savedXs; + } + + protected: + typedef InlineMatrix Matrix3x6d; + + void poseDerivatives(int i, int j, Vector3d& XX, + Matrix3x6d& d_dRT, Matrix3x3d& d_dX) const; + + vector& _cams; + vector& _Xs; + + vector const& _measurements; + + vector _savedTranslations; + vector _savedRotations; + vector _savedXs; + + double const _inlierThreshold; + double _cachedParamLength; + }; // end struct MetricBundleOptimizerBase + + struct StdMetricBundleOptimizer : public MetricBundleOptimizerBase + { + typedef MetricBundleOptimizerBase Base; + + StdMetricBundleOptimizer(double inlierThreshold, + vector& cams, + vector& Xs, + vector const& measurements, + vector const& corrspondingView, + vector const& corrspondingPoint) + : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements, + corrspondingView, corrspondingPoint, 0, 0) + { } + + virtual void evalResidual(VectorArray& e) + { + for (unsigned int k = 0; k < e.count(); ++k) + { + int const i = _correspondingParamA[k]; + int const j = _correspondingParamB[k]; + + Vector2d const q = _cams[i].projectPoint(_Xs[j]); + e[k][0] = q[0] - _measurements[k][0]; + e[k][1] = q[1] - _measurements[k][1]; + } + } + + virtual void fillJacobians(Matrix& Ak, Matrix& Bk, Matrix& Ck, + int i, int j, int k); + }; // end struct StdMetricBundleOptimizer + +//---------------------------------------------------------------------- + + enum + { + FULL_BUNDLE_METRIC = 0, + FULL_BUNDLE_FOCAL_LENGTH = 1, // f + FULL_BUNDLE_FOCAL_LENGTH_PP = 2, // f, cx, cy + FULL_BUNDLE_RADIAL = 3, // f, cx, cy, k1, k2 + FULL_BUNDLE_RADIAL_TANGENTIAL = 4 // f, cx, cy, k1, k2, p1, p2 + }; + + struct CommonInternalsMetricBundleOptimizer : public MetricBundleOptimizerBase + { + static int globalParamDimensionFromMode(int mode) + { + switch (mode) + { + case FULL_BUNDLE_METRIC: return 0; + case FULL_BUNDLE_FOCAL_LENGTH: return 1; + case FULL_BUNDLE_FOCAL_LENGTH_PP: return 3; + case FULL_BUNDLE_RADIAL: return 5; + case FULL_BUNDLE_RADIAL_TANGENTIAL: return 7; + } + return 0; + } + + typedef MetricBundleOptimizerBase Base; + + CommonInternalsMetricBundleOptimizer(int mode, + double inlierThreshold, + Matrix3x3d& K, + StdDistortionFunction& distortion, + vector& cams, + vector& Xs, + vector const& measurements, + vector const& corrspondingView, + vector const& corrspondingPoint) + : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements, + corrspondingView, corrspondingPoint, + 0, globalParamDimensionFromMode(mode)), + _mode(mode), _K(K), _distortion(distortion) + { + _cachedAspectRatio = K[1][1] / K[0][0]; + } + + Vector2d projectPoint(Vector3d const& X, int i) const + { + Vector3d const XX = _cams[i].transformPointIntoCameraSpace(X); + Vector2d p; + p[0] = XX[0] / XX[2]; + p[1] = XX[1] / XX[2]; + p = _distortion(p); + Vector2d res; + res[0] = _K[0][0] * p[0] + _K[0][1] * p[1] + _K[0][2]; + res[1] = _K[1][1] * p[1] + _K[1][2]; + return res; + } + + virtual void evalResidual(VectorArray& e) + { + for (unsigned int k = 0; k < e.count(); ++k) + { + int const i = _correspondingParamA[k]; + int const j = _correspondingParamB[k]; + + Vector2d const q = this->projectPoint(_Xs[j], i); + e[k][0] = q[0] - _measurements[k][0]; + e[k][1] = q[1] - _measurements[k][1]; + } + } + + virtual void fillJacobians(Matrix& Ak, Matrix& Bk, Matrix& Ck, + int i, int j, int k); + + virtual void updateParametersC(Vector const& deltaC); + + virtual void saveAllParameters() + { + Base::saveAllParameters(); + _savedK = _K; + _savedDistortion = _distortion; + } + + virtual void restoreAllParameters() + { + Base::restoreAllParameters(); + _K = _savedK; + _distortion = _savedDistortion; + } + + protected: + int _mode; + Matrix3x3d& _K; + StdDistortionFunction& _distortion; + + Matrix3x3d _savedK; + StdDistortionFunction _savedDistortion; + double _cachedAspectRatio; + }; // end struct CommonInternalsMetricBundleOptimizer + +//---------------------------------------------------------------------- + + struct VaryingInternalsMetricBundleOptimizer : public MetricBundleOptimizerBase + { + static int extParamDimensionFromMode(int mode) + { + switch (mode) + { + case FULL_BUNDLE_METRIC: return 0; + case FULL_BUNDLE_FOCAL_LENGTH: return 1; + case FULL_BUNDLE_FOCAL_LENGTH_PP: return 3; + case FULL_BUNDLE_RADIAL: return 5; + case FULL_BUNDLE_RADIAL_TANGENTIAL: return 7; + } + return 0; + } + + typedef MetricBundleOptimizerBase Base; + + VaryingInternalsMetricBundleOptimizer(int mode, + double inlierThreshold, + std::vector& distortions, + vector& cams, + vector& Xs, + vector const& measurements, + vector const& corrspondingView, + vector const& corrspondingPoint) + : MetricBundleOptimizerBase(inlierThreshold, cams, Xs, measurements, + corrspondingView, corrspondingPoint, + extParamDimensionFromMode(mode), 0), + _mode(mode), _distortions(distortions), + _savedKs(cams.size()), _savedDistortions(cams.size()) + { } + + Vector2d projectPoint(Vector3d const& X, int i) const + { + return _cams[i].projectPoint(_distortions[i], X); + } + + virtual void evalResidual(VectorArray& e) + { + for (unsigned int k = 0; k < e.count(); ++k) + { + int const i = _correspondingParamA[k]; + int const j = _correspondingParamB[k]; + + Vector2d const q = this->projectPoint(_Xs[j], i); + e[k][0] = q[0] - _measurements[k][0]; + e[k][1] = q[1] - _measurements[k][1]; + } + } + + virtual void fillJacobians(Matrix& Ak, Matrix& Bk, Matrix& Ck, + int i, int j, int k); + + virtual void updateParametersA(VectorArray const& deltaAi); + + virtual void saveAllParameters() + { + Base::saveAllParameters(); + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + _savedKs[i] = _cams[i].getIntrinsic(); + std::copy(_distortions.begin(), _distortions.end(), _savedDistortions.begin()); + } + + virtual void restoreAllParameters() + { + Base::restoreAllParameters(); + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + _cams[i].setIntrinsic(_savedKs[i]); + std::copy(_savedDistortions.begin(), _savedDistortions.end(), _distortions.begin()); + } + + protected: + int _mode; + std::vector& _distortions; + + std::vector _savedKs; + std::vector _savedDistortions; + }; // end struct VaryingInternalsMetricBundleOptimizer + +} // end namespace V3D + +# endif + +#endif diff --git a/extern/libmv/third_party/ssba/Math/v3d_linear.h b/extern/libmv/third_party/ssba/Math/v3d_linear.h new file mode 100644 index 00000000000..7d6e898169c --- /dev/null +++ b/extern/libmv/third_party/ssba/Math/v3d_linear.h @@ -0,0 +1,923 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_LINEAR_H +#define V3D_LINEAR_H + +#include +#include +#include +#include + +namespace V3D +{ + using namespace std; + + //! Unboxed vector type + template + struct InlineVectorBase + { + typedef Elem value_type; + typedef Elem element_type; + + typedef Elem const * const_iterator; + typedef Elem * iterator; + + static unsigned int size() { return Size; } + + Elem& operator[](unsigned int i) { return _vec[i]; } + Elem operator[](unsigned int i) const { return _vec[i]; } + + Elem& operator()(unsigned int i) { return _vec[i-1]; } + Elem operator()(unsigned int i) const { return _vec[i-1]; } + + const_iterator begin() const { return _vec; } + iterator begin() { return _vec; } + const_iterator end() const { return _vec + Size; } + iterator end() { return _vec + Size; } + + void newsize(unsigned int sz) const + { + assert(sz == Size); + } + + protected: + Elem _vec[Size]; + }; + + //! Boxed (heap allocated) vector. + template + struct VectorBase + { + typedef Elem value_type; + typedef Elem element_type; + + typedef Elem const * const_iterator; + typedef Elem * iterator; + + VectorBase() + : _size(0), _ownsVec(true), _vec(0) + { } + + VectorBase(unsigned int size) + : _size(size), _ownsVec(true), _vec(0) + { + if (size > 0) _vec = new Elem[size]; + } + + VectorBase(unsigned int size, Elem * values) + : _size(size), _ownsVec(false), _vec(values) + { } + + VectorBase(VectorBase const& a) + : _size(0), _ownsVec(true), _vec(0) + { + _size = a._size; + if (_size == 0) return; + _vec = new Elem[_size]; + std::copy(a._vec, a._vec + _size, _vec); + } + + ~VectorBase() { if (_ownsVec && _vec != 0) delete [] _vec; } + + VectorBase& operator=(VectorBase const& a) + { + if (this == &a) return *this; + + this->newsize(a._size); + std::copy(a._vec, a._vec + _size, _vec); + return *this; + } + + unsigned int size() const { return _size; } + + VectorBase& newsize(unsigned int sz) + { + if (sz == _size) return *this; + assert(_ownsVec); + + __destroy(); + _size = sz; + if (_size > 0) _vec = new Elem[_size]; + + return *this; + } + + + Elem& operator[](unsigned int i) { return _vec[i]; } + Elem operator[](unsigned int i) const { return _vec[i]; } + + Elem& operator()(unsigned int i) { return _vec[i-1]; } + Elem operator()(unsigned int i) const { return _vec[i-1]; } + + const_iterator begin() const { return _vec; } + iterator begin() { return _vec; } + const_iterator end() const { return _vec + _size; } + iterator end() { return _vec + _size; } + + protected: + void __destroy() + { + assert(_ownsVec); + + if (_vec != 0) delete [] _vec; + _size = 0; + _vec = 0; + } + + unsigned int _size; + bool _ownsVec; + Elem * _vec; + }; + + template + struct InlineMatrixBase + { + typedef Elem value_type; + typedef Elem element_type; + + typedef Elem * iterator; + typedef Elem const * const_iterator; + + static unsigned int num_rows() { return Rows; } + static unsigned int num_cols() { return Cols; } + + Elem * operator[](unsigned int row) { return _m[row]; } + Elem const * operator[](unsigned int row) const { return _m[row]; } + + Elem& operator()(unsigned int row, unsigned int col) { return _m[row-1][col-1]; } + Elem operator()(unsigned int row, unsigned int col) const { return _m[row-1][col-1]; } + + template + void getRowSlice(unsigned int row, unsigned int first, unsigned int last, Vec& dst) const + { + for (unsigned int c = first; c < last; ++c) dst[c-first] = _m[row][c]; + } + + template + void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const + { + for (unsigned int r = 0; r < len; ++r) dst[r] = _m[r+first][col]; + } + + void newsize(unsigned int rows, unsigned int cols) const + { + assert(rows == Rows && cols == Cols); + } + + const_iterator begin() const { return &_m[0][0]; } + iterator begin() { return &_m[0][0]; } + const_iterator end() const { return &_m[0][0] + Rows*Cols; } + iterator end() { return &_m[0][0] + Rows*Cols; } + + protected: + Elem _m[Rows][Cols]; + }; + + template + struct MatrixBase + { + typedef Elem value_type; + typedef Elem element_type; + + typedef Elem const * const_iterator; + typedef Elem * iterator; + + MatrixBase() + : _rows(0), _cols(0), _ownsData(true), _m(0) + { } + + MatrixBase(unsigned int rows, unsigned int cols) + : _rows(rows), _cols(cols), _ownsData(true), _m(0) + { + if (_rows * _cols == 0) return; + _m = new Elem[rows*cols]; + } + + MatrixBase(unsigned int rows, unsigned int cols, Elem * values) + : _rows(rows), _cols(cols), _ownsData(false), _m(values) + { } + + MatrixBase(MatrixBase const& a) + : _ownsData(true), _m(0) + { + _rows = a._rows; _cols = a._cols; + if (_rows * _cols == 0) return; + _m = new Elem[_rows*_cols]; + std::copy(a._m, a._m+_rows*_cols, _m); + } + + ~MatrixBase() + { + if (_ownsData && _m != 0) delete [] _m; + } + + MatrixBase& operator=(MatrixBase const& a) + { + if (this == &a) return *this; + + this->newsize(a.num_rows(), a.num_cols()); + + std::copy(a._m, a._m+_rows*_cols, _m); + return *this; + } + + void newsize(unsigned int rows, unsigned int cols) + { + if (rows == _rows && cols == _cols) return; + + assert(_ownsData); + + __destroy(); + + _rows = rows; + _cols = cols; + if (_rows * _cols == 0) return; + _m = new Elem[rows*cols]; + } + + unsigned int num_rows() const { return _rows; } + unsigned int num_cols() const { return _cols; } + + Elem * operator[](unsigned int row) { return _m + row*_cols; } + Elem const * operator[](unsigned int row) const { return _m + row*_cols; } + + Elem& operator()(unsigned int row, unsigned int col) { return _m[(row-1)*_cols + col-1]; } + Elem operator()(unsigned int row, unsigned int col) const { return _m[(row-1)*_cols + col-1]; } + + const_iterator begin() const { return _m; } + iterator begin() { return _m; } + const_iterator end() const { return _m + _rows*_cols; } + iterator end() { return _m + _rows*_cols; } + + template + void getRowSlice(unsigned int row, unsigned int first, unsigned int last, Vec& dst) const + { + Elem const * v = (*this)[row]; + for (unsigned int c = first; c < last; ++c) dst[c-first] = v[c]; + } + + template + void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const + { + for (unsigned int r = 0; r < len; ++r) dst[r] = _m[r+first][col]; + } + + protected: + void __destroy() + { + assert(_ownsData); + if (_m != 0) delete [] _m; + _m = 0; + _rows = _cols = 0; + } + + unsigned int _rows, _cols; + bool _ownsData; + Elem * _m; + }; + + template + struct CCS_Matrix + { + CCS_Matrix() + : _rows(0), _cols(0) + { } + + CCS_Matrix(int const rows, int const cols, vector > const& nonZeros) + : _rows(rows), _cols(cols) + { + this->initialize(nonZeros); + } + + CCS_Matrix(CCS_Matrix const& b) + : _rows(b._rows), _cols(b._cols), + _colStarts(b._colStarts), _rowIdxs(b._rowIdxs), _destIdxs(b._destIdxs), _values(b._values) + { } + + CCS_Matrix& operator=(CCS_Matrix const& b) + { + if (this == &b) return *this; + _rows = b._rows; + _cols = b._cols; + _colStarts = b._colStarts; + _rowIdxs = b._rowIdxs; + _destIdxs = b._destIdxs; + _values = b._values; + return *this; + } + + void create(int const rows, int const cols, vector > const& nonZeros) + { + _rows = rows; + _cols = cols; + this->initialize(nonZeros); + } + + unsigned int num_rows() const { return _rows; } + unsigned int num_cols() const { return _cols; } + + int getNonzeroCount() const { return _values.size(); } + + T const * getValues() const { return &_values[0]; } + T * getValues() { return &_values[0]; } + + int const * getDestIndices() const { return &_destIdxs[0]; } + int const * getColumnStarts() const { return &_colStarts[0]; } + int const * getRowIndices() const { return &_rowIdxs[0]; } + + void getRowRange(unsigned int col, unsigned int& firstRow, unsigned int& lastRow) const + { + firstRow = _rowIdxs[_colStarts[col]]; + lastRow = _rowIdxs[_colStarts[col+1]-1]+1; + } + + template + void getColumnSlice(unsigned int first, unsigned int len, unsigned int col, Vec& dst) const + { + unsigned int const last = first + len; + + for (int r = 0; r < len; ++r) dst[r] = 0; // Fill vector with zeros + + int const colStart = _colStarts[col]; + int const colEnd = _colStarts[col+1]; + + int i = colStart; + int r; + // Skip rows less than the given start row + while (i < colEnd && (r = _rowIdxs[i]) < first) ++i; + + // Copy elements until the final row + while (i < colEnd && (r = _rowIdxs[i]) < last) + { + dst[r-first] = _values[i]; + ++i; + } + } // end getColumnSlice() + + int getColumnNonzeroCount(unsigned int col) const + { + int const colStart = _colStarts[col]; + int const colEnd = _colStarts[col+1]; + return colEnd - colStart; + } + + template + void getSparseColumn(unsigned int col, VecA& rows, VecB& values) const + { + int const colStart = _colStarts[col]; + int const colEnd = _colStarts[col+1]; + int const nnz = colEnd - colStart; + + for (int i = 0; i < nnz; ++i) + { + rows[i] = _rowIdxs[colStart + i]; + values[i] = _values[colStart + i]; + } + } + + protected: + struct NonzeroInfo + { + int row, col, serial; + + // Sort wrt the column first + bool operator<(NonzeroInfo const& rhs) const + { + if (col < rhs.col) return true; + if (col > rhs.col) return false; + return row < rhs.row; + } + }; + + void initialize(std::vector > const& nonZeros) + { + using namespace std; + + int const nnz = nonZeros.size(); + + _colStarts.resize(_cols + 1); + _rowIdxs.resize(nnz); + + vector nz(nnz); + for (int k = 0; k < nnz; ++k) + { + nz[k].row = nonZeros[k].first; + nz[k].col = nonZeros[k].second; + nz[k].serial = k; + } + + // Sort in column major order + std::sort(nz.begin(), nz.end()); + + for (size_t k = 0; k < nnz; ++k) _rowIdxs[k] = nz[k].row; + + int curCol = -1; + for (int k = 0; k < nnz; ++k) + { + NonzeroInfo const& el = nz[k]; + if (el.col != curCol) + { + // Update empty cols between + for (int c = curCol+1; c < el.col; ++c) _colStarts[c] = k; + + curCol = el.col; + _colStarts[curCol] = k; + } // end if + } // end for (k) + + // Update remaining columns + for (int c = curCol+1; c <= _cols; ++c) _colStarts[c] = nnz; + + _destIdxs.resize(nnz); + for (int k = 0; k < nnz; ++k) _destIdxs[nz[k].serial] = k; + + _values.resize(nnz); + } // end initialize() + + int _rows, _cols; + std::vector _colStarts; + std::vector _rowIdxs; + std::vector _destIdxs; + std::vector _values; + }; // end struct CCS_Matrix + +//---------------------------------------------------------------------- + + template + inline void + fillVector(Vec& v, Elem val) + { + // We do not use std::fill since we rely only on size() and operator[] member functions. + for (unsigned int i = 0; i < v.size(); ++i) v[i] = val; + } + + template + inline void + makeZeroVector(Vec& v) + { + fillVector(v, 0); + } + + template + inline void + copyVector(VecA const& src, VecB& dst) + { + assert(src.size() == dst.size()); + // We do not use std::fill since we rely only on size() and operator[] member functions. + for (unsigned int i = 0; i < src.size(); ++i) dst[i] = src[i]; + } + + template + inline void + copyVectorSlice(VecA const& src, unsigned int srcStart, unsigned int srcLen, + VecB& dst, unsigned int dstStart) + { + unsigned int const end = std::min(srcStart + srcLen, src.size()); + unsigned int const sz = dst.size(); + unsigned int i0, i1; + for (i0 = srcStart, i1 = dstStart; i0 < end && i1 < sz; ++i0, ++i1) dst[i1] = src[i0]; + } + + template + inline typename Vec::value_type + norm_L1(Vec const& v) + { + typename Vec::value_type res(0); + for (unsigned int i = 0; i < v.size(); ++i) res += fabs(v[i]); + return res; + } + + template + inline typename Vec::value_type + norm_Linf(Vec const& v) + { + typename Vec::value_type res(0); + for (unsigned int i = 0; i < v.size(); ++i) res = std::max(res, fabs(v[i])); + return res; + } + + template + inline typename Vec::value_type + norm_L2(Vec const& v) + { + typename Vec::value_type res(0); + for (unsigned int i = 0; i < v.size(); ++i) res += v[i]*v[i]; + return sqrt((double)res); + } + + template + inline typename Vec::value_type + sqrNorm_L2(Vec const& v) + { + typename Vec::value_type res(0); + for (unsigned int i = 0; i < v.size(); ++i) res += v[i]*v[i]; + return res; + } + + template + inline void + normalizeVector(Vec& v) + { + typename Vec::value_type norm(norm_L2(v)); + for (unsigned int i = 0; i < v.size(); ++i) v[i] /= norm; + } + + template + inline typename VecA::value_type + innerProduct(VecA const& a, VecB const& b) + { + assert(a.size() == b.size()); + typename VecA::value_type res(0); + for (unsigned int i = 0; i < a.size(); ++i) res += a[i] * b[i]; + return res; + } + + template + inline void + scaleVector(Elem s, VecA const& v, VecB& dst) + { + for (unsigned int i = 0; i < v.size(); ++i) dst[i] = s * v[i]; + } + + template + inline void + scaleVectorIP(Elem s, Vec& v) + { + typedef typename Vec::value_type Elem2; + for (unsigned int i = 0; i < v.size(); ++i) + v[i] = (Elem2)(v[i] * s); + } + + template + inline void + makeCrossProductVector(VecA const& v, VecB const& w, VecC& dst) + { + assert(v.size() == 3); + assert(w.size() == 3); + assert(dst.size() == 3); + dst[0] = v[1]*w[2] - v[2]*w[1]; + dst[1] = v[2]*w[0] - v[0]*w[2]; + dst[2] = v[0]*w[1] - v[1]*w[0]; + } + + template + inline void + addVectors(VecA const& v, VecB const& w, VecC& dst) + { + assert(v.size() == w.size()); + assert(v.size() == dst.size()); + for (unsigned int i = 0; i < v.size(); ++i) dst[i] = v[i] + w[i]; + } + + template + inline void + subtractVectors(VecA const& v, VecB const& w, VecC& dst) + { + assert(v.size() == w.size()); + assert(v.size() == dst.size()); + for (unsigned int i = 0; i < v.size(); ++i) dst[i] = v[i] - w[i]; + } + + template + inline void + copyMatrix(MatA const& src, MatB& dst) + { + unsigned int const rows = src.num_rows(); + unsigned int const cols = src.num_cols(); + assert(dst.num_rows() == rows); + assert(dst.num_cols() == cols); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) dst[r][c] = src[r][c]; + } + + template + inline void + copyMatrixSlice(MatA const& src, unsigned int rowStart, unsigned int colStart, unsigned int rowLen, unsigned int colLen, + MatB& dst, unsigned int dstRow, unsigned int dstCol) + { + unsigned int const rows = dst.num_rows(); + unsigned int const cols = dst.num_cols(); + + unsigned int const rowEnd = std::min(rowStart + rowLen, src.num_rows()); + unsigned int const colEnd = std::min(colStart + colLen, src.num_cols()); + + unsigned int c0, c1, r0, r1; + + for (c0 = colStart, c1 = dstCol; c0 < colEnd && c1 < cols; ++c0, ++c1) + for (r0 = rowStart, r1 = dstRow; r0 < rowEnd && r1 < rows; ++r0, ++r1) + dst[r1][c1] = src[r0][c0]; + } + + template + inline void + makeTransposedMatrix(MatA const& src, MatB& dst) + { + unsigned int const rows = src.num_rows(); + unsigned int const cols = src.num_cols(); + assert(dst.num_cols() == rows); + assert(dst.num_rows() == cols); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) dst[c][r] = src[r][c]; + } + + template + inline void + fillMatrix(Mat& m, typename Mat::value_type val) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) m[r][c] = val; + } + + template + inline void + makeZeroMatrix(Mat& m) + { + fillMatrix(m, 0); + } + + template + inline void + makeIdentityMatrix(Mat& m) + { + makeZeroMatrix(m); + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + unsigned int n = std::min(rows, cols); + for (unsigned int i = 0; i < n; ++i) + m[i][i] = 1; + } + + template + inline void + makeCrossProductMatrix(Vec const& v, Mat& m) + { + assert(v.size() == 3); + assert(m.num_rows() == 3); + assert(m.num_cols() == 3); + m[0][0] = 0; m[0][1] = -v[2]; m[0][2] = v[1]; + m[1][0] = v[2]; m[1][1] = 0; m[1][2] = -v[0]; + m[2][0] = -v[1]; m[2][1] = v[0]; m[2][2] = 0; + } + + template + inline void + makeOuterProductMatrix(Vec const& v, Mat& m) + { + assert(m.num_cols() == m.num_rows()); + assert(v.size() == m.num_cols()); + unsigned const sz = v.size(); + for (unsigned r = 0; r < sz; ++r) + for (unsigned c = 0; c < sz; ++c) m[r][c] = v[r]*v[c]; + } + + template + inline void + makeOuterProductMatrix(VecA const& u, VecB const& v, Mat& m) + { + assert(m.num_cols() == m.num_rows()); + assert(u.size() == m.num_cols()); + assert(v.size() == m.num_cols()); + unsigned const sz = u.size(); + for (unsigned r = 0; r < sz; ++r) + for (unsigned c = 0; c < sz; ++c) m[r][c] = u[r]*v[c]; + } + + template + void addMatrices(MatA const& a, MatB const& b, MatC& dst) + { + assert(a.num_cols() == b.num_cols()); + assert(a.num_rows() == b.num_rows()); + assert(dst.num_cols() == a.num_cols()); + assert(dst.num_rows() == a.num_rows()); + + unsigned int const rows = a.num_rows(); + unsigned int const cols = a.num_cols(); + + for (unsigned r = 0; r < rows; ++r) + for (unsigned c = 0; c < cols; ++c) dst[r][c] = a[r][c] + b[r][c]; + } + + template + void addMatricesIP(MatA const& a, MatB& dst) + { + assert(dst.num_cols() == a.num_cols()); + assert(dst.num_rows() == a.num_rows()); + + unsigned int const rows = a.num_rows(); + unsigned int const cols = a.num_cols(); + + for (unsigned r = 0; r < rows; ++r) + for (unsigned c = 0; c < cols; ++c) dst[r][c] += a[r][c]; + } + + template + void subtractMatrices(MatA const& a, MatB const& b, MatC& dst) + { + assert(a.num_cols() == b.num_cols()); + assert(a.num_rows() == b.num_rows()); + assert(dst.num_cols() == a.num_cols()); + assert(dst.num_rows() == a.num_rows()); + + unsigned int const rows = a.num_rows(); + unsigned int const cols = a.num_cols(); + + for (unsigned r = 0; r < rows; ++r) + for (unsigned c = 0; c < cols; ++c) dst[r][c] = a[r][c] - b[r][c]; + } + + template + inline void + makeScaledMatrix(MatA const& m, Elem scale, MatB& dst) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) dst[r][c] = m[r][c] * scale; + } + + template + inline void + scaleMatrixIP(Elem scale, Mat& m) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) m[r][c] *= scale; + } + + template + inline void + multiply_A_v(Mat const& m, VecA const& in, VecB& dst) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + assert(in.size() == cols); + assert(dst.size() == rows); + + makeZeroVector(dst); + + for (unsigned int r = 0; r < rows; ++r) + for (unsigned int c = 0; c < cols; ++c) dst[r] += m[r][c] * in[c]; + } + + template + inline void + multiply_A_v_projective(Mat const& m, VecA const& in, VecB& dst) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + assert(in.size() == cols-1); + assert(dst.size() == rows-1); + + typename VecB::value_type w = m(rows-1, cols-1); + unsigned int r, i; + for (i = 0; i < cols-1; ++i) w += m(rows-1, i) * in[i]; + for (r = 0; r < rows-1; ++r) dst[r] = m(r, cols-1); + for (r = 0; r < rows-1; ++r) + for (unsigned int c = 0; c < cols-1; ++c) dst[r] += m[r][c] * in[c]; + for (i = 0; i < rows-1; ++i) dst[i] /= w; + } + + template + inline void + multiply_A_v_affine(Mat const& m, VecA const& in, VecB& dst) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + assert(in.size() == cols-1); + assert(dst.size() == rows); + + unsigned int r; + + for (r = 0; r < rows; ++r) dst[r] = m(r, cols-1); + for (r = 0; r < rows; ++r) + for (unsigned int c = 0; c < cols-1; ++c) dst[r] += m[r][c] * in[c]; + } + + template + inline void + multiply_At_v(Mat const& m, VecA const& in, VecB& dst) + { + unsigned int const rows = m.num_rows(); + unsigned int const cols = m.num_cols(); + assert(in.size() == rows); + assert(dst.size() == cols); + + makeZeroVector(dst); + for (unsigned int c = 0; c < cols; ++c) + for (unsigned int r = 0; r < rows; ++r) dst[c] += m[r][c] * in[r]; + } + + template + inline void + multiply_At_A(MatA const& a, MatB& dst) + { + assert(dst.num_rows() == a.num_cols()); + assert(dst.num_cols() == a.num_cols()); + + typedef typename MatB::value_type Elem; + + Elem accum; + for (unsigned int r = 0; r < a.num_cols(); ++r) + for (unsigned int c = 0; c < a.num_cols(); ++c) + { + accum = 0; + for (unsigned int k = 0; k < a.num_rows(); ++k) accum += a[k][r] * a[k][c]; + dst[r][c] = accum; + } + } + + template + inline void + multiply_A_B(MatA const& a, MatB const& b, MatC& dst) + { + assert(a.num_cols() == b.num_rows()); + assert(dst.num_rows() == a.num_rows()); + assert(dst.num_cols() == b.num_cols()); + + typedef typename MatC::value_type Elem; + + Elem accum; + for (unsigned int r = 0; r < a.num_rows(); ++r) + for (unsigned int c = 0; c < b.num_cols(); ++c) + { + accum = 0; + for (unsigned int k = 0; k < a.num_cols(); ++k) accum += a[r][k] * b[k][c]; + dst[r][c] = accum; + } + } + + template + inline void + multiply_At_B(MatA const& a, MatB const& b, MatC& dst) + { + assert(a.num_rows() == b.num_rows()); + assert(dst.num_rows() == a.num_cols()); + assert(dst.num_cols() == b.num_cols()); + + typedef typename MatC::value_type Elem; + + Elem accum; + for (unsigned int r = 0; r < a.num_cols(); ++r) + for (unsigned int c = 0; c < b.num_cols(); ++c) + { + accum = 0; + for (unsigned int k = 0; k < a.num_rows(); ++k) accum += a[k][r] * b[k][c]; + dst[r][c] = accum; + } + } + + template + inline void + multiply_A_Bt(MatA const& a, MatB const& b, MatC& dst) + { + assert(a.num_cols() == b.num_cols()); + assert(dst.num_rows() == a.num_rows()); + assert(dst.num_cols() == b.num_rows()); + + typedef typename MatC::value_type Elem; + + Elem accum; + for (unsigned int r = 0; r < a.num_rows(); ++r) + for (unsigned int c = 0; c < b.num_rows(); ++c) + { + accum = 0; + for (unsigned int k = 0; k < a.num_cols(); ++k) accum += a[r][k] * b[c][k]; + dst[r][c] = accum; + } + } + + template + inline void + transposeMatrixIP(Mat& a) + { + assert(a.num_rows() == a.num_cols()); + + for (unsigned int r = 0; r < a.num_rows(); ++r) + for (unsigned int c = 0; c < r; ++c) + std::swap(a[r][c], a[c][r]); + } + +} // end namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h b/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h new file mode 100644 index 00000000000..969ec99694f --- /dev/null +++ b/extern/libmv/third_party/ssba/Math/v3d_linear_utils.h @@ -0,0 +1,391 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_LINEAR_UTILS_H +#define V3D_LINEAR_UTILS_H + +#include "Math/v3d_linear.h" + +#include + +namespace V3D +{ + + template + struct InlineVector : public InlineVectorBase + { + }; // end struct InlineVector + + template + struct Vector : public VectorBase + { + Vector() + : VectorBase() + { } + + Vector(unsigned int size) + : VectorBase(size) + { } + + Vector(unsigned int size, Elem * values) + : VectorBase(size, values) + { } + + Vector(Vector const& a) + : VectorBase(a) + { } + + Vector& operator=(Vector const& a) + { + (VectorBase::operator=)(a); + return *this; + } + + Vector& operator+=(Vector const& rhs) + { + addVectorsIP(rhs, *this); + return *this; + } + + Vector& operator*=(Elem scale) + { + scaleVectorsIP(scale, *this); + return *this; + } + + Vector operator+(Vector const& rhs) const + { + Vector res(this->size()); + addVectors(*this, rhs, res); + return res; + } + + Vector operator-(Vector const& rhs) const + { + Vector res(this->size()); + subtractVectors(*this, rhs, res); + return res; + } + + Elem operator*(Vector const& rhs) const + { + return innerProduct(*this, rhs); + } + + }; // end struct Vector + + template + struct InlineMatrix : public InlineMatrixBase + { + }; // end struct InlineMatrix + + template + struct Matrix : public MatrixBase + { + Matrix() + : MatrixBase() + { } + + Matrix(unsigned int rows, unsigned int cols) + : MatrixBase(rows, cols) + { } + + Matrix(unsigned int rows, unsigned int cols, Elem * values) + : MatrixBase(rows, cols, values) + { } + + Matrix(Matrix const& a) + : MatrixBase(a) + { } + + Matrix& operator=(Matrix const& a) + { + (MatrixBase::operator=)(a); + return *this; + } + + Matrix& operator+=(Matrix const& rhs) + { + addMatricesIP(rhs, *this); + return *this; + } + + Matrix& operator*=(Elem scale) + { + scaleMatrixIP(scale, *this); + return *this; + } + + Matrix operator+(Matrix const& rhs) const + { + Matrix res(this->num_rows(), this->num_cols()); + addMatrices(*this, rhs, res); + return res; + } + + Matrix operator-(Matrix const& rhs) const + { + Matrix res(this->num_rows(), this->num_cols()); + subtractMatrices(*this, rhs, res); + return res; + } + + }; // end struct Matrix + +//---------------------------------------------------------------------- + + typedef InlineVector Vector2f; + typedef InlineVector Vector2d; + typedef InlineVector Vector3f; + typedef InlineVector Vector3d; + typedef InlineVector Vector4f; + typedef InlineVector Vector4d; + + typedef InlineMatrix Matrix2x2f; + typedef InlineMatrix Matrix2x2d; + typedef InlineMatrix Matrix3x3f; + typedef InlineMatrix Matrix3x3d; + typedef InlineMatrix Matrix4x4f; + typedef InlineMatrix Matrix4x4d; + + typedef InlineMatrix Matrix2x3f; + typedef InlineMatrix Matrix2x3d; + typedef InlineMatrix Matrix3x4f; + typedef InlineMatrix Matrix3x4d; + + template + struct VectorArray + { + VectorArray(unsigned count, unsigned size) + : _count(count), _size(size), _values(0), _vectors(0) + { + unsigned const nTotal = _count * _size; + if (count > 0) _vectors = new Vector[count]; + if (nTotal > 0) _values = new Elem[nTotal]; + for (unsigned i = 0; i < _count; ++i) new (&_vectors[i]) Vector(_size, _values + i*_size); + } + + VectorArray(unsigned count, unsigned size, Elem initVal) + : _count(count), _size(size), _values(0), _vectors(0) + { + unsigned const nTotal = _count * _size; + if (count > 0) _vectors = new Vector[count]; + if (nTotal > 0) _values = new Elem[nTotal]; + for (unsigned i = 0; i < _count; ++i) new (&_vectors[i]) Vector(_size, _values + i*_size); + std::fill(_values, _values + nTotal, initVal); + } + + ~VectorArray() + { + delete [] _values; + delete [] _vectors; + } + + unsigned count() const { return _count; } + unsigned size() const { return _size; } + + //! Get the submatrix at position ix + Vector const& operator[](unsigned ix) const + { + return _vectors[ix]; + } + + //! Get the submatrix at position ix + Vector& operator[](unsigned ix) + { + return _vectors[ix]; + } + + protected: + unsigned _count, _size; + Elem * _values; + Vector * _vectors; + + private: + VectorArray(VectorArray const&); + void operator=(VectorArray const&); + }; + + template + struct MatrixArray + { + MatrixArray(unsigned count, unsigned nRows, unsigned nCols) + : _count(count), _rows(nRows), _columns(nCols), _values(0), _matrices(0) + { + unsigned const nTotal = _count * _rows * _columns; + if (count > 0) _matrices = new Matrix[count]; + if (nTotal > 0) _values = new double[nTotal]; + for (unsigned i = 0; i < _count; ++i) + new (&_matrices[i]) Matrix(_rows, _columns, _values + i*(_rows*_columns)); + } + + ~MatrixArray() + { + delete [] _matrices; + delete [] _values; + } + + //! Get the submatrix at position ix + Matrix const& operator[](unsigned ix) const + { + return _matrices[ix]; + } + + //! Get the submatrix at position ix + Matrix& operator[](unsigned ix) + { + return _matrices[ix]; + } + + unsigned count() const { return _count; } + unsigned num_rows() const { return _rows; } + unsigned num_cols() const { return _columns; } + + protected: + unsigned _count, _rows, _columns; + double * _values; + Matrix * _matrices; + + private: + MatrixArray(MatrixArray const&); + void operator=(MatrixArray const&); + }; + +//---------------------------------------------------------------------- + + template + inline InlineVector + operator+(InlineVector const& v, InlineVector const& w) + { + InlineVector res; + addVectors(v, w, res); + return res; + } + + template + inline InlineVector + operator-(InlineVector const& v, InlineVector const& w) + { + InlineVector res; + subtractVectors(v, w, res); + return res; + } + + template + inline InlineVector + operator*(Elem scale, InlineVector const& v) + { + InlineVector res; + scaleVector(scale, v, res); + return res; + } + + template + inline InlineVector + operator*(InlineMatrix const& A, InlineVector const& v) + { + InlineVector res; + multiply_A_v(A, v, res); + return res; + } + + template + inline InlineMatrix + operator*(InlineMatrix const& A, InlineMatrix const& B) + { + InlineMatrix res; + multiply_A_B(A, B, res); + return res; + } + + template + inline InlineMatrix + transposedMatrix(InlineMatrix const& A) + { + InlineMatrix At; + makeTransposedMatrix(A, At); + return At; + } + + template + inline InlineMatrix + invertedMatrix(InlineMatrix const& A) + { + Elem a = A[0][0], b = A[0][1], c = A[0][2]; + Elem d = A[1][0], e = A[1][1], f = A[1][2]; + Elem g = A[2][0], h = A[2][1], i = A[2][2]; + + Elem const det = a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h; + + InlineMatrix res; + res[0][0] = e*i-f*h; res[0][1] = c*h-b*i; res[0][2] = b*f-c*e; + res[1][0] = f*g-d*i; res[1][1] = a*i-c*g; res[1][2] = c*d-a*f; + res[2][0] = d*h-e*g; res[2][1] = b*g-a*h; res[2][2] = a*e-b*d; + + scaleMatrixIP(1.0/det, res); + return res; + } + + template + inline InlineVector + makeVector2(Elem a, Elem b) + { + InlineVector res; + res[0] = a; res[1] = b; + return res; + } + + template + inline InlineVector + makeVector3(Elem a, Elem b, Elem c) + { + InlineVector res; + res[0] = a; res[1] = b; res[2] = c; + return res; + } + + template + inline void + displayVector(Vec const& v) + { + using namespace std; + + for (int r = 0; r < v.size(); ++r) + cout << v[r] << " "; + cout << endl; + } + + template + inline void + displayMatrix(Mat const& A) + { + using namespace std; + + for (int r = 0; r < A.num_rows(); ++r) + { + for (int c = 0; c < A.num_cols(); ++c) + cout << A[r][c] << " "; + cout << endl; + } + } + +} // end namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h b/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h new file mode 100644 index 00000000000..9e38b92a94b --- /dev/null +++ b/extern/libmv/third_party/ssba/Math/v3d_mathutilities.h @@ -0,0 +1,59 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_MATH_UTILITIES_H +#define V3D_MATH_UTILITIES_H + +#include "Math/v3d_linear.h" +#include "Math/v3d_linear_utils.h" + +#include + +namespace V3D +{ + + template + inline void + createRotationMatrixRodriguez(Vec const& omega, Mat& R) + { + assert(omega.size() == 3); + assert(R.num_rows() == 3); + assert(R.num_cols() == 3); + + double const theta = norm_L2(omega); + makeIdentityMatrix(R); + if (fabs(theta) > 1e-6) + { + Matrix3x3d J, J2; + makeCrossProductMatrix(omega, J); + multiply_A_B(J, J, J2); + double const c1 = sin(theta)/theta; + double const c2 = (1-cos(theta))/(theta*theta); + for (int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) + R[i][j] += c1*J[i][j] + c2*J2[i][j]; + } + } // end createRotationMatrixRodriguez() + + template inline double sqr(T x) { return x*x; } + +} // namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp b/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp new file mode 100644 index 00000000000..234815fcd1f --- /dev/null +++ b/extern/libmv/third_party/ssba/Math/v3d_optimization.cpp @@ -0,0 +1,955 @@ +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#include "Math/v3d_optimization.h" + +#if defined(V3DLIB_ENABLE_SUITESPARSE) +//# include "COLAMD/Include/colamd.h" +# include "colamd.h" +extern "C" +{ +//# include "LDL/Include/ldl.h" +# include "ldl.h" +} +#endif + +#include +#include + +#define USE_BLOCK_REORDERING 1 +#define USE_MULTIPLICATIVE_UPDATE 1 + +using namespace std; + +namespace +{ + + using namespace V3D; + + inline double + squaredResidual(VectorArray const& e) + { + int const N = e.count(); + int const M = e.size(); + + double res = 0.0; + + for (int n = 0; n < N; ++n) + for (int m = 0; m < M; ++m) + res += e[n][m] * e[n][m]; + + return res; + } // end squaredResidual() + +} // end namespace <> + +namespace V3D +{ + + int optimizerVerbosenessLevel = 0; + +#if defined(V3DLIB_ENABLE_SUITESPARSE) + + void + SparseLevenbergOptimizer::setupSparseJtJ() + { + int const nVaryingA = _nParametersA - _nNonvaryingA; + int const nVaryingB = _nParametersB - _nNonvaryingB; + int const nVaryingC = _paramDimensionC - _nNonvaryingC; + + int const bColumnStart = nVaryingA*_paramDimensionA; + int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB; + int const nColumns = cColumnStart + nVaryingC; + + _jointNonzerosW.clear(); + _jointIndexW.resize(_nMeasurements); +#if 1 + { + map, int> jointNonzeroMap; + for (size_t k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k] - _nNonvaryingA; + int const j = _correspondingParamB[k] - _nNonvaryingB; + if (i >= 0 && j >= 0) + { + map, int>::const_iterator p = jointNonzeroMap.find(make_pair(i, j)); + if (p == jointNonzeroMap.end()) + { + jointNonzeroMap.insert(make_pair(make_pair(i, j), _jointNonzerosW.size())); + _jointIndexW[k] = _jointNonzerosW.size(); + _jointNonzerosW.push_back(make_pair(i, j)); + } + else + { + _jointIndexW[k] = (*p).second; + } // end if + } // end if + } // end for (k) + } // end scope +#else + for (size_t k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k] - _nNonvaryingA; + int const j = _correspondingParamB[k] - _nNonvaryingB; + if (i >= 0 && j >= 0) + { + _jointIndexW[k] = _jointNonzerosW.size(); + _jointNonzerosW.push_back(make_pair(i, j)); + } + } // end for (k) +#endif + +#if defined(USE_BLOCK_REORDERING) + int const bBlockColumnStart = nVaryingA; + int const cBlockColumnStart = bBlockColumnStart + nVaryingB; + + int const nBlockColumns = cBlockColumnStart + ((nVaryingC > 0) ? 1 : 0); + + //cout << "nBlockColumns = " << nBlockColumns << endl; + + // For the column reordering we treat the columns belonging to one set + // of parameters as one (logical) column. + + // Determine non-zeros of JtJ (we forget about the non-zero diagonal for now) + // Only consider nonzeros of Ai^t * Bj induced by the measurements. + vector > nz_blockJtJ(_jointNonzerosW.size()); + for (int k = 0; k < _jointNonzerosW.size(); ++k) + { + nz_blockJtJ[k].first = _jointNonzerosW[k].second + bBlockColumnStart; + nz_blockJtJ[k].second = _jointNonzerosW[k].first; + } + + if (nVaryingC > 0) + { + // We assume, that the global unknowns are linked to every other variable. + for (int i = 0; i < nVaryingA; ++i) + nz_blockJtJ.push_back(make_pair(cBlockColumnStart, i)); + for (int j = 0; j < nVaryingB; ++j) + nz_blockJtJ.push_back(make_pair(cBlockColumnStart, j + bBlockColumnStart)); + } // end if + + int const nnzBlock = nz_blockJtJ.size(); + + vector permBlockJtJ(nBlockColumns + 1); + + if (nnzBlock > 0) + { +// cout << "nnzBlock = " << nnzBlock << endl; + + CCS_Matrix blockJtJ(nBlockColumns, nBlockColumns, nz_blockJtJ); + +// cout << " nz_blockJtJ: " << endl; +// for (size_t k = 0; k < nz_blockJtJ.size(); ++k) +// cout << " " << nz_blockJtJ[k].first << ":" << nz_blockJtJ[k].second << endl; +// cout << endl; + + int * colStarts = (int *)blockJtJ.getColumnStarts(); + int * rowIdxs = (int *)blockJtJ.getRowIndices(); + +// cout << "blockJtJ_colStarts = "; +// for (int k = 0; k <= nBlockColumns; ++k) cout << colStarts[k] << " "; +// cout << endl; + +// cout << "blockJtJ_rowIdxs = "; +// for (int k = 0; k < nnzBlock; ++k) cout << rowIdxs[k] << " "; +// cout << endl; + + int stats[COLAMD_STATS]; + symamd(nBlockColumns, rowIdxs, colStarts, &permBlockJtJ[0], (double *) NULL, stats, &calloc, &free); + if (optimizerVerbosenessLevel >= 2) symamd_report(stats); + } + else + { + for (int k = 0; k < permBlockJtJ.size(); ++k) permBlockJtJ[k] = k; + } // end if + +// cout << "permBlockJtJ = "; +// for (int k = 0; k < permBlockJtJ.size(); ++k) +// cout << permBlockJtJ[k] << " "; +// cout << endl; + + // From the determined symbolic permutation with logical variables, determine the actual ordering + _perm_JtJ.resize(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC + 1); + + int curDstCol = 0; + for (int k = 0; k < permBlockJtJ.size()-1; ++k) + { + int const srcCol = permBlockJtJ[k]; + if (srcCol < nVaryingA) + { + for (int n = 0; n < _paramDimensionA; ++n) + _perm_JtJ[curDstCol + n] = srcCol*_paramDimensionA + n; + curDstCol += _paramDimensionA; + } + else if (srcCol >= bBlockColumnStart && srcCol < cBlockColumnStart) + { + int const bStart = nVaryingA*_paramDimensionA; + int const j = srcCol - bBlockColumnStart; + + for (int n = 0; n < _paramDimensionB; ++n) + _perm_JtJ[curDstCol + n] = bStart + j*_paramDimensionB + n; + curDstCol += _paramDimensionB; + } + else if (srcCol == cBlockColumnStart) + { + int const cStart = nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB; + + for (int n = 0; n < nVaryingC; ++n) + _perm_JtJ[curDstCol + n] = cStart + n; + curDstCol += nVaryingC; + } + else + { + cerr << "Should not reach " << __LINE__ << ":" << __LINE__ << "!" << endl; + assert(false); + } + } +#else + vector > nz, nzL; + this->serializeNonZerosJtJ(nz); + + for (int k = 0; k < nz.size(); ++k) + { + // Swap rows and columns, since serializeNonZerosJtJ() generates the + // upper triangular part but symamd wants the lower triangle. + nzL.push_back(make_pair(nz[k].second, nz[k].first)); + } + + _perm_JtJ.resize(nColumns+1); + + if (nzL.size() > 0) + { + CCS_Matrix symbJtJ(nColumns, nColumns, nzL); + + int * colStarts = (int *)symbJtJ.getColumnStarts(); + int * rowIdxs = (int *)symbJtJ.getRowIndices(); + +// cout << "symbJtJ_colStarts = "; +// for (int k = 0; k <= nColumns; ++k) cout << colStarts[k] << " "; +// cout << endl; + +// cout << "symbJtJ_rowIdxs = "; +// for (int k = 0; k < nzL.size(); ++k) cout << rowIdxs[k] << " "; +// cout << endl; + + int stats[COLAMD_STATS]; + symamd(nColumns, rowIdxs, colStarts, &_perm_JtJ[0], (double *) NULL, stats, &calloc, &free); + if (optimizerVerbosenessLevel >= 2) symamd_report(stats); + } + else + { + for (int k = 0; k < _perm_JtJ.size(); ++k) _perm_JtJ[k] = k; + } //// end if +#endif + _perm_JtJ.back() = _perm_JtJ.size() - 1; + +// cout << "_perm_JtJ = "; +// for (int k = 0; k < _perm_JtJ.size(); ++k) cout << _perm_JtJ[k] << " "; +// cout << endl; + + // Finally, compute the inverse of the full permutation. + _invPerm_JtJ.resize(_perm_JtJ.size()); + for (size_t k = 0; k < _perm_JtJ.size(); ++k) + _invPerm_JtJ[_perm_JtJ[k]] = k; + + vector > nz_JtJ; + this->serializeNonZerosJtJ(nz_JtJ); + + for (int k = 0; k < nz_JtJ.size(); ++k) + { + int const i = nz_JtJ[k].first; + int const j = nz_JtJ[k].second; + + int pi = _invPerm_JtJ[i]; + int pj = _invPerm_JtJ[j]; + // Swap values if in lower triangular part + if (pi > pj) std::swap(pi, pj); + nz_JtJ[k].first = pi; + nz_JtJ[k].second = pj; + } + + int const nnz = nz_JtJ.size(); + +// cout << "nz_JtJ = "; +// for (int k = 0; k < nnz; ++k) cout << nz_JtJ[k].first << ":" << nz_JtJ[k].second << " "; +// cout << endl; + + _JtJ.create(nColumns, nColumns, nz_JtJ); + +// cout << "_colStart_JtJ = "; +// for (int k = 0; k < _JtJ.num_cols(); ++k) cout << _JtJ.getColumnStarts()[k] << " "; +// cout << endl; + +// cout << "_rowIdxs_JtJ = "; +// for (int k = 0; k < nnz; ++k) cout << _JtJ.getRowIndices()[k] << " "; +// cout << endl; + + vector workFlags(nColumns); + + _JtJ_Lp.resize(nColumns+1); + _JtJ_Parent.resize(nColumns); + _JtJ_Lnz.resize(nColumns); + + ldl_symbolic(nColumns, (int *)_JtJ.getColumnStarts(), (int *)_JtJ.getRowIndices(), + &_JtJ_Lp[0], &_JtJ_Parent[0], &_JtJ_Lnz[0], + &workFlags[0], NULL, NULL); + + if (optimizerVerbosenessLevel >= 1) + cout << "SparseLevenbergOptimizer: Nonzeros in LDL decomposition: " << _JtJ_Lp[nColumns] << endl; + + } // end SparseLevenbergOptimizer::setupSparseJtJ() + + void + SparseLevenbergOptimizer::serializeNonZerosJtJ(vector >& dst) const + { + int const nVaryingA = _nParametersA - _nNonvaryingA; + int const nVaryingB = _nParametersB - _nNonvaryingB; + int const nVaryingC = _paramDimensionC - _nNonvaryingC; + + int const bColumnStart = nVaryingA*_paramDimensionA; + int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB; + + dst.clear(); + + // Add the diagonal block matrices (only the upper triangular part). + + // Ui submatrices of JtJ + for (int i = 0; i < nVaryingA; ++i) + { + int const i0 = i * _paramDimensionA; + + for (int c = 0; c < _paramDimensionA; ++c) + for (int r = 0; r <= c; ++r) + dst.push_back(make_pair(i0 + r, i0 + c)); + } + + // Vj submatrices of JtJ + for (int j = 0; j < nVaryingB; ++j) + { + int const j0 = j*_paramDimensionB + bColumnStart; + + for (int c = 0; c < _paramDimensionB; ++c) + for (int r = 0; r <= c; ++r) + dst.push_back(make_pair(j0 + r, j0 + c)); + } + + // Z submatrix of JtJ + for (int c = 0; c < nVaryingC; ++c) + for (int r = 0; r <= c; ++r) + dst.push_back(make_pair(cColumnStart + r, cColumnStart + c)); + + // Add the elements i and j linked by an observation k + // W submatrix of JtJ + for (size_t n = 0; n < _jointNonzerosW.size(); ++n) + { + int const i0 = _jointNonzerosW[n].first; + int const j0 = _jointNonzerosW[n].second; + int const r0 = i0*_paramDimensionA; + int const c0 = j0*_paramDimensionB + bColumnStart; + + for (int r = 0; r < _paramDimensionA; ++r) + for (int c = 0; c < _paramDimensionB; ++c) + dst.push_back(make_pair(r0 + r, c0 + c)); + } // end for (n) + + if (nVaryingC > 0) + { + // Finally, add the dense columns linking i (resp. j) with the global parameters. + // X submatrix of JtJ + for (int i = 0; i < nVaryingA; ++i) + { + int const i0 = i*_paramDimensionA; + + for (int r = 0; r < _paramDimensionA; ++r) + for (int c = 0; c < nVaryingC; ++c) + dst.push_back(make_pair(i0 + r, cColumnStart + c)); + } + + // Y submatrix of JtJ + for (int j = 0; j < nVaryingB; ++j) + { + int const j0 = j*_paramDimensionB + bColumnStart; + + for (int r = 0; r < _paramDimensionB; ++r) + for (int c = 0; c < nVaryingC; ++c) + dst.push_back(make_pair(j0 + r, cColumnStart + c)); + } + } // end if + } // end SparseLevenbergOptimizer::serializeNonZerosJtJ() + + void + SparseLevenbergOptimizer::fillSparseJtJ(MatrixArray const& Ui, + MatrixArray const& Vj, + MatrixArray const& Wn, + Matrix const& Z, + Matrix const& X, + Matrix const& Y) + { + int const nVaryingA = _nParametersA - _nNonvaryingA; + int const nVaryingB = _nParametersB - _nNonvaryingB; + int const nVaryingC = _paramDimensionC - _nNonvaryingC; + + int const bColumnStart = nVaryingA*_paramDimensionA; + int const cColumnStart = bColumnStart + nVaryingB*_paramDimensionB; + + int const nCols = _JtJ.num_cols(); + int const nnz = _JtJ.getNonzeroCount(); + + // The following has to replicate the procedure as in serializeNonZerosJtJ() + + int serial = 0; + + double * values = _JtJ.getValues(); + int const * destIdxs = _JtJ.getDestIndices(); + + // Add the diagonal block matrices (only the upper triangular part). + + // Ui submatrices of JtJ + for (int i = 0; i < nVaryingA; ++i) + { + int const i0 = i * _paramDimensionA; + + for (int c = 0; c < _paramDimensionA; ++c) + for (int r = 0; r <= c; ++r, ++serial) + values[destIdxs[serial]] = Ui[i][r][c]; + } + + // Vj submatrices of JtJ + for (int j = 0; j < nVaryingB; ++j) + { + int const j0 = j*_paramDimensionB + bColumnStart; + + for (int c = 0; c < _paramDimensionB; ++c) + for (int r = 0; r <= c; ++r, ++serial) + values[destIdxs[serial]] = Vj[j][r][c]; + } + + // Z submatrix of JtJ + for (int c = 0; c < nVaryingC; ++c) + for (int r = 0; r <= c; ++r, ++serial) + values[destIdxs[serial]] = Z[r][c]; + + // Add the elements i and j linked by an observation k + // W submatrix of JtJ + for (size_t n = 0; n < _jointNonzerosW.size(); ++n) + { + for (int r = 0; r < _paramDimensionA; ++r) + for (int c = 0; c < _paramDimensionB; ++c, ++serial) + values[destIdxs[serial]] = Wn[n][r][c]; + } // end for (k) + + if (nVaryingC > 0) + { + // Finally, add the dense columns linking i (resp. j) with the global parameters. + // X submatrix of JtJ + for (int i = 0; i < nVaryingA; ++i) + { + int const r0 = i * _paramDimensionA; + for (int r = 0; r < _paramDimensionA; ++r) + for (int c = 0; c < nVaryingC; ++c, ++serial) + values[destIdxs[serial]] = X[r0+r][c]; + } + + // Y submatrix of JtJ + for (int j = 0; j < nVaryingB; ++j) + { + int const r0 = j * _paramDimensionB; + for (int r = 0; r < _paramDimensionB; ++r) + for (int c = 0; c < nVaryingC; ++c, ++serial) + values[destIdxs[serial]] = Y[r0+r][c]; + } + } // end if + } // end SparseLevenbergOptimizer::fillSparseJtJ() + + void + SparseLevenbergOptimizer::minimize() + { + status = LEVENBERG_OPTIMIZER_TIMEOUT; + bool computeDerivatives = true; + + int const nVaryingA = _nParametersA - _nNonvaryingA; + int const nVaryingB = _nParametersB - _nNonvaryingB; + int const nVaryingC = _paramDimensionC - _nNonvaryingC; + + if (nVaryingA == 0 && nVaryingB == 0 && nVaryingC == 0) + { + // No degrees of freedom, nothing to optimize. + status = LEVENBERG_OPTIMIZER_CONVERGED; + return; + } + + this->setupSparseJtJ(); + + Vector weights(_nMeasurements); + + MatrixArray Ak(_nMeasurements, _measurementDimension, _paramDimensionA); + MatrixArray Bk(_nMeasurements, _measurementDimension, _paramDimensionB); + MatrixArray Ck(_nMeasurements, _measurementDimension, _paramDimensionC); + + MatrixArray Ui(nVaryingA, _paramDimensionA, _paramDimensionA); + MatrixArray Vj(nVaryingB, _paramDimensionB, _paramDimensionB); + + // Wn = Ak^t*Bk + MatrixArray Wn(_jointNonzerosW.size(), _paramDimensionA, _paramDimensionB); + + Matrix Z(nVaryingC, nVaryingC); + + // X = A^t*C + Matrix X(nVaryingA*_paramDimensionA, nVaryingC); + // Y = B^t*C + Matrix Y(nVaryingB*_paramDimensionB, nVaryingC); + + VectorArray residuals(_nMeasurements, _measurementDimension); + VectorArray residuals2(_nMeasurements, _measurementDimension); + + VectorArray diagUi(nVaryingA, _paramDimensionA); + VectorArray diagVj(nVaryingB, _paramDimensionB); + Vector diagZ(nVaryingC); + + VectorArray At_e(nVaryingA, _paramDimensionA); + VectorArray Bt_e(nVaryingB, _paramDimensionB); + Vector Ct_e(nVaryingC); + + Vector Jt_e(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC); + + Vector delta(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC); + Vector deltaPerm(nVaryingA*_paramDimensionA + nVaryingB*_paramDimensionB + nVaryingC); + + VectorArray deltaAi(_nParametersA, _paramDimensionA); + VectorArray deltaBj(_nParametersB, _paramDimensionB); + Vector deltaC(_paramDimensionC); + + double err = 0.0; + + for (currentIteration = 0; currentIteration < maxIterations; ++currentIteration) + { + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: currentIteration: " << currentIteration << endl; + if (computeDerivatives) + { + this->evalResidual(residuals); + this->fillWeights(residuals, weights); + for (int k = 0; k < _nMeasurements; ++k) + scaleVectorIP(weights[k], residuals[k]); + + err = squaredResidual(residuals); + + if (optimizerVerbosenessLevel >= 1) cout << "SparseLevenbergOptimizer: |residual|^2 = " << err << endl; + if (optimizerVerbosenessLevel >= 2) cout << "SparseLevenbergOptimizer: lambda = " << lambda << endl; + + for (int k = 0; k < residuals.count(); ++k) scaleVectorIP(-1.0, residuals[k]); + + this->setupJacobianGathering(); + this->fillAllJacobians(weights, Ak, Bk, Ck); + + // Compute the different parts of J^t*e + if (nVaryingA > 0) + { + for (int i = 0; i < nVaryingA; ++i) makeZeroVector(At_e[i]); + + Vector tmp(_paramDimensionA); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k] - _nNonvaryingA; + if (i < 0) continue; + multiply_At_v(Ak[k], residuals[k], tmp); + addVectors(tmp, At_e[i], At_e[i]); + } // end for (k) + } // end if + + if (nVaryingB > 0) + { + for (int j = 0; j < nVaryingB; ++j) makeZeroVector(Bt_e[j]); + + Vector tmp(_paramDimensionB); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const j = _correspondingParamB[k] - _nNonvaryingB; + if (j < 0) continue; + multiply_At_v(Bk[k], residuals[k], tmp); + addVectors(tmp, Bt_e[j], Bt_e[j]); + } // end for (k) + } // end if + + if (nVaryingC > 0) + { + makeZeroVector(Ct_e); + + Vector tmp(_paramDimensionC); + + for (int k = 0; k < _nMeasurements; ++k) + { + multiply_At_v(Ck[k], residuals[k], tmp); + for (int l = 0; l < nVaryingC; ++l) Ct_e[l] += tmp[_nNonvaryingC + l]; + } + } // end if + + int pos = 0; + for (int i = 0; i < nVaryingA; ++i) + for (int l = 0; l < _paramDimensionA; ++l, ++pos) + Jt_e[pos] = At_e[i][l]; + for (int j = 0; j < nVaryingB; ++j) + for (int l = 0; l < _paramDimensionB; ++l, ++pos) + Jt_e[pos] = Bt_e[j][l]; + for (int l = 0; l < nVaryingC; ++l, ++pos) + Jt_e[pos] = Ct_e[l]; + +// cout << "Jt_e = "; +// for (int k = 0; k < Jt_e.size(); ++k) cout << Jt_e[k] << " "; +// cout << endl; + + if (this->applyGradientStoppingCriteria(norm_Linf(Jt_e))) + { + status = LEVENBERG_OPTIMIZER_CONVERGED; + goto end; + } + + // The lhs J^t*J consists of several parts: + // [ U W X ] + // J^t*J = [ W^t V Y ] + // [ X^t Y^t Z ], + // where U, V and W are block-sparse matrices (due to the sparsity of A and B). + // X, Y and Z contain only a few columns (the number of global parameters). + + if (nVaryingA > 0) + { + // Compute Ui + Matrix U(_paramDimensionA, _paramDimensionA); + + for (int i = 0; i < nVaryingA; ++i) makeZeroMatrix(Ui[i]); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k] - _nNonvaryingA; + if (i < 0) continue; + multiply_At_A(Ak[k], U); + addMatricesIP(U, Ui[i]); + } // end for (k) + } // end if + + if (nVaryingB > 0) + { + // Compute Vj + Matrix V(_paramDimensionB, _paramDimensionB); + + for (int j = 0; j < nVaryingB; ++j) makeZeroMatrix(Vj[j]); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const j = _correspondingParamB[k] - _nNonvaryingB; + if (j < 0) continue; + multiply_At_A(Bk[k], V); + addMatricesIP(V, Vj[j]); + } // end for (k) + } // end if + + if (nVaryingC > 0) + { + Matrix ZZ(_paramDimensionC, _paramDimensionC); + Matrix Zsum(_paramDimensionC, _paramDimensionC); + + makeZeroMatrix(Zsum); + + for (int k = 0; k < _nMeasurements; ++k) + { + multiply_At_A(Ck[k], ZZ); + addMatricesIP(ZZ, Zsum); + } // end for (k) + + // Ignore the non-varying parameters + for (int i = 0; i < nVaryingC; ++i) + for (int j = 0; j < nVaryingC; ++j) + Z[i][j] = Zsum[i+_nNonvaryingC][j+_nNonvaryingC]; + } // end if + + if (nVaryingA > 0 && nVaryingB > 0) + { + for (int n = 0; n < Wn.count(); ++n) makeZeroMatrix(Wn[n]); + + Matrix W(_paramDimensionA, _paramDimensionB); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const n = _jointIndexW[k]; + if (n >= 0) + { + int const i0 = _jointNonzerosW[n].first; + int const j0 = _jointNonzerosW[n].second; + + multiply_At_B(Ak[k], Bk[k], W); + addMatricesIP(W, Wn[n]); + } // end if + } // end for (k) + } // end if + + if (nVaryingA > 0 && nVaryingC > 0) + { + Matrix XX(_paramDimensionA, _paramDimensionC); + + makeZeroMatrix(X); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k] - _nNonvaryingA; + // Ignore the non-varying parameters + if (i < 0) continue; + + multiply_At_B(Ak[k], Ck[k], XX); + + for (int r = 0; r < _paramDimensionA; ++r) + for (int c = 0; c < nVaryingC; ++c) + X[r+i*_paramDimensionA][c] += XX[r][c+_nNonvaryingC]; + } // end for (k) + } // end if + + if (nVaryingB > 0 && nVaryingC > 0) + { + Matrix YY(_paramDimensionB, _paramDimensionC); + + makeZeroMatrix(Y); + + for (int k = 0; k < _nMeasurements; ++k) + { + int const j = _correspondingParamB[k] - _nNonvaryingB; + // Ignore the non-varying parameters + if (j < 0) continue; + + multiply_At_B(Bk[k], Ck[k], YY); + + for (int r = 0; r < _paramDimensionB; ++r) + for (int c = 0; c < nVaryingC; ++c) + Y[r+j*_paramDimensionB][c] += YY[r][c+_nNonvaryingC]; + } // end for (k) + } // end if + + if (currentIteration == 0) + { + // Initialize lambda as tau*max(JtJ[i][i]) + double maxEl = -1e30; + if (nVaryingA > 0) + { + for (int i = 0; i < nVaryingA; ++i) + for (int l = 0; l < _paramDimensionA; ++l) + maxEl = std::max(maxEl, Ui[i][l][l]); + } + if (nVaryingB > 0) + { + for (int j = 0; j < nVaryingB; ++j) + for (int l = 0; l < _paramDimensionB; ++l) + maxEl = std::max(maxEl, Vj[j][l][l]); + } + if (nVaryingC > 0) + { + for (int l = 0; l < nVaryingC; ++l) + maxEl = std::max(maxEl, Z[l][l]); + } + + lambda = tau * maxEl; + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: initial lambda = " << lambda << endl; + } // end if (currentIteration == 0) + } // end if (computeDerivatives) + + for (int i = 0; i < nVaryingA; ++i) + { + for (int l = 0; l < _paramDimensionA; ++l) diagUi[i][l] = Ui[i][l][l]; + } // end for (i) + + for (int j = 0; j < nVaryingB; ++j) + { + for (int l = 0; l < _paramDimensionB; ++l) diagVj[j][l] = Vj[j][l][l]; + } // end for (j) + + for (int l = 0; l < nVaryingC; ++l) diagZ[l] = Z[l][l]; + + // Augment the diagonals with lambda (either by the standard additive update or by multiplication). +#if !defined(USE_MULTIPLICATIVE_UPDATE) + for (int i = 0; i < nVaryingA; ++i) + for (unsigned l = 0; l < _paramDimensionA; ++l) + Ui[i][l][l] += lambda; + + for (int j = 0; j < nVaryingB; ++j) + for (unsigned l = 0; l < _paramDimensionB; ++l) + Vj[j][l][l] += lambda; + + for (unsigned l = 0; l < nVaryingC; ++l) + Z[l][l] += lambda; +#else + for (int i = 0; i < nVaryingA; ++i) + for (unsigned l = 0; l < _paramDimensionA; ++l) + Ui[i][l][l] = std::max(Ui[i][l][l] * (1.0 + lambda), 1e-15); + + for (int j = 0; j < nVaryingB; ++j) + for (unsigned l = 0; l < _paramDimensionB; ++l) + Vj[j][l][l] = std::max(Vj[j][l][l] * (1.0 + lambda), 1e-15); + + for (unsigned l = 0; l < nVaryingC; ++l) + Z[l][l] = std::max(Z[l][l] * (1.0 + lambda), 1e-15); +#endif + + this->fillSparseJtJ(Ui, Vj, Wn, Z, X, Y); + + bool success = true; + double rho = 0.0; + { + int const nCols = _JtJ_Parent.size(); + int const nnz = _JtJ.getNonzeroCount(); + int const lnz = _JtJ_Lp.back(); + + vector Li(lnz); + vector Lx(lnz); + vector D(nCols), Y(nCols); + vector workPattern(nCols), workFlag(nCols); + + int * colStarts = (int *)_JtJ.getColumnStarts(); + int * rowIdxs = (int *)_JtJ.getRowIndices(); + double * values = _JtJ.getValues(); + + int const d = ldl_numeric(nCols, colStarts, rowIdxs, values, + &_JtJ_Lp[0], &_JtJ_Parent[0], &_JtJ_Lnz[0], + &Li[0], &Lx[0], &D[0], + &Y[0], &workPattern[0], &workFlag[0], + NULL, NULL); + + if (d == nCols) + { + ldl_perm(nCols, &deltaPerm[0], &Jt_e[0], &_perm_JtJ[0]); + ldl_lsolve(nCols, &deltaPerm[0], &_JtJ_Lp[0], &Li[0], &Lx[0]); + ldl_dsolve(nCols, &deltaPerm[0], &D[0]); + ldl_ltsolve(nCols, &deltaPerm[0], &_JtJ_Lp[0], &Li[0], &Lx[0]); + ldl_permt(nCols, &delta[0], &deltaPerm[0], &_perm_JtJ[0]); + } + else + { + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: LDL decomposition failed. Increasing lambda." << endl; + success = false; + } + } + + if (success) + { + double const deltaSqrLength = sqrNorm_L2(delta); + + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: ||delta||^2 = " << deltaSqrLength << endl; + + double const paramLength = this->getParameterLength(); + if (this->applyUpdateStoppingCriteria(paramLength, sqrt(deltaSqrLength))) + { + status = LEVENBERG_OPTIMIZER_SMALL_UPDATE; + goto end; + } + + // Copy the updates from delta to the respective arrays + int pos = 0; + + for (int i = 0; i < _nNonvaryingA; ++i) makeZeroVector(deltaAi[i]); + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + for (int l = 0; l < _paramDimensionA; ++l, ++pos) + deltaAi[i][l] = delta[pos]; + + for (int j = 0; j < _nNonvaryingB; ++j) makeZeroVector(deltaBj[j]); + for (int j = _nNonvaryingB; j < _nParametersB; ++j) + for (int l = 0; l < _paramDimensionB; ++l, ++pos) + deltaBj[j][l] = delta[pos]; + + makeZeroVector(deltaC); + for (int l = _nNonvaryingC; l < _paramDimensionC; ++l, ++pos) + deltaC[l] = delta[pos]; + + saveAllParameters(); + if (nVaryingA > 0) updateParametersA(deltaAi); + if (nVaryingB > 0) updateParametersB(deltaBj); + if (nVaryingC > 0) updateParametersC(deltaC); + + this->evalResidual(residuals2); + for (int k = 0; k < _nMeasurements; ++k) + scaleVectorIP(weights[k], residuals2[k]); + + double const newErr = squaredResidual(residuals2); + rho = err - newErr; + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: |new residual|^2 = " << newErr << endl; + +#if !defined(USE_MULTIPLICATIVE_UPDATE) + double const denom1 = lambda * deltaSqrLength; +#else + double denom1 = 0.0f; + for (int i = _nNonvaryingA; i < _nParametersA; ++i) + for (int l = 0; l < _paramDimensionA; ++l) + denom1 += deltaAi[i][l] * deltaAi[i][l] * diagUi[i-_nNonvaryingA][l]; + + for (int j = _nNonvaryingB; j < _nParametersB; ++j) + for (int l = 0; l < _paramDimensionB; ++l) + denom1 += deltaBj[j][l] * deltaBj[j][l] * diagVj[j-_nNonvaryingB][l]; + + for (int l = _nNonvaryingC; l < _paramDimensionC; ++l) + denom1 += deltaC[l] * deltaC[l] * diagZ[l-_nNonvaryingC]; + + denom1 *= lambda; +#endif + double const denom2 = innerProduct(delta, Jt_e); + rho = rho / (denom1 + denom2); + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: rho = " << rho + << " denom1 = " << denom1 << " denom2 = " << denom2 << endl; + } // end if (success) + + if (success && rho > 0) + { + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: Improved solution - decreasing lambda." << endl; + // Improvement in the new solution + decreaseLambda(rho); + computeDerivatives = true; + } + else + { + if (optimizerVerbosenessLevel >= 2) + cout << "SparseLevenbergOptimizer: Inferior solution - increasing lambda." << endl; + restoreAllParameters(); + increaseLambda(); + computeDerivatives = false; + + // Restore diagonal elements in Ui, Vj and Z. + for (int i = 0; i < nVaryingA; ++i) + { + for (int l = 0; l < _paramDimensionA; ++l) Ui[i][l][l] = diagUi[i][l]; + } // end for (i) + + for (int j = 0; j < nVaryingB; ++j) + { + for (int l = 0; l < _paramDimensionB; ++l) Vj[j][l][l] = diagVj[j][l]; + } // end for (j) + + for (int l = 0; l < nVaryingC; ++l) Z[l][l] = diagZ[l]; + } // end if + } // end for + + end:; + if (optimizerVerbosenessLevel >= 2) + cout << "Leaving SparseLevenbergOptimizer::minimize()." << endl; + } // end SparseLevenbergOptimizer::minimize() + +#endif // defined(V3DLIB_ENABLE_SUITESPARSE) + +} // end namespace V3D diff --git a/extern/libmv/third_party/ssba/Math/v3d_optimization.h b/extern/libmv/third_party/ssba/Math/v3d_optimization.h new file mode 100644 index 00000000000..27d2e12287f --- /dev/null +++ b/extern/libmv/third_party/ssba/Math/v3d_optimization.h @@ -0,0 +1,273 @@ +// -*- C++ -*- +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ + +#ifndef V3D_OPTIMIZATION_H +#define V3D_OPTIMIZATION_H + +#include "Math/v3d_linear.h" +#include "Math/v3d_mathutilities.h" + +#include +#include + +namespace V3D +{ + + enum + { + LEVENBERG_OPTIMIZER_TIMEOUT = 0, + LEVENBERG_OPTIMIZER_SMALL_UPDATE = 1, + LEVENBERG_OPTIMIZER_CONVERGED = 2 + }; + + extern int optimizerVerbosenessLevel; + + struct LevenbergOptimizerCommon + { + LevenbergOptimizerCommon() + : status(LEVENBERG_OPTIMIZER_TIMEOUT), currentIteration(0), maxIterations(50), + tau(1e-3), lambda(1e-3), + gradientThreshold(1e-10), updateThreshold(1e-10), + _nu(2.0) + { } + virtual ~LevenbergOptimizerCommon() {} + + // See Madsen et al., "Methods for non-linear least squares problems." + virtual void increaseLambda() + { + lambda *= _nu; _nu *= 2.0; + } + + virtual void decreaseLambda(double const rho) + { + double const r = 2*rho - 1.0; + lambda *= std::max(1.0/3.0, 1 - r*r*r); + if (lambda < 1e-10) lambda = 1e-10; + _nu = 2; + } + + bool applyGradientStoppingCriteria(double maxGradient) const + { + return maxGradient < gradientThreshold; + } + + bool applyUpdateStoppingCriteria(double paramLength, double updateLength) const + { + return updateLength < updateThreshold * (paramLength + updateThreshold); + } + + int status; + int currentIteration, maxIterations; + double tau, lambda; + double gradientThreshold, updateThreshold; + + protected: + double _nu; + }; // end struct LevenbergOptimizerCommon + +# if defined(V3DLIB_ENABLE_SUITESPARSE) + + struct SparseLevenbergOptimizer : public LevenbergOptimizerCommon + { + SparseLevenbergOptimizer(int measurementDimension, + int nParametersA, int paramDimensionA, + int nParametersB, int paramDimensionB, + int paramDimensionC, + std::vector const& correspondingParamA, + std::vector const& correspondingParamB) + : LevenbergOptimizerCommon(), + _nMeasurements(correspondingParamA.size()), + _measurementDimension(measurementDimension), + _nParametersA(nParametersA), _paramDimensionA(paramDimensionA), + _nParametersB(nParametersB), _paramDimensionB(paramDimensionB), + _paramDimensionC(paramDimensionC), + _nNonvaryingA(0), _nNonvaryingB(0), _nNonvaryingC(0), + _correspondingParamA(correspondingParamA), + _correspondingParamB(correspondingParamB) + { + assert(correspondingParamA.size() == correspondingParamB.size()); + } + + ~SparseLevenbergOptimizer() { } + + void setNonvaryingCounts(int nNonvaryingA, int nNonvaryingB, int nNonvaryingC) + { + _nNonvaryingA = nNonvaryingA; + _nNonvaryingB = nNonvaryingB; + _nNonvaryingC = nNonvaryingC; + } + + void getNonvaryingCounts(int& nNonvaryingA, int& nNonvaryingB, int& nNonvaryingC) const + { + nNonvaryingA = _nNonvaryingA; + nNonvaryingB = _nNonvaryingB; + nNonvaryingC = _nNonvaryingC; + } + + void minimize(); + + virtual void evalResidual(VectorArray& residuals) = 0; + + virtual void fillWeights(VectorArray const& residuals, Vector& w) + { + (void)residuals; + std::fill(w.begin(), w.end(), 1.0); + } + + void fillAllJacobians(Vector const& w, + MatrixArray& Ak, + MatrixArray& Bk, + MatrixArray& Ck) + { + int const nVaryingA = _nParametersA - _nNonvaryingA; + int const nVaryingB = _nParametersB - _nNonvaryingB; + int const nVaryingC = _paramDimensionC - _nNonvaryingC; + + for (unsigned k = 0; k < _nMeasurements; ++k) + { + int const i = _correspondingParamA[k]; + int const j = _correspondingParamB[k]; + + if (i < _nNonvaryingA && j < _nNonvaryingB) continue; + + fillJacobians(Ak[k], Bk[k], Ck[k], i, j, k); + } // end for (k) + + if (nVaryingA > 0) + { + for (unsigned k = 0; k < _nMeasurements; ++k) + scaleMatrixIP(w[k], Ak[k]); + } + if (nVaryingB > 0) + { + for (unsigned k = 0; k < _nMeasurements; ++k) + scaleMatrixIP(w[k], Bk[k]); + } + if (nVaryingC > 0) + { + for (unsigned k = 0; k < _nMeasurements; ++k) + scaleMatrixIP(w[k], Ck[k]); + } + } // end fillAllJacobians() + + virtual void setupJacobianGathering() { } + + virtual void fillJacobians(Matrix& Ak, Matrix& Bk, Matrix& Ck, + int i, int j, int k) = 0; + + virtual double getParameterLength() const = 0; + + virtual void updateParametersA(VectorArray const& deltaAi) = 0; + virtual void updateParametersB(VectorArray const& deltaBj) = 0; + virtual void updateParametersC(Vector const& deltaC) = 0; + virtual void saveAllParameters() = 0; + virtual void restoreAllParameters() = 0; + + int currentIteration, maxIterations; + + protected: + void serializeNonZerosJtJ(std::vector >& dst) const; + void setupSparseJtJ(); + void fillSparseJtJ(MatrixArray const& Ui, MatrixArray const& Vj, MatrixArray const& Wk, + Matrix const& Z, Matrix const& X, Matrix const& Y); + + int const _nMeasurements, _measurementDimension; + int const _nParametersA, _paramDimensionA; + int const _nParametersB, _paramDimensionB; + int const _paramDimensionC; + + int _nNonvaryingA, _nNonvaryingB, _nNonvaryingC; + + std::vector const& _correspondingParamA; + std::vector const& _correspondingParamB; + + std::vector > _jointNonzerosW; + std::vector _jointIndexW; + + std::vector _JtJ_Lp, _JtJ_Parent, _JtJ_Lnz; + std::vector _perm_JtJ, _invPerm_JtJ; + + CCS_Matrix _JtJ; + }; // end struct SparseLevenbergOptimizer + + struct StdSparseLevenbergOptimizer : public SparseLevenbergOptimizer + { + StdSparseLevenbergOptimizer(int measurementDimension, + int nParametersA, int paramDimensionA, + int nParametersB, int paramDimensionB, + int paramDimensionC, + std::vector const& correspondingParamA, + std::vector const& correspondingParamB) + : SparseLevenbergOptimizer(measurementDimension, nParametersA, paramDimensionA, + nParametersB, paramDimensionB, paramDimensionC, + correspondingParamA, correspondingParamB), + curParametersA(nParametersA, paramDimensionA), savedParametersA(nParametersA, paramDimensionA), + curParametersB(nParametersB, paramDimensionB), savedParametersB(nParametersB, paramDimensionB), + curParametersC(paramDimensionC), savedParametersC(paramDimensionC) + { } + + virtual double getParameterLength() const + { + double res = 0.0; + for (int i = 0; i < _nParametersA; ++i) res += sqrNorm_L2(curParametersA[i]); + for (int j = 0; j < _nParametersB; ++j) res += sqrNorm_L2(curParametersB[j]); + res += sqrNorm_L2(curParametersC); + return sqrt(res); + } + + virtual void updateParametersA(VectorArray const& deltaAi) + { + for (int i = 0; i < _nParametersA; ++i) addVectors(deltaAi[i], curParametersA[i], curParametersA[i]); + } + + virtual void updateParametersB(VectorArray const& deltaBj) + { + for (int j = 0; j < _nParametersB; ++j) addVectors(deltaBj[j], curParametersB[j], curParametersB[j]); + } + + virtual void updateParametersC(Vector const& deltaC) + { + addVectors(deltaC, curParametersC, curParametersC); + } + + virtual void saveAllParameters() + { + for (int i = 0; i < _nParametersA; ++i) savedParametersA[i] = curParametersA[i]; + for (int j = 0; j < _nParametersB; ++j) savedParametersB[j] = curParametersB[j]; + savedParametersC = curParametersC; + } + + virtual void restoreAllParameters() + { + for (int i = 0; i < _nParametersA; ++i) curParametersA[i] = savedParametersA[i]; + for (int j = 0; j < _nParametersB; ++j) curParametersB[j] = savedParametersB[j]; + curParametersC = savedParametersC; + } + + VectorArray curParametersA, savedParametersA; + VectorArray curParametersB, savedParametersB; + Vector curParametersC, savedParametersC; + }; // end struct StdSparseLevenbergOptimizer + +# endif + +} // end namespace V3D + +#endif diff --git a/extern/libmv/third_party/ssba/README.TXT b/extern/libmv/third_party/ssba/README.TXT new file mode 100644 index 00000000000..734962b1df8 --- /dev/null +++ b/extern/libmv/third_party/ssba/README.TXT @@ -0,0 +1,92 @@ +Description + +This is an implementation of a sparse Levenberg-Marquardt optimization +procedure and several bundle adjustment modules based on it. There are three +versions of bundle adjustment: +1) Pure metric adjustment. Camera poses have 6 dof and 3D points have 3 dof. +2) Common, but adjustable intrinsic and distortion parameters. This is useful, + if the set of images are taken with the same camera under constant zoom + settings. +3) Variable intrinsics and distortion parameters for each view. This addresses + the "community photo collection" setting, where each image is captured with + a different camera and/or with varying zoom setting. + +There are two demo applications in the Apps directory, bundle_common and +bundle_varying, which correspond to item 2) and 3) above. + +The input data file for both applications is a text file with the following +numerical values: + +First, the number of 3D points, views and 2D measurements: + +Then, the values of the intrinsic matrix + [ fx skew cx ] +K = [ 0 fy cy ] + [ 0 0 1 ], +and the distortion parameters according to the convention of the Bouget +toolbox: + + + +For the bundle_varying application this is given times, one for each +camera/view. +Then the 3D point positions are given: + + + +Note: the point-ids need not to be exactly from 0 to M-1, any (unique) ids +will do. +The camera poses are given subsequently: + + <12 entries of the RT matrix> + +There is a lot of confusion how to specify the orientation of cameras. We use +projection matrix notation, i.e. P = K [R|T], and a 3D point X in world +coordinates is transformed into the camera coordinate system by XX=R*X+T. + +Finally, the 2d image measurements (given in pixels) are provided: + + 1 + +See the example in the Dataset folder. + + +Performance + +This software is able to perform successful loop closing for a video sequence +containing 1745 views, 37920 3D points and 627228 image measurements in about +16min on a 2.2 GHz Core 2. The footprint in memory was <700MB. + + +Requirements + +Solving the augmented normal equation in the LM optimizer is done with LDL, a +Cholsky like decomposition method for sparse matrices (see +http://www.cise.ufl.edu/research/sparse/ldl). The appropriate column +reordering is done with COLAMD (see +http://www.cise.ufl.edu/research/sparse/colamd). Both packages are licensed +under the GNU LGPL. + +This software was developed under Linux, but should compile equally well on +other operating systems. + +-Christopher Zach (cmzach@cs.unc.edu) + +/* +Copyright (c) 2008 University of North Carolina at Chapel Hill + +This file is part of SSBA (Simple Sparse Bundle Adjustment). + +SSBA is free software: you can redistribute it and/or modify it under the +terms of the GNU Lesser General Public License as published by the Free +Software Foundation, either version 3 of the License, or (at your option) any +later version. + +SSBA is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with SSBA. If not, see . +*/ diff --git a/extern/libmv/third_party/ssba/README.libmv b/extern/libmv/third_party/ssba/README.libmv new file mode 100755 index 00000000000..45e0a31f6fc --- /dev/null +++ b/extern/libmv/third_party/ssba/README.libmv @@ -0,0 +1,23 @@ +Project: SSBA +URL: http://www.cs.unc.edu/~cmzach/opensource.html +License: LGPL3 +Upstream version: 1.0 + +Local modifications: + + * Added + SET(CMAKE_CXX_FLAGS "") + to CMakeLists.txt to prevent warnings from being treated as errors. + * Fixed "unused variable" in the header files. Warnings in the cpps files + are still there. + * Fixed a bug in CameraMatrix::opticalAxis() in file + Geometry/v3d_cameramatrix.h + * Deleted the Dataset directory. + * Added '#include ' to ssba/Apps/bundle_common.cpp and + ssba/Apps/bundle_varying.cpp to stop undefined references to strcmp + * Removed unnecessary elements from the CMakeLists.txt file, including the + obsoleted local_config.cmake and friends. + * Added a virtual destructor to V3D::LevenbergOptimizerCommon in + Math/v3d_optimization.h + * Added /EHsc WIN32-specific flag to CMakeLists.txt + * Remove unused variable Vector3d np in bundle_common.cpp and bundle_varying (in main() function). diff --git a/release/datafiles/blender_icons.png b/release/datafiles/blender_icons.png index a68a1f8394c4ffbed66b5fbbaeb36321a9a7f084..c309ad11da2eed0a4134f9a429e0d391b203eea0 100644 GIT binary patch delta 160000 zcmYKF1y~i|_dSkZKvGIly1S&MySp0^>28p^AV>&^fOLz1bazWjw{&-R!|(Wdf4=|! zJomXU%#5Bnv-jC+t-U5V8m&4Bt-KTk2?>h@nSU`kw5k@xa|+6<_4xjwWmdp?j*H}b z0&H%aR@Q+Uy?K1p56ZVN@RIP|F!X<7X(Y7a;a}lk>X{eN_vOLM2Ua#(jxXlPaUS13 ziVc)ae*M`UxHNLUK-b^U;5clw-FlnhzI_lMkZvP1{|vWOf(==;DQc!O!fv{TjC= z!NgoSTo0mRXE&L+C}~AUf8%{G#(g1Sg!0R)h0m-cwFvGz6a|^JXE|t0oYl`DxXoR# zQY5C|%4}-&OevM;v;AzP`O3Uw8%sKuHCC`V#f7&}b91vv)vVLOU-qt^o;|CSCuArw z4>|0Vw>7cKr=7s%@lX=4y@K8!$dGZL>gKG^*1dB=mOTf8{-3?iXIqPvVTNEJ4h|0A z1~$=cg%O_IphJ68jSUSAb*`?iHD#@LHYQq~o`IsOY6Sg^h4w@OXVwTOcL^*8=n3Dy z6GOMtJBX8Ft*ruy= zi>)W}p(?%K88o`m1w8!)=;*fR=eVjWE4MuMCaqhwi;V0N^;&&AUGkOFw`^+W%rDca z!X+syX6}}v-3W@dgt$0t z4%e+g0)<3YlDO2=dn1VyYisL>&d$#5#RgYPDA8Ui?2~E7C-^NA0gvW{*x1USFhiYS zjzUS^wz>N~XVaz*`Frk;=N5yA2*j-XZBaE9KXUVUf9-fYTebaD$ma@4LR>uWbySZL zno*{Ai~n+lkWWunZ?BJ13YXl@@i9i#Y-Cy*vE5vC0VM?mMOA&hS0rA z(IaEu@C+7nJSpPEftE$580g{GFiSRow-&#%U zvt~ocIqM*_3N0g1bm==bAxw?zu!4|R>IH6N54Yz!hRt5iQkt5RD1oBozs^j~_xN5x zlP&O7-iFrwP?o99+bL*?uf=baR|K>5Zn?{sXVc=AlN&>q8SfL~ln0`!XZ#BEerkF< zFF!x-&-K?04Q~Gjug2oyNWsU8i5F-ps~Tl_qU1=&6Zz3naXPXNbe1tMoq79DAQq>;kaClySp50=$##w3Q@m(TmKtfi6?c)_DSQYQSEtz2we+LH(Y1&~l?XTkZBiuMspjlXgD2JRMLQINcs?tgt1eWc z$+)b^81Gm(wU>YE>z|r;(4>$Wwz`x}b;W!9hIy#zgJz0je$2hmoFuAaVV+8U3}Ul@ zbgqvlamHNbK;L6wKo|vdn=j=rY6hIaZ+Ybrs*MXltT8M%Pr4VOFqLAjUNMCa)w&G+ zQe%3A;KP>NvesCKz@9-v=f4s+RN`h4B8A;w9kqP=YsW+ zJ);Fv(tAs}@wnO=oR%SjC%CD?-|*fPF2!ByOU6!ELXIrs%Nd&Zve;gySHd1c4x}g1 zR!TJJXe&5tVu@z`ZROt^V z_KpX``G%~^XOkK#v-O5YjlC7e!^6W0jUIq0NMA(26nd1E;6ph!eT7hx~;} z|M-yI0Jv8ra9(dB8sAZ!Gk6c)FDd7$lU$yk57>_Vkg8QLSb%RY3QwUpIyzdeZ)jM& zJUI!|DbUPZ@A!2dHND}|V6?cf;D3I3$#QjiI`&Jm@Yp8YY&K^%aPB3p@h1OPcBd6b zO5_$50+hBAHv!!adA~iOTu z?yHhQm!*nTlD+mjI09nh#AM(^ zA!j}f{<}BYoc{lA5vpAErEyES#c16%$NThA$7FBzzej1t_1_QZL*2xVbM@>0x9#N* z|04SE|JzRqK_pdF!wq^?(ZWUJ5`-V2Vm500zPY_kw|RbR9~T>|Th{jE9VdWQeB(

jyZ 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 z%0D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¨@!6jY!JFZU=YW#f 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℞e%Y>oP^y4FDe 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 delta 158791 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

&o{_nXnc=iMThORjkPNkD(SBIXaQ^YPwBG4#ocJ zoIh(hEG3SuR&_sTk$%UZv>oyzC!nv=`UBe?y+7HJA5Jg}V=&ev4LdKQd@3m|r7F>H zypaRF{snMg4gv`GVOL+DSb*fS*a5Xg-Pq{p5uY9tBG_KaN6D&@d|&cvqV4WO*_8gi z;f*Igw+H!ChDGlTImoI3$Z-bAB7ac|tE&2{U_9N0XhDj}pEj>epvLhMATXg|+bKK4 z=xNua3FFHI)G;o!8w|mL{F8XeRH`qM+p`x=ltgHq&;yY54$Q|BhCmkH1#2Avaqrp* z)9rQ`xfy9`WBok1kg=A9xMcW{nAFH08gSgT4i= z(<R3L3y^@aTX!gcdG{7ierM(Z6{GEiMlZuf?M zkO?;#yK&_Q<)4PiHoq`UXAR2`@&keX;AZ~2 zLPGU_!(F|#s2%f(RHBw?QptB~$MW&;zM0d!5$&w6cUe#jF3Aj2A}N~kXXKiuoT}ip z^A-Qz9LDls=cP_EMxx(=S)19c+FhHOrw+AFXKN3nR}%<+i{A|7uh^E={{Ez%9qn1B zV&cS(Q;pKshvqyKiZbnaBg4qslr2}^hb_n~AK$^j;2fQ(4%dLN9cph{ytEAU9&HZP z*-p*eWgMEmfp5dwsEEd;&Ux}r(sCY`THQumSrDNL_3}4BUOflc_91AfgqWNe8ll@K z43gve02<~f*-AhJXDJT2@>u`2>^;~Rt=Y9RT6fpEa>`o4=0!Tx2#;4E(UiyXoBa9& zD?Q)u7CY+}kX2;|>FS4D{ohe1pg#l)`v6#g!Q&o=!B!~=!U#@LrO}@{;A08uKg>43 z_0bE94@rnR<~w_Lh9Q%P7paF|peIJE6=Ck=?5sArVci4DDH^Tn53J8p2WDXfUtza` zcRxxN$!r(UMUOe(3Ld#ccX#(5;AOyG+>%YVf&=i$8OtzqCjsW%zV!a{J*`xTT;PQV z%D}yKEB>bb6X)pM^RRuDN6J4FO!t&!81fww25~idHg4aK&a-ydh+mTP4gR$pVzDS^ z&AP7sbF1!ck#sE%XOLjR+(X5$1OSdlV%65vh%2iG-n@L{Ujj<8;f}TgNF34QaoX1B zfkc8|kJj1i&%I$D(wc(4*EDF+R}!I&jOyvhq-_|aJj|s>e&-I~Ds0LbfWy3sr!NRP znDKEBsSz^k@O}y**r`1NBQu(darIeEK@>xm**U|_HPhl zrATuk*a)ElMLVG7O~lYiUy+$Y?of&vIdsKKTDXxne3XwzH0u>vbI+XVZ8?u!N^V(g zpT`GyRGSZjQAzkgMb#PKn2#f?VkyvA)zJUpfF*jTN&_F{)Z zd_0^<+U@)mEb1)(drxk7&o+*C;21u0K$^l}H?`1Dc9w8lEeP&0;qymK`^ z&B$QPXnQpszpz9{(Xyzh+15fc=I1;1&WGp5G2DDfW|61AUUF)Yy?V~@lAa%W?&u)t zS5mxg$^V_8GuC_g(JyyV4BA?TQ1Y#UWZ!z=;k~_v2vI!YBK(oqw%|a4EHTC&E>*gl zk?w=)!$lS_G^V+cC-kAT?_^uz+Ye=iXBjGwKzY=#vWG<)Je-1)Z6Dt%jp3vDlmN|1 z*rOZ3F|SFebKIeUZ2(%dC{A28C2(sLOwo4sb*QZo->S{4 zjHUf$(tTdzeItc*83}*5avBLdHXCh`RRUF^Ix8-AL&%hwc$+h ze1hE1sa{O9^;LN^i@vkE?3A{0BKTPO`q93%#QMBlCqN@CGgMt(|6kv2QRF@I$M0^}TPj4YcS& zA$+anP$~awx7^*>h77yA16NJcAD1t(CGHWrUkA)W_DQlN%{+-b~#-SEdlh)33vDS)a1FGoH__sWQe+} zb9#L2ChF$yKJZNfRky~eXix)_RRf|o*rb#}T>?iOnXgGp5CBWLhlt~_+uG0)j!^o_ zPsb*5+PtvyBAX_5yHBT-$*q~mOFd@@7{rde)Rf6pNE_*ne!2#yOjvFs^uL)cGC#+3 z!nv15GOJ*zuBDpHGGK&l;Wf&I!lUpchg&=%#?K)pDnM5GNzP}99Okcn#)gK?RUQ}X zUv-c_t(63vwrROrn&z!g`g2(nnRBX4h+|wWlxDe5dOk_Xf4OmxsMFN?8{J&%mavN} z`oHO$siCRNCViW&uWJv-p5v{lGxPC@*4NmR)=ORdKeoO*9?SUs_pxQ9kWGqE*^#|T z$SQlU?3rY{ZP}4cSs@|WA$w)7Y*|?u*^zlJ-|zXI^T#>8UP`Z?*Yo7Q@6YFRUGM8X zoY=6Rn>30yVzO$;puM^l;g{ndN>(qzJX6qu2Hx> z<%a0PBw#wU-N-2;rJ9_Wyb^tJeZM9++1Geo?`>0Mxmk=JS_rzDi{4r&iidS&vR~ke zpSa^6peU3=aeyOOC@$wRe<*cfr;``NA)zR6hsmoU;YM2}gNqYuF^K=(;Lu~QU z_4+Rx@i*G$_KZ0gy6borfVBa2F!Y*iK7j59;7M!zrf&=YcXu1G$KwJX^`+wvtQHUi zVnPZ#47;UR$xOjS`lEUQ86F-UcoP}*nwQy$?pYc(yB{9^9C5$7#i|I$o#AR&84#|YdQ`$VTXu8fbpyh_?akKjC&~IirtZpKaoQ$=F<1aikC=ZoT zMqr;FA?AHtt{wV2sFO9+T}u$x3kz-bey_4WJwyjzCj7!`h(#>`^z62~cqJ@bHLgWq z0p>#NU_Jeo#4_cPh6dT=*gzGQKm?MSmGU4d23V_Pe3k=7pA3o-9WrJaRcEjenf?ov zf{W|MI9icLEokTnF|Y|xGODXT@}JqHg>( zK=?Hv*W=&Z%iN8OGTc>E-fRNVlL$!u$C}M@sBxe-a^^ragZO7rcQ_no9mKL68=FB^>vb6}SaX~#gepo+JxdZesE2k@?5 z&GkH3lOaU}1#XGm@4naGmpLd0m9UIc1I1R-lL87)&*!43)yGtsTQ7EwrKoO;evoK= z(07zI7!&kB!-~rKUxR^;i##PyP4jO$L?@EiJ=q~t;;d#n?@2PItSs}??$Jx(^Nrum z9$KSc%ovUadCSi~-#ik2Si1KEh4wAF?uv@}>j*i?f?&xb*8}2oF%prRjohX~3c11< z9d$zE*dqJdgBdSK&|)yu0x2ejq`!GOj(&7~6qc1cF+RS?u3h@U8=g@Y;1d%nBTt^B zolH!1Ie_g#J5-j8K+vg9jgPM=55uArA0F4>Ax(6dZw^`pZ9{6E-PFSq$_M6-7684F zH5T6>BwyZhdp9=Sp#1jk-4q5P*B7oq!R&*oYKqiCLJKDvMWmA04EKdZ-jx^WCQ>4M zxx8%GK0vMluOWM4BDG*hrx|jun~I$kA98yqOP3wh2W~At<0&dDd=~O&GGFnGXt1Qj zOF<#m)0?lKZ)+ia5IZ1+{ zCjK>8>Fr6dHac>Dwb@V#vWi0SI`*je?w6PqeX=_%F3DJ&CLTm8GLwb)O}J`$2#->5 z&PHH*RSZXcLkEnpDZxNp$IHu07v*rj<}oYTSa(;KKk&POSOI7&Hq>lT`wJuIX^`m1 z1l(MF3k!?OD6PCG(cal-AWbC`6k(vpyr zQ3g4W)%!wXnpjFMGZjIwKgdP2A?IlN3AlN{EdtmtIU64-5-mvPxo^MBD|#l=JijnL}BF)>&4y{igi#T=F9eh-?u3Y(A( zi87A~!O@rgIRZqgst(}8T3!9NJM8L*^5e$Uz;6vA<7X>6iw$a)-q-iusJ}A4$_;23 zYiMA>uNOgFZ5r&Ci(P_%d;H-B{?j}TYnIil-p83ad~;GS8R@2v@E^)wDP2fGPkS`* zX*XkZElfHTZJtBwO?o1RL%IPfU zyCarsw7yT0@&3v4&iLT^KkKa_@V_zDsg;@I?s+xEmAuKx4*#>oO-_C9nEm6c&BgXI zU8x}%cQI&0bf`|=Ymz z*YZq5u3{<!eK62X!sPw&O&o{{kC7LSQVg-1K@ zT8;eptFAUpeGxT_z|VPwUabPc1Nej+cts0UJ*DXS)(w|K!_WfDC^ACd+qnLJx3@3D=aQZ_i+>2@un%p7lHMy^TCn4$!kQ9={ z+;`>5M!-&Px$;rAgsm+rwCe+Ojdk}DTx_+pwD>^5+R~fKS1dcsL&a+y2;`yLEG)P% z(}bTa+aAbQ*BX~U{hgQjw~h!HHTs6YRVnN0>kF38@dwQzocV)*ngPXP4!UMW#o-(A zA`ox1K}0~XA>woD1}t)XXy3)tMZGy89uLm+Ne3AHs10(?@4`n(vM2rmpC8pnqI;0Q z1sUD!nCKF}Eh13Y${`2I7>e{qFsexGXlt{Rp+pL#?}nwY#yl?6Vol(ci+!x5)DDAt zPP@tSH25WlB1U7S1V#B8Jg^Bra^QDtK=E>>8m1^1*zNy^Opx+x-gx3o_hN7C4bGzH z+}d(e0O@27T8fsKIq}=BlPTKhYuv^6@i`H#nnwLLIAEp1mmw>gs$AzsvTUkuCVw!9 zULWI_?-z5;4k*T18+8bzd|;t%S#H+Yn>t3OE$Z%AL@(y*B$IaW>#H8)XZA#ams$z_ ztS{#2?;l&4K7W2t+hnwA1ZUAbK5Pd=VVS51!pJUE7(1!%qbuZ*WQWCut(8T(Z{EEl zoV__I)%QYzEm23MAWnve5Xl%`Gq%|Z(=2X2_=hJ`O-LM4y!Yw(7Fy(I!XrKQUA*!) zH$n@uEwH7s)%<>}iCZ6hDdI)VPPk$||N7&L{DdrJMtB2}{;4CR6 zAHcD{-~mX4LJ5pgg(+b9C*vB)4{rCi!oZUOHm9J z>Td*%_V$xZ&R1FPn_0J{P#^W1M6==Qzk2eXGk34 z_k~tL!UgMqCBoAlroll?P5mJ!2eO`tplE~^Fe47n@_F^Z@{+GgLE{68j6QkU%^DY9 zr08+sOO{Wpnd+yVe0(^vjMxFa4+Z%JeU|~G5q1IAMjyZ`y6|+ZyP`rN@p`!QdH4G> z7;k=q1IYdI!6)?<>tawX7|8=mG2!Wv5oAOZJYpaw6%3C(5C4eIPg9}9U%o7tFVe68 zf!H!L6VsYe>%FEMLLZ{{hW{K^xjK3@lmB>?y;OYMOSxKZwN4p&tYd52G{o*QdLPd~ zx$I@aRt*`AMUV7R>_`wW=^?qssO&O@8vKz#F478u+56Ojr_yFH8>!Pq;9=hTAorHv zOY|lJ|zSpW};zW&%v8RHs@1MQubpNG%cLQ&#PrwE6>av92!!yK8nJIKMw{9GndP~ z=lgdSgHvAwY}#n}9mOGQ@!Sg*d9M*C`^xe%`)Bblo3n5old|T;(?mQIW=fyqmjI^# zq7&gvNAvUZD}%}4Te$8|D0nQd0UsDENV24&G%+5pl^kvE1ROAHK>kb(;E4?M1X$qg z<%x>mC^&`Y1L6lk+kZ*NTIxm;yX8X*wV&la(H5~8Wi8aNO#t(S?-ZOyzL$w&$$*!p z=cwJgu#@aA^NBoQOR3UbTvfX%8%-+H25&!E^3JI9G{bB?r*Id7Bv08iF5wUWM#JrS@iI4&2RSJGl;Py z0AD{w>G^Mkc!%oO!y@*}xqxjYhJX$`d_Q8Jf-X@ZtnD;~LH5b>rRC+TIP`o8Pnh1` zVrRdK?uVjzNF67CB|!43ixN|kAlp}L3~O9>$C4^pHeKp$ezEC#Rqma-eaHFS1cSM- z);T04l#BPsesGEfN9%6^SNTJ@s|W-;MZ8T;2B+LFjwp9j4@w0(*{a(N44yZNY6@&C z#uI?s;IeaYaOdarv^4Mo*}0P=V&!wvlL7&4Yr4g?;mX5?gsb{mZ5R4i%tZ%|Q%wYEyPwzYZR z{>Y@1_8Rc-Y*vVEvfK>2aUbA~_q})TgmHQwzg%2eGKLj-Y0eNYbl$I$2cVt^EiEm; zhL<^dN5{v1>s`0rQ~MrSkDlb8pPv^%Ox%?^gJ_uE%mWUWH-j`F4Mnhe9+0!^Svo+v zDs0c;5bt70Cl^V@J9@U$akB+(cPEqpaP7RQuUxqTLOyyqVyK2&K}(k-Q$Q_774x|S zVwx!*I4?heyjC=r-}8fRXdWE$ht1(Hjex?iFBI>O6h#enHmN z%9pAtoahb=#o^2S|2x`E!WinKY%6ygP;6& zY_hyD@%7~f#k4LVR_2WWQmU#oiK3@j5@lOlmfP1DkvmMy4P&T}BVDn45hmdY8U+E7 z@9;05qSmiY4kcx_*?|%r-n4tFKObry;AQp)WDG+~GswNlVlytF9B6=`{Y$RG58)~l zqQ7(Z3IWrKqKosJr)ECt*{O+%iR9$uu1q{UFQuVBgIgYX1vLOO4A>uTv$OvJHwA+k zq>9B3W^tm>cio(X#Cr&52*~}7^GIae_95)W@H60|CaSC5F3v?Dl{I5*J@ZZXT@E55 z0Yz1FbvfnVH-cGAM~rvst*5OQ%9x{L@fKg`-d89+OYFGtC+KOM3{wA53 zbS5xAKT9>z^F6bD@P#ob?I$Azk6jife|gI*e;SFFIS;k>MIp$`VPkUM}Q^N}=eeA0M@9Z+HgK*(OM za(WaG?x*AIp+*mAKqj*k}{`MrTh+6e_Mc1Vj~bTkpz z>}IIlgU~}xXh6z=!uPjbR2G5U(!V{)51asyhk~C5ol}&9!(jkCJCyb}r^vySWTij7 z1BP>LKVQm6mb`4k(W^^EpKLRJ3 zYN)o`p#i)`Mivaa*vpOam|IG>4ex%49UvL!}#)3_OYfE!>UWEodG7=i=M(*Dz@X47gV!+f1^p$~0iOA!9p@ z$U;O3PUS21+@>b$EVI=w`zsb*4cW!T9M1qLDAKr0yoEjQOL?iZt+ntZzRTn6-Rn2b z+r>F2jN{LYl^b$>4WB)s7Ap7G)S$ZUoZ6g89ee6aEA)Lgkj!dew#H}gRd-4D@fU~b z8JxNVe|ZPAARYXmD8gVFSNe6jBvyn@hc7>RZ{_ov<>)1D-^)-YMr6rFQ*j zybqg8hYe>M$R$>zp(VNg3RD>esvY@49{V3lzf+p4?}YNX!QN;Nx6$$vB8#MafbB3_ z-v)XgleMv8MD`vVBJ=QVcW;7)nO4}(X)O(N^L))>J*Um-9Q>HLI3y58$bd}*289gU zGCc_5U01x|PC zYIJ*5C{-lW5um$b0KO!X?+Fr^8PJuxb33wNSo7GR=PF@X9yso1W%k`zm>IULdz793 zBj31Wz{HD*;4Ac>ZsyB#p>65-!CfuR!im$JGltb0;~h*HV_T2 zladBr20o%Y4!oXX#zL1c^rzo|zHMl9RO2PAHDXs1AX*23tR6>3>DK1P#yE2RFYh@F z=C%?ArUzGRv0NVC7pu>xOs!Tl{o%BQi&{m7Y*^QR6bGFaj@etQONw1pFh4L4SuD!P zJEV|l|9Qyb>5e4Rg2;=-m4B2XM*X8UMP=Kb7m6MlbMSS5x?p>MUs_4&Dm070&4B1V zd=Qh_{;atH9;;rMMhVw1ZaKQT-uwx&%*!R)pDvaN8o{5PK>7#Y2Gh&@TZElz?E%^C zOWP;d;AG9r7@3scrvVSb>l}dYUoiOS+de!DQM=a$CNBi=zS9Io>UaJfu?q-HXu~7Q z%!~sgt9-QuV9(&<;mLClYu}7e)C0-}6-*x>PZ}MSkTqa>@egEmaz1AVnt5&Ez6`jy6I{w!$kreSrtT{agKyhc@bLq}!|}nXN*fxA@k%>t zDE^$u#76<~4uLYI2;)mW@gUvm;v!E>u9Z%{8WU_KwmN0zgz&lmP;COSln7`fmtG69 z9Qrk+a1>?Vz-#-1xFWKO!`Lj(V>m4f2g+lZQ#{7n52iTKQ17shB=cDsGo?It=36|! zjN59BI&!uXSUc{cTHZvHL(fndZc=%1*g1`f3s#S8qy^#Dy+S zxUMy;ja)bL5yHl?c#nslc9;00#q>kr$vgEz zELST2Rne*xEV@y7P;zTCosWC=b$5pTefya4Fycldkdl+eK7n@3MPKh)3*-!9Ec;U=C3a zZ@Lk#S{$!>bv_NPKRQd8B!pw=fb#-4Dv_wHURW63d8cJHGXD}* zb?kgF1PuQu)FuJq`uG0+4rpXqk$+3%s7AnWRCF@DqFyJeraI$WQnDc<93fsKAF~ne zntiH()FvFKlVi3YM#!C3DK$sl`=a;7WajBsN4$ieefmnrpRG(VJQyQb=cepqFJt8b zVMBFw-kmfM2p$A=lwYousf>oIq11D*Hu4lr2Z0Wc*Xhx9h(^Ej8G|Kk2v&Kzh-o{) z#zYwoKxp2WMt4xAhNHpY?>7FVU}OQLnvA{%zy|R_E_VzKP$KpK#LWBcV?+d*4)jwr zpkRf)@D{9aBJm$^h@t~X{%vY%s@4Zo3ZB(^qBk1XyS@W2tplEev|JX*(p>4wn)Ny9 z6&4hv0%bu4%RO{;0^R;dd|?44m6MUt+yLNr~}e5u`15) zG$Ufh6e4N4jJk+Y%uus(`n{n2EeaPWpvku`0H3wU_8Q3^-AA{I5`(IoCc)hPBaUsx9zSHm>l-$5Ke^R$;1spP!y+Z}rY69l87rG*+z8)^v2|mxz9Jlz@pCr$(zyQYgPC6++s^iGrEa;*Q zC)U393yAIT_nUF2fb>uYy0+r*h=^8jGW!VI#SGA=gkaoQ!>y!SCwi(SE*_9@b~4;z z-lO8*ky>rlodAG7@Jv*{6sa;iM}`;L*0HbBv3l-pXVULCW1%H78dAmdIrzO001|3l zt?SLXf%@5uVJrH0Ms!qZ>7GjH_v5s;8u#MQ63=(L-{v@*3!M(+KZtE^$>{FH%w%q2 z(o!+Qjfr9J$YRLjUX*`+!7UidJ*;h8vXGqW$3Pr#|KUk%SR3GHnvB@tNH?1e`XPDR zi)ydNMn4QgG0(p}*5Idg1fZE=zS^g&D7;Up>7+7p;NFgdEpct(I>V!F*a{Sc3%ZwH zz!QDr{rjMT8izFDe@ltB2Omnh|G8Sb($>z0Iho!>BStg#{=D=xDs@(R>Gd8^NVfc~Sr|HHy-qIvKpaj~?tRPWYLdH3#T zoSnR1GAtBkYX~Q{P^hqZXq}4uCfIz21m){2T0>K3+4;Y{{^n+W!09VfqT4)an za*e`5PlRx;0ywNZ&;i@t_O#;nJg|Yegw!P1mo+`mi@Y=zZSPob5G-yUm<(mDSScPVp#Xw1>>-+#;dm= z6A(>TS9V;0pMi_(N;JFS;Jvs{c6uTe^(K9kL212s0`Xx49~UX_z@U;hoS$Teb3aTc zN98m(Co~d4_UbP9vaL(5DuA@DH-*RQX~-ql?k!_yp=vfZ>`|QnS}uNH+SMMBBMk5L z+59sw+7D+Yw_o>J?=Xs7FV|er0zE1Va z^Ug{i{az93hx0r|7HIF@OUujSu^Zry$<({OL6l=AZ*{T$lH8ugcx?8I$U*4mU`6Vy zzNv$bOssJ8DDsNEP5;-rI8G0bK1db~+AnaH+~KC~O1ih~r&BcQJ(CV6z|XOSeMk{| z^Zxy3#mA4oK8jt;$MY9K{NDLirayAF$uD-O${8!(ljYF+NXzwN(aVxY(6O3Ffziab z!xU+7KT`SP-4#a_sNuP%f@P1<)yQY)qGda1JzG!vC^{WO{ciZ^uNAI=Rikp50$jN( zot;G%?AjjouMuVrhp|av-KxoJLj3eX4@ij8W!E*|36pCxmPYK}mr_-mXLLoqGiO6@ zGDDZKrwP-%T3vBOhZ&BAp(v3(Nb%q|$I>sPBN_vu`mPhx(DXo&>EHq6sWqFmDES;~ zLX?-N*bLC+tN^P4P#kPVV0i? z{TLHMzrzzji~9_cCLu92^4HQ*5KNos`T3LJbag6~%sis>rD}{^Tg-=rK^@+9k52xi z&hl^zTGX4|aO(U3w+#t3HBusVwFbQz*@UD}P>~RYS{0o7W))WenaQJ{|=xSSATLZlb z9ejN1@7=vCHx4OB>ENF69ePwA8ZjT?(PBg8Sx`RH`xabCZ_%FJVt#FBq;FVpTxGa6 z;*u(C-(!>;;wi=T zswk<@LzZjs^~KSC_wnMmQBb_P{)6lx?W=3!O`|`tYlZEu#MctO8Yu}V8ay=E`I7EO zZzMj?ZL1bgmK0#Zog9(|f&^9G5EnzoC`{|<#T}-!tGE=j$l;&Yr(eGsyO)#%v?#r& z**$r4iy>skjRXhXC2|RQ32duFz!!{6tDZJ@ubvj_cKohERy6ka<<5TpetSH8{!Vw$ zWu0IDB8>Ys%==Zqa9NL$^wI0UW?c9-4fy*qZO$J>=gTWAeT*GosvX}8b4m3ZLjn+q zz?R%(WLvcGK>vDPtvLPb8==y7bNKwkRVKOO0QLFCNQ{J5Qnpk($+Z~L{Y?7n@hdjC z!OO?CJzB#wJ+QFn{Z96Xmg$g{g@x-F#1>gwSTI*qRTVpym6W&}V=~Y7^w_2*Cu`R{ zX5e|}4R4!NlTq4(I*$@2Csy#( zQTdJ_e5|fG_wN@JK+z`$Es_x0>rb6>D2lbkMbc47-O73U_8E(B{VeA@5d;jh;JFLU zwMtQvm(RNVD_&64?S@=M1McTtq{qNm+J}bhH)zaj01qYgO|LI~*HKmDS}gd`rJ=yV z#rgO|7|D_Pn^T z9BG~vncpzXZBuT0I`L7vjH$FtcSoDmkS==6ugPqtv$H2nf4}DWk!!N`{f&Wje_e^k z{%ejt+%a`2Y3lQwVP)SkhT+4h z|0rbZ9U8+*xi?0i33I0Uf?3&wAB-N-wtFb8(g?RM^LZamEU7(`u}OMkc)<}!nzx$=Tk=91^-9ubt%?5HN2+t{QMyyZOV3)sjL{3 zk3D;DPH9(C|10`x7K^B3u~^*}ldv4Y9H0vFbI3*$M$w<(iBh8iuJ}`6qIeY3AI*P? zVKrr6-uw64x?=M4s%NlH5j$>q}W9-0gc`ybc0hS+ohSOV=lC%Xw@A$f>n`ALF{>9rC-}yD! z_8CA$h5D1YFlLbpk@qkbTZZDtRQa9YK}yy~A=G=+qw1&EG6$5qx8a4Z27p79fz`1} zz8Vm2KW_nuQVAAOt7N{Wpg+r)M!8*H8-5CAiEFRmJoD1f(Yw*6$zYk{^W>WJ$0j4U z7l2}zDQAo@^7SQ8>d5|vR zsnGzYJ9jdT1zpwxm0*?+6}0^e0D+iJki)I9puj*H>9%v#+_3^phhdlyx`CVE+>YBF zoK_PqkHbHaFo=Ed?Afz3fQ}X$z@*d;+{V04yA_;+E{Ryml(ogzF?T@q_64|RjGm|i z=7Xd2)$j^A&-^8NwHN5c&Zo*bb8C^U&{{edh}Q+cttw!U47d*?E>MRI}nKX z%y{*62+=LF@Dl408iG9zKteshFImD|C5~DgrdKBVj`J@n3(%B zapr;Z%a=USorU8!tszgB%W+QJ&BNmb)DaiX?vmmCD;C! zGL+_|kbdifKiF~0!5n}MYLqQ|qHYaBH%iLy?(k{0g7z;f<&~5yOH}G7qux>=u++N2 z6RN?cQ{D)QoNMIdA^Feptn(C8+bMaiNx1;4qNL`t7si+yBqu@-=go4sxTWWAU$0Xz zXk|05^^__|C;3jdCK08m#L4o=@O4!EH66p`^#86Y3bd45UDOw>H*(0e*1e&IaHYFZ zqr3mMSV^PgwG*?tCFft>)J0*V`XO!I`#JG_gXa`9G*1%GVK88sl56GtS5}9_IbK6_ z_OLD2!#N>AR7gflLZg>RdW;<8rYvQoW5PlcXP;viE`2>{n&{B3wmi}L|^B&V{!@Od{7O=aRDQd z+L)M_eHdyrtN59UbBOa~RRa61(@tzuT@L}MB9+?K>Av-!chM}mz@djq~ zG4!M5#l;TR`TLX62QL-J{ut)xE3uh8NNx~oa1TD;p5r;&XcatO9WvgJs4sfCjQ*ZV zykqxs>L}TPh|N?xBNNk*;JYZg2j&EuTU*Mmo0IV{6n^kC{~2=)bk8u_s`~xohgyv@ zQo9^xV6dGpIrI(2%EN%hTfI|~4G9b!0JcLWAdsMUMo~3p-hGz)5%_@cX6gRi-`Z@JpzVki$T4>yu~W4C1_ z3oK$vvY8c!--(_4EPKrFy@LqR(;GSco^4wJ$ea~hyvk~L8H|k&8YFg^6H3(W2k&7g z?-I}){xPE7AFz-K=u*U#zN&KF#7u!?=TFl_7=|3_ygbi1N-`@e3r;&BMrLLy7E&Ll z8Nl6cUBd!qf=BOkvFJ+cNLly@UXhR{kGFMDy#0HjTp4 zz8ws$Z&V8kwTb;NOogwS7sQIvtJ`t*#WIsgun@~*p&NHP-txuur=I~IqT5^-Lro*j zv`NL1N1up_yB9$Ox5tR;wo2)kSv&-2{lM(u;y;;jG_04Cy$nyUJ(;9-(>=a zffD2pU;Y95GQkpo^-oR)rlmLKkf(?5vNgR&GiEj?JIf5EY=2Tjw}=^Z#Xm2AW}{ioDHZGlj-BY$aUA!J}6GgyWn2K@t}*xh~0EVY%lN4CSx0 z-sU&Y7nBl9u()rSGAAfIbSk`_v%YjUcg`}X=rkg ze(pV<4sXHL^#hUmWmB_wo9M{H=yUH$zG`8sMdH)(?E8-@9K<{FmOr9RvvSvIV0XfM z)|_s)5XnLq&6>>r!v^i|N5+1Bbuy*)#dyS|VEO#H%O;4iDkU?o0p-#c*r1@5fO4%} zzrp8h9#Y>Wz=h@)>=PF-$vT*1i4Z!JxdU_*&uA>#NiMr%g1jl^nPAIBEV9p^JO5Q` zn3UO3Ym7n+!`rUD{@RiMS&8-HK{_AG-H!Ea)n$+mXewBkn5R(cIf{!n_QMA}LwkHC zB&`uTa4ANwo0~J*UmICBs3wg=t2sIuXqyem=zVfpVLxucr>rjIQm6UzThXAU79`Ez zORmB~fqpzS(L_B^BWB>__H}#Vow_<_?25{VEEAIj7*T(Btv*<@C>p{1S|FZ~NAcpO=PWH* z+lZUDc_oL!R)%j_7LSA~DYZ!`6<5h&Y|^R?U&3oDQ#n#%Qx4U)6y4PLB{I^HY?iIT zEcz1;*9=tBvu5=Tr3d9X0j0*f;EM!^FUy@dy?WgJ( zPw}~}RDa)zf3b8=L?)r#7Uum2@U?`2o5Js8vY5nWdhN!IAh2esMY}fk9;rg(#ea_A z)9a`1fW|l4unzq11_!TS(l`KWO%re?g_o}MC2<9?aBz(AYr}u6ZBm*H1?HRv!Y;d( z#qcOZTCa?D^5{QRH8NwoHWOCU*= zOfj^gG|I2-(nl8D=XO6+X80wK?-;tV*_6}J-|KXBB2yK&)tO!C^K{sBPo(cE#BknZ z3tFi9k-{-f%(Eu+D?*8r&1cu zR9SrDPrdA(vKC98g>!R}A#ACZ$c%IUeE%1$vlsWtm&%S%fI)8gX~?up8}*uV0kGV(>k zrr5R@zt$Qw>7!X(tw$)M_0CisK^o@&RdmeCJpU)o(7b-|o7O)d;DAm;S@Xu)o%d7= zXG$s++}NJ#^jAKAmwaf_62Cs#2Plq*kWRT??tRsiJLT3Vmii_X%eR^m(v5jU4#$oDUzi$BX?^jdS~BhY3PAJ#w&9eFft&u;FY6 zOmPQ>8@~WUWsiwLVx~Zx+h|g9?fP}Jc=`C;Aaj^!mL**BIN+=c(PH)K?F5&j)XOMH zEbq=k$$b@4A?7jp{vXc9q}|?KJMZUnhL38cMET* z21Ra;k!VG3k`U@~$^`t1zUcBC>K-(ia+i9Su7W6A-uU)P&&VWSb2w9;@Na!UihDU` zTU#5tjg5`Ax1W)j8EC>};}Q}s2MoS{lm@Mbxt`67SuxR-FZ-$9691cd6CoqW`{<_eu4ja}sN}!~~&8ti>jH zvo|CdQv~P!=0&N9eN$LQy5#!b&g-O)99+!yVkDzBL%5dP^y1+UlIfpnOHz1jlcsly;CNZMOUG%SS}a&(Z|0)M># zT=4o8Q4jf!g-a*Wy$(h+dw{bT3VYL980!kXRpzqA~Y4E_gsW*MK zLY_`tBhBT(ojRVb*bd#vPc|!LZF#T)U>R(+ws{QvIG;sD^3tv$cglxe6`hZ7{&MfW z_3}5N`!3}`{68vL1tVKD1q-4$_0H=)o3~IOc$w9Ji*@O;{~-GpD*1yJJtqB1YFFRx zu|af1L}9MgF~9F)TAp=Cc6jA5Q5v+u_1jc!rfy_F!cT<-GreCHNY9@Q8$P4HD9QTI zJS!N92AOfpa3-Q(km;lEMfO>T(j@lfx@+M?dFr15yT|V1C1tTMOjrD#?!1-tm|pvZ zeS1B}Q#TJy|65%`v3A)c&(7!#uYa4O?Y*ul|Elu()JZ8T+?6%nyf94Xj|dB!Br-yN z`m}5Z+m1`PZitriY>elB!XsIcPz)MtH&rVheMpw*>V0+-$^JIYy8X|Kf|{B^K`*#s zN?GHsmB;E79vfg#^G2oiC{!BS5EU zz=CK670Y(|#i?uwSfcy^ZfYpZE)oQ_QNA$w!n#T~PEv={ANurrm%aH1nyA~!Q~n9< zdB}h7$pzTqnQV*u{v5%A3*1inAV@}DwqS~2F}RHnuoV(UOM?~H{leaH3ACpEmbz; z+gF>Fi55lvt7xvnbI)MezdR8cOhnqKKoE~_7*`Jwh~63 z-`;HFzXpO39nAv!DMXz^_CB6UHpNMuUHrw*a`&+zkrN^|!;)&SscS{T3T zowxTNI%|)|szj`*(Pn;pC%ewu+TKp3U5W7G3=gMNYajCNVYi{oMZAt26;xCP+Lb*| zqTkQjpw#Z&h@uhj@9F6oMro|Ce{JjNAa}2H)owK|N$gJ*?m}|6wTWNEnxdgzRI9}& zz8bC)@B=5GL*Qn<2LV#tE87*GaH75x0TQutw!X&_uS^uXKk8`|^~lxE&&2+4adMgu z=TG`+>2`x#{d_o%{dilg`$p=hgV65GShv_hYD&t2ar3jn36DbgPb!3LVPYprDIFBS ze)2g(o*4mTg~;~7!DcyNT2-KHowIvac>K8kJE7Im;@ZFc&K7!wTZat}Bms6}jt`ISZXs#mA;|(D^@MK^v zL-TF1*GAJ0=RukJeD!WPA*$L!R8OYHP$?q`HqFQ*$(zb!8s4=YSG3|t1v>jxp5AGR zZ|&iZy@lA@XS@f4dmPkwGUc7a1KX|X{{HUQQY>%Y?q6Gaishr+!-^wO{#ELr7SF-w zv>KxlXu^Uj#P$hndXneQ4DVGC<()&)RJxHqsXxA0y=P3jLknt9SjB>9ok6HLm#x7(gC0<6cix ze~6+!Rn0y9II?yF67BMS{raW+NLDs{Ht74Y!tm^Wib`MPo=)Y*@`v9PVh&uTn}^AL z5G;p2-c%MNMhFUP>zD#;P+BNr0ReFoXFhGaP7%f@~LZl z*rync-|ojezbusCm|*kOkPY|!8-t;lx`V?;>FqeuXf?;{E^~w#Yea zxtm2-k&3B2#Mo#>h@Zb_cV}k@s+SMax3v*~zFY{E*Va3ujAJa%*2vN6wNP^YCU2bY zD^2#k`GeSe#Z|QPVR%dy{q(*>e%#03_UafZ8WvCG|6Q{qpE`+pq48{=4^@Ukzk@MD(5=nRK-Sy!cX#rCRA4*%b=4MZ{!2?_}*n^`^vw2!yO_ahie1;)gvdfJVt ztE-2$nK%uIow{$}7?Goju^aMGT9|W_Q|A)&jg=VY&VK!9;#a&Ic z&C7m%f?tfpp#`C#axj)7&L3GT2N9Z2?}yZIO$949oG(?$9fX{7aF=-3zL+W^=f2{o zvl_soHPzLF;^N}GP<&|8BR)@OWgg4Lp4x-RTY;QaD?^(=5cDPW^$va4yKWC2xBn}s zBwBbj=shs5lPQC)Zh}ep*TL%A6KEMmNieyh80FptQ7I0Sws6jaYnBb#p6X?ebkU;B92iPz()1j>D+LQ(BwyfZ^rlBRyrOOHlDTQx;b*GFV?!(~ zQaA9Ubb;q4`(7T~62>OCLTUU?}XJa^2sUc;HKq;PRq^bFFq^#PAk;7si&A zQ_*NJ>G|R&uur3Fv~g1Im)}Oid=huF8KQ4qBMY>EH?);v7gEYJ?741j*?P-^_ANdMk69vvUxWM)& zc!5;Y5X+Gq=hUEb##&IS*l%uNQB0uUt|jXLB}>~eP+{2q?(hHTF@fBP42=R%2dL=i zgxyg{_(57ufRU2x1eQ-&5Vs;}W%b)4(&_KMbJ(pbr7rI@TU6Bge##2`{6X3l+Zh-6 zS&jXgV=AdT&DA`YA%}*ESYbMfFmy{Qgg|lZk;P_6{=djfOU`?E>eAYhlTp;#ZaT276Qs9bTo+v7R1DX^i)oP9s4# zk?(j@E)lhk%a1iyqtd-lS}2y0N4ac~xD_cEv-@6TDAGSuIO-B;G-KdV`oyVXxVE}w za#Aq3WxjmW_oK_i4|u2pLDEE17-_pZWW--RF+#>v-m-}w z-RyI`rkM)eM$Um!ssQ*OWqtih0f$EI-NbG&luBmg+pHK89w$7@;A{4^hZvb}#0{h`AZ- zR^1dH51$&2?m?0b+fein8(wtX9`(iN%)`6+N^FaSvD%MROe?a87vG= zQt<*b9V}d$wEa-*3ynVe>#3E0coPdKXvACzDJlD#Zp(eGbZzkj8P1E-8XSJ_TKnJs z619~>(7w)Yyw0VR@U*ZwJsOr8*P<|;{(g9ibbF`wbNbFf*FQ&Rm!|Vg>IwsUbMwlk zmZG}unHKW7`9FP=o{Q+h!ZuX~bcJ=Y?2W_SZz~SJV;#An zt&tDc^I}IyF*%ld&`^=cfb~^=8l`opk0#dyl@o1L*3H`B4wI6SUW0he2nfpiu5hCH zj&i7@3KK;q=3`4qRb#annuPaw>krfU|03(X;C8#km|!u7bW$N4zVeqNdSAX!z&=rNPYc!zdpp4ZNmycGktY^NEn>0s~$2kuVGRk%^r92?p-p_sK99U z5PG`$;L!NI4&a+S$SP5=?!skFQtm1=sKN(CGY>DX|3l`>*D_Q`lWc!mAkMef=|$7j z?oYStuBxj3O#nomMV}89^6{Qy+u^SHhne~U?p~RATs*v?rH8M2mNKCOC~^eU)khVR zo8z`Qwp9kCkgS!RlN0tZnsSIg5~dhnk|qFlSQZQ%xY^n1isYS^Q1LO$wE+Vw6+bF% zVrs!3CR*iiizes>{Be<+65r^TOD&y%N-*}l9zVHOo(K~plCAI+I;!N~OJ@}uoDJ+| z3`uo+*&)>)-@AUys8rO%*!7p-4O1ZS&zl|!3kez2dJ+&2Ab=Gf8j5#a%mXs4P0h^E zVK@yb&Ka4R=n4u74;2(zL4GbtiU}hi^#kv6upW}Z1Jz>wqHt>NqEqs874uM{1#asNgA)v;C zUsRXv2`t^gq%9!jWEd1#f=4Ly^wc{<<|ZuFSD=@@-udzL7z6b>$bru7&l9ZttQXQ= zR@622i(fG|tT?QSrjd)%8PQ_{AxPQ{f~Pwg3X~BE(aFhEdBu6PpYfs!bPA@|lPN}R z1t7o(4!0e)>ocIK^YZfWV1yuF5XDpy;^Vi$+zDt-g7#A~mxFR>l3s!--i!Ox>B`Cm z79aAHh05T7DS#V{v(U!jSGi=|!N+)b2;LJXj8)FGlf(-Q5;Ptzb(NK`n1hQ^8Ii3)b8GZ z=%?6(7}O4v)SzO}kxu%-H59wWl9RK2q~`5@v)By?}TLyC4z<2Nyt&xWLiB5)xNOK{QDKg`GAyj#Kt}xA%8<*Suh( zdka%iGqCmk(>@D;Vrb?vKZ@7(doB|gb7y|M7yD(u=ZUd0`&KiBDlhPw6e-#MpUt_t zGnmF{XJjB5p_o!K-!B@s8m7LP$(Wy1jT;mj)((qua@uLaKxTJ!b#(;=Rao*?miCJW z`;O&O89}f!YiVg+TChOcS>Tf)41fc8O+F`_a=NoHV1#magMlvva{F{)1&4}wQ!tlf zW4`LJELZ=n(*!hziqPgD5J48jbuTR(66uG+CT|KZOLYG$uOQ`f)k@^1+1p zsEt~<&SjX@|PI~Y$rLji1Y6)3O@)w zUJS;-DfRk|9f_`{N%>u*T_HNa>*WKZBXUkE0*uoi0i9+~oFwIeB}BOPn^-U7<>8d>xa(F5NKsMec1cS{_ua+3wYqf(|pDew{v_&pc3zTxwD*+Ree*e(9f1 zerEG|M3R;AxNLGW7-3;ysf45mg%Qf%OG|xqmB?sPoh!i5+$D4{Y zbJo+FFw54cm3qq@rpZb<4FomH{=hoKrL8nAyjslOXRgP+^0h|Qx1K{ef*E(=| z?&)*tq#QS2p{9NuasB?~vv?b#GU^`vK1n$Nz`rUM>iS!pXl6E=oswX#I~pde0+fc} zscR)d3b^y>PK+<6N|Dl1mHnFRJGf0-;s&77S7yT3a9kxfa06MAHdIOH@BXcJw)_(> zCJj5>Mw{qd*-KDP5hQ}ghpe=8+ar%2bs+$rCmeY7Z+q8=lVEI8KUrqatk9Np7eo=ltyK*AWyZ|C!@Zp2x${88vtL^^O_P8CV zhV6~;k%Mg}yQ!x&^_A!k$V_n=Hzph?b+r}}o>i;g%n*62=mZgjk}2q&6b24tXug{VX|q zG?32@IgcNLbt`1zr86Ym-9Phka}N|pEgsAACYATp|)j$z-j-4Yhj{-4)3@AU9S~u|MDex zXr(E?pkOaqNDRH@7>fL4AneYA?TLoZGQu!VD+jFwo*|-Of#Gg|aXIt~oxqktA}x>O z3EJ3ZV7YuW0Q)vz5CxHb4-g zK2jJ6>B0^22gNM^uJPABP9dHl#&ae~VXmyIGE#{C<&m7Df91-R$+whY#A#ey?v3(q zWQ2p;r<{M&C2>d5UFK20H~}p9>@t+1t22!!92>@YG5~x^&W!%co^0CzSk~|S(HfRx?o7@$( z=+r@(tvviR$>{Barp`5T1k2up$vJb|+a&&-=-JWcKSNqs?ofR}{#g08JBrHf?rQ4v$m9@Kn*^x@hqw91(Ess&rS`|}PRyKC6fW;#%EzJW`fXJ^4F113>S4qL*haD(ApJC;}fLbjG zUX=eH=9+4zRirb(dR?LkBQtaG$LQz?WV9(RaXc6q9UX

R$@k!xx#BwgK`gVK-?b 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 Bp!NU& diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index 6eb19c0ff05..fab6886b314 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -92,6 +92,10 @@ KM_HIERARCHY = [ ('Script', 'SCRIPTS_WINDOW', 'WINDOW', []), ('Text', 'TEXT_EDITOR', 'WINDOW', []), ('Console', 'CONSOLE', 'WINDOW', []), + ('Clip', 'CLIP_EDITOR', 'WINDOW', [ + ('Clip Editor', 'CLIP_EDITOR', 'WINDOW', []), + ('Clip Graph Editor', 'CLIP_EDITOR', 'WINDOW', []), + ]), ('View3D Gesture Circle', 'EMPTY', 'WINDOW', []), ('Gesture Border', 'EMPTY', 'WINDOW', []), diff --git a/release/scripts/presets/tracking_camera/Blender.py b/release/scripts/presets/tracking_camera/Blender.py new file mode 100644 index 00000000000..507cedac4fc --- /dev/null +++ b/release/scripts/presets/tracking_camera/Blender.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 32.0 +camera.units = 'MILLIMETERS' +camera.focal_length = 35.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_1100D.py b/release/scripts/presets/tracking_camera/Canon_1100D.py new file mode 100644 index 00000000000..7ea78412f40 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_1100D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.2 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_1D.py b/release/scripts/presets/tracking_camera/Canon_1D.py new file mode 100644 index 00000000000..89590d3cc19 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_1D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 27.9 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_1DS.py b/release/scripts/presets/tracking_camera/Canon_1DS.py new file mode 100644 index 00000000000..7d9b6c8b390 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_1DS.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 36.0 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_500D.py b/release/scripts/presets/tracking_camera/Canon_500D.py new file mode 100644 index 00000000000..3dd66c5b609 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_500D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.3 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_550D.py b/release/scripts/presets/tracking_camera/Canon_550D.py new file mode 100644 index 00000000000..3dd66c5b609 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_550D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.3 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_5D.py b/release/scripts/presets/tracking_camera/Canon_5D.py new file mode 100644 index 00000000000..7d9b6c8b390 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_5D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 36.0 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_600D.py b/release/scripts/presets/tracking_camera/Canon_600D.py new file mode 100644 index 00000000000..3dd66c5b609 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_600D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.3 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_60D.py b/release/scripts/presets/tracking_camera/Canon_60D.py new file mode 100644 index 00000000000..3dd66c5b609 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_60D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.3 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Canon_7D.py b/release/scripts/presets/tracking_camera/Canon_7D.py new file mode 100644 index 00000000000..3dd66c5b609 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Canon_7D.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.3 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D300S.py b/release/scripts/presets/tracking_camera/Nikon_D300S.py new file mode 100644 index 00000000000..8db89189cd7 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D300S.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.6 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D3100.py b/release/scripts/presets/tracking_camera/Nikon_D3100.py new file mode 100644 index 00000000000..a112dd22dd2 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D3100.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.1 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D35.py b/release/scripts/presets/tracking_camera/Nikon_D35.py new file mode 100644 index 00000000000..7d9b6c8b390 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D35.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 36.0 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D5000.py b/release/scripts/presets/tracking_camera/Nikon_D5000.py new file mode 100644 index 00000000000..8db89189cd7 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D5000.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.6 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D5100.py b/release/scripts/presets/tracking_camera/Nikon_D5100.py new file mode 100644 index 00000000000..8db89189cd7 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D5100.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.6 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D7000.py b/release/scripts/presets/tracking_camera/Nikon_D7000.py new file mode 100644 index 00000000000..8db89189cd7 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D7000.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.6 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Nikon_D90.py b/release/scripts/presets/tracking_camera/Nikon_D90.py new file mode 100644 index 00000000000..8db89189cd7 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Nikon_D90.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 23.6 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Red_Epic.py b/release/scripts/presets/tracking_camera/Red_Epic.py new file mode 100644 index 00000000000..913b507d296 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Red_Epic.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 30.0 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Red_One_2K.py b/release/scripts/presets/tracking_camera/Red_One_2K.py new file mode 100644 index 00000000000..0a52b377959 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Red_One_2K.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 11.1 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Red_One_3K.py b/release/scripts/presets/tracking_camera/Red_One_3K.py new file mode 100644 index 00000000000..88c232bb944 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Red_One_3K.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 16.65 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_camera/Red_One_4K.py b/release/scripts/presets/tracking_camera/Red_One_4K.py new file mode 100644 index 00000000000..7ea78412f40 --- /dev/null +++ b/release/scripts/presets/tracking_camera/Red_One_4K.py @@ -0,0 +1,10 @@ +import bpy +camera = bpy.context.edit_movieclip.tracking.camera + +camera.sensor_width = 22.2 +camera.units = 'MILLIMETERS' +camera.focal_length = 24.0 +camera.pixel_aspect = 1 +camera.k1 = 0.0 +camera.k2 = 0.0 +camera.k3 = 0.0 diff --git a/release/scripts/presets/tracking_track_color/default.py b/release/scripts/presets/tracking_track_color/default.py new file mode 100644 index 00000000000..3213d6e0c83 --- /dev/null +++ b/release/scripts/presets/tracking_track_color/default.py @@ -0,0 +1,5 @@ +import bpy +track = bpy.context.edit_movieclip.tracking.tracks.active + +track.color = (0.0, 0.0, 0.0) +track.use_custom_color = False diff --git a/release/scripts/presets/tracking_track_color/far_plane.py b/release/scripts/presets/tracking_track_color/far_plane.py new file mode 100644 index 00000000000..579d5562642 --- /dev/null +++ b/release/scripts/presets/tracking_track_color/far_plane.py @@ -0,0 +1,5 @@ +import bpy +track = bpy.context.edit_movieclip.tracking.tracks.active + +track.color = (0.0, 0.0, 1.0) +track.use_custom_color = True diff --git a/release/scripts/presets/tracking_track_color/near_plane.py b/release/scripts/presets/tracking_track_color/near_plane.py new file mode 100644 index 00000000000..790429ce7a1 --- /dev/null +++ b/release/scripts/presets/tracking_track_color/near_plane.py @@ -0,0 +1,5 @@ +import bpy +track = bpy.context.edit_movieclip.tracking.tracks.active + +track.color = (0.0, 1.0, 0.0) +track.use_custom_color = True diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index c0e83cee9d6..06b4429d25c 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -25,6 +25,7 @@ if "bpy" in locals(): _modules = ( "add_mesh_torus", "anim", + "clip", "console", "image", "mesh", diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py new file mode 100644 index 00000000000..d085b7ea105 --- /dev/null +++ b/release/scripts/startup/bl_operators/clip.py @@ -0,0 +1,318 @@ +# ##### 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 ##### + +# +import bpy +import os +import shutil +from bpy.types import Operator +from bpy_extras.io_utils import unpack_list + + +class CLIP_OT_track_to_empty(Operator): + """Create an Empty object which will be copying movement of active track""" + + bl_idname = "clip.track_to_empty" + bl_label = "2D Track to Empty" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + clip = sc.clip + + return clip and clip.tracking.tracks.active + + def execute(self, context): + sc = context.space_data + clip = sc.clip + track = clip.tracking.tracks.active + constraint = None + ob = None + + ob = bpy.data.objects.new(name=track.name, object_data=None) + ob.select = True + bpy.context.scene.objects.link(ob) + bpy.context.scene.objects.active = ob + + for con in ob.constraints: + if con.type == 'FOLLOW_TRACK': + constraint = con + break + + if constraint is None: + constraint = ob.constraints.new(type='FOLLOW_TRACK') + + constraint.clip = sc.clip + constraint.track = track.name + constraint.reference = 'TRACK' + + return {'FINISHED'} + + +class CLIP_OT_bundles_to_mesh(Operator): + """Create vertex cloud using coordinates of bundles""" + + bl_idname = "clip.bundles_to_mesh" + bl_label = "Bundles to Mesh" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + clip = sc.clip + + return clip + + def execute(self, context): + sc = context.space_data + clip = sc.clip + + new_verts = [] + + mesh = bpy.data.meshes.new(name="Bundles") + for track in clip.tracking.tracks: + if track.has_bundle: + new_verts.append(track.bundle) + + if new_verts: + mesh.vertices.add(len(new_verts)) + mesh.vertices.foreach_set("co", unpack_list(new_verts)) + + ob = bpy.data.objects.new(name="Bundles", object_data=mesh) + + bpy.context.scene.objects.link(ob) + + return {'FINISHED'} + + +class CLIP_OT_delete_proxy(Operator): + """Delete movie clip proxy files from the hard drive""" + + bl_idname = "clip.delete_proxy" + bl_label = "Delete Proxy" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def invoke(self, context, event): + wm = context.window_manager + + return wm.invoke_confirm(self, event) + + def _rmproxy(self, abspath): + if not os.path.exists(abspath): + return + + if os.path.isdir(abspath): + shutil.rmtree(abspath) + else: + os.remove(abspath) + + def execute(self, context): + sc = context.space_data + clip = sc.clip + if clip.use_proxy_custom_directory: + proxydir = clip.proxy.directory + else: + clipdir = os.path.dirname(clip.filepath) + proxydir = os.path.join(clipdir, 'BL_proxy') + + clipfile = os.path.basename(clip.filepath) + proxy = os.path.join(proxydir, clipfile) + absproxy = bpy.path.abspath(proxy) + + # proxy_[_undostorted] + for x in (25, 50, 75, 100): + d = os.path.join(absproxy, 'proxy_' + str(x)) + + self._rmproxy(d) + self._rmproxy(d + '_undistorted') + self._rmproxy(os.path.join(absproxy, 'proxy_' + str(x) + '.avi')) + + tc = ('free_run.blen_tc', 'interp_free_run.blen_tc', \ + 'record_run.blen_tc') + + for x in tc: + self._rmproxy(os.path.join(absproxy, x)) + + # remove proxy per-clip directory + try: + os.rmdir(absproxy) + except OSError: + pass + + # remove [custom] proxy directory if empty + try: + absdir = bpy.path.abspath(proxydir) + os.rmdir(absdir) + except OSError: + pass + + return {'FINISHED'} + + +class CLIP_OT_set_viewport_background(Operator): + """Set current movie clip as a camera background in 3D viewport""" + + bl_idname = "clip.set_viewport_background" + bl_label = "Set as Background" + bl_options = {'UNDO', 'REGISTER'} + + @classmethod + def poll(cls, context): + if context.space_data.type != 'CLIP_EDITOR': + return False + + sc = context.space_data + + return sc.clip + + def _set_background(self, space_v3d, clip, user): + bgpic = None + + for x in space_v3d.background_images: + if x.source == 'MOVIE': + bgpic = x + break + + if not bgpic: + bgpic = space_v3d.background_images.add() + + bgpic.source = 'MOVIE' + bgpic.clip = clip + bgpic.clip_user.proxy_render_size = user.proxy_render_size + bgpic.clip_user.use_render_undistorted = user.use_render_undistorted + bgpic.use_camera_clip = False + bgpic.view_axis = 'CAMERA' + + space_v3d.show_background_images = True + + def execute(self, context): + sc = context.space_data + clip = sc.clip + + for area in context.window.screen.areas: + if area.type == 'VIEW_3D': + for space in area.spaces: + if space.type == 'VIEW_3D': + self._set_background(space, clip, sc.clip_user) + + return {'FINISHED'} + + +class CLIP_OT_constraint_to_fcurve(Operator): + """Create F-Curves for object which will copy object's movement caused by this constraint""" + + bl_idname = "clip.constraint_to_fcurve" + bl_label = "Constraint to F-Curve" + bl_options = {'UNDO', 'REGISTER'} + + def _bake_object(self, scene, ob): + con = None + clip = None + sfra = None + efra = None + frame_current = scene.frame_current + matrices = [] + + # Find constraint which would eb converting + # TODO: several camera solvers and track followers would fail, + # but can't think about eal workflow where it'll be useful + for x in ob.constraints: + if x.type in ('CAMERA_SOLVER', 'FOLLOW_TRACK'): + con = x + + if not con: + return + + if con.type == 'FOLLOW_TRACK' and con.reference == 'BUNDLE': + mat = ob.matrix_world.copy() + ob.constraints.remove(con) + ob.matrix_world = mat + + return + + # Get clip used for parenting + if con.use_active_clip: + clip = scene.active_clip + else: + clip = con.clip + + if not clip: + return + + # Find start and end frames + for track in clip.tracking.tracks: + if sfra is None: + sfra = track.markers[0].frame + else: + sfra = min(sfra, track.markers[0].frame) + + if efra is None: + efra = track.markers[-1].frame + else: + efra = max(efra, track.markers[-1].frame) + + if sfra is None or efra is None: + return + + # Store object matrices + for x in range(sfra, efra+1): + scene.frame_set(x) + matrices.append(ob.matrix_world.copy()) + + ob.animation_data_create() + + # Apply matrices on object and insert keyframes + i = 0 + for x in range(sfra, efra+1): + scene.frame_set(x) + ob.matrix_world = matrices[i] + + ob.keyframe_insert("location") + + if ob.rotation_mode == 'QUATERNION': + ob.keyframe_insert("rotation_quaternion") + else: + ob.keyframe_insert("rotation_euler") + + i += 1 + + ob.constraints.remove(con) + + scene.frame_set(frame_current) + + def execute(self, context): + scene = context.scene + + for ob in scene.objects: + if ob.select: + self._bake_object(scene, ob) + + return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 21ac128f177..ac19bab4c66 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -319,6 +319,47 @@ class AddPresetInteraction(AddPresetBase, Operator): preset_subdir = "interaction" +class AddPresetTrackingCamera(AddPresetBase, Operator): + '''Add a Tracking Camera Intrinsics Preset''' + bl_idname = "clip.camera_preset_add" + bl_label = "Add Camera Preset" + preset_menu = "CLIP_MT_camera_presets" + + preset_defines = [ + "camera = bpy.context.edit_movieclip.tracking.camera" + ] + + preset_values = [ + "camera.sensor_width", + "camera.units", + "camera.focal_length", + "camera.pixel_aspect", + "camera.k1", + "camera.k2", + "camera.k3" + ] + + preset_subdir = "tracking_camera" + + +class AddPresetTrackingTrackColor(AddPresetBase, Operator): + '''Add a Clip Track Color Preset''' + bl_idname = "clip.track_color_preset_add" + bl_label = "Add Track Color Preset" + preset_menu = "CLIP_MT_track_color_presets" + + preset_defines = [ + "track = bpy.context.edit_movieclip.tracking.tracks" + ] + + preset_values = [ + "track.color", + "track.use_custom_color" + ] + + preset_subdir = "tracking_track_color" + + class AddPresetKeyconfig(AddPresetBase, Operator): '''Add a Keyconfig Preset''' bl_idname = "wm.keyconfig_preset_add" diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 682341cbf2f..48aefa93a5c 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -52,6 +52,7 @@ _modules = ( "properties_scene", "properties_texture", "properties_world", + "space_clip", "space_console", "space_dopesheet", "space_filebrowser", diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index dc19f58ca35..4def354741e 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -753,6 +753,27 @@ class ConstraintButtonsPanel(): col = layout.column() col.prop(con, "rotation_range", text="Pivot When") + def FOLLOW_TRACK(self, context, layout, con): + layout.prop(con, "use_active_clip") + + if not con.use_active_clip: + layout.prop(con, "clip") + + layout.prop(con, "track") + + row = layout.row() + row.prop(con, "reference", expand=True) + + layout.operator("clip.constraint_to_fcurve") + + def CAMERA_SOLVER(self, context, layout, con): + layout.prop(con, "use_active_clip") + + if not con.use_active_clip: + layout.prop(con, "clip") + + layout.operator("clip.constraint_to_fcurve") + def SCRIPT(self, context, layout, con): layout.label("Blender 2.5 has no py-constraints") diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index d3859a78bea..6e28c8b42f1 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -218,6 +218,16 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): col.prop(rd, "simplify_ao_sss", text="AO and SSS") +class SCENE_PT_movie_clip(SceneButtonsPanel, Panel): + bl_label = "Movie Clip" + + def draw(self, context): + layout = self.layout + scene = context.scene + + layout.prop(scene, "active_clip", text="Active Clip") + + class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} _context_path = "scene" diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py new file mode 100644 index 00000000000..09209017823 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -0,0 +1,885 @@ +# ##### 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 ##### + +# +import bpy +from bpy.types import Panel, Header, Menu + + +class CLIP_HT_header(Header): + bl_space_type = 'CLIP_EDITOR' + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + row = layout.row(align=True) + row.template_header() + + if context.area.show_menus: + sub = row.row(align=True) + sub.menu("CLIP_MT_view") + + if clip: + sub.menu("CLIP_MT_select") + + sub.menu("CLIP_MT_clip") + + if clip: + sub.menu("CLIP_MT_track") + sub.menu("CLIP_MT_reconstruction") + + if clip: + layout.prop(sc, "mode", text="") + layout.prop(sc, "view", text="", expand=True) + + if sc.view == 'GRAPH': + row = layout.row(align=True) + + if sc.show_filters: + row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN', text="Filters") + row.prop(sc, "show_graph_frames", icon='SEQUENCE', text="") + row.prop(sc, "show_graph_tracks", icon='ANIM', text="") + else: + row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT', text="Filters") + + row = layout.row() + row.template_ID(sc, "clip", open='clip.open') + + if clip: + r = clip.tracking.reconstruction + + if r.is_valid: + layout.label(text="Average solve error: %.4f" % + (r.average_error)) + + layout.template_running_jobs() + + +class CLIP_PT_tools_marker(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Marker" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + col.operator("clip.add_marker_move") + col.operator("clip.detect_features") + col.operator("clip.delete_track") + + +class CLIP_PT_tools_tracking(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Track" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + row = layout.row(align=True) + + props = row.operator("clip.track_markers", text="", icon='FRAME_PREV') + props.backwards = True + props = row.operator("clip.track_markers", text="", + icon='PLAY_REVERSE') + props.backwards = True + props.sequence = True + props = row.operator("clip.track_markers", text="", icon='PLAY') + props.sequence = True + row.operator("clip.track_markers", text="", icon='FRAME_NEXT') + + col = layout.column(align=True) + props = col.operator("clip.clear_track_path", text="Clear After") + props.action = 'REMAINED' + + props = col.operator("clip.clear_track_path", text="Clear Before") + props.action = 'UPTO' + + props = col.operator("clip.clear_track_path", text="Clear Track Path") + props.action = 'ALL' + + layout.operator("clip.join_tracks") + + +class CLIP_PT_tools_solving(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Solving" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + col = layout.column(align=True) + col.operator("clip.solve_camera") + col.operator("clip.clear_solution") + + col = layout.column(align=True) + col.prop(settings, "keyframe_a") + col.prop(settings, "keyframe_b") + + +class CLIP_PT_tools_cleanup(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Clean up" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'TRACKING' + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + layout.operator("clip.clean_tracks") + + layout.prop(settings, 'clean_frames', text="Frames") + layout.prop(settings, 'clean_error', text="Error") + layout.prop(settings, 'clean_action', text="") + + +class CLIP_PT_tools_geometry(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Geometry" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'RECONSTRUCTION' + + def draw(self, context): + layout = self.layout + + layout.operator("clip.bundles_to_mesh") + layout.operator("clip.track_to_empty") + + +class CLIP_PT_tools_orientation(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Orientation" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'RECONSTRUCTION' + + def draw(self, context): + sc = context.space_data + layout = self.layout + settings = sc.clip.tracking.settings + + col = layout.column(align=True) + col.label(text="Scene Orientation:") + col.operator("clip.set_floor") + col.operator("clip.set_origin") + + row = col.row() + row.operator("clip.set_axis", text="Set X Axis").axis = 'X' + row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y' + + layout.separator() + + col = layout.column() + col.operator("clip.set_scale") + col.prop(settings, "distance") + + +class CLIP_PT_tools_grease_pencil(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Grease Pencil" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return clip and sc.mode == 'DISTORTION' + + def draw(self, context): + layout = self.layout + + col = layout.column(align=True) + + row = col.row(align=True) + row.operator("gpencil.draw", text="Draw").mode = 'DRAW' + row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT' + + row = col.row(align=True) + row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY' + row.operator("gpencil.draw", text="Erase").mode = 'ERASER' + + row = col.row() + row.prop(context.tool_settings, "use_grease_pencil_sessions") + + +class CLIP_PT_track(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Track" + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return sc.mode == 'TRACKING' and clip + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = context.space_data.clip + act_track = clip.tracking.tracks.active + + if not act_track: + layout.active = False + layout.label(text="No active track") + return + + row = layout.row() + row.prop(act_track, "name", text="") + + sub = row.row(align=True) + + sub.template_marker(sc, "clip", sc.clip_user, act_track, True) + + icon = 'LOCKED' if act_track.lock else 'UNLOCKED' + sub.prop(act_track, "lock", text="", icon=icon) + + layout.template_track(sc, "scopes") + + row = layout.row(align=True) + row.prop(act_track, "use_red_channel", text="R", toggle=True) + row.prop(act_track, "use_green_channel", text="G", toggle=True) + row.prop(act_track, "use_blue_channel", text="B", toggle=True) + + layout.separator() + + row = layout.row(align=True) + label = bpy.types.CLIP_MT_track_color_presets.bl_label + row.menu('CLIP_MT_track_color_presets', text=label) + row.menu('CLIP_MT_track_color_specials', text="", icon="DOWNARROW_HLT") + row.operator("clip.track_color_preset_add", text="", icon="ZOOMIN") + props = row.operator("clip.track_color_preset_add", + text="", icon="ZOOMOUT") + props.remove_active = True + + row = layout.row() + row.prop(act_track, "use_custom_color") + if act_track.use_custom_color: + row.prop(act_track, "color", text="") + + if act_track.has_bundle: + label_text = "Average Error: %.4f" % (act_track.average_error) + layout.label(text=label_text) + + +class CLIP_PT_tracking_camera(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Camera Data" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode in ['TRACKING', 'DISTORTION'] and sc.clip + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + row = layout.row(align=True) + label = bpy.types.CLIP_MT_camera_presets.bl_label + row.menu('CLIP_MT_camera_presets', text=label) + row.operator("clip.camera_preset_add", text="", icon="ZOOMIN") + props = row.operator("clip.camera_preset_add", text="", icon="ZOOMOUT") + props.remove_active = True + + row = layout.row(align=True) + sub = row.split(percentage=0.65) + if clip.tracking.camera.units == 'MILLIMETERS': + sub.prop(clip.tracking.camera, "focal_length") + else: + sub.prop(clip.tracking.camera, "focal_length_pixels") + sub.prop(clip.tracking.camera, "units", text="") + + col = layout.column(align=True) + col.label(text="Sensor:") + col.prop(clip.tracking.camera, "sensor_width", text="Width") + col.prop(clip.tracking.camera, "pixel_aspect") + + col = layout.column() + col.label(text="Principal Point") + row = col.row() + row.prop(clip.tracking.camera, "principal", text="") + col.operator("clip.set_center_principal", text="Center") + + col = layout.column(align=True) + col.label(text="Undistortion:") + col.prop(clip.tracking.camera, "k1") + col.prop(clip.tracking.camera, "k2") + col.prop(clip.tracking.camera, "k3") + + +class CLIP_PT_display(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Display" + + def draw(self, context): + layout = self.layout + sc = context.space_data + + col = layout.column(align=True) + + col.prop(sc, "show_marker_pattern", text="Pattern") + col.prop(sc, "show_marker_search", text="Search") + col.prop(sc, "show_pyramid_levels", text="Pyramid") + + col.prop(sc, "show_track_path", text="Track Path") + row = col.row() + row.active = sc.show_track_path + row.prop(sc, "path_length", text="Length") + + col.prop(sc, "show_disabled", "Disabled Tracks") + col.prop(sc, "show_bundles", text="Bundles") + + col.prop(sc, "show_names", text="Track Names") + col.prop(sc, "show_tiny_markers", text="Tiny Markers") + + col.prop(sc, "show_grease_pencil", text="Grease Pencil") + col.prop(sc, "use_mute_footage", text="Mute") + + if sc.mode == 'DISTORTION': + col.prop(sc, "show_grid", text="Grid") + col.prop(sc, "use_manual_calibration") + elif sc.mode == 'RECONSTRUCTION': + col.prop(sc, "show_stable", text="Stable") + + col.prop(sc, "lock_selection") + + clip = sc.clip + if clip: + col.label(text="Display Aspect:") + col.prop(clip, "display_aspect", text="") + + +class CLIP_PT_track_settings(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Tracking Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode == 'TRACKING' and sc.clip + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + settings = clip.tracking.settings + + active = clip.tracking.tracks.active + if active: + layout.prop(active, "tracker") + if active.tracker == "KLT": + layout.prop(active, "pyramid_levels") + if active.tracker == "SAD": + layout.prop(active, "correlation_min") + + layout.prop(settings, "frames_adjust") + layout.prop(settings, "speed") + layout.prop(settings, "frames_limit") + layout.prop(settings, "margin") + + +class CLIP_PT_stabilization(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "2D Stabilization" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.mode == 'RECONSTRUCTION' and sc.clip + + def draw_header(self, context): + sc = context.space_data + tracking = sc.clip.tracking + stab = tracking.stabilization + + self.layout.prop(stab, "use_2d_stabilization", text="") + + def draw(self, context): + layout = self.layout + sc = context.space_data + tracking = sc.clip.tracking + stab = tracking.stabilization + + layout.active = stab.use_2d_stabilization + + row = layout.row() + row.template_list(stab, "tracks", stab, "active_track_index", rows=3) + + sub = row.column(align=True) + + sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="") + sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="") + + sub.menu('CLIP_MT_stabilize_2d_specials', text="", + icon="DOWNARROW_HLT") + + layout.prop(stab, "influence_location") + + layout.separator() + + layout.prop(stab, "use_autoscale") + col = layout.column() + col.active = stab.use_autoscale + col.prop(stab, "scale_max") + col.prop(stab, "influence_scale") + + layout.separator() + + layout.label(text="Rotation:") + + row = layout.row(align=True) + row.prop_search(stab, "rotation_track", tracking, "tracks", text="") + row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN') + + row = layout.row() + row.active = stab.rotation_track is not None + row.prop(stab, "influence_rotation") + + +class CLIP_PT_marker(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Marker" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + clip = sc.clip + + return sc.mode == 'TRACKING' and clip + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = context.space_data.clip + act_track = clip.tracking.tracks.active + + if act_track: + layout.template_marker(sc, "clip", sc.clip_user, act_track, False) + else: + layout.active = False + layout.label(text="No active track") + + +class CLIP_PT_proxy(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Proxy / Timecode" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw_header(self, context): + sc = context.space_data + + self.layout.prop(sc.clip, "use_proxy", text="") + + def draw(self, context): + layout = self.layout + sc = context.space_data + clip = sc.clip + + layout.active = clip.use_proxy + + layout.label(text="Build Sizes:") + + row = layout.row() + row.prop(clip.proxy, "build_25") + row.prop(clip.proxy, "build_50") + + row = layout.row() + row.prop(clip.proxy, "build_75") + row.prop(clip.proxy, "build_100") + + layout.prop(clip.proxy, "build_undistorted") + + layout.prop(clip.proxy, "quality") + + layout.prop(clip, 'use_proxy_custom_directory') + if clip.use_proxy_custom_directory: + layout.prop(clip.proxy, "directory") + + layout.operator("clip.rebuild_proxy", text="Rebuild Proxy") + + if clip.source == 'MOVIE': + col = layout.column() + + col.label(text="Use timecode index:") + col.prop(clip.proxy, "timecode", text="") + + col = layout.column() + col.label(text="Proxy render size:") + + col.prop(sc.clip_user, "proxy_render_size", text="") + col.prop(sc.clip_user, "use_render_undistorted") + + +class CLIP_PT_footage(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'UI' + bl_label = "Footage Settings" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + if clip: + layout.template_movieclip(sc, "clip", compact=True) + else: + layout.operator("clip.open", icon='FILESEL') + + +class CLIP_PT_tools_clip(Panel): + bl_space_type = 'CLIP_EDITOR' + bl_region_type = 'TOOLS' + bl_label = "Clip" + + @classmethod + def poll(cls, context): + sc = context.space_data + + return sc.clip + + def draw(self, context): + layout = self.layout + clip = context.space_data.clip + + layout.operator("clip.set_viewport_background") + + +class CLIP_MT_view(Menu): + bl_label = "View" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.properties", icon='MENU_PANEL') + layout.operator("clip.tools", icon='MENU_PANEL') + layout.separator() + + layout.operator("clip.view_selected") + layout.operator("clip.view_all") + + layout.separator() + layout.operator("clip.view_zoom_in") + layout.operator("clip.view_zoom_out") + + layout.separator() + + ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1)) + + for a, b in ratios: + text = "Zoom %d:%d" % (a, b) + layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b + + layout.separator() + layout.operator("screen.area_dupli") + layout.operator("screen.screen_full_area") + + +class CLIP_MT_clip(Menu): + bl_label = "Clip" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + layout.operator("clip.open") + + if clip: + layout.operator("clip.reload") + layout.menu("CLIP_MT_proxy") + + +class CLIP_MT_proxy(Menu): + bl_label = "Proxy" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + clip = sc.clip + + layout.operator("clip.rebuild_proxy") + layout.operator("clip.delete_proxy") + + +class CLIP_MT_track(Menu): + bl_label = "Track" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.clear_solution") + layout.operator("clip.solve_camera") + + layout.separator() + props = layout.operator("clip.clear_track_path", text="Clear After") + props.action = 'REMAINED' + + props = layout.operator("clip.clear_track_path", text="Clear Before") + props.action = 'UPTO' + + props = layout.operator("clip.clear_track_path", text="Clear Track Path") + props.action = 'ALL' + + layout.separator() + layout.operator("clip.join_tracks") + + layout.separator() + layout.operator("clip.clean_tracks") + + layout.separator() + props = layout.operator("clip.track_markers", + text="Track Frame Backwards") + props.backwards = True + + props = layout.operator("clip.track_markers", text="Track Backwards") + props.backwards = True + props.sequence = True + + props = layout.operator("clip.track_markers", text="Track Forwards") + props.sequence = True + layout.operator("clip.track_markers", text="Track Frame Forwards") + + layout.separator() + layout.operator("clip.delete_track") + layout.operator("clip.delete_marker") + + layout.separator() + layout.operator("clip.add_marker_move") + + layout.separator() + layout.menu("CLIP_MT_track_visibility") + layout.menu("CLIP_MT_track_transform") + + +class CLIP_MT_reconstruction(Menu): + bl_label = "Reconstruction" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.set_origin") + layout.operator("clip.set_floor") + + layout.operator("clip.set_axis", text="Set X Asix").axis = "X" + layout.operator("clip.set_axis", text="Set Y Asix").axis = "Y" + + layout.operator("clip.set_scale") + + layout.separator() + + layout.operator("clip.track_to_empty") + layout.operator("clip.bundles_to_mesh") + + +class CLIP_MT_track_visibility(Menu): + bl_label = "Show/Hide" + + def draw(self, context): + layout = self.layout + + layout.operator("clip.hide_tracks_clear", text="Show Hidden") + layout.operator("clip.hide_tracks", text="Hide Selected") + + props = layout.operator("clip.hide_tracks", text="Hide Unselected") + props.unselected = True + + +class CLIP_MT_track_transform(Menu): + bl_label = "Transform" + + def draw(self, context): + layout = self.layout + + layout.operator("transform.translate") + layout.operator("transform.resize") + + +class CLIP_MT_select(Menu): + bl_label = "Select" + + def draw(self, context): + layout = self.layout + + sc = context.space_data + + layout.operator("clip.select_border") + layout.operator("clip.select_circle") + + layout.separator() + + layout.operator("clip.select_all", text="Select/Deselect all") + layout.operator("clip.select_all", text="Inverse").action = 'INVERT' + + layout.menu("CLIP_MT_select_grouped") + + +class CLIP_MT_select_grouped(Menu): + bl_label = "Select Grouped" + + def draw(self, context): + layout = self.layout + + layout.operator_enum("clip.select_grouped", "group") + + +class CLIP_MT_tracking_specials(Menu): + bl_label = "Specials" + + @classmethod + def poll(cls, context): + return context.space_data.clip + + def draw(self, context): + layout = self.layout + + props = layout.operator("clip.disable_markers", text="Enable Markers") + props.action = 'ENABLE' + + props = layout.operator("clip.disable_markers", text="Disable markers") + props.action = 'DISABLE' + + layout.separator() + layout.operator("clip.set_origin") + + layout.separator() + layout.operator("clip.hide_tracks") + layout.operator("clip.hide_tracks_clear", text="Show Tracks") + + layout.separator() + props = layout.operator("clip.lock_tracks", text="Lock Tracks") + props.action = 'LOCK' + + props = layout.operator("clip.lock_tracks", text="Unlock Tracks") + props.action = 'UNLOCK' + + +class CLIP_MT_camera_presets(Menu): + bl_label = "Camera Presets" + preset_subdir = "tracking_camera" + preset_operator = "script.execute_preset" + draw = bpy.types.Menu.draw_preset + + +class CLIP_MT_track_color_presets(Menu): + bl_label = "Color Presets" + preset_subdir = "tracking_track_color" + preset_operator = "script.execute_preset" + draw = bpy.types.Menu.draw_preset + + +class CLIP_MT_track_color_specials(Menu): + bl_label = "Track Color Specials" + + def draw(self, context): + layout = self.layout + + layout.operator('clip.track_copy_color', icon='COPY_ID') + + +class CLIP_MT_stabilize_2d_specials(Menu): + bl_label = "Track Color Specials" + + def draw(self, context): + layout = self.layout + + layout.operator('clip.stabilize_2d_select') + +if __name__ == "__main__": # only for live edit. + bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 6f8e6a574ec..5209e8be597 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -177,6 +177,7 @@ class TIME_MT_playback(Menu): layout.prop(screen, "use_play_image_editors") layout.prop(screen, "use_play_sequence_editors") layout.prop(screen, "use_play_node_editors") + layout.prop(screen, "use_play_clip_editors") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 7041e3f8c3d..9edb1ea1197 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2164,6 +2164,16 @@ class VIEW3D_PT_view3d_display(Panel): layout.separator() + layout.prop(view, "show_reconstruction") + if view.show_reconstruction: + layout.label(text="Bundle type:") + layout.prop(view, "bundle_draw_type", text="") + layout.prop(view, "bundle_draw_size") + layout.prop(view, "show_bundle_name") + layout.prop(view, "show_camera_path") + + layout.separator() + region = view.region_quadview layout.operator("screen.region_quadview", text="Toggle Quad View") @@ -2269,8 +2279,10 @@ class VIEW3D_PT_background_image(Panel): box = layout.box() row = box.row(align=True) row.prop(bg, "show_expanded", text="", emboss=False) - if bg.image: + if bg.source == 'IMAGE' and bg.image: row.prop(bg.image, "name", text="", emboss=False) + if bg.source == 'MOVIE' and bg.clip: + row.prop(bg.clip, "name", text="", emboss=False) else: row.label(text="Not Set") row.operator("view3d.background_image_remove", text="", emboss=False, icon='X').index = i @@ -2279,10 +2291,36 @@ class VIEW3D_PT_background_image(Panel): if bg.show_expanded: row = box.row() - row.template_ID(bg, "image", open="image.open") - if (bg.image): - box.template_image(bg, "image", bg.image_user, compact=True) + row.prop(bg, "source", expand=True) + hasbg = False + if bg.source == 'IMAGE': + row = box.row() + row.template_ID(bg, "image", open="image.open") + if (bg.image): + box.template_image(bg, "image", bg.image_user, compact=True) + hasbg = True + + elif bg.source == 'MOVIE': + has_clip = False + box.prop(bg, 'use_camera_clip') + + column = box.column() + column.active = not bg.use_camera_clip + column.template_ID(bg, "clip", open="clip.open") + + if bg.clip: + column.template_movieclip(bg, "clip", compact=True) + + if bg.use_camera_clip or bg.clip: + hasbg = True + + column = box.column() + column.active = hasbg + column.prop(bg.clip_user, "proxy_render_size", text="") + column.prop(bg.clip_user, "use_render_undistorted") + + if hasbg: box.prop(bg, "opacity", slider=True) if bg.view_axis != 'CAMERA': box.prop(bg, "size") diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 934579b8a8a..853303b9cb8 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -82,6 +82,8 @@ set(SRC_DNA_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_view3d_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_windowmanager_types.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_world_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_tracking_types.h ) add_subdirectory(editors) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index c065a210a98..0aefe2231a5 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -61,6 +61,7 @@ struct wmWindow; struct wmWindowManager; struct SpaceText; struct SpaceImage; +struct SpaceClip; struct ID; /* Structs */ @@ -158,6 +159,7 @@ struct SpaceIpo *CTX_wm_space_graph(const bContext *C); struct SpaceAction *CTX_wm_space_action(const bContext *C); struct SpaceInfo *CTX_wm_space_info(const bContext *C); struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C); +struct SpaceClip *CTX_wm_space_clip(const bContext *C); void CTX_wm_manager_set(bContext *C, struct wmWindowManager *wm); void CTX_wm_window_set(bContext *C, struct wmWindow *win); @@ -252,6 +254,7 @@ struct Object *CTX_data_edit_object(const bContext *C); struct Image *CTX_data_edit_image(const bContext *C); struct Text *CTX_data_edit_text(const bContext *C); +struct MovieClip *CTX_data_edit_movieclip(const bContext *C); int CTX_data_selected_nodes(const bContext *C, ListBase *list); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 308d7ff22c2..ade055ac457 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -64,7 +64,7 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id); struct ListBase *which_libbase(struct Main *mainlib, short type); -#define MAX_LIBARRAY 39 +#define MAX_LIBARRAY 40 int set_listbasepointers(struct Main *main, struct ListBase **lb); void free_libblock(struct ListBase *lb, void *idv); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index 2f587d3b29c..28eb59ebdb6 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -85,6 +85,7 @@ typedef struct Main { ListBase particle; ListBase wm; ListBase gpencil; + ListBase movieclip; char id_tag_update[256]; } Main; diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h new file mode 100644 index 00000000000..4d16df8afa3 --- /dev/null +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -0,0 +1,70 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_MOVIECLIP_H +#define BKE_MOVIECLIP_H + +/** \file BKE_movieclip.h + * \ingroup bke + * \author Sergey Sharybin + */ + +struct ImBuf; +struct Main; +struct MovieClip; +struct MovieClipScopes; +struct MovieClipUser; +struct MovieTrackingTrack; +struct MovieDistortion; + +void free_movieclip(struct MovieClip *clip); +void unlink_movieclip(struct Main *bmain, struct MovieClip *clip); + +struct MovieClip *BKE_add_movieclip_file(const char *name); +void BKE_movieclip_reload(struct MovieClip *clip); + +struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user); +struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, struct MovieClipUser *user, float loc[2], float *scale, float *angle); +struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, struct MovieClipUser *user, int flag); +void BKE_movieclip_get_size(struct MovieClip *clip, struct MovieClipUser *user, int *width, int *height); +void BKE_movieclip_aspect(struct MovieClip *clip, float *aspx, float *aspy); +int BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user); +void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr); + +void BKE_movieclip_select_track(struct MovieClip *clip, struct MovieTrackingTrack *track, int area, int extend); + +void BKE_movieclip_update_scopes(struct MovieClip *clip, struct MovieClipUser *user, struct MovieClipScopes *scopes); + +void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUser *user, int *totseg_r, int **points_r); + +void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, struct MovieDistortion *distortion, + int cfra, int *build_sizes, int build_count, int undistorted); + +#define TRACK_CLEAR_UPTO 0 +#define TRACK_CLEAR_REMAINED 1 +#define TRACK_CLEAR_ALL 2 + +#endif diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 9ccdd080158..2ef942a2e09 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -48,6 +48,7 @@ struct Group; struct bAction; struct RenderData; struct rctf; +struct MovieClip; void clear_workob(struct Object *workob); void what_does_parent(struct Scene *scene, struct Object *ob, struct Object *workob); @@ -99,6 +100,7 @@ struct Object *object_pose_armature_get(struct Object *ob); void where_is_object_time(struct Scene *scene, struct Object *ob, float ctime); void where_is_object(struct Scene *scene, struct Object *ob); void where_is_object_simul(struct Scene *scene, struct Object *ob); +void where_is_object_mat(struct Scene *scene, struct Object *ob, float obmat[4][4]); struct BoundBox *unit_boundbox(void); void boundbox_set_from_min_max(struct BoundBox *bb, float min[3], float max[3]); @@ -127,6 +129,8 @@ int object_is_modified(struct Scene *scene, struct Object *ob); void object_relink(struct Object *ob); +struct MovieClip *object_get_movieclip(struct Scene *scene, struct Object *ob, int use_default); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h new file mode 100644 index 00000000000..a8fb2c836de --- /dev/null +++ b/source/blender/blenkernel/BKE_tracking.h @@ -0,0 +1,145 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_TRACKING_H +#define BKE_TRACKING_H + +/** \file BKE_trackingp.h + * \ingroup bke + * \author Sergey Sharybin + */ + +struct bGPDlayer; +struct ImBuf; +struct MovieTrackingTrack; +struct MovieTrackingMarker; +struct MovieTracking; +struct MovieTrackingContext; +struct MovieClipUser; +struct MovieDistortion; +struct Camera; +struct Object; +struct Scene; + +void BKE_tracking_clamp_track(struct MovieTrackingTrack *track, int event); +void BKE_tracking_track_flag(struct MovieTrackingTrack *track, int area, int flag, int clear); + +struct MovieTrackingTrack *BKE_tracking_add_track(struct MovieTracking *tracking, float x, float y, + int framenr, int width, int height); +void BKE_tracking_insert_marker(struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); +void BKE_tracking_delete_marker(struct MovieTrackingTrack *track, int framenr); + +struct MovieTrackingMarker *BKE_tracking_get_marker(struct MovieTrackingTrack *track, int framenr); +struct MovieTrackingMarker *BKE_tracking_ensure_marker(struct MovieTrackingTrack *track, int framenr); +struct MovieTrackingMarker *BKE_tracking_exact_marker(struct MovieTrackingTrack *track, int framenr); +int BKE_tracking_has_marker(struct MovieTrackingTrack *track, int framenr); + +void BKE_tracking_free_track(struct MovieTrackingTrack *track); +struct MovieTrackingTrack *BKE_tracking_copy_track(struct MovieTrackingTrack *track); + +void BKE_tracking_clear_path(struct MovieTrackingTrack *track, int ref_frame, int action); + +int BKE_tracking_test_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); +void BKE_tracking_join_tracks(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); +void BKE_tracking_free(struct MovieTracking *tracking); + +struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); +struct ImBuf *BKE_tracking_get_search_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track, + struct MovieTrackingMarker *marker, int margin, int anchored, float pos[2], int origin[2]); + +void BKE_track_unique_name(struct MovieTracking *tracking, struct MovieTrackingTrack *track); + +struct MovieTrackingTrack *BKE_tracking_named_track(struct MovieTracking *tracking, const char *name); +struct MovieTrackingTrack *BKE_tracking_indexed_track(struct MovieTracking *tracking, int tracknr); + +void BKE_tracking_camera_shift(struct MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty); +void BKE_tracking_camera_to_blender(struct MovieTracking *tracking, struct Scene *scene, struct Camera *camera, int width, int height); + +void BKE_get_tracking_mat(struct Scene *scene, struct Object *ob, float mat[4][4]); +void BKE_tracking_projection_matrix(struct MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]); + +/* 2D tracking */ +struct MovieTrackingContext *BKE_tracking_context_new(struct MovieClip *clip, struct MovieClipUser *user, + short backwards, short disable_failed); +void BKE_tracking_context_free(struct MovieTrackingContext *context); +void BKE_tracking_sync(struct MovieTrackingContext *context); +void BKE_tracking_sync_user(struct MovieClipUser *user, struct MovieTrackingContext *context); +int BKE_tracking_next(struct MovieTrackingContext *context); + +/* Camera solving */ +float BKE_tracking_solve_reconstruction(struct MovieTracking *tracking, int width, int height); + +struct MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(struct MovieTracking *tracking, int framenr); +void BKE_tracking_get_interpolated_camera(struct MovieTracking *tracking, int framenr, float mat[4][4]); + +/* Feature detection */ +void BKE_tracking_detect_fast(struct MovieTracking *tracking, struct ImBuf *imbuf, + int framenr, int margin, int min_trackness, int min_distance, struct bGPDlayer *layer, + int place_outside_layer); + +/* 2D stabilization */ +void BKE_tracking_stabilization_data(struct MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle); +struct ImBuf *BKE_tracking_stabilize(struct MovieTracking *tracking, int framenr, struct ImBuf *ibuf, float loc[2], float *scale, float *angle); +void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4]); + +/* Distortion/Undistortion */ +void BKE_tracking_apply_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); +void BKE_tracking_invert_intrinsics(struct MovieTracking *tracking, float co[2], float nco[2]); + +struct MovieDistortion *BKE_tracking_distortion_create(void); +struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion); +struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking, + struct ImBuf *ibuf, int width, int height, float overscan, int undistort); +void BKE_tracking_distortion_destroy(struct MovieDistortion *distortion); + +struct ImBuf *BKE_tracking_undistort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); +struct ImBuf *BKE_tracking_distort(struct MovieTracking *tracking, struct ImBuf *ibuf, int width, int height, float overscan); + +/* Select */ +void BKE_tracking_select_track(struct MovieTracking *tracking, struct MovieTrackingTrack *track, int area, int extend); +void BKE_tracking_deselect_track(struct MovieTrackingTrack *track, int area); + +#define TRACK_SELECTED(track) ((((track)->flag&TRACK_HIDDEN)==0) && ((track)->flag&SELECT || (track)->pat_flag&SELECT || (track)->search_flag&SELECT)) +#define TRACK_AREA_SELECTED(track, area) ((((track)->flag&TRACK_HIDDEN)==0) && ((area)==TRACK_AREA_POINT?(track)->flag&SELECT : ((area)==TRACK_AREA_PAT?(track)->pat_flag&SELECT:(track)->search_flag&SELECT))) +#define TRACK_VIEW_SELECTED(sc, track) ((TRACK_AREA_SELECTED(track, TRACK_AREA_POINT) || (((sc)->flag&SC_SHOW_MARKER_PATTERN && TRACK_AREA_SELECTED(track, TRACK_AREA_PAT))) || (((sc)->flag&SC_SHOW_MARKER_SEARCH && TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH))))) + +#define MARKER_VISIBLE(sc, marker) (((marker)->flag&MARKER_DISABLED)==0 || ((sc)->flag&SC_HIDE_DISABLED)==0) + +#define CLAMP_PAT_DIM 1 +#define CLAMP_PAT_POS 2 +#define CLAMP_SEARCH_DIM 3 +#define CLAMP_SEARCH_POS 4 +#define CLAMP_PYRAMID_LEVELS 5 + +#define TRACK_AREA_NONE -1 +#define TRACK_AREA_POINT 1 +#define TRACK_AREA_PAT 2 +#define TRACK_AREA_SEARCH 4 + +#define TRACK_AREA_ALL (TRACK_AREA_POINT|TRACK_AREA_PAT|TRACK_AREA_SEARCH) + +#endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 78b1b52e52c..df4e247bc93 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -112,6 +112,7 @@ set(SRC intern/mesh.c intern/mesh_validate.c intern/modifier.c + intern/movieclip.c intern/multires.c intern/nla.c intern/node.c @@ -140,6 +141,7 @@ set(SRC intern/suggestions.c intern/text.c intern/texture.c + intern/tracking.c intern/unit.c intern/world.c intern/writeavi.c @@ -196,6 +198,7 @@ set(SRC BKE_mball.h BKE_mesh.h BKE_modifier.h + BKE_movieclip.h BKE_multires.h BKE_nla.h BKE_node.h @@ -222,6 +225,7 @@ set(SRC BKE_suggestions.h BKE_text.h BKE_texture.h + BKE_tracking.h BKE_unit.h BKE_utildefines.h BKE_world.h @@ -365,6 +369,11 @@ if(WITH_GAMEENGINE) add_definitions(-DWITH_GAMEENGINE) endif() +if(WITH_LIBMV) + list(APPEND INC ../../../extern/libmv) + add_definitions(-DWITH_LIBMV) +endif() + ## Warnings as errors, this is too strict! #if(MSVC) # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index ebb09352a55..48a68c433a6 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -96,6 +96,10 @@ if env['WITH_BF_GAMEENGINE']: else: sources.remove('intern' + os.sep + 'navmesh_conversion.c') +if env['WITH_BF_LIBMV']: + incs += ' #/extern/libmv' + defs.append('WITH_LIBMV') + if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8b5cf3bd196..f904d6e66df 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" #include "DNA_armature_types.h" +#include "DNA_camera_types.h" #include "DNA_constraint_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" @@ -51,15 +52,19 @@ #include "DNA_curve_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" + #include "DNA_lattice_types.h" #include "DNA_scene_types.h" #include "DNA_text_types.h" +#include "DNA_tracking_types.h" +#include "DNA_movieclip_types.h" #include "BKE_action.h" #include "BKE_anim.h" /* for the curve calculation part */ #include "BKE_armature.h" #include "BKE_blender.h" +#include "BKE_camera.h" #include "BKE_constraint.h" #include "BKE_displist.h" #include "BKE_deform.h" @@ -72,6 +77,8 @@ #include "BKE_idprop.h" #include "BKE_shrinkwrap.h" #include "BKE_mesh.h" +#include "BKE_tracking.h" +#include "BKE_movieclip.h" #ifdef WITH_PYTHON #include "BPY_extern.h" @@ -3924,6 +3931,203 @@ static bConstraintTypeInfo CTI_PIVOT = { pivotcon_evaluate /* evaluate */ }; +/* ----------- Follow Track ------------- */ + +static void followtrack_new_data (void *cdata) +{ + bFollowTrackConstraint *data= (bFollowTrackConstraint *)cdata; + + data->clip= NULL; + data->flag|= FOLLOWTRACK_ACTIVECLIP; + data->reference= FOLLOWTRACK_TRACK; +} + +static void followtrack_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bFollowTrackConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); +} + +static void followtrack_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bFollowTrackConstraint *data= con->data; + MovieClip *clip= data->clip; + MovieTrackingTrack *track; + + if(data->flag&FOLLOWTRACK_ACTIVECLIP) + clip= scene->clip; + + if(!clip || !data->track[0]) + return; + + track= BKE_tracking_named_track(&clip->tracking, data->track); + + if(!track) + return; + + if(data->reference==FOLLOWTRACK_BUNDLE) { + if(track->flag&TRACK_HAS_BUNDLE) { + float pos[3], mat[4][4], obmat[4][4]; + + copy_m4_m4(obmat, cob->matrix); + + BKE_get_tracking_mat(cob->scene, NULL, mat); + mul_v3_m4v3(pos, mat, track->bundle_pos); + + cob->matrix[3][0]+= pos[0]; + cob->matrix[3][1]+= pos[1]; + cob->matrix[3][2]+= pos[2]; + } + } else { + Object *camob= cob->scene->camera; + + if(camob) { + MovieClipUser user; + MovieTrackingMarker *marker; + float vec[3], disp[3], axis[3], mat[4][4]; + float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); + float sensor_x, sensor_y, lens, len, d, ortho_scale= 1.f; + + where_is_object_mat(scene, camob, mat); + + /* camera axis */ + vec[0]= 0.f; + vec[1]= 0.f; + vec[2]= 1.f; + mul_v3_m4v3(axis, mat, vec); + + /* distance to projection plane */ + copy_v3_v3(vec, cob->matrix[3]); + sub_v3_v3(vec, mat[3]); + project_v3_v3v3(disp, vec, axis); + + len= len_v3(disp); + + if(len>FLT_EPSILON) { + float pos[2], rmat[4][4], shiftx= 0.0f, shifty= 0.0f, clipsta= 0.0f, clipend= 0.0f; + short is_ortho= 0, sensor_fit= CAMERA_SENSOR_FIT_AUTO; + Camera *cam= NULL; + + user.framenr= scene->r.cfra; + marker= BKE_tracking_get_marker(track, user.framenr); + + add_v2_v2v2(pos, marker->pos, track->offset); + + object_camera_intrinsics(camob, &cam, &is_ortho, &shiftx, &shifty, &clipsta, &clipend, &lens, &sensor_x, &sensor_y, &sensor_fit); + + if(is_ortho) { + if(cam) + ortho_scale= cam->ortho_scale; + + vec[0]= ortho_scale * (pos[0]-0.5f+shiftx); + vec[1]= ortho_scale * (pos[1]-0.5f+shifty); + vec[2]= -len; + + if(aspect>1.f) vec[1]/= aspect; + else vec[0]*= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); + + copy_v3_v3(cob->matrix[3], disp); + } + else { + d= (len*sensor_x) / (2.f*lens); + + vec[0]= d*(2.f*(pos[0]+shiftx)-1.f); + vec[1]= d*(2.f*(pos[1]+shifty)-1.f); + vec[2]= -len; + + if(aspect>1.f) vec[1]/= aspect; + else vec[0]*= aspect; + + mul_v3_m4v3(disp, camob->obmat, vec); + + /* apply camera rotation so Z-axis would be co-linear */ + copy_m4_m4(rmat, camob->obmat); + zero_v3(rmat[3]); + mul_m4_m4m4(cob->matrix, rmat, cob->matrix); + + copy_v3_v3(cob->matrix[3], disp); + } + } + } + } +} + +static bConstraintTypeInfo CTI_FOLLOWTRACK = { + CONSTRAINT_TYPE_FOLLOWTRACK, /* type */ + sizeof(bFollowTrackConstraint), /* size */ + "Follow Track", /* name */ + "bFollowTrackConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + followtrack_id_looper, /* id looper */ + NULL, /* copy data */ + followtrack_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + followtrack_evaluate /* evaluate */ +}; + +/* ----------- Camre Solver ------------- */ + +static void camerasolver_new_data (void *cdata) +{ + bCameraSolverConstraint *data= (bCameraSolverConstraint *)cdata; + + data->clip= NULL; + data->flag|= CAMERASOLVER_ACTIVECLIP; +} + +static void camerasolver_id_looper (bConstraint *con, ConstraintIDFunc func, void *userdata) +{ + bCameraSolverConstraint *data= con->data; + + func(con, (ID**)&data->clip, userdata); +} + +static void camerasolver_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *UNUSED(targets)) +{ + Scene *scene= cob->scene; + bCameraSolverConstraint *data= con->data; + MovieClip *clip= data->clip; + + if(data->flag&CAMERASOLVER_ACTIVECLIP) + clip= scene->clip; + + if(clip) { + float mat[4][4], obmat[4][4]; + + BKE_tracking_get_interpolated_camera(&clip->tracking, scene->r.cfra, mat); + + copy_m4_m4(obmat, cob->matrix); + mul_m4_m4m4(cob->matrix, mat, obmat); + } +} + +static bConstraintTypeInfo CTI_CAMERASOLVER = { + CONSTRAINT_TYPE_CAMERASOLVER, /* type */ + sizeof(bCameraSolverConstraint), /* size */ + "Camera Solver", /* name */ + "bCameraSolverConstraint", /* struct name */ + NULL, /* free data */ + NULL, /* relink data */ + camerasolver_id_looper, /* id looper */ + NULL, /* copy data */ + camerasolver_new_data, /* new data */ + NULL, /* get constraint targets */ + NULL, /* flush constraint targets */ + NULL, /* get target matrix */ + camerasolver_evaluate /* evaluate */ +}; + /* ************************* Constraints Type-Info *************************** */ /* All of the constraints api functions use bConstraintTypeInfo structs to carry out * and operations that involve constraint specific code. @@ -3962,6 +4166,8 @@ static void constraints_init_typeinfo (void) constraintsTypeInfo[23]= &CTI_TRANSLIKE; /* Copy Transforms Constraint */ constraintsTypeInfo[24]= &CTI_SAMEVOL; /* Maintain Volume Constraint */ constraintsTypeInfo[25]= &CTI_PIVOT; /* Pivot Constraint */ + constraintsTypeInfo[26]= &CTI_FOLLOWTRACK; /* Follow Track Constraint */ + constraintsTypeInfo[27]= &CTI_CAMERASOLVER; /* Camera Solver Constraint */ } /* This function should be used for getting the appropriate type-info when only diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 18c08b617de..9e9a0ca2d54 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -361,6 +361,13 @@ struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C) return NULL; } +struct SpaceClip *CTX_wm_space_clip(const bContext *C) +{ + if(C->wm.area && C->wm.area->spacetype==SPACE_CLIP) + return C->wm.area->spacedata.first; + return NULL; +} + void CTX_wm_manager_set(bContext *C, wmWindowManager *wm) { C->wm.manager= wm; @@ -882,6 +889,11 @@ struct Text *CTX_data_edit_text(const bContext *C) return ctx_data_pointer_get(C, "edit_text"); } +struct MovieClip *CTX_data_edit_movieclip(const bContext *C) +{ + return ctx_data_pointer_get(C, "edit_movieclip"); +} + struct EditBone *CTX_data_active_bone(const bContext *C) { return ctx_data_pointer_get(C, "active_bone"); diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 51edee9ea71..79930fdd8bf 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -50,6 +50,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" +#include "DNA_movieclip_types.h" #include "BKE_animsys.h" #include "BKE_action.h" @@ -639,7 +640,26 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { + if(!cti) + continue; + + /* special case for camera tracking -- it doesn't use targets to define relations */ + if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) { + bFollowTrackConstraint *data= (bFollowTrackConstraint *)con->data; + + if((data->clip || data->flag&FOLLOWTRACK_ACTIVECLIP) && data->track[0]) { + if(scene->camera) { + node2 = dag_get_node(dag, scene->camera); + dag_add_relation(dag, node2, node, DAG_RL_DATA_OB|DAG_RL_OB_OB, cti->name); + } + } + } + + dag_add_relation(dag,scenenode,node,DAG_RL_SCENE, "Scene Relation"); + addtoroot = 0; + } + else if (cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); for (ct= targets.first; ct; ct= ct->next) { @@ -2127,18 +2147,25 @@ static void dag_object_time_update_flags(Object *ob) ListBase targets = {NULL, NULL}; bConstraintTarget *ct; - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - - for (ct= targets.first; ct; ct= ct->next) { - if (ct->tar) { - ob->recalc |= OB_RECALC_OB; - break; + if (cti) { + /* special case for camera tracking -- it doesn't use targets to define relations */ + if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + ob->recalc |= OB_RECALC_OB; + } + else if (cti->get_constraint_targets) { + cti->get_constraint_targets(con, &targets); + + for (ct= targets.first; ct; ct= ct->next) { + if (ct->tar) { + ob->recalc |= OB_RECALC_OB; + break; + } } + + if (cti->flush_constraint_targets) + cti->flush_constraint_targets(con, &targets, 1); } - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(con, &targets, 1); } } } @@ -2511,6 +2538,36 @@ static void dag_id_flush_update(Scene *sce, ID *id) BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH); } + if(idtype == ID_MC) { + for(obt=bmain->object.first; obt; obt= obt->id.next){ + bConstraint *con; + for (con = obt->constraints.first; con; con=con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + if(ELEM(cti->type, CONSTRAINT_TYPE_FOLLOWTRACK, CONSTRAINT_TYPE_CAMERASOLVER)) { + obt->recalc |= OB_RECALC_OB; + break; + } + } + } + + if(sce->nodetree) { + bNode *node; + + for(node= sce->nodetree->nodes.first; node; node= node->next) { + if(node->id==id) { + nodeUpdate(sce->nodetree, node); + } + } + } + } + + /* camera's matrix is used to orient reconstructed stuff, + so it should happen tracking-related constraints recalculation + when camera is changing (sergey) */ + if(sce->camera && &sce->camera->id == id && object_get_movieclip(sce, sce->camera, 1)) { + dag_id_flush_update(sce, &sce->clip->id); + } + /* update editors */ dag_editors_update(bmain, id); } diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c index d305499d3a1..0824a9f6685 100644 --- a/source/blender/blenkernel/intern/idcode.c +++ b/source/blender/blenkernel/intern/idcode.c @@ -78,6 +78,7 @@ static IDType idtypes[]= { { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE}, { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE}, { ID_WM, "WindowManager", "window_managers", 0}, + { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE}, }; static int nidtypes= sizeof(idtypes)/sizeof(idtypes[0]); diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 878b87759b7..650f85da5b3 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -70,6 +70,7 @@ #include "DNA_windowmanager_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_movieclip_types.h" #include "BLI_blenlib.h" #include "BLI_dynstr.h" @@ -111,6 +112,7 @@ #include "BKE_fcurve.h" #include "BKE_speaker.h" #include "BKE_utildefines.h" +#include "BKE_movieclip.h" #include "RNA_access.h" @@ -484,6 +486,8 @@ ListBase *which_libbase(Main *mainlib, short type) return &(mainlib->wm); case ID_GD: return &(mainlib->gpencil); + case ID_MC: + return &(mainlib->movieclip); } return NULL; } @@ -565,6 +569,7 @@ int set_listbasepointers(Main *main, ListBase **lb) lb[a++]= &(main->scene); lb[a++]= &(main->library); lb[a++]= &(main->wm); + lb[a++]= &(main->movieclip); lb[a]= NULL; @@ -673,6 +678,9 @@ static ID *alloc_libblock_notest(short type) case ID_GD: id = MEM_callocN(sizeof(bGPdata), "Grease Pencil"); break; + case ID_MC: + id = MEM_callocN(sizeof(MovieClip), "Movie Clip"); + break; } return id; } @@ -878,6 +886,9 @@ void free_libblock(ListBase *lb, void *idv) case ID_GD: free_gpencil_data((bGPdata *)id); break; + case ID_MC: + free_movieclip((MovieClip *)id); + break; } if (id->properties) { diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c new file mode 100644 index 00000000000..18a7ad65dae --- /dev/null +++ b/source/blender/blenkernel/intern/movieclip.c @@ -0,0 +1,1033 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/movieclip.c + * \ingroup bke + */ + + +#include +#include +#include + +#ifndef WIN32 +#include +#else +#include +#endif + +#include + +#ifdef _WIN32 +#define open _open +#define close _close +#endif + +#include "MEM_guardedalloc.h" + +#include "DNA_constraint_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BLI_utildefines.h" + +#include "BLI_blenlib.h" +#include "BLI_ghash.h" +#include "BLI_math.h" +#include "BLI_mempool.h" +#include "BLI_threads.h" + +#include "BKE_constraint.h" +#include "BKE_library.h" +#include "BKE_global.h" +#include "BKE_main.h" +#include "BKE_utildefines.h" +#include "BKE_movieclip.h" +#include "BKE_image.h" /* openanim */ +#include "BKE_tracking.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" +#include "IMB_moviecache.h" + +/*********************** movieclip buffer loaders *************************/ + +static int sequence_guess_offset(const char *full_name, int head_len, int numlen) +{ + char num[FILE_MAX]= {0}; + + BLI_strncpy(num, full_name+head_len, numlen+1); + + return atoi(num); +} + +static int rendersize_to_proxy(MovieClipUser *user, int flag) +{ + if((flag&MCLIP_USE_PROXY)==0) + return IMB_PROXY_NONE; + + switch(user->render_size) { + case MCLIP_PROXY_RENDER_SIZE_25: + return IMB_PROXY_25; + + case MCLIP_PROXY_RENDER_SIZE_50: + return IMB_PROXY_50; + + case MCLIP_PROXY_RENDER_SIZE_75: + return IMB_PROXY_75; + + case MCLIP_PROXY_RENDER_SIZE_100: + return IMB_PROXY_100; + + case MCLIP_PROXY_RENDER_SIZE_FULL: + return IMB_PROXY_NONE; + } + + return IMB_PROXY_NONE; +} + +static int rendersize_to_number(int render_size) +{ + switch(render_size) { + case MCLIP_PROXY_RENDER_SIZE_25: + return 25; + + case MCLIP_PROXY_RENDER_SIZE_50: + return 50; + + case MCLIP_PROXY_RENDER_SIZE_75: + return 75; + + case MCLIP_PROXY_RENDER_SIZE_100: + return 100; + + case MCLIP_PROXY_RENDER_SIZE_FULL: + return 100; + } + + return 100; +} + +static int get_timecode(MovieClip *clip, int flag) +{ + if((flag&MCLIP_USE_PROXY)==0) + return IMB_TC_NONE; + + return clip->proxy.tc; +} + +static void get_sequence_fname(MovieClip *clip, int framenr, char *name) +{ + unsigned short numlen; + char head[FILE_MAX], tail[FILE_MAX]; + int offset; + + BLI_strncpy(name, clip->name, sizeof(clip->name)); + BLI_stringdec(name, head, tail, &numlen); + + /* movieclips always points to first image from sequence, + autoguess offset for now. could be something smarter in the future */ + offset= sequence_guess_offset(clip->name, strlen(head), numlen); + + if(numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1); + else strncpy(name, clip->name, sizeof(name)); + + if(clip->id.lib) + BLI_path_abs(name, clip->id.lib->filepath); + else + BLI_path_abs(name, G.main->name); +} + +/* supposed to work with sequences only */ +static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistorted, int framenr, char *name) +{ + int size= rendersize_to_number(proxy_render_size); + char dir[FILE_MAX], clipdir[FILE_MAX], clipfile[FILE_MAX]; + + BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); + + if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) { + strcpy(dir, clip->proxy.dir); + } else { + BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir); + } + + if(undistorted) + BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d_undistorted/%08d", dir, clipfile, size, framenr); + else + BLI_snprintf(name, FILE_MAX, "%s/%s/proxy_%d/%08d", dir, clipfile, size, framenr); + + BLI_path_abs(name, G.main->name); + BLI_path_frame(name, 1, 0); + + strcat(name, ".jpg"); +} + +static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag) +{ + struct ImBuf *ibuf; + char name[FILE_MAX]; + int loadflag, size, undistort; + + size= rendersize_to_number(user->render_size); + + undistort= user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT; + + if((flag&MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL) + get_proxy_fname(clip, user->render_size, undistort, framenr, name); + else + get_sequence_fname(clip, framenr, name); + + loadflag= IB_rect|IB_multilayer; + + /* read ibuf */ + ibuf= IMB_loadiffname(name, loadflag); + + return ibuf; +} + +static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, int framenr, int flag) +{ + ImBuf *ibuf= NULL; + int tc= get_timecode(clip, flag); + int proxy= rendersize_to_proxy(user, flag); + char str[FILE_MAX]; + + if(!clip->anim) { + BLI_strncpy(str, clip->name, FILE_MAX); + + if(clip->id.lib) + BLI_path_abs(str, clip->id.lib->filepath); + else + BLI_path_abs(str, G.main->name); + + /* FIXME: make several stream accessible in image editor, too */ + clip->anim= openanim(str, IB_rect, 0); + + if(clip->anim) { + if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) { + char dir[FILE_MAX]; + strcpy(dir, clip->proxy.dir); + BLI_path_abs(dir, G.main->name); + IMB_anim_set_index_dir(clip->anim, dir); + } + } + } + + if(clip->anim) { + int dur; + int fra= framenr-1; + + dur= IMB_anim_get_duration(clip->anim, tc); + fra= framenr-1; + + if(fra<0) + fra= 0; + + if(fra>(dur-1)) + fra= dur-1; + + ibuf= IMB_anim_absolute(clip->anim, fra, tc, proxy); + } + + return ibuf; +} + +/*********************** image buffer cache *************************/ + +typedef struct MovieClipCache { + /* regular movie cache */ + struct MovieCache *moviecache; + + /* cache for stable shot */ + int stable_framenr; + float stable_loc[2], stable_scale, stable_angle; + ImBuf *stableibuf; + int proxy; + short render_flag; + + /* cache for undistorted shot */ + int undist_framenr; + float principal[2]; + float k1, k2, k3; + ImBuf *undistibuf; +} MovieClipCache; + +typedef struct MovieClipImBufCacheKey { + int framenr; + int proxy; + short render_flag; +} MovieClipImBufCacheKey; + +static void moviecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags) +{ + MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)userkey; + + *framenr= key->framenr; + *proxy= key->proxy; + *render_flags= key->render_flag; +} + +static unsigned int moviecache_hashhash(const void *keyv) +{ + MovieClipImBufCacheKey *key= (MovieClipImBufCacheKey*)keyv; + int rval= key->framenr; + + return rval; +} + +static int moviecache_hashcmp(const void *av, const void *bv) +{ + const MovieClipImBufCacheKey *a= (MovieClipImBufCacheKey*)av; + const MovieClipImBufCacheKey *b= (MovieClipImBufCacheKey*)bv; + + if(a->framenrframenr) return -1; + else if(a->framenr>b->framenr) return 1; + + if(a->proxyproxy) return -1; + else if(a->proxy>b->proxy) return 1; + + if(a->render_flagrender_flag) return -1; + else if(a->render_flag>b->render_flag) return 1; + + return 0; +} + +static ImBuf *get_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag) +{ + if(clip->cache) { + MovieClipImBufCacheKey key; + + key.framenr= user?user->framenr:clip->lastframe; + + if(flag&MCLIP_USE_PROXY) { + key.proxy= rendersize_to_proxy(user, flag); + key.render_flag= user->render_flag; + } + else { + key.proxy= IMB_PROXY_NONE; + key.render_flag= 0; + } + + return IMB_moviecache_get(clip->cache->moviecache, &key); + } + + return NULL; +} + +static void put_imbuf_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int flag) +{ + MovieClipImBufCacheKey key; + + if(!clip->cache) { + clip->cache= MEM_callocN(sizeof(MovieClipCache), "movieClipCache"); + + clip->cache->moviecache= IMB_moviecache_create(sizeof(MovieClipImBufCacheKey), moviecache_hashhash, + moviecache_hashcmp, moviecache_keydata); + } + + key.framenr= user?user->framenr:clip->lastframe; + + if(flag&MCLIP_USE_PROXY) { + key.proxy= rendersize_to_proxy(user, flag); + key.render_flag= user->render_flag; + } + else { + key.proxy= IMB_PROXY_NONE; + key.render_flag= 0; + } + + IMB_moviecache_put(clip->cache->moviecache, &key, ibuf); +} + +/*********************** common functions *************************/ + +/* only image block itself */ +static MovieClip *movieclip_alloc(const char *name) +{ + MovieClip *clip; + + clip= alloc_libblock(&G.main->movieclip, ID_MC, name); + + clip->aspx= clip->aspy= 1.0f; + + clip->tracking.camera.sensor_width= 35.0f; + clip->tracking.camera.pixel_aspect= 1.0f; + clip->tracking.camera.units= CAMERA_UNITS_MM; + + clip->tracking.settings.frames_limit= 0; + clip->tracking.settings.keyframe1= 1; + clip->tracking.settings.keyframe2= 30; + clip->tracking.settings.dist= 1; + + clip->tracking.stabilization.scaleinf= 1.0f; + clip->tracking.stabilization.locinf= 1.0f; + clip->tracking.stabilization.rotinf= 1.0f; + clip->tracking.stabilization.maxscale= 2.0f; + + clip->proxy.build_size_flag= IMB_PROXY_25; + clip->proxy.build_tc_flag= IMB_TC_RECORD_RUN|IMB_TC_FREE_RUN|IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN; + clip->proxy.quality= 90; + + return clip; +} + +/* checks if image was already loaded, then returns same image + otherwise creates new. + does not load ibuf itself + pass on optional frame for #name images */ +MovieClip *BKE_add_movieclip_file(const char *name) +{ + MovieClip *clip; + MovieClipUser user; + int file, len, width, height; + const char *libname; + char str[FILE_MAX], strtest[FILE_MAX]; + + BLI_strncpy(str, name, sizeof(str)); + BLI_path_abs(str, G.main->name); + + /* exists? */ + file= open(str, O_BINARY|O_RDONLY); + if(file== -1) return NULL; + close(file); + + /* ** first search an identical clip ** */ + for(clip= G.main->movieclip.first; clip; clip= clip->id.next) { + BLI_strncpy(strtest, clip->name, sizeof(clip->name)); + BLI_path_abs(strtest, G.main->name); + + if(strcmp(strtest, str)==0) { + BLI_strncpy(clip->name, name, sizeof(clip->name)); /* for stringcode */ + clip->id.us++; /* officially should not, it doesn't link here! */ + + return clip; + } + } + + /* ** add new movieclip ** */ + + /* create a short library name */ + len= strlen(name); + + while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--; + libname= name+len; + + clip= movieclip_alloc(libname); + BLI_strncpy(clip->name, name, sizeof(clip->name)); + + if(BLI_testextensie_array(name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE; + else clip->source= MCLIP_SRC_SEQUENCE; + + user.framenr= 1; + BKE_movieclip_get_size(clip, &user, &width, &height); + if(width && height) { + clip->tracking.camera.principal[0]= ((float)width)/2; + clip->tracking.camera.principal[1]= ((float)height)/2; + + clip->tracking.camera.focal= 24.0f*width/clip->tracking.camera.sensor_width; + } + + return clip; +} + +static void real_ibuf_size(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int *width, int *height) +{ + *width= ibuf->x; + *height= ibuf->y; + + if(clip->flag&MCLIP_USE_PROXY) { + switch(user->render_size) { + case MCLIP_PROXY_RENDER_SIZE_25: + (*width)*= 4; + (*height)*= 4; + break; + + case MCLIP_PROXY_RENDER_SIZE_50: + (*width)*= 2.0f; + (*height)*= 2.0f; + break; + + case MCLIP_PROXY_RENDER_SIZE_75: + *width= ((float)*width)*4.0f/3.0f; + *height= ((float)*height)*4.0f/3.0f; + break; + } + } +} + +static int need_undistorted_cache(MovieClipUser *user, int flag) +{ + if (!user) + return 0; + + /* only full undistorted render can be used as on-fly undistorting image */ + if(flag&MCLIP_USE_PROXY) { + if(user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL || (user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT)==0) + return 0; + } + else return 0; + + return 1; +} + +static ImBuf *get_undistorted_cache(MovieClip *clip, MovieClipUser *user) +{ + MovieClipCache *cache= clip->cache; + MovieTrackingCamera *camera= &clip->tracking.camera; + int framenr= user?user->framenr:clip->lastframe; + + /* no cache or no cached undistorted image */ + if(!clip->cache || !clip->cache->undistibuf) + return NULL; + + /* undistortion happened for other frame */ + if(cache->undist_framenr!=framenr) + return NULL; + + /* check for distortion model changes */ + if(!equals_v2v2(camera->principal, cache->principal)) + return NULL; + + if(!equals_v3v3(&camera->k1, &cache->k1)) + return NULL; + + IMB_refImBuf(cache->undistibuf); + + return cache->undistibuf; +} + +static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distoriton, ImBuf *ibuf) +{ + ImBuf *undistibuf; + + /* XXX: because of #27997 do not use float buffers to undistort, + otherwise, undistorted proxy can be darker than it should */ + imb_freerectfloatImBuf(ibuf); + + if(distoriton) + undistibuf= BKE_tracking_distortion_exec(distoriton, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); + else + undistibuf= BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); + + if(undistibuf->userflags|= IB_RECT_INVALID) { + ibuf->userflags&= ~IB_RECT_INVALID; + IMB_rect_from_float(undistibuf); + } + + IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); + + return undistibuf; +} + +static ImBuf *put_undistorted_cache(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf) +{ + MovieClipCache *cache= clip->cache; + MovieTrackingCamera *camera= &clip->tracking.camera; + + copy_v2_v2(cache->principal, camera->principal); + copy_v3_v3(&cache->k1, &camera->k1); + cache->undist_framenr= user?user->framenr:clip->lastframe; + + if(cache->undistibuf) + IMB_freeImBuf(cache->undistibuf); + + cache->undistibuf= get_undistorted_ibuf(clip, NULL, ibuf); + + if(cache->stableibuf) { + /* force stable buffer be re-calculated */ + IMB_freeImBuf(cache->stableibuf); + cache->stableibuf= NULL; + } + + IMB_refImBuf(cache->undistibuf); + + return cache->undistibuf; +} + +ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user) +{ + ImBuf *ibuf= NULL; + int framenr= user?user->framenr:clip->lastframe; + int cache_undistorted= 0; + + /* cache isn't threadsafe itself and also loading of movies + can't happen from concurent threads that's why we use lock here */ + BLI_lock_thread(LOCK_MOVIECLIP); + + /* try to obtain cached undistorted image first */ + if(need_undistorted_cache(user, clip->flag)) { + ibuf= get_undistorted_cache(clip, user); + if(!ibuf) + cache_undistorted= 1; + } + + if(!ibuf) + ibuf= get_imbuf_cache(clip, user, clip->flag); + + if(!ibuf) { + int use_sequence= 1; + + /* undistorted proxies for movies should be read as image sequence */ + use_sequence&= user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT; + use_sequence&= user->render_size!=MCLIP_PROXY_RENDER_SIZE_FULL; + + if(clip->source==MCLIP_SRC_SEQUENCE || use_sequence) + ibuf= movieclip_load_sequence_file(clip, user, framenr, clip->flag); + else { + ibuf= movieclip_load_movie_file(clip, user, framenr, clip->flag); + } + + if(ibuf) + put_imbuf_cache(clip, user, ibuf, clip->flag); + } + + if(ibuf) { + clip->lastframe= framenr; + real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]); + + /* put undistorted frame to cache */ + if(cache_undistorted) { + ImBuf *tmpibuf= ibuf; + ibuf= put_undistorted_cache(clip, user, tmpibuf); + IMB_freeImBuf(tmpibuf); + } + } + + BLI_unlock_thread(LOCK_MOVIECLIP); + + return ibuf; +} + +ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag) +{ + ImBuf *ibuf= NULL; + int framenr= user?user->framenr:clip->lastframe; + int cache_undistorted= 0; + + /* cache isn't threadsafe itself and also loading of movies + can't happen from concurent threads that's why we use lock here */ + BLI_lock_thread(LOCK_MOVIECLIP); + + /* try to obtain cached undistorted image first */ + if(need_undistorted_cache(user, flag)) { + ibuf= get_undistorted_cache(clip, user); + if(!ibuf) + cache_undistorted= 1; + } + + ibuf= get_imbuf_cache(clip, user, flag); + + if(!ibuf) { + if(clip->source==MCLIP_SRC_SEQUENCE) { + ibuf= movieclip_load_sequence_file(clip, user, framenr, flag); + } else { + ibuf= movieclip_load_movie_file(clip, user, framenr, flag); + } + + if(ibuf) { + int bits= MCLIP_USE_PROXY|MCLIP_USE_PROXY_CUSTOM_DIR; + + if((flag&bits)==(clip->flag&bits)) + put_imbuf_cache(clip, user, ibuf, clip->flag); + } + } + + /* put undistorted frame to cache */ + if(ibuf && cache_undistorted) { + ImBuf *tmpibuf= ibuf; + ibuf= put_undistorted_cache(clip, user, tmpibuf); + IMB_freeImBuf(tmpibuf); + } + + BLI_unlock_thread(LOCK_MOVIECLIP); + + return ibuf; +} + +ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, MovieClipUser *user, float loc[2], float *scale, float *angle) +{ + ImBuf *ibuf, *stableibuf= NULL; + int framenr= user?user->framenr:clip->lastframe; + + ibuf= BKE_movieclip_get_ibuf(clip, user); + + if(!ibuf) + return NULL; + + if(clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) { + float tloc[2], tscale, tangle; + short proxy= IMB_PROXY_NONE; + int render_flag= 0; + + if(clip->flag&MCLIP_USE_PROXY) { + proxy= rendersize_to_proxy(user, clip->flag); + render_flag= user->render_flag; + } + + if(clip->cache->stableibuf && clip->cache->stable_framenr==framenr) { /* there's cached ibuf */ + if(clip->cache->render_flag==render_flag && clip->cache->proxy==proxy) { /* cached ibuf used the same proxy settings */ + stableibuf= clip->cache->stableibuf; + + BKE_tracking_stabilization_data(&clip->tracking, framenr, stableibuf->x, stableibuf->y, tloc, &tscale, &tangle); + + /* check for stabilization parameters */ + if(!equals_v2v2(tloc, clip->cache->stable_loc) || tscale!=clip->cache->stable_scale || tangle!=clip->cache->stable_angle) { + stableibuf= NULL; + } + } + } + + if(!stableibuf) { + if(clip->cache->stableibuf) + IMB_freeImBuf(clip->cache->stableibuf); + + stableibuf= BKE_tracking_stabilize(&clip->tracking, framenr, ibuf, tloc, &tscale, &tangle); + + copy_v2_v2(clip->cache->stable_loc, tloc); + clip->cache->stable_scale= tscale; + clip->cache->stable_angle= tangle; + clip->cache->stable_framenr= framenr; + clip->cache->stableibuf= stableibuf; + clip->cache->proxy= proxy; + clip->cache->render_flag= render_flag; + } + + IMB_refImBuf(stableibuf); + + if(loc) copy_v2_v2(loc, tloc); + if(scale) *scale= tscale; + if(angle) *angle= tangle; + } else { + if(loc) zero_v2(loc); + if(scale) *scale= 1.0f; + if(angle) *angle= 0.0f; + + stableibuf= ibuf; + } + + if(stableibuf!=ibuf) { + IMB_freeImBuf(ibuf); + ibuf= stableibuf; + } + + return ibuf; + +} + +int BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user) +{ + ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user); + + if(ibuf) { + IMB_freeImBuf(ibuf); + return 1; + } + + return 0; +} + +void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height) +{ + if(!user || user->framenr==clip->lastframe) { + *width= clip->lastsize[0]; + *height= clip->lastsize[1]; + } else { + ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user); + + if(ibuf && ibuf->x && ibuf->y) { + real_ibuf_size(clip, user, ibuf, width, height); + } else { + *width= 0; + *height= 0; + } + + if(ibuf) + IMB_freeImBuf(ibuf); + } +} + +void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy) +{ + *aspx= *aspy= 1.0; + + /* x is always 1 */ + *aspy = clip->aspy/clip->aspx/clip->tracking.camera.pixel_aspect; +} + +/* get segments of cached frames. useful for debugging cache policies */ +void BKE_movieclip_get_cache_segments(MovieClip *clip, MovieClipUser *user, int *totseg_r, int **points_r) +{ + *totseg_r= 0; + *points_r= NULL; + + if(clip->cache) { + int proxy= rendersize_to_proxy(user, clip->flag); + + IMB_moviecache_get_cache_segments(clip->cache->moviecache, proxy, user->render_flag, totseg_r, points_r); + } +} + +void BKE_movieclip_user_set_frame(MovieClipUser *iuser, int framenr) +{ + /* TODO: clamp framenr here? */ + + iuser->framenr= framenr; +} + +static void free_buffers(MovieClip *clip) +{ + if(clip->cache) { + IMB_moviecache_free(clip->cache->moviecache); + + if(clip->cache->stableibuf) + IMB_freeImBuf(clip->cache->stableibuf); + + if(clip->cache->undistibuf) + IMB_freeImBuf(clip->cache->undistibuf); + + MEM_freeN(clip->cache); + clip->cache= NULL; + } + + if(clip->anim) { + IMB_free_anim(clip->anim); + clip->anim= FALSE; + } +} + +void BKE_movieclip_reload(MovieClip *clip) +{ + /* clear cache */ + free_buffers(clip); + + clip->tracking.stabilization.ok= 0; + + /* update clip source */ + if(BLI_testextensie_array(clip->name, imb_ext_movie)) clip->source= MCLIP_SRC_MOVIE; + else clip->source= MCLIP_SRC_SEQUENCE; +} + +void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) +{ + if(scopes->ok) return; + + if(scopes->track_preview) { + IMB_freeImBuf(scopes->track_preview); + scopes->track_preview= NULL; + } + + scopes->marker= NULL; + scopes->track= NULL; + + if(clip) { + if(clip->tracking.act_track) { + MovieTrackingTrack *track= clip->tracking.act_track; + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); + + if(marker->flag&MARKER_DISABLED) { + scopes->track_disabled= 1; + } else { + ImBuf *ibuf= BKE_movieclip_get_ibuf(clip, user); + + scopes->track_disabled= 0; + + if(ibuf && ibuf->rect) { + ImBuf *tmpibuf; + MovieTrackingMarker undist_marker= *marker; + + if(user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT) { + int width, height; + float aspy= 1.0f/clip->tracking.camera.pixel_aspect;; + + BKE_movieclip_get_size(clip, user, &width, &height); + + undist_marker.pos[0]*= width; + undist_marker.pos[1]*= height*aspy; + + BKE_tracking_invert_intrinsics(&clip->tracking, undist_marker.pos, undist_marker.pos); + + undist_marker.pos[0]/= width; + undist_marker.pos[1]/= height*aspy; + } + + tmpibuf= BKE_tracking_get_pattern_imbuf(ibuf, track, &undist_marker, 1, 1, scopes->track_pos, NULL); + + if(tmpibuf->rect_float) + IMB_rect_from_float(tmpibuf); + + if(tmpibuf->rect) + scopes->track_preview= tmpibuf; + else + IMB_freeImBuf(tmpibuf); + } + + IMB_freeImBuf(ibuf); + } + + if((track->flag&TRACK_LOCKED)==0) { + scopes->marker= marker; + scopes->track= track; + scopes->slide_scale[0]= track->pat_max[0]-track->pat_min[0]; + scopes->slide_scale[1]= track->pat_max[1]-track->pat_min[1]; + } + } + } + + scopes->framenr= user->framenr; + scopes->ok= 1; +} + +static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted) +{ + char name[FILE_MAXFILE+FILE_MAXDIR]; + int quality, rectx, recty; + int size= size= rendersize_to_number(proxy_render_size); + ImBuf *scaleibuf; + + get_proxy_fname(clip, proxy_render_size, undistorted, cfra, name); + + rectx= ibuf->x*size/100.0f; + recty= ibuf->y*size/100.0f; + + scaleibuf= IMB_dupImBuf(ibuf); + + IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty); + + quality= clip->proxy.quality; + scaleibuf->ftype= JPG | quality; + + /* unsupported feature only confuses other s/w */ + if(scaleibuf->depth==32) + scaleibuf->depth= 24; + + BLI_lock_thread(LOCK_MOVIECLIP); + + BLI_make_existing_file(name); + if(IMB_saveiff(scaleibuf, name, IB_rect)==0) + perror(name); + + BLI_unlock_thread(LOCK_MOVIECLIP); + + IMB_freeImBuf(scaleibuf); +} + +void BKE_movieclip_build_proxy_frame(MovieClip *clip, struct MovieDistortion *distortion, + int cfra, int *build_sizes, int build_count, int undistorted) +{ + ImBuf *ibuf; + MovieClipUser user; + + user.framenr= cfra; + + ibuf= BKE_movieclip_get_ibuf_flag(clip, &user, 0); + + if(ibuf) { + ImBuf *tmpibuf= ibuf; + int i; + + if(undistorted) + tmpibuf= get_undistorted_ibuf(clip, distortion, ibuf); + + for(i= 0; itracking); +} + +void unlink_movieclip(Main *bmain, MovieClip *clip) +{ + bScreen *scr; + ScrArea *area; + SpaceLink *sl; + Scene *sce; + Object *ob; + + for(scr= bmain->screen.first; scr; scr= scr->id.next) { + for(area= scr->areabase.first; area; area= area->next) { + for(sl= area->spacedata.first; sl; sl= sl->next) { + if(sl->spacetype==SPACE_CLIP) { + SpaceClip *sc= (SpaceClip *) sl; + + if(sc->clip==clip) + sc->clip= NULL; + } + else if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D *) sl; + BGpic *bgpic; + + for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) { + if(bgpic->clip==clip) + bgpic->clip= NULL; + } + } + } + } + } + + for(sce= bmain->scene.first; sce; sce= sce->id.next) { + if(sce->clip==clip) + sce->clip= NULL; + } + + for(ob= bmain->object.first; ob; ob= ob->id.next) { + bConstraint *con= ob->constraints.first; + + for (con= ob->constraints.first; con; con= con->next) { + bConstraintTypeInfo *cti= constraint_get_typeinfo(con); + + if(cti->type==CONSTRAINT_TYPE_FOLLOWTRACK) { + bFollowTrackConstraint *data= (bFollowTrackConstraint *) con->data; + + if(data->clip==clip) + data->clip= NULL; + } + else if(cti->type==CONSTRAINT_TYPE_CAMERASOLVER) { + bCameraSolverConstraint *data= (bCameraSolverConstraint *) con->data; + + if(data->clip==clip) + data->clip= NULL; + } + } + } + + clip->id.us= 0; +} diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 1d654839969..45bd8f095a4 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -46,6 +46,7 @@ #include "DNA_material_types.h" #include "DNA_meta_types.h" #include "DNA_meshdata_types.h" +#include "DNA_movieclip_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_sequence_types.h" @@ -1810,11 +1811,30 @@ void set_no_parent_ipo(int val) no_parent_ipo= val; } +static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4]) +{ + float *fp1, *fp2; + float fac1, fac2; + int a; + + // include framerate + fac1= ( 1.0f / (1.0f + (float)fabs(ob->sf)) ); + if(fac1 >= 1.0f) return 0; + fac2= 1.0f-fac1; + + fp1= obmat[0]; + fp2= slowmat[0]; + for(a=0; a<16; a++, fp1++, fp2++) { + fp1[0]= fac1*fp1[0] + fac2*fp2[0]; + } + + return 1; +} + void where_is_object_time(Scene *scene, Object *ob, float ctime) { - float *fp1, *fp2, slowmat[4][4] = MAT4_UNITY; - float stime=ctime, fac1, fac2; - int a; + float slowmat[4][4] = MAT4_UNITY; + float stime=ctime; /* new version: correct parent+vertexparent and track+parent */ /* this one only calculates direct attached parent and track */ @@ -1848,16 +1868,8 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) * An old-fashioned hack which probably doesn't really cut it anymore */ if(ob->partype & PARSLOW) { - // include framerate - fac1= ( 1.0f / (1.0f + (float)fabs(ob->sf)) ); - if(fac1 >= 1.0f) return; - fac2= 1.0f-fac1; - - fp1= ob->obmat[0]; - fp2= slowmat[0]; - for(a=0; a<16; a++, fp1++, fp2++) { - fp1[0]= fac1*fp1[0] + fac2*fp2[0]; - } + if(!where_is_object_parslow(ob, ob->obmat, slowmat)) + return; } } else { @@ -1881,6 +1893,27 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) else ob->transflag &= ~OB_NEG_SCALE; } +/* get object transformation matrix without recalculating dependencies and + constraints -- assume dependencies are already solved by depsgraph. + no changes to object and it's parent would be done. + used for bundles orientation in 3d space relative to parented blender camera */ +void where_is_object_mat(Scene *scene, Object *ob, float obmat[4][4]) +{ + float slowmat[4][4] = MAT4_UNITY; + + if(ob->parent) { + Object *par= ob->parent; + + solve_parenting(scene, ob, par, obmat, slowmat, 1); + + if(ob->partype & PARSLOW) + where_is_object_parslow(ob, obmat, slowmat); + } + else { + object_to_mat4(ob, obmat); + } +} + static void solve_parenting (Scene *scene, Object *ob, Object *par, float obmat[][4], float slowmat[][4], int simul) { float totmat[4][4]; @@ -2811,3 +2844,28 @@ void object_relink(Object *ob) ID_NEW(ob->proxy); ID_NEW(ob->proxy_group); } + +MovieClip *object_get_movieclip(Scene *scene, Object *ob, int use_default) +{ + MovieClip *clip= use_default ? scene->clip : NULL; + bConstraint *con= ob->constraints.first, *scon= NULL; + + while(con){ + if(con->type==CONSTRAINT_TYPE_CAMERASOLVER){ + if(scon==NULL || (scon->flag&CONSTRAINT_OFF)) + scon= con; + } + + con= con->next; + } + + if(scon) { + bCameraSolverConstraint *solver= scon->data; + if((solver->flag&CAMERASOLVER_ACTIVECLIP)==0) + clip= solver->clip; + else + clip= scene->clip; + } + + return clip; +} diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c new file mode 100644 index 00000000000..06a985e7d72 --- /dev/null +++ b/source/blender/blenkernel/intern/tracking.c @@ -0,0 +1,2168 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenkernel/intern/tracking.c + * \ingroup bke + */ + +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_gpencil_types.h" +#include "DNA_camera_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_math_base.h" +#include "BLI_listbase.h" +#include "BLI_ghash.h" +#include "BLI_path_util.h" + +#include "BKE_global.h" +#include "BKE_tracking.h" +#include "BKE_movieclip.h" +#include "BKE_object.h" +#include "BKE_scene.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#ifdef WITH_LIBMV +#include "libmv-capi.h" +#endif + +typedef struct MovieDistortion { + struct libmv_CameraIntrinsics *intrinsics; +} MovieDistortion; + +/*********************** common functions *************************/ + +void BKE_tracking_clamp_track(MovieTrackingTrack *track, int event) +{ + int a; + float pat_min[2]; + float pat_max[2]; + float max_pyramid_level_factor = 1.0; + if (track->tracker == TRACKER_KLT) { + max_pyramid_level_factor = 1 << (track->pyramid_levels - 1); + } + + /* sort */ + for(a= 0; a<2; a++) { + if(track->pat_min[a]>track->pat_max[a]) + SWAP(float, track->pat_min[a], track->pat_max[a]); + + if(track->search_min[a]>track->search_max[a]) + SWAP(float, track->search_min[a], track->search_max[a]); + } + + /* compute the effective pattern size, which differs from the fine resolution + * pattern size for the pyramid KLT tracker */ + for(a= 0; a<2; a++) { + pat_min[a] = max_pyramid_level_factor * track->pat_min[a]; + pat_max[a] = max_pyramid_level_factor * track->pat_max[a]; + } + + if(event==CLAMP_PAT_DIM) { + for(a= 0; a<2; a++) { + /* search shouldn't be resized smaller than pattern */ + track->search_min[a]= MIN2(pat_min[a], track->search_min[a]); + track->search_max[a]= MAX2(pat_max[a], track->search_max[a]); + } + } + else if(event==CLAMP_PAT_POS) { + float dim[2]; + sub_v2_v2v2(dim, track->pat_max, pat_min); + + for(a= 0; a<2; a++) { + /* pattern shouldn't be moved outside of search */ + if(pat_min[a] < track->search_min[a]) { + track->pat_min[a]= track->search_min[a] - (pat_min[a] - track->pat_min[a]); + track->pat_max[a]= (pat_min[a] - track->pat_min[a])+dim[a]; + } + if(track->pat_max[a] > track->search_max[a]) { + track->pat_max[a]= track->search_max[a] - (pat_max[a] - track->pat_max[a]); + track->pat_min[a]= track->pat_max[a]-dim[a] - (pat_min[a] - track->pat_min[a]); + } + } + } + else if(event==CLAMP_SEARCH_DIM) { + float max_pyramid_level_factor = 1.0; + if (track->tracker == TRACKER_KLT) { + max_pyramid_level_factor = 1 << (track->pyramid_levels - 1); + } + for(a= 0; a<2; a++) { + /* search shouldn't be resized smaller than pattern */ + track->search_min[a]= MIN2(pat_min[a], track->search_min[a]); + track->search_max[a]= MAX2(pat_max[a], track->search_max[a]); + } + } + else if(event==CLAMP_SEARCH_POS) { + float dim[2]; + sub_v2_v2v2(dim, track->search_max, track->search_min); + + for(a= 0; a<2; a++) { + /* search shouldn't be moved inside pattern */ + if(track->search_min[a] > pat_min[a]) { + track->search_min[a]= pat_min[a]; + track->search_max[a]= track->search_min[a]+dim[a]; + } + if(track->search_max[a] < pat_max[a]) { + track->search_max[a]= pat_max[a]; + track->search_min[a]= track->search_max[a]-dim[a]; + } + } + } + + else if(event==CLAMP_PYRAMID_LEVELS || (event==CLAMP_SEARCH_DIM && track->tracker == TRACKER_KLT)) { + float dim[2]; + sub_v2_v2v2(dim, track->pat_max, track->pat_min); + { + float search_ratio = 2.3f * max_pyramid_level_factor; + + /* resize the search area to something sensible based + * on the number of pyramid levels */ + for(a= 0; a<2; a++) { + track->search_min[a]= search_ratio * track->pat_min[a]; + track->search_max[a]= search_ratio * track->pat_max[a]; + } + } + } + + /* marker's center should be in center of pattern */ + if(event==CLAMP_PAT_DIM || event==CLAMP_PAT_POS) { + float dim[2]; + sub_v2_v2v2(dim, track->pat_max, track->pat_min); + + for(a= 0; a<2; a++) { + track->pat_min[a]= -dim[a]/2.0f; + track->pat_max[a]= dim[a]/2.0f; + } + } +} + +void BKE_tracking_track_flag(MovieTrackingTrack *track, int area, int flag, int clear) +{ + if(area==TRACK_AREA_NONE) + return; + + if(clear) { + if(area&TRACK_AREA_POINT) track->flag&= ~flag; + if(area&TRACK_AREA_PAT) track->pat_flag&= ~flag; + if(area&TRACK_AREA_SEARCH) track->search_flag&= ~flag; + } else { + if(area&TRACK_AREA_POINT) track->flag|= flag; + if(area&TRACK_AREA_PAT) track->pat_flag|= flag; + if(area&TRACK_AREA_SEARCH) track->search_flag|= flag; + } +} + +MovieTrackingTrack *BKE_tracking_add_track(MovieTracking *tracking, float x, float y, + int framenr, int width, int height) +{ + MovieTrackingTrack *track; + MovieTrackingMarker marker; + + /* pick reasonable defaults */ + float pat[2]= {5.5f, 5.5f}, search[2]= {25.5f, 25.5f}; /* TODO: move to default setting? */ + + pat[0] /= (float)width; + pat[1] /= (float)height; + + search[0] /= (float)width; + search[1] /= (float)height; + + track= MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track"); + strcpy(track->name, "Track"); + + /* default to KLT tracker */ + track->tracker = TRACKER_KLT; + track->pyramid_levels = 2; + + /* set SAD defaults even though it's not selected by default */ + track->minimum_correlation= 0.75f; + + memset(&marker, 0, sizeof(marker)); + marker.pos[0]= x; + marker.pos[1]= y; + marker.framenr= framenr; + + copy_v2_v2(track->pat_max, pat); + negate_v2_v2(track->pat_min, pat); + + copy_v2_v2(track->search_max, search); + negate_v2_v2(track->search_min, search); + + BKE_tracking_insert_marker(track, &marker); + + BLI_addtail(&tracking->tracks, track); + BKE_track_unique_name(tracking, track); + + return track; +} + +void BKE_tracking_insert_marker(MovieTrackingTrack *track, MovieTrackingMarker *marker) +{ + MovieTrackingMarker *old_marker= BKE_tracking_get_marker(track, marker->framenr); + + if(old_marker && old_marker->framenr==marker->framenr) { + *old_marker= *marker; + } else { + int a= track->markersnr; + + while(a--) { + if(track->markers[a].framenrframenr) + break; + } + + track->markersnr++; + + if(track->markers) track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + else track->markers= MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers"); + + memmove(track->markers+a+2, track->markers+a+1, (track->markersnr-a-2)*sizeof(MovieTrackingMarker)); + track->markers[a+1]= *marker; + + track->last_marker= a+1; + } +} + +void BKE_tracking_delete_marker(MovieTrackingTrack *track, int framenr) +{ + int a= 0; + + while(amarkersnr) { + if(track->markers[a].framenr==framenr) { + if(track->markersnr>1) { + memmove(track->markers+a, track->markers+a+1, (track->markersnr-a-1)*sizeof(MovieTrackingMarker)); + track->markersnr--; + track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + } else { + MEM_freeN(track->markers); + track->markers= NULL; + track->markersnr= 0; + } + + break; + } + + a++; + } +} + +MovieTrackingMarker *BKE_tracking_get_marker(MovieTrackingTrack *track, int framenr) +{ + int a= track->markersnr-1; + + if(!track->markersnr) + return NULL; + + /* approximate pre-first framenr marker with first marker */ + if(framenrmarkers[0].framenr) + return &track->markers[0]; + + if(track->last_markermarkersnr) + a= track->last_marker; + + if(track->markers[a].framenr<=framenr) { + while(amarkersnr && track->markers[a].framenr<=framenr) { + if(track->markers[a].framenr==framenr) { + track->last_marker= a; + return &track->markers[a]; + } + a++; + } + + /* if there's no marker for exact position, use nearest marker from left side */ + return &track->markers[a-1]; + } else { + while(a>=0 && track->markers[a].framenr>=framenr) { + if(track->markers[a].framenr==framenr) { + track->last_marker= a; + return &track->markers[a]; + } + + a--; + } + + /* if there's no marker for exact position, use nearest marker from left side */ + return &track->markers[a]; + } + + return NULL; +} + +MovieTrackingMarker *BKE_tracking_ensure_marker(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); + + if(marker && marker->framenr!=framenr) { + MovieTrackingMarker marker_new; + + marker_new= *marker; + marker_new.framenr= framenr; + + BKE_tracking_insert_marker(track, &marker_new); + marker= BKE_tracking_get_marker(track, framenr); + } + + return marker; +} + +MovieTrackingMarker *BKE_tracking_exact_marker(MovieTrackingTrack *track, int framenr) +{ + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); + + if(marker && marker->framenr!=framenr) + return NULL; + + return marker; +} + +int BKE_tracking_has_marker(MovieTrackingTrack *track, int framenr) +{ + return BKE_tracking_exact_marker(track, framenr) != 0; +} + +void BKE_tracking_free_track(MovieTrackingTrack *track) +{ + if(track->markers) MEM_freeN(track->markers); +} + +MovieTrackingTrack *BKE_tracking_copy_track(MovieTrackingTrack *track) +{ + MovieTrackingTrack *new_track= MEM_dupallocN(track); + + new_track->next= new_track->prev= NULL; + + if(new_track->markers) + new_track->markers= MEM_dupallocN(new_track->markers); + + return new_track; +} + +static void put_disabled_marker(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker, int before, int overwrite) +{ + MovieTrackingMarker marker_new; + + marker_new= *ref_marker; + marker_new.flag&= ~MARKER_TRACKED; + marker_new.flag|= MARKER_DISABLED; + + if(before) marker_new.framenr--; + else marker_new.framenr++; + + if(!BKE_tracking_has_marker(track, marker_new.framenr) || overwrite) + BKE_tracking_insert_marker(track, &marker_new); +} + +void BKE_tracking_clear_path(MovieTrackingTrack *track, int ref_frame, int action) +{ + int a; + + if(action==TRACK_CLEAR_REMAINED) { + a= 1; + while(amarkersnr) { + if(track->markers[a].framenr>ref_frame) { + track->markersnr= a; + track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + + break; + } + + a++; + } + + if(track->markersnr) + put_disabled_marker(track, &track->markers[track->markersnr-1], 0, 1); + } else if(action==TRACK_CLEAR_UPTO) { + a= track->markersnr-1; + while(a>=0) { + if(track->markers[a].framenr<=ref_frame) { + memmove(track->markers, track->markers+a, (track->markersnr-a)*sizeof(MovieTrackingMarker)); + + track->markersnr= track->markersnr-a; + track->markers= MEM_reallocN(track->markers, sizeof(MovieTrackingMarker)*track->markersnr); + + break; + } + + a--; + } + + if(track->markersnr) + put_disabled_marker(track, &track->markers[0], 1, 1); + } else if(action==TRACK_CLEAR_ALL) { + MovieTrackingMarker *marker, marker_new; + + marker= BKE_tracking_get_marker(track, ref_frame); + marker_new= *marker; + + MEM_freeN(track->markers); + track->markers= NULL; + track->markersnr= 0; + + BKE_tracking_insert_marker(track, &marker_new); + + put_disabled_marker(track, &marker_new, 1, 1); + put_disabled_marker(track, &marker_new, 0, 1); + } +} + +int BKE_tracking_test_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +{ + int i, a= 0, b= 0, tot= dst_track->markersnr+src_track->markersnr; + int count= 0; + + for(i= 0; i=src_track->markersnr) { + b++; + count++; + } + else if(b>=dst_track->markersnr) { + a++; + count++; + } + else if(src_track->markers[a].framenrmarkers[b].framenr) { + a++; + count++; + } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) { + b++; + count++; + } else { + if((src_track->markers[a].flag&MARKER_DISABLED)==0 && (dst_track->markers[b].flag&MARKER_DISABLED)==0) + return 0; + + a++; + b++; + count++; + } + } + + return count; +} + +void BKE_tracking_join_tracks(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +{ + int i, a= 0, b= 0, tot; + MovieTrackingMarker *markers; + + tot= BKE_tracking_test_join_tracks(dst_track, src_track); + + markers= MEM_callocN(tot*sizeof(MovieTrackingMarker), "tracking joined tracks"); + + for(i= 0; i=dst_track->markersnr) { + markers[i]= src_track->markers[a++]; + } + else if(a>=src_track->markersnr) { + markers[i]= dst_track->markers[b++]; + } + else if(src_track->markers[a].framenrmarkers[b].framenr) { + markers[i]= src_track->markers[a++]; + } else if(src_track->markers[a].framenr>dst_track->markers[b].framenr) { + markers[i]= dst_track->markers[b++]; + } else { + if((src_track->markers[a].flag&MARKER_DISABLED)) markers[i]= dst_track->markers[b]; + else markers[i]= src_track->markers[a++]; + + a++; + b++; + } + } + + MEM_freeN(dst_track->markers); + + dst_track->markers= markers; + dst_track->markersnr= tot; +} + +void BKE_tracking_free(MovieTracking *tracking) +{ + MovieTrackingTrack *track; + + for(track= tracking->tracks.first; track; track= track->next) { + BKE_tracking_free_track(track); + } + + BLI_freelistN(&tracking->tracks); + + if(tracking->reconstruction.cameras) + MEM_freeN(tracking->reconstruction.cameras); + + if(tracking->stabilization.scaleibuf) + IMB_freeImBuf(tracking->stabilization.scaleibuf); + + if(tracking->camera.intrinsics) + BKE_tracking_distortion_destroy(tracking->camera.intrinsics); +} + +/*********************** tracking *************************/ + +typedef struct TrackContext { + MovieTrackingTrack *track; + +#ifdef WITH_LIBMV + float keyframed_pos[2]; + + /* ** KLT tracker ** */ + struct libmv_RegionTracker *region_tracker; + float *patch; /* keyframed patch */ + + /* ** SAD tracker ** */ + int patsize; /* size of pattern (currently only 16x16 due to libmv side) */ + unsigned char *pattern; /* keyframed pattern */ + unsigned char *warped; /* warped version of reference */ +#endif +} TrackContext; + +typedef struct MovieTrackingContext { + MovieClipUser user; + MovieClip *clip; + + int first_time, frames; + + TrackContext *track_context; + int num_tracks; + + GHash *hash; + MovieTrackingSettings settings; + + short backwards, disable_failed; + int sync_frame; +} MovieTrackingContext; + +MovieTrackingContext *BKE_tracking_context_new(MovieClip *clip, MovieClipUser *user, short backwards, short disable_failed) +{ + MovieTrackingContext *context= MEM_callocN(sizeof(MovieTrackingContext), "trackingContext"); + MovieTracking *tracking= &clip->tracking; + MovieTrackingSettings *settings= &tracking->settings; + MovieTrackingTrack *track; + TrackContext *track_context; + + context->settings= *settings; + context->backwards= backwards; + context->disable_failed= disable_failed; + context->hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "tracking trackHash"); + context->sync_frame= user->framenr; + context->first_time= 1; + + /* count */ + track= tracking->tracks.first; + while(track) { + if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); + + if((marker->flag&MARKER_DISABLED)==0) + context->num_tracks++; + } + + track= track->next; + } + + if(context->num_tracks) { + int width, height; + + BKE_movieclip_get_size(clip, user, &width, &height); + + /* create tracking data */ + context->track_context= MEM_callocN(sizeof(TrackContext)*context->num_tracks, "tracking track_context"); + + track_context= context->track_context; + track= tracking->tracks.first; + while(track) { + if(TRACK_SELECTED(track) && (track->flag&TRACK_LOCKED)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, user->framenr); + + if((marker->flag&MARKER_DISABLED)==0) { + MovieTrackingTrack *new_track= BKE_tracking_copy_track(track); + + track_context->track= new_track; +#ifdef WITH_LIBMV + { + if(track_context->track->tracker==TRACKER_KLT) { + float search_size_x= (track->search_max[0]-track->search_min[0])*width; + float search_size_y= (track->search_max[1]-track->search_min[1])*height; + float pattern_size_x= (track->pat_max[0]-track->pat_min[0])*width; + float pattern_size_y= (track->pat_max[1]-track->pat_min[1])*height; + + /* compute the maximum pyramid size */ + double search_to_pattern_ratio= MIN2(search_size_x, search_size_y) + / MAX2(pattern_size_x, pattern_size_y); + double log2_search_to_pattern_ratio = log(floor(search_to_pattern_ratio)) / M_LN2; + int max_pyramid_levels= floor(log2_search_to_pattern_ratio + 1); + + /* try to accomodate the user's choice of pyramid level in a way + * that doesn't cause the coarsest pyramid pattern to be larger + * than the search size */ + int level= MIN2(track_context->track->pyramid_levels, max_pyramid_levels); + track_context->region_tracker= libmv_regionTrackerNew(100, level); + } + else if(track_context->track->tracker==TRACKER_SAD) { + /* nothing to initialize */ + } + } +#endif + + BLI_ghash_insert(context->hash, new_track, track); + + track_context++; + } + } + + track= track->next; + } + } + + context->clip= clip; + context->user= *user; + + return context; +} + +void BKE_tracking_context_free(MovieTrackingContext *context) +{ + int a; + TrackContext *track_context; + + for(a= 0, track_context= context->track_context; anum_tracks; a++, track_context++) { + BKE_tracking_free_track(context->track_context[a].track); + +#if WITH_LIBMV + if(track_context->region_tracker) + libmv_regionTrackerDestroy(track_context->region_tracker); + + if(track_context->patch) + MEM_freeN(track_context->patch); + + if(track_context->pattern) + MEM_freeN(track_context->pattern); + + if(track_context->warped) + MEM_freeN(track_context->warped); +#endif + + MEM_freeN(track_context->track); + } + + if(context->track_context) + MEM_freeN(context->track_context); + + BLI_ghash_free(context->hash, NULL, NULL); + + MEM_freeN(context); +} + +static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track) +{ + int x, y; + + if((track->flag&(TRACK_DISABLE_RED|TRACK_DISABLE_GREEN|TRACK_DISABLE_BLUE))==0) + return; + + for(y= 0; yy; y++) { + for (x= 0; xx; x++) { + int pixel= ibuf->x*y + x; + + if(ibuf->rect_float) { + float *rrgbf= ibuf->rect_float + pixel*4; + + if(track->flag&TRACK_DISABLE_RED) rrgbf[0]= 0; + if(track->flag&TRACK_DISABLE_GREEN) rrgbf[1]= 0; + if(track->flag&TRACK_DISABLE_BLUE) rrgbf[2]= 0; + } else { + char *rrgb= (char*)ibuf->rect + pixel*4; + + if(track->flag&TRACK_DISABLE_RED) rrgb[0]= 0; + if(track->flag&TRACK_DISABLE_GREEN) rrgb[1]= 0; + if(track->flag&TRACK_DISABLE_BLUE) rrgb[2]= 0; + } + } + } +} + +static ImBuf *get_area_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + float min[2], float max[2], int margin, int anchored, float pos[2], int origin[2]) +{ + ImBuf *tmpibuf; + int x, y; + int x1, y1, x2, y2, w, h; + float mpos[2]; + + copy_v2_v2(mpos, marker->pos); + if(anchored) + add_v2_v2(mpos, track->offset); + + x= mpos[0]*ibuf->x; + y= mpos[1]*ibuf->y; + x1= x-(int)(-min[0]*ibuf->x); + y1= y-(int)(-min[1]*ibuf->y); + x2= x+(int)(max[0]*ibuf->x); + y2= y+(int)(max[1]*ibuf->y); + + /* dimensions should be odd */ + w= (x2-x1)|1; + h= (y2-y1)|1; + + tmpibuf= IMB_allocImBuf(w+margin*2, h+margin*2, 32, IB_rect); + IMB_rectcpy(tmpibuf, ibuf, 0, 0, x1-margin, y1-margin, w+margin*2, h+margin*2); + + if(pos != NULL) { + pos[0]= mpos[0]*ibuf->x-x1+margin; + pos[1]= mpos[1]*ibuf->y-y1+margin; + } + + if(origin != NULL) { + origin[0]= x1-margin; + origin[1]= y1-margin; + } + + disable_imbuf_channels(tmpibuf, track); + + return tmpibuf; +} + +ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int margin, int anchored, float pos[2], int origin[2]) +{ + return get_area_imbuf(ibuf, track, marker, track->pat_min, track->pat_max, margin, anchored, pos, origin); +} + +ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int margin, int anchored, float pos[2], int origin[2]) +{ + return get_area_imbuf(ibuf, track, marker, track->search_min, track->search_max, margin, anchored, pos, origin); +} + +#ifdef WITH_LIBMV +static float *get_search_floatbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int *width_r, int *height_r, float pos[2], int origin[2]) +{ + ImBuf *tmpibuf; + float *pixels, *fp; + int x, y, width, height; + + width= (track->search_max[0]-track->search_min[0])*ibuf->x; + height= (track->search_max[1]-track->search_min[1])*ibuf->y; + + tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); + disable_imbuf_channels(tmpibuf, track); + + *width_r= width; + *height_r= height; + + fp= pixels= MEM_callocN(width*height*sizeof(float), "tracking floatBuf"); + for(y= 0; y<(int)height; y++) { + for (x= 0; x<(int)width; x++) { + int pixel= tmpibuf->x*y + x; + + if(tmpibuf->rect_float) { + float *rrgbf= tmpibuf->rect_float + pixel*4; + + *fp= 0.2126*rrgbf[0] + 0.7152*rrgbf[1] + 0.0722*rrgbf[2]; + } else { + unsigned char *rrgb= (unsigned char*)tmpibuf->rect + pixel*4; + + *fp= (0.2126*rrgb[0] + 0.7152*rrgb[1] + 0.0722*rrgb[2])/255.0f; + } + + fp++; + } + } + + IMB_freeImBuf(tmpibuf); + + return pixels; +} + +static unsigned char *get_ucharbuf(ImBuf *ibuf) +{ + int x, y; + unsigned char *pixels, *cp; + + cp= pixels= MEM_callocN(ibuf->x*ibuf->y*sizeof(unsigned char), "tracking ucharBuf"); + for(y= 0; yy; y++) { + for (x= 0; xx; x++) { + int pixel= ibuf->x*y + x; + + if(ibuf->rect_float) { + float *rrgbf= ibuf->rect_float + pixel*4; + + *cp= FTOCHAR(0.2126f*rrgbf[0] + 0.7152f*rrgbf[1] + 0.0722f*rrgbf[2]); + } else { + unsigned char *rrgb= (unsigned char*)ibuf->rect + pixel*4; + + *cp= 0.2126f*rrgb[0] + 0.7152f*rrgb[1] + 0.0722f*rrgb[2]; + } + + cp++; + } + } + + return pixels; +} + +static unsigned char *get_search_bytebuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int *width_r, int *height_r, float pos[2], int origin[2]) +{ + ImBuf *tmpibuf; + unsigned char *pixels; + + tmpibuf= BKE_tracking_get_search_imbuf(ibuf, track, marker, 0, 0, pos, origin); + disable_imbuf_channels(tmpibuf, track); + + *width_r= tmpibuf->x; + *height_r= tmpibuf->y; + + pixels= get_ucharbuf(tmpibuf); + + IMB_freeImBuf(tmpibuf); + + return pixels; +} + +static ImBuf *get_frame_ibuf(MovieTrackingContext *context, int framenr) +{ + ImBuf *ibuf; + int framenr_old= context->user.framenr; + + context->user.framenr= framenr; + + ibuf= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0); + + context->user.framenr= framenr_old; + + return ibuf; +} + +static ImBuf *get_keyframed_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, + MovieTrackingMarker *marker, MovieTrackingMarker **marker_keyed) +{ + int framenr= marker->framenr; + int a= marker-track->markers; + + *marker_keyed= marker; + + while(a>=0 && amarkersnr) { + int next= (context->backwards) ? a+1 : a-1; + int is_keyframed= 0; + MovieTrackingMarker *marker= &track->markers[a]; + MovieTrackingMarker *next_marker= NULL; + + if(next>=0 && nextmarkersnr) + next_marker= &track->markers[next]; + + /* if next mrker is disabled, stop searching keyframe and use current frame as keyframe */ + if(next_marker && next_marker->flag&MARKER_DISABLED) + is_keyframed= 1; + + is_keyframed|= (marker->flag&MARKER_TRACKED)==0; + + if(is_keyframed) { + framenr= marker->framenr; + *marker_keyed= marker; + break; + } + + a= next; + } + + return get_frame_ibuf(context, framenr); +} + +static ImBuf *get_adjust_ibuf(MovieTrackingContext *context, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int curfra, MovieTrackingMarker **marker_keyed) +{ + ImBuf *ibuf= NULL; + + if(context->settings.adjframes == 0) { + ibuf= get_keyframed_ibuf(context, track, marker, marker_keyed); + } else { + ibuf= get_frame_ibuf(context, curfra); + + /* use current marker as keyframed position */ + *marker_keyed= marker; + } + + return ibuf; +} + +static void get_warped(TrackContext *track_context, int x, int y, int width, unsigned char *image) +{ + int i, j; + + for(i=0; ipatsize; i++) { + for(j=0; jpatsize; j++) { + track_context->warped[i*track_context->patsize+j]= + image[(y+i-track_context->patsize/2)*width+x+j-track_context->patsize/2]; + } + } +} + +#endif + +void BKE_tracking_sync(MovieTrackingContext *context) +{ + TrackContext *track_context; + MovieTracking *tracking= &context->clip->tracking; + MovieTrackingTrack *track; + ListBase tracks= {NULL, NULL}, new_tracks= {NULL, NULL}; + ListBase *old_tracks= &context->clip->tracking.tracks; + int a, newframe; + + /* duplicate currently tracking tracks to temporary list. + this is needed to keep names in unique state and it's faster to change names + of currently tracking tracks (if needed) */ + for(a= 0, track_context= context->track_context; anum_tracks; a++, track_context++) { + int replace_sel= 0; + MovieTrackingTrack *new_track, *old; + + track= track_context->track; + + /* find original of tracking track in list of previously displayed tracks */ + old= BLI_ghash_lookup(context->hash, track); + if(old) { + MovieTrackingTrack *cur= old_tracks->first; + + while(cur) { + if(cur==old) + break; + + cur= cur->next; + } + + /* original track was found, re-use flags and remove this track */ + if(cur) { + if(cur==tracking->act_track) + replace_sel= 1; + + track->flag= cur->flag; + track->pat_flag= cur->pat_flag; + track->search_flag= cur->search_flag; + + BKE_tracking_free_track(cur); + BLI_freelinkN(old_tracks, cur); + } + } + + new_track= BKE_tracking_copy_track(track); + + BLI_ghash_remove(context->hash, track, NULL, NULL); /* XXX: are we actually need this */ + BLI_ghash_insert(context->hash, track, new_track); + + if(replace_sel) /* update current selection in clip */ + tracking->act_track= new_track; + + BLI_addtail(&tracks, new_track); + } + + /* move all tracks, which aren't tracking */ + track= old_tracks->first; + while(track) { + MovieTrackingTrack *next= track->next; + + track->next= track->prev= NULL; + BLI_addtail(&new_tracks, track); + + track= next; + } + + /* now move all tracks which are currently tracking and keep their names unique */ + track= tracks.first; + while(track) { + MovieTrackingTrack *next= track->next; + + BLI_remlink(&tracks, track); + + track->next= track->prev= NULL; + BLI_addtail(&new_tracks, track); + + BLI_uniquename(&new_tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); + + track= next; + } + + context->clip->tracking.tracks= new_tracks; + + if(context->backwards) newframe= context->user.framenr+1; + else newframe= context->user.framenr-1; + + context->sync_frame= newframe; +} + +void BKE_tracking_sync_user(MovieClipUser *user, MovieTrackingContext *context) +{ + user->framenr= context->sync_frame; +} + +int BKE_tracking_next(MovieTrackingContext *context) +{ + ImBuf *ibuf_new; + int curfra= context->user.framenr; + int a, ok= 0; + + /* nothing to track, avoid unneeded frames reading to save time and memory */ + if(!context->num_tracks) + return 0; + + if(context->backwards) context->user.framenr--; + else context->user.framenr++; + + ibuf_new= BKE_movieclip_get_ibuf_flag(context->clip, &context->user, 0); + if(!ibuf_new) + return 0; + + #pragma omp parallel for private(a) shared(ibuf_new, ok) if(context->num_tracks>1) + for(a= 0; anum_tracks; a++) { + TrackContext *track_context= &context->track_context[a]; + MovieTrackingTrack *track= track_context->track; + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, curfra); + + if(marker && (marker->flag&MARKER_DISABLED)==0 && marker->framenr==curfra) { +#ifdef WITH_LIBMV + int width, height, origin[2], tracked= 0, need_readjust= 0; + float pos[2], margin[2]; + double x1, y1, x2, y2; + ImBuf *ibuf= NULL; + MovieTrackingMarker marker_new, *marker_keyed; + int onbound= 0, coords_correct= 0; + int nextfra; + + if(!context->settings.adjframes) need_readjust= context->first_time; + else need_readjust= context->frames%context->settings.adjframes == 0; + + if(context->backwards) nextfra= curfra-1; + else nextfra= curfra+1; + + /* margin from frame boundaries */ + sub_v2_v2v2(margin, track->pat_max, track->pat_min); + + margin[0]= MAX2(margin[0], (float)context->settings.margin / ibuf_new->x); + margin[1]= MAX2(margin[1], (float)context->settings.margin / ibuf_new->y); + + /* do not track markers which are too close to boundary */ + if(marker->pos[0]pos[0]>1.0f-margin[0] || + marker->pos[1]pos[1]>1.0f-margin[1]) { + onbound= 1; + } + else if(track_context->track->tracker==TRACKER_KLT) { + int wndx, wndy; + float *patch_new; + + if(need_readjust) { + /* calculate patch for keyframed position */ + ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + + if(track_context->patch) + MEM_freeN(track_context->patch); + + track_context->patch= get_search_floatbuf(ibuf, track, marker_keyed, &width, &height, track_context->keyframed_pos, origin); + + IMB_freeImBuf(ibuf); + } + + patch_new= get_search_floatbuf(ibuf_new, track, marker, &width, &height, pos, origin); + + x1= track_context->keyframed_pos[0]; + y1= track_context->keyframed_pos[1]; + + x2= pos[0]; + y2= pos[1]; + + wndx= (int)((track->pat_max[0]-track->pat_min[0])*ibuf_new->x)/2; + wndy= (int)((track->pat_max[1]-track->pat_min[1])*ibuf_new->y)/2; + + tracked= libmv_regionTrackerTrack(track_context->region_tracker, track_context->patch, patch_new, + width, height, MAX2(wndx, wndy), x1, y1, &x2, &y2); + + MEM_freeN(patch_new); + } + else if(track_context->track->tracker==TRACKER_SAD) { + unsigned char *image_new; + float correlation; + float warp[3][2]={{0}}; + + if(need_readjust) { + unsigned char *image; + + /* calculate pattern for keyframed position */ + ibuf= get_adjust_ibuf(context, track, marker, curfra, &marker_keyed); + + image= get_search_bytebuf(ibuf, track, marker_keyed, &width, &height, pos, origin); + + memset(warp, 0, sizeof(warp)); + warp[0][0]= 1; + warp[1][1]= 1; + warp[2][0]= pos[0]; + warp[2][1]= pos[1]; + + /* pattern size is hardcoded to 16x16px in libmv */ + track_context->patsize= 16; + + if(!track_context->pattern) + track_context->pattern= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking pattern"); + + libmv_SADSamplePattern(image, width, warp, track_context->pattern); + + MEM_freeN(image); + IMB_freeImBuf(ibuf); + } + + image_new= get_search_bytebuf(ibuf_new, track, marker, &width, &height, pos, origin); + + if(track_context->warped==NULL) { + unsigned char *image_old; + + ibuf= get_frame_ibuf(context, curfra); + + if(track_context->warped==NULL) + track_context->warped= MEM_callocN(sizeof(unsigned char)*track_context->patsize*track_context->patsize, "trackking warped"); + + image_old= get_search_bytebuf(ibuf, track, marker, &width, &height, pos, origin); + get_warped(track_context, pos[0], pos[1], width, image_old); + IMB_freeImBuf(ibuf); + MEM_freeN(image_old); + } + + memset(warp, 0, sizeof(warp)); + warp[0][0]= 1; + warp[1][1]= 1; + warp[2][0]= pos[0]; + warp[2][1]= pos[1]; + + correlation= libmv_SADTrackerTrack(track_context->pattern, track_context->warped, image_new, width, width, height, warp); + + x2= warp[2][0]; + y2= warp[2][1]; + + tracked= track_context->track->minimum_correlation < correlation; + + if(tracked) + get_warped(track_context, x2, y2, width, image_new); + + MEM_freeN(image_new); + } + + coords_correct= !isnan(x2) && !isnan(y2) && finite(x2) && finite(y2); + if(coords_correct && (tracked || !context->disable_failed)) { + if(context->first_time) { + #pragma omp critical + { + /* check if there's no keyframe/tracked markers before tracking marker. + if so -- create disabled marker before currently tracking "segment" */ + put_disabled_marker(track, marker, 1, 0); + } + } + + memset(&marker_new, 0, sizeof(marker_new)); + + if(!onbound) { + marker_new.pos[0]= (origin[0]+x2)/ibuf_new->x; + marker_new.pos[1]= (origin[1]+y2)/ibuf_new->y; + } else { + copy_v2_v2(marker_new.pos, marker->pos); + } + + marker_new.flag|= MARKER_TRACKED; + marker_new.framenr= nextfra; + + #pragma omp critical + { + BKE_tracking_insert_marker(track, &marker_new); + } + + /* make currently tracked segment be finished with disabled marker */ + #pragma omp critical + { + put_disabled_marker(track, &marker_new, 0, 0); + } + } else { + marker_new= *marker; + + marker_new.framenr= nextfra; + marker_new.flag|= MARKER_DISABLED; + + #pragma omp critical + { + BKE_tracking_insert_marker(track, &marker_new); + } + } + + ok= 1; +#endif + } + } + + IMB_freeImBuf(ibuf_new); + + context->first_time= 0; + context->frames++; + + return ok; +} + +#if WITH_LIBMV +static struct libmv_Tracks *create_libmv_tracks(MovieTracking *tracking, int width, int height) +{ + int tracknr= 0; + MovieTrackingTrack *track; + struct libmv_Tracks *tracks= libmv_tracksNew(); + + track= tracking->tracks.first; + while(track) { + int a= 0; + + for(a= 0; amarkersnr; a++) { + MovieTrackingMarker *marker= &track->markers[a]; + + if((marker->flag&MARKER_DISABLED)==0) + libmv_tracksInsert(tracks, marker->framenr, tracknr, + marker->pos[0]*width, marker->pos[1]*height); + } + + track= track->next; + tracknr++; + } + + return tracks; +} + +static int retrieve_libmv_reconstruct(MovieTracking *tracking, struct libmv_Reconstruction *libmv_reconstruction) +{ + int tracknr= 0; + int sfra= INT_MAX, efra= INT_MIN, a, origin_set= 0; + MovieTrackingTrack *track; + MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieReconstructedCamera *reconstructed; + float origin[3]= {0.0f, 0.0f, 0.0f}; + int ok= 1; + + track= tracking->tracks.first; + while(track) { + double pos[3]; + + if(libmv_reporojectionPointForTrack(libmv_reconstruction, tracknr, pos)) { + track->bundle_pos[0]= pos[0]; + track->bundle_pos[1]= pos[1]; + track->bundle_pos[2]= pos[2]; + + track->flag|= TRACK_HAS_BUNDLE; + track->error= libmv_reporojectionErrorForTrack(libmv_reconstruction, tracknr); + } else { + track->flag&= ~TRACK_HAS_BUNDLE; + ok= 0; + + printf("No bundle for track #%d '%s'\n", tracknr, track->name); + } + + if(track->markersnr) { + if(track->markers[0].framenrmarkers[0].framenr; + if(track->markers[track->markersnr-1].framenr>efra) efra= track->markers[track->markersnr-1].framenr; + } + + track= track->next; + tracknr++; + } + + if(reconstruction->cameras) + MEM_freeN(reconstruction->cameras); + + reconstruction->camnr= 0; + reconstruction->cameras= NULL; + reconstructed= MEM_callocN((efra-sfra+1)*sizeof(MovieReconstructedCamera), "temp reconstructed camera"); + + for(a= sfra; a<=efra; a++) { + double matd[4][4]; + + if(libmv_reporojectionCameraForImage(libmv_reconstruction, a, matd)) { + int i, j; + float mat[4][4]; + float error= libmv_reporojectionErrorForImage(libmv_reconstruction, a); + + for(i=0; i<4; i++) + for(j= 0; j<4; j++) + mat[i][j]= matd[i][j]; + + if(!origin_set) { + copy_v3_v3(origin, mat[3]); + origin_set= 1; + } + + if(origin_set) + sub_v3_v3(mat[3], origin); + + copy_m4_m4(reconstructed[reconstruction->camnr].mat, mat); + reconstructed[reconstruction->camnr].framenr= a; + reconstructed[reconstruction->camnr].error= error; + reconstruction->camnr++; + } else { + ok= 0; + printf("No camera for frame %d\n", a); + } + } + + if(reconstruction->camnr) { + reconstruction->cameras= MEM_callocN(reconstruction->camnr*sizeof(MovieReconstructedCamera), "reconstructed camera"); + memcpy(reconstruction->cameras, reconstructed, reconstruction->camnr*sizeof(MovieReconstructedCamera)); + } + + if(origin_set) { + track= tracking->tracks.first; + while(track) { + if(track->flag&TRACK_HAS_BUNDLE) + sub_v3_v3(track->bundle_pos, origin); + + track= track->next; + } + } + + MEM_freeN(reconstructed); + + return ok; +} + +#endif + +float BKE_tracking_solve_reconstruction(MovieTracking *tracking, int width, int height) +{ +#if WITH_LIBMV + { + MovieTrackingCamera *camera= &tracking->camera; + float aspy= 1.0f/tracking->camera.pixel_aspect; + struct libmv_Tracks *tracks= create_libmv_tracks(tracking, width, height*aspy); + struct libmv_Reconstruction *reconstruction = libmv_solveReconstruction(tracks, + tracking->settings.keyframe1, tracking->settings.keyframe2, + camera->focal, + camera->principal[0], camera->principal[1]*aspy, + camera->k1, camera->k2, camera->k3); + float error= libmv_reprojectionError(reconstruction); + + tracking->reconstruction.error= error; + + if(!retrieve_libmv_reconstruct(tracking, reconstruction)) + error= -1.0f; + + libmv_destroyReconstruction(reconstruction); + libmv_tracksDestroy(tracks); + + tracking->reconstruction.flag|= TRACKING_RECONSTRUCTED; + + return error; + } +#endif +} + +void BKE_track_unique_name(MovieTracking *tracking, MovieTrackingTrack *track) +{ + BLI_uniquename(&tracking->tracks, track, "Track", '.', offsetof(MovieTrackingTrack, name), sizeof(track->name)); +} + +MovieTrackingTrack *BKE_tracking_named_track(MovieTracking *tracking, const char *name) +{ + MovieTrackingTrack *track= tracking->tracks.first; + + while(track) { + if(!strcmp(track->name, name)) + return track; + + track= track->next; + } + + return NULL; +} + +static int reconstruction_camera_index(MovieTracking *tracking, int framenr, int nearest) +{ + MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieReconstructedCamera *cameras= reconstruction->cameras; + int a= 0, d= 1; + + if(!reconstruction->camnr) + return -1; + + if(framenrcameras[reconstruction->camnr-1].framenr) { + if(nearest) return reconstruction->camnr-1; + else return -1; + } + + if(reconstruction->last_cameracamnr) + a= reconstruction->last_camera; + + if(cameras[a].framenr>=framenr) + d= -1; + + while(a>=0 && acamnr) { + int cfra= cameras[a].framenr; + + /* check if needed framenr was "skipped" -- no data for requested frame */ + + if(d>0 && cfra>framenr) { + /* interpolate with previous position */ + if(nearest) return a-1; + else break; + } + + if(d<0 && cfralast_camera= a; + + return a; + } + + a+= d; + } + + return -1; +} + +MovieReconstructedCamera *BKE_tracking_get_reconstructed_camera(MovieTracking *tracking, int framenr) +{ + int a= reconstruction_camera_index(tracking, framenr, 0); + + if(a==-1) + return NULL; + + return &tracking->reconstruction.cameras[a]; +} + +void BKE_tracking_get_interpolated_camera(MovieTracking *tracking, int framenr, float mat[4][4]) +{ + MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieReconstructedCamera *cameras= reconstruction->cameras; + int a= reconstruction_camera_index(tracking, framenr, 1); + + if(a==-1) { + unit_m4(mat); + return; + } + + if(cameras[a].framenr!=framenr && a>0 && acamnr-1) { + float t= ((float)framenr-cameras[a].framenr) / (cameras[a+1].framenr-cameras[a].framenr); + + blend_m4_m4m4(mat, cameras[a].mat, cameras[a+1].mat, t); + } else { + copy_m4_m4(mat, cameras[a].mat); + } +} + +void BKE_get_tracking_mat(Scene *scene, Object *ob, float mat[4][4]) +{ + if(!ob) { + if(scene->camera) ob= scene->camera; + else ob= scene_find_camera(scene); + } + + if(ob) + where_is_object_mat(scene, ob, mat); + else + unit_m4(mat); +} + +void BKE_tracking_camera_shift(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty) +{ + *shiftx= (0.5f*winx-tracking->camera.principal[0]) / winx; + *shifty= (0.5f*winy-tracking->camera.principal[1]) / winx; +} + +void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height) +{ + float focal= tracking->camera.focal; + + camera->sensor_x= tracking->camera.sensor_width; + camera->sensor_fit= CAMERA_SENSOR_FIT_AUTO; + camera->lens= focal*camera->sensor_x/width; + + scene->r.xsch= width*tracking->camera.pixel_aspect; + scene->r.ysch= height; + + scene->r.xasp= 1.0f; + scene->r.yasp= 1.0f; + + BKE_tracking_camera_shift(tracking, width, height, &camera->shiftx, &camera->shifty); +} + +void BKE_tracking_projection_matrix(MovieTracking *tracking, int framenr, int winx, int winy, float mat[4][4]) +{ + MovieReconstructedCamera *camera; + float lens= tracking->camera.focal*tracking->camera.sensor_width/(float)winx; + float viewfac, pixsize, left, right, bottom, top, clipsta, clipend; + float winmat[4][4]; + float ycor= 1.0f/tracking->camera.pixel_aspect; + float shiftx, shifty, winside= MAX2(winx, winy); + + BKE_tracking_camera_shift(tracking, winx, winy, &shiftx, &shifty); + + clipsta= 0.1f; + clipend= 1000.0f; + + if(winx >= winy) + viewfac= (lens*winx)/tracking->camera.sensor_width; + else + viewfac= (ycor*lens*winy)/tracking->camera.sensor_width; + + pixsize= clipsta/viewfac; + + left= -0.5f*(float)winx + shiftx*winside; + bottom= -0.5f*(ycor)*(float)winy + shifty*winside; + right= 0.5f*(float)winx + shiftx*winside; + top= 0.5f*(ycor)*(float)winy + shifty*winside; + + left *= pixsize; + right *= pixsize; + bottom *= pixsize; + top *= pixsize; + + perspective_m4(winmat, left, right, bottom, top, clipsta, clipend); + + camera= BKE_tracking_get_reconstructed_camera(tracking, framenr); + if(camera) { + float imat[4][4]; + + invert_m4_m4(imat, camera->mat); + mul_m4_m4m4(mat, imat, winmat); + } else copy_m4_m4(mat, winmat); +} + +void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float nco[2]) +{ + MovieTrackingCamera *camera= &tracking->camera; + +#ifdef WITH_LIBMV + double x, y; + float aspy= 1.0f/tracking->camera.pixel_aspect; + + /* normalize coords */ + x= (co[0]-camera->principal[0]) / camera->focal; + y= (co[1]-camera->principal[1] * aspy) / camera->focal; + + libmv_applyCameraIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, x, y, &x, &y); + + /* result is in image coords already */ + nco[0]= x; + nco[1]= y; +#endif +} + +void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[2]) +{ + MovieTrackingCamera *camera= &tracking->camera; + +#ifdef WITH_LIBMV + double x= co[0], y= co[1]; + float aspy= 1.0f/tracking->camera.pixel_aspect; + + libmv_InvertIntrinsics(camera->focal, camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, x, y, &x, &y); + + nco[0]= x * camera->focal + camera->principal[0]; + nco[1]= y * camera->focal + camera->principal[1] * aspy; +#endif +} + +static int point_in_stroke(bGPDstroke *stroke, float x, float y) +{ + int i, prev; + int count= 0; + bGPDspoint *points= stroke->points; + + prev= stroke->totpoints-1; + + for(i= 0; itotpoints; i++) { + if((points[i].y=y) || (points[prev].y=y)) { + float fac= (y-points[i].y)/(points[prev].y-points[i].y); + + if (points[i].x+fac*(points[prev].x-points[i].x)frames.first; + + while(frame) { + bGPDstroke *stroke= frame->strokes.first; + while(stroke) { + if(point_in_stroke(stroke, x, y)) + return 1; + + stroke= stroke->next; + } + frame= frame->next; + } + + return 0; +} + +static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features, + int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer) +{ +#ifdef WITH_LIBMV + int a; + + a= libmv_countFeatures(features); + while(a--) { + MovieTrackingTrack *track; + double x, y, size, score; + int ok= 1; + float xu, yu; + + libmv_getFeature(features, a, &x, &y, &score, &size); + + xu= x/width; + yu= y/height; + + if(layer) + ok= point_in_layer(layer, xu, yu)!=place_outside_layer; + + if(ok) { + track= BKE_tracking_add_track(tracking, xu, yu, framenr, width, height); + track->flag|= SELECT; + track->pat_flag|= SELECT; + track->search_flag|= SELECT; + } + } +#endif +} + +void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf, + int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer, + int place_outside_layer) +{ +#ifdef WITH_LIBMV + struct libmv_Features *features; + unsigned char *pixels= get_ucharbuf(ibuf); + + features= libmv_detectFeaturesFAST(pixels, ibuf->x, ibuf->y, ibuf->x, margin, min_trackness, min_distance); + + MEM_freeN(pixels); + + retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer); + + libmv_destroyFeatures(features); +#endif +} + +MovieTrackingTrack *BKE_tracking_indexed_track(MovieTracking *tracking, int tracknr) +{ + MovieTrackingTrack *track= tracking->tracks.first; + int cur= 1; + + while(track) { + if(track->flag&TRACK_HAS_BUNDLE) { + if(cur==tracknr) + return track; + + cur++; + } + + track= track->next; + } + + return NULL; +} + +static int stabilization_median_point(MovieTracking *tracking, int framenr, float median[2]) +{ + int ok= 0; + float min[2], max[2]; + MovieTrackingTrack *track; + + INIT_MINMAX2(min, max); + + track= tracking->tracks.first; + while(track) { + if(track->flag&TRACK_USE_2D_STAB) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); + + DO_MINMAX2(marker->pos, min, max); + + ok= 1; + } + + track= track->next; + } + + median[0]= (max[0]+min[0])/2.0f; + median[1]= (max[1]+min[1])/2.0f; + + return ok; +} + +static void calculate_stabdata(MovieTracking *tracking, int framenr, float width, float height, + float firstmedian[2], float median[2], float loc[2], float *scale, float *angle) +{ + MovieTrackingStabilization *stab= &tracking->stabilization; + + *scale= (stab->scale-1.0f)*stab->scaleinf+1.0f; + *angle= 0.0f; + + loc[0]= (firstmedian[0]-median[0])*width*(*scale); + loc[1]= (firstmedian[1]-median[1])*height*(*scale); + + mul_v2_fl(loc, stab->locinf); + + if(stab->rot_track && stab->rotinf) { + MovieTrackingMarker *marker; + float a[2], b[2]; + float x0= (float)width/2.0f, y0= (float)height/2.0f; + float x= median[0]*width, y= median[1]*height; + + marker= BKE_tracking_get_marker(stab->rot_track, 1); + sub_v2_v2v2(a, marker->pos, firstmedian); + a[0]*= width; + a[1]*= height; + + marker= BKE_tracking_get_marker(stab->rot_track, framenr); + sub_v2_v2v2(b, marker->pos, median); + b[0]*= width; + b[1]*= height; + + *angle= -atan2(a[0]*b[1]-a[1]*b[0], a[0]*b[0]+a[1]*b[1]); + *angle*= stab->rotinf; + + /* convert to rotation around image center */ + loc[0]-= (x0 + (x-x0)*cos(*angle)-(y-y0)*sin(*angle) - x)*(*scale); + loc[1]-= (y0 + (x-x0)*sin(*angle)+(y-y0)*cos(*angle) - y)*(*scale); + } +} + +static float stabilization_auto_scale_factor(MovieTracking *tracking, int width, int height) +{ + float firstmedian[2]; + MovieTrackingStabilization *stab= &tracking->stabilization; + + if(stab->ok) + return stab->scale; + + if(stabilization_median_point(tracking, 1, firstmedian)) { + int sfra= INT_MAX, efra= INT_MIN, cfra; + float delta[2]= {0.0f, 0.0f}, scalex= 1.0f, scaley= 1.0f; + MovieTrackingTrack *track; + + stab->scale= 1.0f; + + track= tracking->tracks.first; + while(track) { + if(track->flag&TRACK_USE_2D_STAB || track==stab->rot_track) { + if(track->markersnr) { + sfra= MIN2(sfra, track->markers[0].framenr); + efra= MAX2(efra, track->markers[track->markersnr-1].framenr); + } + } + + track= track->next; + } + + for(cfra=sfra; cfra<=efra; cfra++) { + float median[2], near[2]; + float loc[2], scale, angle; + + stabilization_median_point(tracking, cfra, median); + + calculate_stabdata(tracking, cfra, width, height, firstmedian, median, + loc, &scale, &angle); + + if(angle==0.0f) { + loc[0]= fabsf(loc[0]); + loc[1]= fabsf(loc[1]); + + delta[0]= MAX2(delta[0], loc[0]); + delta[1]= MAX2(delta[1], loc[1]); + + near[0]= MIN2(median[0], 1.0f-median[0]); + near[1]= MIN2(median[1], 1.0f-median[1]); + near[0]= MAX2(near[0], 0.05f); + near[1]= MAX2(near[1], 0.05f); + + scalex= 1.0f+delta[0]/(near[0]*width); + scaley= 1.0f+delta[1]/(near[1]*height); + } else { + int i; + float mat[4][4]; + float points[4][2]={{0.0f, 0.0f}, {0.0f, height}, {width, height}, {width, 0.0f}}; + + BKE_tracking_stabdata_to_mat4(width, height, loc, scale, angle, mat); + + for(i= 0; i<4; i++) { + int j; + float a[3]= {0.0f, 0.0f, 0.0f}, b[3]= {0.0f, 0.0f, 0.0f}; + + copy_v3_v3(a, points[i]); + copy_v3_v3(b, points[(i+1)%4]); + + mul_m4_v3(mat, a); + mul_m4_v3(mat, b); + + for(j= 0; j<4; j++) { + float point[3]= {points[j][0], points[j][1], 0.0f}; + float v1[3], v2[3]; + + sub_v3_v3v3(v1, b, a); + sub_v3_v3v3(v2, point, a); + + if(cross_v2v2(v1, v2) >= 0.0f) { + float dist= dist_to_line_v2(point, a, b); + if(i%2==0) { + scalex= MAX2(scalex, (width+2*dist)/width); + } else { + scaley= MAX2(scaley, (height+2*dist)/height); + } + } + } + } + } + } + + stab->scale= MAX2(scalex, scaley); + + if(stab->maxscale>0.0f) + stab->scale= MIN2(stab->scale, stab->maxscale); + } else { + stab->scale= 1.0f; + } + + stab->ok= 1; + + return stab->scale; +} + +static ImBuf* stabilize_alloc_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int fill) +{ + int flags; + + if(cacheibuf && (cacheibuf->x != srcibuf->x || cacheibuf->y != srcibuf->y)) { + IMB_freeImBuf(cacheibuf); + cacheibuf= NULL; + } + + flags= IB_rect; + + if(srcibuf->rect_float) + flags|= IB_rectfloat; + + if(cacheibuf) { + if(fill) { + float col[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + IMB_rectfill(cacheibuf, col); + } + } + else { + cacheibuf= IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->depth, flags); + cacheibuf->profile= srcibuf->profile; + } + + return cacheibuf; +} + +void BKE_tracking_stabilization_data(MovieTracking *tracking, int framenr, int width, int height, float loc[2], float *scale, float *angle) +{ + float firstmedian[2], median[2]; + MovieTrackingStabilization *stab= &tracking->stabilization; + + if((stab->flag&TRACKING_2D_STABILIZATION)==0) { + zero_v2(loc); + *scale= 1.0f; + *angle= 0.0f; + + return; + } + + if(stabilization_median_point(tracking, 1, firstmedian)) { + stabilization_median_point(tracking, framenr, median); + + if((stab->flag&TRACKING_AUTOSCALE)==0) + stab->scale= 1.0f; + + if(!stab->ok) { + if(stab->flag&TRACKING_AUTOSCALE) + stabilization_auto_scale_factor(tracking, width, height); + + calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + + stab->ok= 1; + } else { + calculate_stabdata(tracking, framenr, width, height, firstmedian, median, loc, scale, angle); + } + } else { + zero_v2(loc); + *scale= 1.0f; + *angle= 0.0f; + } +} + +ImBuf *BKE_tracking_stabilize(MovieTracking *tracking, int framenr, ImBuf *ibuf, float loc[2], float *scale, float *angle) +{ + float tloc[2], tscale, tangle; + MovieTrackingStabilization *stab= &tracking->stabilization; + ImBuf *tmpibuf; + float width= ibuf->x, height= ibuf->y; + + if(loc) copy_v2_v2(tloc, loc); + if(scale) tscale= *scale; + + if((stab->flag&TRACKING_2D_STABILIZATION)==0) { + if(loc) zero_v2(loc); + if(scale) *scale= 1.0f; + + return ibuf; + } + + BKE_tracking_stabilization_data(tracking, framenr, width, height, tloc, &tscale, &tangle); + + tmpibuf= stabilize_alloc_ibuf(NULL, ibuf, 1); + + /* scale would be handled by matrix transformation when angle is non-zero */ + if(tscale!=1.0f && tangle==0.0f) { + ImBuf *scaleibuf; + + stabilization_auto_scale_factor(tracking, width, height); + + scaleibuf= stabilize_alloc_ibuf(stab->scaleibuf, ibuf, 0); + stab->scaleibuf= scaleibuf; + + IMB_rectcpy(scaleibuf, ibuf, 0, 0, 0, 0, ibuf->x, ibuf->y); + IMB_scalefastImBuf(scaleibuf, ibuf->x*tscale, ibuf->y*tscale); + + ibuf= scaleibuf; + } + + if(tangle==0.0f) { + /* if angle is zero, then it's much faster to use rect copy + but could be issues with subpixel precisions */ + IMB_rectcpy(tmpibuf, ibuf, tloc[0]-(tscale-1.0f)*width/2.0f, tloc[1]-(tscale-1.0f)*height/2.0f, 0, 0, ibuf->x, ibuf->y); + } else { + float mat[4][4]; + int i, j; + + BKE_tracking_stabdata_to_mat4(ibuf->x, ibuf->y, tloc, tscale, tangle, mat); + invert_m4(mat); + + for(j=0; jy; j++) { + for(i=0; ix;i++) { + float vec[3]= {i, j, 0}; + + mul_v3_m4v3(vec, mat, vec); + + /* TODO: add selector for interpolation method */ + neareast_interpolation(ibuf, tmpibuf, vec[0], vec[1], i, j); + } + } + } + + tmpibuf->userflags|= IB_MIPMAP_INVALID; + + if(tmpibuf->rect_float) + tmpibuf->userflags|= IB_RECT_INVALID; + + if(loc) copy_v2_v2(loc, tloc); + if(scale) *scale= tscale; + if(angle) *angle= tangle; + + return tmpibuf; +} + +void BKE_tracking_stabdata_to_mat4(int width, int height, float loc[2], float scale, float angle, float mat[4][4]) +{ + float lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4]; + float svec[3]= {scale, scale, scale}; + + unit_m4(rmat); + unit_m4(lmat); + unit_m4(smat); + unit_m4(cmat); + + /* image center as rotation center */ + cmat[3][0]= (float)width/2.0f; + cmat[3][1]= (float)height/2.0f; + invert_m4_m4(icmat, cmat); + + size_to_mat4(smat, svec); /* scale matrix */ + add_v2_v2(lmat[3], loc); /* tranlation matrix */ + rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + + /* compose transformation matrix */ + mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL); +} + +MovieDistortion *BKE_tracking_distortion_create(void) +{ + MovieDistortion *distortion; + + distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); + + return distortion; +} + +MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) +{ + MovieDistortion *new_distortion; + + new_distortion= MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create"); + +#ifdef WITH_LIBMV + new_distortion->intrinsics= libmv_CameraIntrinsicsCopy(distortion->intrinsics); +#endif + + return new_distortion; +} + +void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking, int width, int height) +{ + MovieTrackingCamera *camera= &tracking->camera; + float aspy= 1.0f/tracking->camera.pixel_aspect; + +#ifdef WITH_LIBMV + if(!distortion->intrinsics) { + distortion->intrinsics= libmv_CameraIntrinsicsNew(camera->focal, + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, width, height * aspy); + } else { + libmv_CameraIntrinsicsUpdate(distortion->intrinsics, camera->focal, + camera->principal[0], camera->principal[1] * aspy, + camera->k1, camera->k2, camera->k3, width, height * aspy); + } +#endif +} + +ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, + ImBuf *ibuf, int width, int height, float overscan, int undistort) +{ + ImBuf *resibuf; + + BKE_tracking_distortion_update(distortion, tracking, width, height); + + resibuf= IMB_dupImBuf(ibuf); + + if(ibuf->rect_float) { +#ifdef WITH_LIBMV + if(undistort) { + libmv_CameraIntrinsicsUndistortFloat(distortion->intrinsics, + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } else { + libmv_CameraIntrinsicsDistortFloat(distortion->intrinsics, + ibuf->rect_float, resibuf->rect_float, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } +#endif + + ibuf->userflags|= IB_RECT_INVALID; + } else { +#ifdef WITH_LIBMV + if(undistort) { + libmv_CameraIntrinsicsUndistortByte(distortion->intrinsics, + (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } else { + libmv_CameraIntrinsicsDistortByte(distortion->intrinsics, + (unsigned char*)ibuf->rect, (unsigned char*)resibuf->rect, + ibuf->x, ibuf->y, overscan, ibuf->channels); + } +#endif + } + + return resibuf; +} + +void BKE_tracking_distortion_destroy(MovieDistortion *distortion) +{ +#ifdef WITH_LIBMV + libmv_CameraIntrinsicsDestroy(distortion->intrinsics); +#endif + + MEM_freeN(distortion); +} + +ImBuf *BKE_tracking_undistort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan) +{ + MovieTrackingCamera *camera= &tracking->camera; + + if(camera->intrinsics == NULL) + camera->intrinsics= BKE_tracking_distortion_create(); + + return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 1); +} + +ImBuf *BKE_tracking_distort(MovieTracking *tracking, ImBuf *ibuf, int width, int height, float overscan) +{ + MovieTrackingCamera *camera= &tracking->camera; + + if(camera->intrinsics == NULL) + camera->intrinsics= BKE_tracking_distortion_create(); + + return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, width, height, overscan, 0); +} + +/* area - which part of marker should be selected. see TRACK_AREA_* constants */ +void BKE_tracking_select_track(MovieTracking *tracking, MovieTrackingTrack *track, int area, int extend) +{ + if(extend) { + BKE_tracking_track_flag(track, area, SELECT, 0); + } else { + MovieTrackingTrack *cur= tracking->tracks.first; + + while(cur) { + if(cur==track) { + BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1); + BKE_tracking_track_flag(cur, area, SELECT, 0); + } + else { + BKE_tracking_track_flag(cur, TRACK_AREA_ALL, SELECT, 1); + } + + cur= cur->next; + } + } +} + +void BKE_tracking_deselect_track(MovieTrackingTrack *track, int area) +{ + BKE_tracking_track_flag(track, area, SELECT, 1); +} diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 8826e9a9936..1c9c9188e44 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -71,6 +71,7 @@ int BLI_system_thread_count(void); /* gets the number of threads the system can #define LOCK_RCACHE 4 #define LOCK_OPENGL 5 #define LOCK_NODES 6 +#define LOCK_MOVIECLIP 7 void BLI_lock_thread(int type); void BLI_unlock_thread(int type); diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 7b156a3ac52..8247b861a7a 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -114,6 +114,7 @@ static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _nodes_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t _movieclip_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_t mainid; static int thread_levels= 0; /* threads can be invoked inside threads */ @@ -350,6 +351,8 @@ void BLI_lock_thread(int type) pthread_mutex_lock(&_opengl_lock); else if (type==LOCK_NODES) pthread_mutex_lock(&_nodes_lock); + else if (type==LOCK_MOVIECLIP) + pthread_mutex_lock(&_movieclip_lock); } void BLI_unlock_thread(int type) @@ -368,6 +371,8 @@ void BLI_unlock_thread(int type) pthread_mutex_unlock(&_opengl_lock); else if(type==LOCK_NODES) pthread_mutex_unlock(&_nodes_lock); + else if(type==LOCK_MOVIECLIP) + pthread_mutex_unlock(&_movieclip_lock); } /* Mutex Locks */ diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 3f08e2301a7..6e4dcb66bfb 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -301,11 +301,17 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil /* makes lookup of existing images in old main */ blo_make_image_pointer_map(fd, oldmain); + /* makes lookup of existing video clips in old main */ + blo_make_movieclip_pointer_map(fd, oldmain); + bfd= blo_read_file_internal(fd, filename); /* ensures relinked images are not freed */ blo_end_image_pointer_map(fd, oldmain); + /* ensures relinked movie clips are not freed */ + blo_end_movieclip_pointer_map(fd, oldmain); + /* move libraries from old main to new main */ if(bfd && mainlist.first!=mainlist.last) { diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 3a03a11b849..ce7ff489465 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -88,6 +88,7 @@ #include "DNA_space_types.h" #include "DNA_vfont_types.h" #include "DNA_world_types.h" +#include "DNA_movieclip_types.h" #include "MEM_guardedalloc.h" @@ -129,6 +130,7 @@ #include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_texture.h" // for open_plugin_tex +#include "BKE_tracking.h" #include "BKE_utildefines.h" // SWITCH_INT DATA ENDB DNA1 O_BINARY GLOB USER TEST REND #include "BKE_sound.h" @@ -1037,6 +1039,8 @@ void blo_freefiledata(FileData *fd) oldnewmap_free(fd->globmap); if (fd->imamap) oldnewmap_free(fd->imamap); + if (fd->movieclipmap) + oldnewmap_free(fd->movieclipmap); if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP)) oldnewmap_free(fd->libmap); if (fd->bheadmap) @@ -1112,6 +1116,13 @@ static void *newimaadr(FileData *fd, void *adr) /* used to restore image data a return NULL; } +static void *newmclipadr(FileData *fd, void *adr) /* used to restore movie clip data after undo */ +{ + if(fd->movieclipmap && adr) + return oldnewmap_lookup_and_inc(fd->movieclipmap, adr); + return NULL; +} + static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */ { @@ -1240,6 +1251,42 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) } } +void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) +{ + MovieClip *clip= oldmain->movieclip.first; + + fd->movieclipmap= oldnewmap_new(); + + for(;clip; clip= clip->id.next) { + if(clip->cache) + oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0); + + if(clip->tracking.camera.intrinsics) + oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0); + } +} + +/* set old main movie clips caches to zero if it has been restored */ +/* this works because freeing old main only happens after this call */ +void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) +{ + OldNew *entry= fd->movieclipmap->entries; + MovieClip *clip= oldmain->movieclip.first; + int i; + + /* used entries were restored, so we put them to zero */ + for (i=0; imovieclipmap->nentries; i++, entry++) { + if (entry->nr>0) + entry->newp= NULL; + } + + for(;clip; clip= clip->id.next) { + clip->cache= newmclipadr(fd, clip->cache); + clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); + } +} + + /* undo file support: add all library pointers in lookup */ void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd) { @@ -4762,6 +4809,7 @@ static void direct_link_scene(FileData *fd, Scene *sce) if(sce->nodetree) direct_link_nodetree(fd, sce->nodetree); + sce->clip= newlibadr_us(fd, sce->id.lib, sce->clip); } /* ************ READ WM ***************** */ @@ -4916,6 +4964,7 @@ static void lib_link_screen(FileData *fd, Main *main) for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) { bgpic->ima= newlibadr_us(fd, sc->id.lib, bgpic->ima); + bgpic->clip= newlibadr_us(fd, sc->id.lib, bgpic->clip); } if(v3d->localvd) { v3d->localvd->camera= newlibadr(fd, sc->id.lib, v3d->localvd->camera); @@ -5038,6 +5087,14 @@ static void lib_link_screen(FileData *fd, Main *main) snode->linkdrag.first = snode->linkdrag.last = NULL; } + else if(sl->spacetype==SPACE_CLIP) { + SpaceClip *sclip= (SpaceClip *)sl; + + sclip->clip= newlibadr_us(fd, sc->id.lib, sclip->clip); + + sclip->scopes.track_preview = NULL; + sclip->scopes.ok = 0; + } } sa= sa->next; } @@ -5125,6 +5182,7 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) for(bgpic= v3d->bgpicbase.first; bgpic; bgpic= bgpic->next) { bgpic->ima= restore_pointer_by_name(newmain, (ID *)bgpic->ima, 1); + bgpic->clip= restore_pointer_by_name(newmain, (ID *)bgpic->clip, 1); } if(v3d->localvd) { /*Base *base;*/ @@ -5267,6 +5325,13 @@ void lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *curscene) snode->nodetree= restore_pointer_by_name(newmain, &snode->nodetree->id, 1); } } + else if(sl->spacetype==SPACE_CLIP) { + SpaceClip *sclip= (SpaceClip *)sl; + + sclip->clip= restore_pointer_by_name(newmain, (ID *)sclip->clip, 1); + + sclip->scopes.ok = 0; + } } sa= sa->next; } @@ -5750,6 +5815,55 @@ static void lib_link_group(FileData *fd, Main *main) } } +/* ***************** READ MOVIECLIP *************** */ + +static void direct_link_movieclip(FileData *fd, MovieClip *clip) +{ + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + + if(fd->movieclipmap) clip->cache= newmclipadr(fd, clip->cache); + else clip->cache= NULL; + + if(fd->movieclipmap) clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); + else clip->tracking.camera.intrinsics= NULL; + + tracking->reconstruction.cameras= newdataadr(fd, tracking->reconstruction.cameras); + + link_list(fd, &tracking->tracks); + + track= tracking->tracks.first; + while(track) { + track->markers= newdataadr(fd, track->markers); + + track= track->next; + } + + clip->tracking.act_track= newdataadr(fd, clip->tracking.act_track); + + clip->anim= NULL; + clip->tracking_context= NULL; + + clip->tracking.stabilization.ok= 0; + clip->tracking.stabilization.scaleibuf= NULL; + clip->tracking.stabilization.rot_track= newdataadr(fd, clip->tracking.stabilization.rot_track); +} + +static void lib_link_movieclip(FileData *fd, Main *main) +{ + MovieClip *clip; + + clip= main->movieclip.first; + while(clip) { + if(clip->id.flag & LIB_NEEDLINK) { + clip->gpd= newlibadr_us(fd, clip->id.lib, clip->gpd); + + clip->id.flag -= LIB_NEEDLINK; + } + clip= clip->id.next; + } +} + /* ************** GENERAL & MAIN ******************** */ @@ -5784,6 +5898,7 @@ static const char *dataname(short id_code) case ID_BR: return "Data from BR"; case ID_PA: return "Data from PA"; case ID_GD: return "Data from GD"; + case ID_MC: return "Data from MC"; } return "Data from Lib Block"; @@ -5953,6 +6068,9 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID case ID_GD: direct_link_gpencil(fd, (bGPdata *)id); break; + case ID_MC: + direct_link_movieclip(fd, (MovieClip *)id); + break; } /*link direct data of ID properties*/ @@ -12121,7 +12239,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) ma= ma->id.next; } } - } if (main->versionfile < 260){ @@ -12157,7 +12274,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } } - } if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 1)){ @@ -12181,7 +12297,65 @@ static void do_versions(FileData *fd, Library *lib, Main *main) /* put compatibility code here until next subversion bump */ { - + { + bScreen *sc; + MovieClip *clip; + + for (sc= main->screen.first; sc; sc= sc->id.next) { + ScrArea *sa; + for (sa= sc->areabase.first; sa; sa= sa->next) { + SpaceLink *sl; + for (sl= sa->spacedata.first; sl; sl= sl->next) { + if(sl->spacetype==SPACE_VIEW3D) { + View3D *v3d= (View3D *)sl; + if(v3d->bundle_size==0.0f) { + v3d->bundle_size= 0.2f; + v3d->flag2 |= V3D_SHOW_RECONSTRUCTION; + } + else if(sl->spacetype==SPACE_CLIP) { + SpaceClip *sc= (SpaceClip *)sl; + if(sc->scopes.track_preview_height==0) + sc->scopes.track_preview_height= 120; + } + + if(v3d->bundle_drawtype==0) + v3d->bundle_drawtype= OB_PLAINAXES; + } + } + } + } + + for (clip= main->movieclip.first; clip; clip= clip->id.next) { + MovieTrackingTrack *track; + + if(clip->aspx<1.0f) { + clip->aspx= 1.0f; + clip->aspy= 1.0f; + } + + /* XXX: a bit hacky, probably include imbuf and use real constants are nicer */ + clip->proxy.build_tc_flag= 7; + if(clip->proxy.build_size_flag==0) + clip->proxy.build_size_flag= 1; + + if(clip->proxy.quality==0) + clip->proxy.quality= 90; + + if(clip->tracking.camera.pixel_aspect<0.01f) + clip->tracking.camera.pixel_aspect= 1.f; + + track= clip->tracking.tracks.first; + while(track) { + if(track->pyramid_levels==0) + track->pyramid_levels= 2; + + if(track->minimum_correlation==0.0f) + track->minimum_correlation= 0.75f; + + track= track->next; + } + } + } } /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ @@ -12228,6 +12402,7 @@ static void lib_link_all(FileData *fd, Main *main) lib_link_nodetree(fd, main); /* has to be done after scene/materials, this will verify group nodes */ lib_link_brush(fd, main); lib_link_particlesettings(fd, main); + lib_link_movieclip(fd, main); lib_link_mesh(fd, main); /* as last: tpage images with users at zero */ diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index fdb567a7dce..358a7659d51 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -78,6 +78,7 @@ typedef struct FileData { struct OldNewMap *globmap; struct OldNewMap *libmap; struct OldNewMap *imamap; + struct OldNewMap *movieclipmap; struct bheadsort *bheadmap; int tot_bheadmap; @@ -120,6 +121,8 @@ FileData *blo_openblendermemfile(struct MemFile *memfile, struct ReportList *rep void blo_clear_proxy_pointers_from_lib(Main *oldmain); void blo_make_image_pointer_map(FileData *fd, Main *oldmain); void blo_end_image_pointer_map(FileData *fd, Main *oldmain); +void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain); +void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain); void blo_add_library_pointer_map(ListBase *mainlist, FileData *fd); void blo_freefiledata( FileData *fd); diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1e0ef4a6a16..f49148342ec 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -128,6 +128,7 @@ Any case: direct data is ALWAYS after the lib block #include "DNA_vfont_types.h" #include "DNA_world_types.h" #include "DNA_windowmanager_types.h" +#include "DNA_movieclip_types.h" #include "MEM_guardedalloc.h" // MEM_freeN #include "BLI_blenlib.h" @@ -2258,6 +2259,9 @@ static void write_screens(WriteData *wd, ListBase *scrbase) else if(sl->spacetype==SPACE_USERPREF) { writestruct(wd, DATA, "SpaceUserPref", 1, sl); } + else if(sl->spacetype==SPACE_CLIP) { + writestruct(wd, DATA, "SpaceClip", 1, sl); + } sl= sl->next; } @@ -2506,6 +2510,38 @@ static void write_scripts(WriteData *wd, ListBase *idbase) } } +static void write_movieclips(WriteData *wd, ListBase *idbase) +{ + MovieClip *clip; + + clip= idbase->first; + while(clip) { + if(clip->id.us>0 || wd->current) { + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + writestruct(wd, ID_MC, "MovieClip", 1, clip); + + if(tracking->reconstruction.camnr) + writestruct(wd, DATA, "MovieReconstructedCamera", tracking->reconstruction.camnr, tracking->reconstruction.cameras); + + track= tracking->tracks.first; + while(track) { + writestruct(wd, DATA, "MovieTrackingTrack", 1, track); + + if(track->markers) + writestruct(wd, DATA, "MovieTrackingMarker", track->markersnr, track->markers); + + track= track->next; + } + } + + clip= clip->id.next; + } + + /* flush helps the compression for undo-save */ + mywrite(wd, MYWRITE_FLUSH, 0); +} + /* context is usually defined by WM, two cases where no WM is available: * - for forward compatibility, curscreen has to be saved * - for undofile, curscene needs to be saved */ @@ -2582,6 +2618,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil write_windowmanagers(wd, &mainvar->wm); write_screens (wd, &mainvar->screen); } + write_movieclips (wd, &mainvar->movieclip); write_scenes (wd, &mainvar->scene); write_curves (wd, &mainvar->curve); write_mballs (wd, &mainvar->mball); diff --git a/source/blender/editors/CMakeLists.txt b/source/blender/editors/CMakeLists.txt index 7b7d11bd487..088376b20ef 100644 --- a/source/blender/editors/CMakeLists.txt +++ b/source/blender/editors/CMakeLists.txt @@ -35,6 +35,7 @@ if(WITH_BLENDER) add_subdirectory(space_action) add_subdirectory(space_api) add_subdirectory(space_buttons) + add_subdirectory(space_clip) add_subdirectory(space_console) add_subdirectory(space_file) add_subdirectory(space_graph) diff --git a/source/blender/editors/SConscript b/source/blender/editors/SConscript index a1b766ec2be..ed66a76a324 100644 --- a/source/blender/editors/SConscript +++ b/source/blender/editors/SConscript @@ -17,6 +17,7 @@ SConscript(['datafiles/SConscript', 'render/SConscript', 'sound/SConscript', 'space_buttons/SConscript', + 'space_clip/SConscript', 'space_file/SConscript', 'space_image/SConscript', 'space_info/SConscript', diff --git a/source/blender/editors/datafiles/blender_icons.png.c b/source/blender/editors/datafiles/blender_icons.png.c index a53e2813d2e..93c3b45a3d9 100644 --- a/source/blender/editors/datafiles/blender_icons.png.c +++ b/source/blender/editors/datafiles/blender_icons.png.c @@ -1,6723 +1,6760 @@ /* DataToC output of file */ -int datatoc_blender_icons_png_size= 214916; +int datatoc_blender_icons_png_size= 216116; char datatoc_blender_icons_png[]= { -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, 9, 1, 15, 54, 15, 19,126,136,129, 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, 67, 81,148,135,213,106,101,245,122,253, 3,163, -209,120,218,106,181,158, 6,112,173, 58,137,245,242,242,106, 53,110,220, 56, 81, 81, 81, 17,132, 66, 33,172, 86, 43,114,115,115, -209,169, 83, 39,193,161, 67,135, 90,212,228, 6, 20, 22, 22, 46,255,230,155,111,206,238,220,185,179,143, 82,169,124, 73, 42,149, - 6, 3, 96,180, 90,109,142, 94,175,255,163, 38,233, 44,211,206, 49, 76,206,181,107,215, 34,148, 74, 37, 30, 62,124, 8,134, 97, -114, 30,183, 14,200,196,228,163,155,231, 15,213,109,230,223, 0, 23, 47, 95,133, 76, 76, 62,226, 67,125, 61,247,176,251, 80,193, - 81, 64,185, 16, 72,151,227,226,226,228,139, 22, 45, 66, 92, 92,220, 45, 87, 22, 45,187,224,138,139,139,187,101, 63,206,225,248, -243,143,145,198,138, 45, 90, 21, 41, 72,160,100,118,161, 90,173,246, 81,169, 84,165, 2, 43, 51, 51, 19,153,153,153,144, 72, 36, - 72, 75, 75,131, 68, 34,201,114,167, 19, 34,151,203,127,107,211,166,205, 11, 41, 41, 41,226,249,243,231,215,189,118,237,154,178, - 83,167, 78, 47,202,229,114,134,227, 56,152, 76, 38, 50, 49, 49,209,115,217,178,101,161,237,219,183,183,180,111,223,254,250,238, -221,187,141,168, 36,254, 21, 65, 16,191,100,101,101, 53,172, 95,191,190, 93,180,149, 17, 87,142,130, 11, 40, 25,242, 20, 10,133, -215, 43, 75,168, 80, 40,188,153,148,148,212, 91, 33,147,194,162,213,192,170,211,128,214,106,193,104,139,193, 20, 23, 3,122, 13, - 36, 52, 13, 17, 67, 65, 46,147, 33, 35, 61, 29, 66,161,240,102,101,156, 18,137,228,102, 78, 78, 78,111,149, 74, 85,250, 18,165, -104,186,100, 97, 24, 88,104,186,212,162, 37, 18,137,240,232,209, 35, 72, 36,146,155, 79,186, 38,147, 36,201,216, 67, 56, 84,144, - 15, 4, 5, 5,177, 29, 58,116,192,148, 41, 83,192, 48,140,173, 24,136,238, 0, 46,162,196,191,229,153,132, 43,113,107,119, 90, - 55, 26,141,208,233,116, 40, 44, 44, 20,202,229,242, 23, 66, 67, 67,175, 90, 44,150, 61, 52, 77,111,121,240,224,129,166, 34, 78, -155, 48, 43, 21, 93, 44,203,130,227, 56, 48, 12, 3,138,162, 32, 22,139,217,115,231,206, 99,217,138, 37,136,223,178,157, 27, 52, -104, 16,113,232,208, 33,176, 44,155,254,132,179,111,177,137,150,202, 26, 13,231,144, 10, 31,161,242,144, 10, 21,113, 58,246,254, - 28,183, 17, 46,142, 41,135, 15, 62,248,224, 4, 74,134, 12,243,108, 98,238,113, 56,191, 44,250,238, 11, 25,104, 70,111, 62,183, - 83,247,237, 93,141,126,222,183, 43,127,179, 72, 4,154,151,187, 5,181,108,216,224, 5,129, 74,229, 67,174,223,184, 42,127,199, -246,189,201, 15, 31, 62,212,172, 93,187,182,227, 11, 47,188,224,253,199, 31,127,132, 86, 36,180, 20, 10, 69,227, 55,223,124,115, - 92, 97, 97,161, 56, 62, 62,126,119, 86, 86,214,111, 40, 9, 45,227, 56,131,122, 0,128,173, 54, 33, 26,100,107,231, 46, 2,152, - 95, 89,127,141, 32, 8,252,244,211, 79,229,102, 7,178,143,167,206, 85,141, 26, 53, 26,145,146,146,114, 33, 39, 39,103,152,243, - 78,177, 88, 60,175, 73,147, 38,125,111,221,186,245, 57,128, 99,213, 33, 54, 24, 12,177,123,247,238, 93, 42, 16, 8,234, 48, 12, -147,105, 52, 26, 99, 31,219,162, 69,177, 19,226,214,239,218,100,180, 48,225,114,137,224,161,137, 98,223,226,117,200,243,107,205, -178, 65,237, 96,141, 82, 3, 32,156,214,255,176,189,140, 44, 28,199,217,143, 85, 59, 88,177, 44, 78, 86, 48, 87,251,212,143, 17, - 44,157,171,168,141,171,200,162,245, 9,128,246, 0,126,201,201,201, 89, 53,118,236,216,101, 59,118,236,240,210,104, 52,200,201, -201, 65,110,110, 46,132, 66, 33,148, 74, 37,214,173, 91,103,204,201,201, 89,229,120, 14,202, 71,144, 7, 0,147,191,191,255,111, -219,183,111, 15,254,250,235,175,133, 49, 49, 49,105, 3, 6, 12,104,186,110,221,186, 20,177, 88,204, 49, 12, 67,152,205,102,226, -237,183,223,142, 88,177, 98, 69,170, 64, 32, 80,140, 24, 49,130,240,240,240,248, 5,149,132, 13, 80,171,213,167,190,255,254,251, -161,211,167, 79,151, 90, 44, 22,151,150, 44,251, 54,149, 74,133, 75,151, 46, 89, 10, 11, 11, 79, 86, 97,197, 56,245,195,177,163, - 93,255, 51,114,164,152,210,106, 64,105, 53,160, 53, 26, 48,218, 34, 16, 58, 13, 68, 12, 13,185,152, 69,112,152, 12,180,209, 19, - 71,127,253,131, 50,155,205,149, 6, 54,212,104, 52,167, 46,198,199,119,111, 95,175,158,240,210,180,105,176, 82, 20, 94, 73, 74, - 42, 21, 87, 86,171, 21, 7, 91,182, 4, 67, 16,104, 61,113, 34,238,209, 52,173,209,104, 78,253, 47, 62, 12, 55,110,220,200, 29, - 61,122,244, 53,150,101,219,226, 9,125, 52,243, 73,128,162,168,114,214, 40,134, 97, 74,172,142, 37,150, 3,201,209,163, 71,187, - 38, 38, 38,138,255,252,243, 79, 92,184,112,161,245,142, 29, 59, 62, 9, 15, 15,111,249,240,225,195,236,170,196,155,171,160,191, -176,249, 31,238,222,185, 7,239,188,243, 14,145,157,157,141,239,190,251, 14, 85, 5, 79,253, 59, 16, 19, 99, 98,227,227,101,117, -225,228,247,228, 34,164,194,239,112, 51,164, 66, 69,156,166,152, 18, 43,153, 44,190, 36,216,168, 41,166,100, 56, 80, 22, 95,165, -165, 12, 49,166, 24,141,205, 33, 62,171, 22, 56,245,160, 25,185,229,220, 78,221,128, 99, 15,181, 87,178,140,243, 1,156,128,137, -225,238, 93,231,110,188,244,146,143, 63, 0,152, 77, 76,112,227,198,141,187, 9,133, 66, 9, 0,120,122,122,190,228,231,231,183, - 46, 63, 63,191,179,171, 50,141,142,142,238, 16, 24, 24,216,230,248,241,227,127,100,101,101,221, 2,240,179,243, 65, 17, 17, 17, -115,110,223,190,221, 78, 36, 18, 17, 85,212, 17, 0, 64,183,110,221, 94,144, 74,165,126,199,238,122, 67, 35,110, 4, 78, 80, 12, - 8,101, 96, 84,173,144, 38,110,142,176,176,171,126,133,133,133,173,139,139,139,255,168,102,209,247, 24, 58,116,232,150,248,248, -248,176,110,221,186,113,215,175, 95, 39,157, 71, 17, 34, 34, 34,250, 92,185,114,165,237, 91,111,189,181, 97,215,174, 93,147, 81, -118,166,109, 85, 72,179,197, 27,172, 53,156, 74,198,105,128,169,103,179,153,241, 10,229, 31,128,234,132, 92,120,140,240, 12,143, -149,196, 10, 13, 24, 21,108,111,111,139,137,213,158,162,168,223,111,220,184,113,112,196,136, 17,186,252,252,124,248,249,249,161, -126,253,250, 32, 8, 2,235,214,173, 51, 62,120,240, 96,159, 45,150, 86,251,204,204,204, 65, 54,177,229, 10,218,213,171, 87,239, -218,182,109,155,234,218,181,107, 2,154,166,149, 77,155, 54, 53, 92,190,124,217, 83, 36, 18,113, 98,177,152,189,118,237,154, 34, - 34, 34,194, 68, 16,132,244,199, 31,127,204,191,122,245,106,248,140, 25, 51,190, 65,217,105,226,206,216,185, 96,193,130,140,148, -148, 20,152,205,102,104, 52, 26, 20, 23, 23,151, 46, 69, 69, 69, 40, 46, 46,134, 72, 36, 66,118,118, 54,246,239,223,159,101,139, - 18, 95,153,101, 99,237,154,117,235,213, 89, 15,211,160, 84,200, 65,107,138,192, 20,231, 3,218, 98, 72, 40, 43, 60, 68, 12,234, - 54,146, 67,166, 80, 34, 71,163, 67,252,229, 95,179,109, 81,226, 43, 54, 23, 88, 44,107,223, 93,177, 34,135, 22,139, 81,111,248, -112, 88,109, 67,133,142, 66,139, 33, 8,132,247,234, 5,210,219, 27, 11,247,237,203,177, 69,137,127,162, 96, 89, 86, 96,177, 88, - 42,203, 7, 88,150, 77, 79, 76, 76,220, 5,224, 44, 65, 16, 28, 65, 16, 28, 74,130,181,233,158,229, 7,153,162, 40,204,157, 59, - 23, 98,177, 24,115,231,206,197,167,159,126,138,101,203,150, 97,253,250,245,248,246,219,111,113,244,232,209, 6, 23, 47, 94, 20, -159, 63,127,158,139,139,139,203,139,136,136, 16, 76,156, 56, 81, 37,151,203, 63,168,140, 51, 54, 54, 22, 94, 94, 94,136,141,141, -197,146, 37, 75,176,121,243,102, 28, 60,120, 16,151, 46, 93,130, 64, 32, 96,211,211, 31,193,100, 50,113,171, 87,175,206, 56,120, -240,160,113,213,170, 85, 16, 10,133,196, 83,106, 36, 62,176, 9, 42, 71, 75,144,115, 72,133,124, 0, 43, 81,181,111, 84, 69,156, -144,197,199,215,181,137,163,100, 7, 65,116, 24,192,116, 84, 62,189,218,206, 49, 25, 64,112, 45,112,206,150,143,254,191, 68,213, -166, 59,247,175,100, 25,103, 3,248,193,158, 39,165, 82, 41, 63,112,224,123, 33, 0,236,219,187, 95,148,148,148,228,253,253,247, -223,203, 2, 3, 3,241,237,183,223,202,228,114,121, 96, 5,156,204,193,131, 7,205, 18,137,196,111,194,132, 9,253,218,181,107, -247,190,173, 35,218, 11, 64, 11,148,204, 94,140,186,127,255,126,130,191,191,255,221,147, 39, 79,234,221, 41, 32,173, 86,251,205, -214,173, 91,235, 23, 48,190, 56,166, 31,138,120,118, 41,142,170,182, 32,173,222,167, 80,212,121, 25,175,191,254,122, 29,134, 97, - 54, 85,179,220, 95, 31, 50,100,200,214,248,248,248,176, 9, 19, 38,100, 95,191,126, 61, 7, 64, 60,128,237,142,203,237,219,183, -243,198,142, 29,155,181,105,211,166,144, 17, 35, 70,172, 7, 48,140,127,245,243,224, 81,182, 47,132,170,102, 29,186,120,225,150, -254,207,205,205, 93, 93, 88, 88,120,233,222,189,123,239, 89, 44,150, 16,130, 32, 56,177, 88,156,157,147,147,179,202, 33, 96,169, - 43,191,146,222,176,197,218, 32, 8,130,226, 56, 46,189, 71,143, 30, 31,244,234,213,235,171, 35, 71,142,152,186,119,239,142,189, -123,247,250,247,232,209,195,192,178, 44,119,236,216, 49,255,190,125,251, 26,206,158, 61,171,127,251,237,183,155, 54,105,210,100, - 98,108,108,172,154, 32, 8,214, 21,167,253, 93, 86, 84, 84, 52,164, 95,191,126,151,246,237,219,167, 84,169, 84,160,105, 26, 6, -131, 1, 6,131, 1, 28,199,193,219,219, 27,106,181, 26,243,231,207,215, 20, 23, 23, 15,118, 33,220,156, 57, 77, 38,147,105,216, -228,247,167,159, 90,245,249, 92,175,240, 6, 13,144,127,199, 4,218,100,128,136, 35, 81,247, 5,111,136, 37,114,220, 75,210,226, -163, 93, 7,180, 70,147,233, 53, 23,189,229,114,156,197,197,197,195, 98, 62,253,244,244,134, 25, 51, 60,219, 4, 5, 65, 32, 16, -192,108, 54,131, 97, 24,136, 68, 34, 68,198,196, 64, 28, 16,128, 57,187,118,233, 53, 26,205, 48,148,255, 20,143, 51,103,109,192, -145,115,242,141, 27, 55,198, 54,107,214, 12,147, 38, 77,194,144, 33, 67,202, 28,248,253,247,223, 99,253,250,245, 48,155,205, 99, - 1, 92, 7,176, 14, 37, 67, 29,112, 18, 89,127,119, 58,107,157,147, 97,152,194,164,164, 36,229,210,165, 75, 9,171,213,138,207, - 63,255, 28,118,193,105,175,215, 83,166, 76,169,227,229,229,133,207, 62,251,204,146,151,151,215,115,201,146, 37,103,182,111,223, -238,255,205, 55,223,188, 14, 32,214,153,147,101,217,220,155, 55,111,122,109,216,176,129,164,105, 26,203,151, 47, 47, 55, 60, 57, -126,252,120, 88,173, 20, 4, 2,161,197,100, 50,183,144,203,229,201,126,126,126,114,174,172,115,215,147,188,159,161, 40, 9, 97, -224,232,248,110,113,244,207, 66,197, 33, 21,170,195,169,150,197,199,119, 55,197,196,156,181, 9,162, 68,219, 49,123,237, 38,253, -106,112,218, 5, 97, 77, 56, 79,217,150, 42, 97, 50,153,160, 86,171,145,151,151, 7,149, 74, 5,129, 64, 64, 84,148, 78,179,217, -252,231, 71, 31,125,116, 99,211,166, 77,189,175, 92,185, 50,240,252,249,243, 61, 78,159, 62,109, 74, 75, 75,163, 41,138,226, 66, - 66, 66,132,157, 59,119,150,245,239,223,223, 67, 42,149,146,179,103,207,206,251,226,139, 47,252, 81,214,135,205, 57,239, 2,130, - 32,240, 97, 87, 45, 98,123, 8, 96,177, 88, 81, 84, 84,132,140,140,116, 36, 36, 36,224,202,149, 59,224, 56,142,172, 70,185,251, - 1,152,253,221,119,223,133, 74, 36, 18, 98,215,174, 93,117,118,237,218, 85,165, 37,117,199,142, 29,117,118,239,222, 61,207, 54, -122,145,254, 44, 62,239, 60,231,255, 44,231,179, 12,231,200,240,168, 82,104,217,218,249,246,176,125,148,148,162,168, 95, 92,132, -112,248, 4,192, 92, 7, 43, 88, 85,230, 60, 13,199,113, 23,122,247,238, 61,165, 87,175, 94, 43,250,244,233,147,149,149,149,213, -112,249,242,229, 97, 52, 77, 91, 19, 18, 18,200,228,228,228,180,223,126,251,173, 81,147, 38, 77, 38,222,190,125,251, 28, 65, 16, - 86, 55, 50,152,144,156,156,220,169, 71,143, 30,251, 39, 78,156, 24,222,161, 67, 7,137, 74,165,130, 80, 40, 68, 74, 74, 10,254, -248,227, 15,203,238,221,187,211,139,138,138,170,243, 9,158, 95, 82, 51, 50,162, 70, 76,125,111,223,196, 33, 3,253,255,213,244, - 5, 73, 72, 72, 8, 96, 52,226,206,195,108, 92,189,243,135,117,243,133,171,106,179,217, 60, 12,238,127,130,231,151,223,238,221, -235,221,115,198,140,125,243,254,243,159, 32,100,101, 9, 67, 66, 66, 32,145, 72,240,224,193, 3, 36,179, 44,189,120,227,198, 28, -155,200,122,210, 81,225,165, 0,150,178, 44, 43, 4, 0,185, 92,142,119,223,125, 23,142,159,220, 89,191,126, 61,140, 70, 35, 0, - 8, 9,130, 88, 10, 96,203,179,110,197,178,163,160,160, 96,206, 43,175,188, 18, 39, 20, 10, 43,140,122,235,227,227, 3,173, 86, - 11,154,166,153,140,140,140, 59, 62, 62, 62, 16,137, 68,224, 56,206,229,115,148,159,159, 63,103,216,176, 97, 11, 72,146,172,200, -242, 1,165, 82,153,118,230,204,153,198,111,189,245, 22,249,223,255,254, 55,101,194,132, 9,210, 51,103,206, 48, 28,199,237,127, -210,247,160, 75,151,157,192,134,152,215, 0,188, 6,148,115,120,207,176,109,171, 86, 72,133, 46, 93,118, 98, 3,254,226,116, 28, -198,179, 11, 34,155, 21,170,185, 44, 62,126, 5, 74,252, 44, 42,229,238,178,179, 11, 54,196,160, 86, 57,221,129,163,246,213,235, -245, 96, 24,166, 50,107,222,239,123,247,238, 93,241,219,111,191, 5, 76,153, 50,165,225,127,254,243, 31,101,143, 30, 61, 60, 29, - 15, 48, 26,141,236,225,195,135,245,235,215,175, 47,190,112,225, 66,234,248,241,227, 59, 84,150,206,135, 15, 31, 30, 93,184,112, -161,119,255,254,253,155, 0, 40,245,207, 82,171,213, 72, 75, 75,195,159,127,254,153,102,181, 90, 15, 85, 35, 75,249, 0,230,141, - 26, 53,106,233,182,109,219,234, 76,152, 48, 33,123,247,238,221,127,162, 36, 96,177, 51, 84, 67,134, 12,105,185,109,219,182,144, - 9, 19, 38,100,163,196,143, 44, 29, 60,120,240,176,163, 59,202,251,105, 85, 58, 50,177,213, 98,177,112, 38,147,137, 51, 24, 12, -156, 78,167,227,224,250, 43,240, 7, 51, 51, 51,185,244,244,116,238,225,195,135, 92,106,106, 42, 7,224, 91, 39,197,235,170,193, -242,216,177, 99, 71,163,208,208,208,207, 21, 10,197, 9,129, 64,160, 17, 8, 4, 26,169, 84,250,131,159,159,223,167,139, 23, 47, - 14,229, 56, 78, 92,137,138,174, 8, 66,145, 72,244, 86, 96, 96,224, 65, 95, 95,223,116, 31, 31,159,244,192,192,192,131, 34,145, -232, 29, 0,162, 42,148,121, 69,144, 9,133,194,143, 60, 60, 60, 78, 73,165,210, 92,169, 84,154,235,225,225,113, 74, 40, 20,126, -132,202, 3,169, 86,202, 41,145, 72, 62, 10, 8, 8, 56,165, 84, 42,115,149, 74,101,110, 64, 64,192, 41,137, 68,242, 56,156,143, -211, 43,177, 11, 45, 3,103, 3, 65, 16, 84,235,214,173, 55,180,109,219,118, 93,219,182,109,215,181,106,213,234,107,155, 85,146, -179, 89, 91, 12,168, 56,120,227,223,153,206,167,198, 25, 25, 25,185,125,219,182,109,236,156, 57,115, 52, 77,154, 52, 41,152, 51, -103,142,102,219,182,109,108,100,100,228,246,154,114, 6, 5, 5,213,139,140,140, 44,216,180,105, 19,157,148,148,196,109,218,180, -137,142,140,140, 44,112,138, 12,255, 36,242, 78, 0,136,176, 89,127, 14, 1,216,131, 18,231,247, 80, 0, 68,140, 41,134,179,205, - 62, 60, 1,160, 79, 5,101,239, 46,103,152, 41, 38,134,179,249, 84,157, 4,144,232,176,222, 13,101,253,191,158, 4,167, 75,180, -104,209,226, 30,231, 0,139,197,194,169,213,106, 46, 41, 41,137,187,112,225, 2, 23, 22, 22,118,207, 13, 78, 63, 0,111, 3, 56, - 28, 28, 28,124,187, 99,199,142, 15, 59,117,234,244,176, 94,189,122, 41, 34,145,232, 10, 74, 34,188, 71,218,150,165, 0,154, 84, -193,217, 81,165, 82, 45, 12, 11, 11, 59,212,184,113,227, 75,245,235,215,191,226,235,235,123, 68, 38,147, 45,194, 95,145,177,171, - 91,231,123, 12, 29, 58, 52, 77,167,211, 49, 47,189,244,210,109, 87, 39, 53,107,214,236,162, 78,167, 99, 70,142, 28,153, 14, 32, -250,159,240,188,243,156, 79,133,243, 31,133,198, 54,193,116,208, 97,249,196,197,113,159, 56, 29,179,213,118,110,149, 5,193,113, -156,128,227, 56, 15,142,227,188, 57,142,243,229, 56, 78,197,113,156, 39,199,113,210, 42,204,223,124,197,254,251, 56, 39,219, 4, -148,193,246,223, 25, 85,237,127,174,239,103,104,104,168, 79,187,118,237,166, 30, 56,112,224,163,251,247,239,127,116,224,192,129, -143,218,181,107, 55, 53, 52, 52,212,231,113,210, 25, 20, 20, 84,175,121,243,230, 95, 53,107,214, 44,189,121,243,230, 95, 57,137, -172, 39,153,119,137, 77,196, 52,179, 45, 13,109,219, 8,148,196,194, 90,107, 19, 54, 17, 21,244,212,170,195,105,231, 59, 4,160, -175,109, 57,100,219, 22,246, 20, 56,203,161, 65,131, 6,199, 91,182,108,121,175, 85,171, 86,201,173, 90,181,186,215,162, 69,139, -123, 77,155, 54,189, 23, 17, 17,113,175,110,221,186,247,252,253,253,143,215,160,140,124, 1,132,160,252,103,192,158,118,157,239, - 30, 25, 25,121, 85, 38,147,185,140, 13, 38, 20, 10,231,181,106,213,234, 38, 74,102, 74,242,237, 39,207,201, 11,173,255, 33,240, -149,240,217,227,148,162,242,207,140, 84,181,159,191,159,207, 54,167,203,111,117,217,132, 76, 67,155,192,145,212, 2,167, 35,159, -189, 78, 69, 56,136,166,167,193,201,215, 37,158,147,231,228,133, 86,173, 67,200,223, 2, 30, 78, 48, 63,230,126, 30,207,197,104, - 60,126, 0, 0, 32, 0, 73, 68, 65, 84, 54,170, 19, 19,235,113, 56, 93,241,221,127,202,156, 60,120,240,224, 81, 91,109,103,119, - 0,231,236,189,194,138, 84,105,117,102, 19,212, 68,217,158,230, 57,121, 78,158,147,231,228, 57,121, 78,158,243, 31,199,105,199, -138, 10,182,223,113, 90,255,250, 25, 21, 94, 79, 36, 76, 15,111, 86,229, 57,121, 78,158,147,231,228, 57,121, 78,158,179,166,152, -248,140,138,172,110,246, 21,126,232,144, 7, 15, 30, 60,120,240,224,193,163,246, 80,117, 28,173, 61,123,246, 8,236,255, 71,141, - 26, 53,158, 97,152,169,246,117,129, 64,176,230,187,239,190,219, 82,217, 21,134, 15, 31,206, 84,198,233, 10, 85, 93,199, 21,103, -139, 38,202, 73,126,222,138,247,138,138, 13, 43, 83, 50,153, 11, 38,147,169,185,125,159, 76, 38, 75,220,178,101,203,221,218, 78, -231,248,241,227,155, 56, 95,167,126,152,168,187,175,151,236,221,130, 34,221,242, 91,247,116, 95,243,117,236,169,192, 31, 64,180, -151, 76, 60,168,133, 74,220,241,207,124,211,101,189,149, 57,140,146,217,176,133,207, 99,134,131,131,131,155, 42,149,202, 49, 0, - 90, 24, 12,134, 64,133, 66,145, 11, 32, 65,163,209,108,207,206,206,190,227, 46, 79,183,250, 72, 3, 16,110, 91,125,120, 46, 21, -245,220,217, 87, 21,250, 68,192,196, 1, 82,130,128,245,100,242, 95,206,232,125, 27,193,196,114,229,183,247,105, 4, 11,199, 65, - 76, 0,230,147,247, 33,123,142,138, 74, 9, 32, 10, 37, 33, 28,110,160, 36,252,132,129,127,100,121,240,120,174,224, 60, 84, 88, -186, 46,172, 64, 76,116, 21, 11,137,175, 56,112, 42,128,243, 51,155,205, 34,137, 68, 2,139,197, 2,133, 66,190,246,237, 9,227, - 63, 7,137, 34,138,198,187, 91,182,108,169,241,151,174,171,115, 29, 0, 63, 57,159,239,163,148, 47, 56,123,248, 99,159,174, 3, - 22, 47,178, 60,200,139,213,106,181,164, 84, 42,133,217,108,134,183,183,119,167, 73, 19, 39,190, 68,138, 56,139, 88,236,113,121, -197,138, 21,217, 53, 77,231, 7, 31,124, 16,108,181,154,254,205,178,172,196, 98,177, 72,157,175,227,173,240, 88,124,246,240,199, -138,110,209,139, 62, 7,120,161,245, 20, 32,169,231,227,113,110,229,168,238,205, 58,182,104, 12, 54,225, 60, 76, 22,235,160,179, -233,186, 65,159, 94,201,156,158,174,179,182, 69, 45, 4,172,252, 31,130,160, 97,195,134, 83, 2, 2, 2, 70,110,220,184, 81,220, -176, 97, 67,200,100, 50, 24,141,198,144,251,247,239,135, 76,154, 52,169,155, 92, 46,223,149,146,146,178, 22,238,125, 8, 46,252, -236,214,255, 3, 0,116, 26, 51, 63, 28, 37, 31,139, 54, 56,239,235, 62,110,126, 56,128, 25, 40,251, 97,228, 44,148,132, 80,112, -213,234, 72,142,108, 91,134, 65, 99, 63, 18, 2,152, 84,154,120, 18,248,225,219, 85,232, 55,234,189, 50,219, 9, 14,194,195,219, -150, 33,122,236, 71, 21,126, 71,177,111, 99,130, 98, 89,174, 66, 75, 60, 73, 18,244,137,123,156,171, 15, 12,231,160, 36, 6, 88, - 57, 74,148,124,208,217,229,241, 3,154, 10,114,172, 20,227, 50,224,172, 88, 36,200, 61,122,135, 41,119,110, 76, 27, 80, 20, 83, -210,182,138,133, 96, 14,166,120,159,157, 61,123,182, 48, 58, 58, 26,155, 55,111,238,252,245,215, 95, 79,212,106,181, 63,218,238, - 91, 50,255,248,242,224,241, 92, 11, 46,215, 66, 75, 40,192,134, 67,251,182, 52,202,201,205, 67,204, 91, 31, 98,231,206,157, 40, - 44, 44,132,143,143, 15, 36, 98,177,104,229,210,255, 11, 86, 42, 61,130, 99, 38,198,110, 0,208,180,166,169,169,230,117, 26, 59, -159, 79,216, 62,165, 35, 20,144, 34,137, 68, 66,238,218,181, 11, 69, 69, 69, 80,169, 84,144, 72, 68,228,138, 69,159,200,149, 74, - 79,249,155,147,103,118, 70, 73,252,159, 26,193, 98,209,117, 62,176,115,139, 82,173, 86, 99,220, 59,177,112,190,142, 88, 44,102, -236, 47, 22,190,142, 61, 21,204,222,248,238,216,102, 47,122, 1,214, 91,151, 32, 18, 8,160,240,246, 65,148, 80, 0, 1,129,230, - 49, 39, 82,103, 1,248,244,121,201,108,195,134, 13,167, 12, 31, 62,124,228,130, 5, 11,196, 36, 89, 18,114, 78,175,215,195,104, - 52, 34, 52, 52, 20,103,207,158, 21,207,153, 51,103,228,247,223,127,143,148,148,148,213,213,229,191,117,235, 86,253,240,240,112, - 19, 0, 12,108,233,229,188,175,158,125, 31, 0,120,121,121, 85,201,231,167,242, 48,223,186,117,181,133,253,188, 41,189, 66,153, - 10,182,155, 0, 40, 42,227, 98, 89, 78,120,242,171, 73, 21,238,127,107,193, 14,250,198,158, 11, 77, 27, 54,108,104,116,220,238, -233,233, 89,209, 41, 65, 58,157, 46,220,121,163,253,120, 43,197, 4, 86,116,189, 62,239,174,119, 41,192, 40, 6,194, 29, 59,118, - 0, 0,190,252,104,180, 96,211,207,121, 66,161,176,164,169, 93,186,116, 41,230,205,155, 39, 57,113,226, 68,255,109,219,182,245, - 63,120,240,224,202,138,132, 42, 15, 30, 60,158, 73,145,229,248, 91,177,208, 34, 9,194, 75,233,229,137,215, 94,127, 27,199,143, -255,128,174, 93,187,150,238,107,208,160, 1,134, 15, 27,140,239,182,174, 0, 0,175,199, 73,209,227, 94,167,176, 88,255,105,191, -145, 95,205,127,152,173,187,114,228,200, 17,116,233,210,165,204,249,175,143,120, 13,223,126,179, 20,149, 68,153,119, 11, 4, 71, -138,189,148, 30, 24, 21,243, 14, 92, 93,103,226,184, 33, 71,250, 14, 95,213, 59, 39, 95,191,130,175,103, 79, 30,141,130,253,250, -180,108,214, 20,133,251,215,226,143, 34, 19,142,103,154,240,102,212,191, 16,233, 43, 71, 23,154, 65,176,135,168,103,182,158,122, - 46,132, 86,112,112,112,211,128,128,128, 50, 34, 75,171,213, 66,167,211, 65,163,209, 64,171,213,130, 36, 73,196,198,198,138,207, -157, 59, 55, 50, 56, 56,248,180, 27,195,136, 15,109,150, 44, 64, 32,210,205,157, 59,215, 28, 24, 24,104, 86, 40, 20,156, 80, 44, -213,118, 31, 55,223, 11, 0, 72,161, 88,187,114,229, 74, 75,104,104,168, 73, 40, 20, 74,222,123,239, 61,210,157, 52,155,205,102, -206,145,211, 98, 49,151,110, 95,188,120,177, 37, 40, 40,200,172, 80, 40, 56,171,213,125,163,227,205, 7, 5,144,138, 5,144,138, - 5,144, 73, 68,240,170,223, 14,210,194, 63, 65,211, 52,150, 44, 89, 98, 13, 14, 14,182, 40, 20, 10, 78, 34,145,136,167, 77,155, - 86,101, 58,199,143, 31,207,169, 84, 42,171, 66,161, 16,207,155, 55,175,220, 76,161, 51, 55, 50, 32,151,136,160,144, 10,209,184, - 65, 24,164,156,209,237,180, 10, 4,101,189, 17,164, 82, 41, 58,119,238,140, 22, 45, 90,224,224,193,131,221,121,161,197,131,199, -115,129, 10,103, 24, 10, 1,224,200,145, 35,221, 80,242, 65, 68, 68, 71, 71, 19, 37,103,112,152, 49,101, 24,222, 28, 55, 10, 12, -195,150,126,231,139, 32, 9, 76,126,163, 63, 88,214,157, 17,137,170,167,120,214,224, 58,165,156, 28, 65, 10, 0,160, 81,189, 16, -110,226,155,255, 1,195,178,127, 13,148, 8,128,183,199,245, 43,217, 86, 11,233, 20,128,193,135,147, 94,133,171,235, 52,109, 84, -135,164,173, 38, 16,101, 63,246,248,119,124,108,147,231,116,129, 22,117, 67, 34, 40,163, 17, 38, 19,133,248, 59, 5,198, 83, 25, -250, 64, 82,149,170, 94,245, 90, 7,153, 64,157,137,122, 94,146,198,217,122,234,185,200,187, 82,169, 28,179,113,227,198,114, 34, - 43, 39, 39,135,212,233,116,176, 90,173,172, 86,171, 5,195, 48,152, 57,115,166,104,206,156, 57, 99,178,179,179,231,217, 53,143, - 43, 78,155,223,213,140, 91,183,110,213,155, 61,123,182,181,103,207,158, 15, 27, 52,104,160, 23, 8, 4, 8, 9, 9, 89, 21, 21, - 21,229,187, 96,193, 2,107,255,254,253, 83, 5, 2, 1, 26, 55,110,172,255,243,207, 63,235, 1,144,187,155,119, 71,206, 45,103, -214,112, 0, 64, 16, 4,162,162,162,210, 26, 55,110,172, 23, 8, 4,184,123,120, 49,231,238,253, 20, 9, 73, 52, 9,245,182, 53, - 34, 4, 32,247, 44,245,196,139,138,138, 74,111,218,180,169,142, 36, 73,220,188,121, 51, 12,229, 63,107, 85,142, 83, 46,151, 83, -175,191,254,250,195, 59,119,238,184, 58, 30, 66, 1,137, 14, 77,109, 6,172,208,182, 64,250,197, 10,211, 41, 18,128,158, 51,101, -180, 80, 37, 3,164, 94,254,102,141, 70, 3,165, 82, 89, 98, 33,179, 90,241,251,239,191,163, 99,199,142,221,246,236,217,115,142, -127,222,121, 78,158,243, 47,184,210, 34,207,160, 53,203,241, 67,247,101,124,180,206, 58,103,138, 97,104, 52, 8, 15,194,226,255, - 27, 15,134, 97,193, 48, 12,104,219, 47,195, 48,160,172,214, 90, 73,217,227, 92,199, 71, 41, 95,240,195,174,119,125,122, 14, 89, -218, 43,110,246,184, 83, 12, 3,176, 44, 5,138, 2, 24,150, 2,203, 48,160,168,218,113,205,161, 88, 22,245,194,130, 17, 55,123, - 28,156,175,179,253,187, 61, 3,207, 28,138, 85,116,141, 94,244,225,221, 52,195, 18, 94,216, 63, 89,200,196, 82, 33, 39,148,193, - 98,161,161,181,176, 22, 0,122, 19,197, 90, 57, 15,127, 25, 0, 8, 73,226,121,154, 93,219,162, 97,195,134,101, 68,214,178,101, -203,252,215,173, 91, 23, 10, 0,195,134, 13,203,232,213,171, 87, 94, 82, 82, 18, 66, 66, 66,136,188,188,188, 1, 0,222,179,157, - 59, 3,192,186, 10,120,245,225,225,225,166,128,128, 0,179, 93, 16,145, 36, 9,161, 80,136,240,240,112, 83, 96, 96,160,185,113, -227,198,122,177, 88, 12,146, 36, 97, 23,122,110,117,243, 8, 2, 2,129, 0,118, 78,103,107,143,157,179, 58, 16, 9,201,242,205, -155, 3, 39, 73,146, 46,175, 87, 97, 29,146,201, 56, 0, 21, 30, 47, 32, 29,154, 71, 97,229, 30, 2,241,191, 67, 4,224, 44,199, -113,184,126,253, 58, 82, 82, 82, 32, 22,139, 17, 28, 28,140,121,243,230,193,108, 46,209,187,195,135, 15,239, 6,224, 38,255, 4, -243,224, 81,138,179,207,160,192,114,182,106, 85,238,163,117,228,200,145,110,209,209,209,231,236, 2,168, 68,236,184, 16, 63, 20, - 13,138,178, 2, 28, 87, 43, 66,171,162,235, 48, 12, 91,233,117,236, 62, 90, 44,203, 9, 93,138, 44,150, 5, 77, 81,181,114,247, - 88,134, 2,203, 82,112,117, 29,130, 32, 25, 91,131, 47,230,159,147, 39,143,224,240,122, 36, 21,222, 0, 23,104, 19, 66,253,164, - 18,228, 25,209,240,133,102,130,223, 13, 20, 46,221, 72,132,191,167,242,185, 41, 23,131,193, 16, 40,147,201,160,215,235, 75, 45, - 89,235,214,173, 11,181, 88, 44, 36, 0, 8,133,162, 48, 53, 27, 42, 99, 88,192, 91,153,133,194,194, 98, 63,142,227, 8,155,224, - 89, 10, 96, 11, 42,137,238, 47, 22,139, 75, 5,138,163, 0,146, 74,165, 53, 18, 48,118,216,197,153, 88, 44,118,185,221,121,120, -173, 42,136, 29,133, 22,184, 18,171,150,147,216, 18, 8, 4,176,251, 70, 85, 5,137, 68, 82,154,119, 87, 16, 10, 28,174, 39,168, -190, 43,166,213,106,133, 78,167, 67, 81, 81, 17,100,178, 18,131, 25,199,113, 32, 8,226, 61, 0,239,243, 79, 49, 15, 30,174,181, -200, 51, 44,182, 92, 11, 45,148,152,236, 8, 0,160, 41,171, 75,241,179,231,240, 37, 60,204,214, 35,216,255, 23,112,213,140,122, - 58,114,228,200,173, 33, 33, 33, 29,236,235, 82,185,167,223,196,119, 63, 3, 77, 91,225, 37, 39,241,214,152,126,101, 68, 86,137, - 69,203, 82,225, 55, 65, 10,139,245,159,246, 27,190,122,190,183,210,239,138,179,248,137,139,191,246, 90,161,198, 28, 70,146,191, -162,144, 8, 97,134,191,253,217,120,135,198,253,198,174,245,115,167,187,109, 15, 36, 72,209,107,147, 86, 77,228,132,158,205, 21, -164,246,252,199,227,254,117,192, 81,204,249,250,250, 30,233,243,218,202,222, 57, 5,188,143,214,211,128,151,183,138, 12,123,185, - 59, 94,126,239, 43,156,249,228, 99, 14, 40,132, 95, 72, 40,217, 99,202, 23,240,124,121, 32,174,190, 53,134, 5, 10,158,139,188, - 42, 20,138, 92,131,193, 16, 98, 52, 26,161,209,104,160,209,104,202, 10, 2,145,136,152,248,206, 84,127,145, 88, 2,202,106,193, -241,237, 95, 84,201,105, 15,225, 48,176,165, 23, 4, 34,137, 54,161, 97,195, 85, 66,161, 16, 36, 73,226,240,218,143,223,219,191, -252, 93, 47, 0,184,113,100,173,102, 84,236,154,213, 36, 73,194,108, 54, 75,171,147,238, 71,143, 30,133,153,205,102,147, 77,160, -217,133, 31, 30, 60,120, 80,215,108, 54, 27, 29,183,187, 3,185,194, 11, 80, 53, 0, 20,129,229,172,103,169,169,169,117, 40,138, - 50, 8,133, 66, 88, 44, 22,183, 84, 17, 73,146,226,155, 55,111,134,177, 44,235,242,248, 22, 17,117,128,224,150,128,196,219,237, - 60,115,110,116, 68,109, 98,235,137, 69,144,230,193,227, 89,177,108, 61,131,207, 4, 81,193,255, 82,161,213,253,200,145, 35,156, - 99, 15,145,166, 40,155,200,250, 75,244, 48, 12,139, 76,181, 9, 73, 73,119,177,114,229, 74, 92,186,250,145,247,130, 5, 11,164, -115,230,204, 49,143, 28, 57,114, 57,203,178,173, 72,146,188,129,191,134, 42,202, 90,133, 88,182,238,181,107,215, 26,218,215, 41, -138,130,151,151, 23,188,188,188,208,180,113, 88, 57,145,197, 48, 12,172,149, 12, 29,218,125,180, 8,142,229, 40,138, 1,195,178, -165,226,167, 80, 99, 14, 59,116,250,122, 35,135,195, 95,176,255,233,220,174,121,197, 98,112,210,188,210,124,236, 90, 63,119,250, -130,205,155,165,133, 76,192,180, 81,175,189, 25, 57,124,212, 24,188,254,234, 43,221,204, 22,203, 65, 1,201,177, 84,233,245, 64, -130,131,179,143, 22,143, 39,132,228, 34, 61, 37,146,202,225, 25, 92, 31,119,117,140, 88, 32, 16,252,114,191,200, 32, 38, 5, 66, -144, 66, 49, 18, 10, 77,212,115,148,221,132,228,228,228,144,186,117,235, 66,163,209,128,166,105,118,216,176, 97, 25, 66,161, 40, - 76, 40, 18, 17,209,163,166,178,217,217,153, 20, 73, 10,192,113, 12, 94, 25, 62,137,144,202,228, 98,171,197, 66,163,100,232,208, -149, 53,203, 49,132,131, 87, 84, 84,148,175,125, 38,224,254,229,239,122, 57,236, 83,190,244,210, 75,190,142,179, 14,221,180, 22, - 17, 35, 71,142,148,135,135,135, 19, 0,240,235,246,217,118,235, 25, 49,112,224, 64, 89,120,120,137, 31,254,143,107,223,117,155, -211, 95,193, 1,197, 15,128,226,212,114,150,172,129, 3, 7, 74, 27, 54,108, 88,173,103,209,230, 0, 95, 97,236, 46, 15, 33, 13, -100, 95,119,139, 43,166, 13,168, 80, 79, 8,151,191, 66, 66,226,233,103,238,240,241,137,159,121,177,197,131,135, 91,112,210, 34, -207, 20,186,217, 4, 98,119,219,111,169,224, 18, 2,128,205, 68, 71, 56,232, 44, 80,180,181,156,200, 98, 24, 6, 34,194,140,149, - 43, 87,226,253,247,223, 7, 0,241,244,233,211, 15, 44, 88,176, 96, 40,203,178,173, 56,142,235, 66, 16, 68,101,189,198,179, 33, - 33, 33, 57, 28,199,137, 72,146,236,178,118,237, 90,223,254,253,251,195,203,203, 11, 28,203,149, 19, 89, 12,195,194,106,181, 84, -248,153, 91, 31,165,124,193, 15,123,166,249,244, 28,188,180, 23,195,178,167,236, 34,139,101, 24,128, 45, 57, 41, 63, 55, 3, 39, -143, 31,196,134,245, 27, 10, 65,112,183,193,129,181,137, 65, 84, 32, 6, 91, 93,252, 53,177, 75,231,118,205,177, 96,243,102,233, -173,107, 89, 7,166,126, 48, 43,114,248,168, 49,216,243,221,118,144,116,209,117, 71,145,197, 80, 44,138, 11,243, 6,254,196,251, -104, 61, 45,248,158, 60,117,138, 24, 51,102, 12,171,213,106, 33,150, 72, 88,138,162, 4,255,254,247,191,153,247,223,127,159,204, -206,206,134, 70,171, 19, 2,240,197,115, 96,214,210,104, 52,219, 39, 77,154,212,237,252,249,243, 98,146, 36,161,209,104,208,163, - 71,143, 60, 53, 27, 42,155,248,206, 84,255,204,204, 12, 90, 41, 23,154,197, 98, 17,114,115,115,217,110,253, 71, 27, 71,141,127, -191,206,251,179,227, 54,102, 93, 94,191,206,157,107, 56,206, 4,116,222,183,105,211, 38, 75,104,104,168, 73, 42,149, 74,198,141, - 27,231,214,248,161,197, 98,225, 22, 47, 94,108,118,158, 93,104,177, 88,184,149, 43, 87, 90,194,194,194,204,114,185,156,163,168, -170,253, 62, 73,146,160,223, 90,176,131,166,105,186,140, 21,203, 46,178, 40,150,208,125,245,213, 87,214,176,176, 48,139, 66,161, -224,164, 82,169,216,157,116, 78,157, 58,149,243,241,241,177,122,120,120,136, 99, 99, 99, 31,107,214, 33,197, 64,184, 96,109,105, -120, 7,169,151,151, 23,180, 90,109,105, 90, 67, 66, 66,120,177,197,131,135, 11,148,211, 34,207,166, 21,206,189, 56, 90, 44,160, -203,201,205, 11,244, 15,170, 15,154,166,109, 11, 5,154,162, 48,237,237, 81, 88,190,254, 43, 0,176,139,173,168,233,211,167, 31, - 0, 80,101, 99,182,107,215,174,249,211,167, 79, 87,230,228,228,156,216,186,117,171,239,232,209,163, 49, 99,198, 12, 44, 93,186, - 20, 34,137, 12,190, 1,117, 75,175, 99,191,110,158,186, 0, 28, 56, 93, 5,118, 58,107, 73, 35, 5,161, 95, 64, 61, 80, 12, 5, -150,162, 64, 81, 20, 8, 65, 73,214, 78, 30, 63,136,209,111, 76,133, 72,170,244, 89,179,114,137, 49,242,229,144,161,115, 38, 76, - 48,187, 97, 4, 36,111, 93,203, 58, 48,245,253,216, 40,187,200,218,183,125,253,237, 47,103, 14,222, 41,149, 8, 75,175, 67,177, - 44, 72, 82,192,251,104, 61, 37,145, 37,149, 74,247, 30, 59,118,236, 94,219,182,109, 9,189, 94, 15,138,162,144,151,151,135, 3, - 7, 14, 36,112, 28, 7, 31, 31, 31, 28, 59,118,140, 29, 61,122,244, 94,179,217,252,218,179, 46,182,178,179,179,239,200,229,242, - 93,179,102,205, 26, 53,115,230, 76, 17,203,178, 72, 74, 74, 2, 8,130, 19,137, 37, 32, 73, 18, 34,145, 16,197,197, 26, 86,225, -169,202,178,114, 2,133, 72, 44, 1, 41, 16, 87, 54, 77,248,161, 45, 24, 41, 72,161, 88,107,159, 9, 40, 22,139,113,117,207, 50, - 77,247,113,243,149, 0, 32,150,202, 11,251,244,233,147,214,188,121,115,253,111,191,253, 86, 15,229,103, 29, 58, 63,159,244,144, -113,177, 2,133, 92,166,143,138,138,122,104,231, 76, 61,181, 70, 51,102,242,108,130, 16, 72,244,209,209,209,105,145,145,145,122, -129, 64,128,196,131, 75, 52, 67,198,197,202,136, 74,130,172,158,184,199,189,117, 99,207,133,166, 95,124,241, 5,213,191,127,255, - 71,118,127,177,212,212,212, 58, 3, 6, 12,144,174, 88,177,130, 26, 48, 96, 64,250,139,255,207,222,117,199, 53,113,254,225,231, - 46,155,189, 71, 16, 68, 69, 81, 20,112,139, 11,197, 58,107, 29,173,226,194,189, 71,157,173,179, 14,220, 74,221,168,117,214, 90, -220, 84,171,162,214, 81, 23, 42, 46, 16, 7, 67, 69, 1, 25, 97, 67,128,144,157,187,223, 31, 36, 52, 32, 35, 65, 91,107,127,121, - 62,159,124,146,220,189,247,220,123,251,185,239,251, 29, 94, 94,197, 36, 73, 34, 50, 50,210,185, 58, 75,149, 6, 70, 70, 70,138, - 9, 19, 38,188,123,254,252,121,109,163, 14,171,133,139,139, 11, 40,138, 66,183,110,221, 32,145, 72, 12,150, 45, 3, 12,248,111, -162, 98, 30,173,170, 51,195, 43,148,138,111,167,204, 94,185, 19, 32, 76,181,238, 2,127, 25,150,104, 16,223,127,255,157, 9, 0, - 35,141,216,154, 59,119,110,141,101, 78,180, 68, 86,155,128,128, 0, 44, 94,188, 24,155, 55,111, 86,253,248,227,143,140,248, 87, -137,242,177,211, 87, 20, 84, 88, 15,104,208,197,148,130,250,182, 50,190,124,161,104,133,239, 87, 27, 86,166,101,150,220, 25, 59, -109,105,217,221, 75, 5,160,144,224,171, 0, 96,207, 79, 63,137, 88, 92,115,147, 33,195, 71, 1, 64,207,157,219,130,206,172,193, -129,154,197, 22, 77,120,124, 59,119,129,149, 70,100,237,218,186,246,185, 5,145, 25, 60,243,187, 24,133,246,122, 0,192,218, 12, -103,124,191,218,208, 59, 43, 79,180,221,112,158,253,115,224,112, 56,171,175, 95,191,110,226,237,237, 77,228,230,230, 66,165, 42, - 61, 34,114,185, 28, 66,161, 16, 69, 69, 69,144, 74,165,104,221,186, 53,185, 99,199, 14,147,153, 51,103,174,150,201,100,211, 63, -247,237,126,251,246,237,174,115,231,206,225,214,173, 91,195, 22, 45, 90,196,114,116,116, 36, 44, 44, 50, 9,133, 92, 6,128,166, -179,179,179, 41, 99, 83, 75,129,173,131,243,187,244,140, 44, 15,133, 92, 6, 74, 37,175,210,219, 92,157,222,225,251, 23, 47, 94, -212,219,180,105,147, 76, 59, 18,112,248,130,157, 59, 90,183,110,109, 29, 28, 28, 44,235,215,175, 95,178,198,121, 93, 23,103,248, - 43,111, 48,251,197,139,103,205, 42,114,250, 77,222,116, 80,195,169, 29,141,216,255,187,189, 7, 27, 53,106,100,237,233,233,153, - 92, 29,111,131, 6, 13,196,124, 62, 95,214,164, 73,147, 98, 22,139, 85,106,201, 82, 40, 74, 26, 52,104, 64, 57, 56, 56,200,154, - 54,109, 90,172,175,211,190,145,145, 17,173,177,138, 85, 6,125,162, 14, 89, 12, 40, 3, 2, 2,202, 50,195,127,223,168,145, 96, -212,168, 81,252,121,243,230,225,224,193,131,184,123,247,238,123, 98,191,107,215,174,184,125,251,246, 74,252,135, 18,235, 26, 96, -192,255, 25,170,207,163, 85, 17,135, 14,133,252, 9, 45,159,166,202,176,102,205, 26,174,218,146,213,115,206,156, 57, 16,139,197, - 86,149, 52,235, 1,117,174,141,202, 68, 86, 80, 80,208, 49,154,166,157, 1,116, 86,169,168, 7,251, 15, 28,234, 86,213,250,134, - 12, 25,242, 30, 39, 77,144, 12,146, 36,138, 57, 44,250,201, 79,251, 14, 30, 41,215,190,212,249,189, 49, 8, 60,221,185, 45, 72, - 12,160,103, 69,177,133,191,202,140,148,113,106, 48,117,218,212, 50,145,181,115, 91,208, 85,207, 54,117,191, 89, 58,113,117,165, -226,108,245,138, 41, 38, 36, 73,116,172,224,163,245, 30,231, 71,128,129,243, 47,116, 11, 8, 8,104,238,227,227, 67,106,139, 44, -153, 76, 86,150,184, 83,227, 44,158,150,150,134,174, 93,187,146,205,155, 55,247,122,248,240, 97, 55,252, 85,206,233,115,221,118, -213,219,183,111,119, 56, 58, 58, 94, 91,190,124,249,168,156,156,156,175,242,243, 11,108,194, 14,173, 70,159, 33,211,136,174,125, - 71,136,100, 52,147,151, 42,200,108,114,243,226, 81,235, 75, 39,118, 65, 46,147, 77, 1, 16,135,191,210, 59, 84,228, 44,209,164, -113,104,210,164,137, 72, 91,168,212,173, 91, 87,226,228,228, 36,245,244,244, 44,155, 94, 69, 52,223,123,219,174, 47,167,218,255, - 75, 84,211,254,212,136,182,138,105, 35,140,141,141,161, 17, 95,250,244, 83, 59,218,178,210, 27,101,205, 81,135,101,156,234,244, - 14,229,116, 90, 72, 72, 72,143,144,144,144, 54, 0,158,160,180,214,161, 2, 40, 29, 74,212,114,154, 15, 84,127, 12,215,187,129, -243,255,149,243,115, 70, 87,252,229,155, 5,148,250,106,221,170, 82,104,213, 4,141,227, 59, 0,114,238,220,185,249, 98,177,216, -106,212,168, 81,213, 46,147,145,145,113,240,240,225,195,229, 68,214,160, 65,131,198,133,134,134, 94,203,202,202,170,213, 86, 89, -153, 27,173,185,117,126,161, 85,215,126, 27,230, 0,248,177, 10, 67, 30,229,217,134,255,205,206,109, 65,103, 42,136,173, 95, 1, - 12,170, 74,149,246,250,114, 32,142, 30,218,169,241,237, 50,122,254, 56,237,210,176,168, 85,149, 70, 43, 90,154,114, 87,169,251, - 49,207,224,163,245,207,128,205,102,251, 45, 90,180,136, 45, 18,137,222, 19, 89, 21,133, 86, 97, 97, 33,158, 62,125,138,177, 99, -199,114,163,163,163,253,228,114,249,141,255,194, 62,200,200,200,136, 87, 39, 35,157,173, 73,225,192,229, 25,177, 71,140,159,227, - 92, 22,117,120, 98, 23,164, 18, 49, 0, 48,117, 73,239,192,100, 50,217,209,209,209,174, 26,171,149, 92, 46,231,106,166, 63,126, -252,216, 85,147, 91, 75, 34,145,232, 28,117,248,119,113, 62,123,246,204, 89, 19, 29,169,137, 46,100, 50,153,236,200,200, 72,103, - 13,167, 84, 42,213, 41,234,144,195,225,176,163,163,163,157, 85, 42,213, 71,139, 58,212, 22,198, 40,173,179, 88,174,214,162,218, -183,140, 32, 8,130, 54, 12, 27, 26, 96,192,103,143,138,145,146,213, 23,149,174, 9, 26,199,119, 61, 22, 97,186,184,184,244, 26, - 62,124,120, 57,145,229,239,239,175, 58,125,250,244, 77, 62,159,159, 73,146,100,188,190,253, 40,243,209,194,123,111,144, 32, 73, -242,105,231,182, 77, 65,146,228,211,165, 19, 39, 74,215,224, 64, 57,177,117,246,204,201,222,169,249, 49,149, 75, 51, 0, 54,246, -117, 16, 48,238, 91, 4,140,251,214, 10, 64, 39,160,234,104,197,234,250, 97,192,223, 3,130, 32, 56, 78, 78, 78,207, 37, 18, 9, - 8,130,128, 84, 42, 45, 19, 88, 69, 69, 69, 16, 10,133,101,255,229,114, 57,178,179,179, 81,183,110, 93, 16, 4,241,159,246,163, -147,203,229,202, 69, 43, 55, 29,102, 48,217, 74,138,146, 19,114,185,124,188, 62,215,249,162, 69,139, 72, 84,226,123, 53,115,230, -204, 74,167,127, 42,206, 37, 75,150, 84, 26, 37, 56,115,230,204,106,163, 7,171,194,119,223,125,247,209,162, 14,117,191,125, 25, - 96,128, 1,255, 49, 84, 26,186, 87, 43,161, 69,146,228,211, 74,162, 11, 9, 0, 52, 73,146, 79, 43,201,114,160,124,247,238,221, - 74, 75, 75,203, 41, 34,145,232,143, 65,131, 6,205,245,247,247, 87, 1,165, 14,242,181,221,162,124,161,104,133, 95,255,141,243, - 10,138,165,193, 21,231, 85,180, 60,105,196,214,174,237, 65,187,207,132, 30,247,207, 72, 79,221, 93,213,182, 85, 37,168,170,138, - 86, 20, 22,138, 87,250,245,223, 56, 39,191, 80,108,240,209,250,135,160, 82,169,174, 24, 25, 25, 17,154, 98,202,218,214,171,194, -194, 66,148,148,148, 64, 93,146, 6, 0, 80, 92, 92, 12, 11, 11, 11,168, 84, 42,250, 63,182, 43,164, 0,230,171,173, 85, 0, 48, - 63,241,230, 14,237,115,251,153,246,188,106,172, 89, 2, 93, 10, 68, 87,182, 92,117,243,254, 6,206,204,106, 10, 68, 87,135, 76, - 61,249, 50, 1,128,205, 98,100, 85, 85, 60,154,205, 98,100, 85,227,183,175,231,123, 3, 65, 3, 88,105,184,178, 13, 48,224,243, -125,255,255, 84, 43,238, 97,224, 52,112, 26, 56,255, 17, 78,174,250,163,235, 60,195,254, 52,112, 26, 56, 13,156,255, 54,206,202, - 48,249, 51, 17, 90,116, 37, 31, 0,181,180,104, 25, 96,128, 1,255, 58, 72,107, 57,207, 0, 3, 12, 48,192,128, 15,199,123,197, -164,181,103, 84,165, 74,245,137, 38,168,141,178,189,102,224, 52,112, 26, 56, 13,156, 6, 78, 3,167,129,243,255,142,179, 38,110, -237,229, 39, 3,216,247,153,136,173, 79, 18,208, 98, 48,171, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,172, 45, 12, 67, -135, 6, 24, 96,128, 1, 6, 24, 96,128, 1,255,231,208, 47, 97,169, 1,149,160,238,192,165,160,176, 68,189, 59,131,144,114, 54, -240,191,182,137,254,254,254, 12,125,218, 39, 38, 90,146, 81,224,111, 54, 55, 97,247, 47, 22, 41, 54, 83, 81, 43,130,107, 58, 17, -109, 27,180, 26,109,204, 51,158, 46,147,201,234,155,154,153,101,229,229,102,239,201,123,247,108,151, 86, 27,243, 7, 15, 30,240, -125,124,124,210, 1, 20,105,189, 41, 24, 96,128, 1, 31, 19,150, 77, 93, 64, 16,227, 1,250,175,176, 75,138,142,129, 48,238, 80, -185,118, 22, 30,227, 64, 18,205,180,166,136, 65, 99, 63, 10, 98, 83,106,120,224, 88, 38, 36, 36,184, 54,108,216, 48, 25, 64, 65, -197,181, 87, 50,207,112,157, 27,240, 57,163, 43,202, 39, 44, 45,187, 22, 62, 92,104, 53, 26, 84, 31, 74,114, 12,104,140, 4,129, -104, 36,134, 14,174, 21,143,219, 55,117, 64, 49,219, 1,104, 5,208,173, 76,140,120, 45,197, 50,121, 22, 69,211,163,241,230,228, - 19,189,249,234,251, 79, 67,213,229, 44, 86, 34, 49,244, 39,189,248, 40,250,135, 71,183, 79,115, 45,141, 9, 52,108, 61,104, 1, -202,103,112,174, 45, 56, 0,124, 73,146,108,102,108,108,204, 47, 41, 41,201,166, 40, 42, 5,165,227,211,249,181,228, 36, 1, 76, - 48, 53, 49,233,227,106,198,105,245, 46, 71,152, 86,164, 80,133,163, 52,161,107,254,199, 58,163, 74, 69,150,227,190, 57, 35,124, -198, 6,205,234, 1, 75,191,141, 11, 74,128,234,132, 22,225,220,184,227,217, 97,195,135,248,205,152, 60,214,180,142,157, 41, 4, - 57, 34,155,159, 14,134,108, 10, 9, 57,218,111,226,176,158,125, 0, 96,245,234,213, 95,187,184,184,212, 99, 48, 24,137,203,150, - 45,251,117,197,138, 21, 52, 81,117,165,114,190,250, 28,214,220,240, 77, 0,120, 2,104, 0,224, 45,128, 23, 40,159,101,188, 54, -248, 44, 56,235,212,169,227, 68, 81,212, 68, 7, 7,135,175, 50, 51, 51, 47,144, 36,121, 32, 45, 45, 45,253, 83,222,117,104,154, -222, 75, 16,196,100,154,166,247,233,241, 61, 69,159,117,240,120,188, 76,137, 68, 98,175,254,157, 37,145, 72, 28,254,174,237,249, - 39,215,245, 15,189,127, 79,186,114,231, 69, 31,237, 73,189, 58, 55,171,228,142, 66, 52,187,114, 39,166, 75,249,118,158,170, 42, -238,129, 4, 77,211, 88,185,114, 37,177,106,213,170,113,110,110,110,141, 72,146,124,185,124,249,242,114,169,111, 42,206,211,186, -206, 13, 98,203,128,207, 21,250, 21,149,174, 17, 77,253, 77, 32,161,253, 1, 98,108,215,182, 45, 59, 79, 25,221,159,160, 25, 60, -140,152,180, 80,169, 55,151,235, 88, 46, 24,226, 53,222,205, 26,207, 29,210,191, 7,217,198,179, 30,248,118, 22, 0,201,194,222, -139, 73, 54,193, 65,203,118, 3,240,169, 69, 47, 87,188,137, 56,102, 47, 40, 80,129, 32, 0,130, 0, 72, 2, 40,150, 80,232,245, -245,152, 21, 0,126,210,243,174, 68, 90, 26, 19,152,123, 76, 2, 0,140,143,112, 80,234,217,217,217,141,155, 61,123,182,137,167, -167,167, 37,143,199,227, 72, 36, 18,135,132,132, 4,187,101,203,150,121,138,197,226,243, 0, 30,233,201, 89,183,161,179,211,201, -224,185, 19,218, 53,111,224, 10,150,172, 24,148, 84,228,242, 42,225,117,135,169,187, 79, 77,138,201,147, 12, 71, 45, 74, 38,228, -228,228, 16, 0, 96,107,107, 75,151, 23, 89,237,199,110,157,215, 11,115,183, 92, 65,137, 68,118,164, 58, 14,235,122, 45, 70,125, -243,205, 64,191,181, 63,204, 52, 77,203,149, 35, 58, 81, 12,107, 83, 54, 86,204,159,198,145, 74, 21, 29,118,255, 26, 50,121,231, -134,133,251, 85, 42,213, 23, 0,218,168, 84,170,199, 0,126, 93,185,114,101, 85, 55,223, 85, 0,150,168, 79,232,163, 12, 6,227, -106,183,110,221,234, 79,156, 56,145,104,221,186, 53, 34, 35, 35, 27, 28, 59,118,172,199,133, 11, 23, 18, 85, 42,213, 51, 0, 47, -161, 46,123,162, 3, 88, 0, 26, 51, 24, 12,239,127, 51, 39,159,207, 55,146,201,100, 99,156,157,157, 39,119,236,216,209,187,127, -255,254, 68,227,198,141, 17, 31, 31,223,250,210,165, 75, 43,194,195,195,159,165,166,166,238,227,112, 56,135, 5, 2,129,248, 31, -127,142, 19,196,100, 0, 78,106,157,188, 82,135,239,116,148,230,146, 18,232,186, 14,137, 68, 98,175, 41, 97, 67, 16,132,253,223, -185, 61,122,174, 43,150, 32, 8,107,117, 91, 84,247, 77,146, 36,148, 74,165, 72,165, 82,185,213,192,217, 88,253, 34,165,179,214, - 5, 80, 93, 34,104, 35, 0,232,213,169, 89, 30, 8,196,148, 89,180,222,127,201,140, 41, 19, 96, 52,154, 93,185, 27, 99, 93,206, - 10, 86,241, 45,118,229, 74, 98,197,138, 21, 8, 12, 12,236, 15,192,151,162,168,112, 15, 15,143, 29,229, 40, 41,170,108,222,138, - 21, 43,182, 87,115,157, 27, 96,192,231, 2, 63,232, 83, 84,186,202,247, 31,183,193, 93,160,194, 88, 87, 27,123,255, 89, 19,135, - 26,121,122, 52,132, 4,166, 72,202, 81,225, 98,216, 37, 0, 56,161,159,213,105,104, 27, 38, 83,114, 56, 40,112,126, 19,223,118, -158,120,158,166,192,227, 52, 21, 74, 18, 21, 96,144, 10,168, 40, 26,160, 33,169,237, 86,167,230, 43,113,231,165, 12, 36, 1, 48, - 72,128, 36, 9, 48,200, 90,146, 81,178, 87,171, 15, 69,121,230,100, 82, 0, 37,123,245,129, 7,164,153,187,187,251,168, 85,171, - 86, 89,102,100,100,152, 68, 70, 70,130,203,229,194,202,202,138,193,231,243,157,182,108,217, 34,158, 53,107,214, 87,114,185, 60, - 9, 64,142,142,156, 30,125,219,120,223,219, 23,180,218, 66,241,224, 18, 10,142,255, 6, 6, 73,131,109, 98,138,250, 70, 70,184, -244, 77, 67,107,255,176,196,211, 15, 51, 69, 30, 0,210,106, 34,139,139,139, 99, 72,165,210,225,230,230,230,237, 89, 44,150, 3, -207,170, 30,149,206,108,147,155, 77, 52,120,155,101, 95,210,101, 94, 15,135, 62,155,231,116,195,220, 45, 87,176,237,216,253, 95, - 90, 33, 99,121,117,121,179,141,141, 77,167,204,154, 62,209, 52, 53, 71,142, 53,167,115,112,232,118, 33,198,248,154, 97,238,151, - 22, 8, 24, 49,204,228,212,111,161, 83, 0,236,215, 90, 36,222,195,195,131,136,139,139,171,236,230,107, 5, 96,161, 76, 38, 35, -217,108, 54,193,227,241, 70,173, 93,187, 86, 62, 98,196,136, 84, 77, 3, 95, 95, 95,248,250,250, 18, 69, 69, 69, 13,110,220,184, -209, 32, 36, 36, 68, 25, 17, 17, 17, 11,224,108,213, 22, 11,163,119, 18,137,216,133,103,100, 84,242,211,238,221,155,187,116,233, - 66,113,185,127,165,159,170, 13, 39, 0, 88, 88, 88,236,183,183,183, 39, 22, 47, 94,156,254,177, 56,235,213,171,119,165, 93,187, -118,221,122,245,234,197,236,212,169, 19,156,156,156,202,230,217,218,218,194,215,215,151, 72, 73, 73,105, 30, 30, 30,190,251,202, -149, 43, 59,158, 60,121,114, 35, 41, 41,169,215, 63,108,209,218,167, 22, 19, 2, 61,219,127,246, 32, 8,194,116,239,222,189,246, -154,154,140, 10,133, 2, 42,149,170,236, 91,243,161, 40, 10, 42,149, 10,107,215,174, 85,137, 68, 34, 93,246,145, 72,235,173, 89, -243,161, 42,251,230,112, 56,182,154,132,189, 53,220,217, 99,248,220,130,166, 38, 38, 38,174, 0,250,194,174,209,194,242, 13, 74, -223,159, 69, 34, 81,178, 64,106, 25, 3,160, 75, 53,108,150,171, 86,173, 26, 19, 24, 24, 56, 80,203, 74,235, 61,100,200,144,138, -101,175,188,213,223, 34,130, 32,110,146, 36,121, 30,192, 33,124, 68,171,187, 1,255, 45,208, 52,221, 22,128,157,214, 36, 25, 74, - 71,133,160,126, 78, 18, 0,108, 42, 76,215,110,167,249,206, 86, 79,183, 83, 47, 71,107,241,102, 19, 4,241,168,150, 93,188,133, - 42,252,180,152, 0, 16, 22, 22, 70,247,235,215,143,208,124, 87, 46,138,252, 47, 78, 24, 49,160,207, 87,221, 59,130,228, 89,225, - 85, 22, 16,241,142, 6,147, 84,128, 4,141, 7,119,111,208, 96, 82,135, 43, 44, 85,181,245,164,222,224,239,188, 61, 61, 54, 30, - 8,154,205,136,205, 98,226, 80,120, 9,228,146, 98,100,103,188, 67, 86,122, 50, 4,169,111,145,246,238,237, 51,128, 88,161, 51, -231,123, 7, 6, 80, 81,234,119, 64, 10,168, 38,242,178,102, 78,185, 40,174, 65, 99, 79,207,124,142, 10,144,139,226,116, 88,125, - 85,156, 94,141, 26, 53, 26,241,195, 15, 63, 88,191,120,241,194,168,164,164, 68,122,233,210,165,248,164,164, 36,115, 62,159,159, - 55,109,218,180, 70, 78, 78, 78,230,131, 6, 13,226, 28, 63,126,252,107,148, 15,107,173,138,211,115, 64,251,150, 17, 7,119,108, - 53,201, 61, 21, 12, 89,194, 83, 92, 20,136,112, 55,179,132,110, 96,193, 37,190,109,110, 7, 83, 46, 19,171, 59, 57,153,246, 61, -147,176, 81, 65, 81, 1,213,113,222,187,119,143,111,108,108,188,101,228,200,145,252,153, 51,103,114, 85, 76, 75,102,104, 68,174, -197,194,221, 17, 78, 37, 82, 57, 99, 68,183,122,152, 55,210, 27,243,182, 93,215,136,172,201,245,235, 23, 80, 81, 81, 85,115, 42, -228,242,250,206,246,230,136, 78, 18,227,208,237, 66,252,249,131, 19,186,175, 77,199,160, 86, 76,120,212, 53,133, 82,174,104, 60, -100,200,144,195,234,183,246, 71, 0,190, 30, 50,100, 72, 19, 6,131,113, 29,192,239, 53, 29, 35, 30,175,242,234, 41, 86, 86, 86, -232,218,181, 43, 60, 60, 60,152, 93,186,116,241,174, 32, 96,202,113,202,229, 50, 62, 69,209, 48, 51, 51, 51,178,177,177,177, 50, - 51, 51,203,173,236, 65,165, 15, 39, 0, 88, 91, 91, 15,238,218,181, 43,243,216,177, 99, 57,137,137,137, 15, 70,140, 24,241,214, -220,220,188,156,245,215,196,196, 4,141, 26, 53,194,178,101,203,152,125,250,244,169,145,211,193,193,161,103, 72, 72, 8, 8,130, - 40,123,104,191,103, 44,118,117,133,163,163, 35,250,246,237,203, 28, 60,120,112,207,164,164,164, 90, 93, 71,122,224, 90, 37, 22, -173,149, 21,142, 83,149,195,111,149,181,215,225,184,103,105,172, 75,106, 62,124,192,181, 89,237,112, 39,143,199, 43,179, 66, 85, -178,174,247, 56, 73,146,196,210,165, 75, 65, 16, 4, 88, 44, 22,216,108,118,165,223,126,126,126,250,246, 51,133, 32, 8,146,205, -102, 47,100, 50,153, 19,165, 82,169, 51,143,199, 75, 87,169, 84,191, 72,165,210,181, 0, 20, 52, 77, 91, 86, 33,178, 42,229, 52, - 49, 49,113,125,245,234,149,123, 85, 29,145, 74,165,240,246,246, 6,164,136,173,142, 51, 33, 33,193,213,205,205,173, 49, 0, 77, -137,182,219, 52, 77,119,209,250,175,141,219, 52, 77,127,169,254,253,242,205,155, 55,174, 13, 27, 54,204,255,167,206, 79, 3,231, -191,143,179, 6, 45, 98, 71, 16, 68,152,113, 48, 25,151, 0, 0, 32, 0, 73, 68, 65, 84,214,181,218, 79,243,127,209,162, 69, 75, -214,175, 95,255,130, 32,136, 48,237,233,218,237,180,191,213,247,155, 48,154,166,251, 45, 94,188,216,115,195,134, 13,235, 52,109, -255, 14,145,168,143, 69,203, 60, 91, 98,130,240,119,230, 96, 50, 84, 96,146, 4,152, 12, 0, 52,129,228,164, 4, 20, 21, 22,220, - 65,226,233, 68,221, 44, 89,254,157, 90,180,240, 10, 58,186,109, 1,249,115,120, 9, 10, 68, 18,196, 61,185,137, 71, 55,127,207, - 80, 41, 85,191,131,160, 31, 3,100, 36,222, 82,241, 64,104,237,106, 92, 16, 52,179, 84,104,169,197, 85, 57,177,245,201,208,188, - 73,147, 38,195,150, 45, 91,102, 27, 21, 21,197, 19, 10,133, 69, 71,143, 30, 77,151, 74,165, 73, 0, 46, 39, 39, 39, 55,217,190, -125, 59, 39, 40, 40,200,203,203,203,139,127,242,228, 73, 89, 37,229,140,222,227,156, 63, 54, 32, 98,226,172, 57,188,216,147,187, -192,137,141,196,210,167, 57,170, 63, 5, 37, 63, 0,216,134,148,226, 78,217, 18,229,213,173, 93, 93,200,122,102,108, 52,180,228, -248,197,229, 73,170,181,100, 25, 27, 27,111, 9, 9, 9,113,109,219,182, 45, 9, 0,225, 47,149,220,133,187, 35,156, 46,175,239, - 68,116,106,102,131,172, 2, 41,102,239,138,198,165,136,172, 63, 52, 34,171,166, 78,154,153,153,101,167,102, 21, 58,216,152,242, - 48,186,179, 41,186,175, 77,135,127, 27, 46,184,108, 2,241,137, 25,104,232, 86,143,136,190,115,182,141, 90,100,181, 21, 8, 4, - 0,208, 6, 64, 98, 74, 74, 10,223,199,199, 71,168, 69,151, 15, 96, 35,135,195, 89, 74, 16, 4,221,182,109,219,104, 47, 47,175, - 98, 43, 43, 43,136,197, 98, 72,165, 82,176,217,108,136,197, 98, 36, 39, 39,227,193,131, 7,176,178,178,210,235, 64, 21, 23, 23, -195,204,204, 12, 20, 69,125, 48,167, 74,165, 34,246,236,217, 99,242,226,197, 11,147,208,208, 80,135,185,115,231,230, 54,109,218, -244,241,176, 97,195, 94,219,219,219, 75,159, 62,125,138,123,247,238, 33, 63, 63, 31,237,219,183,215,137, 83, 38,147,129,201,100, - 66, 44, 22,131,203,229,130,201,100, 66,169, 84,130,162,168, 50,241, 85, 92, 92,140,188,188, 60,176,217,108,200,100,178, 79,241, - 6,250,158,133,170,186,225,183,218, 88,180,180,133,154,142, 34,171, 38, 75, 84,149,195,157, 5, 5, 5, 70,150,150,150, 11, 1, - 8,106, 90, 23, 65, 16, 96, 48, 24, 96,179,217, 32, 8, 2, 93,186,116,193,132, 9, 19,208,170, 85, 43, 36, 36, 36,224,248,241, -227,120,244,232, 17, 88, 44, 86, 89,123,157,199, 39,252,252, 24, 60, 30,239,222,128, 1, 3, 60,127,248,225, 7, 94,189,122,245, - 16, 27, 27, 91,119,195,134, 13, 11,175, 93,187, 54, 80, 36, 18,181,209,220,237,170,183,210,171,135, 4, 75,135, 11,251, 74,165, - 82,196,198,198,234,179,204,123,104,216,176, 97, 50, 73,146,175, 41,138, 10, 7,224, 77,211,116, 23,130, 32, 46,161,212, 47, 81, - 27, 34,154,166,191, 36, 8,162, 16,192, 51,146, 36, 95, 82, 20,149,108,176,219, 24,160,195,125,165, 95,197,255, 4, 65,132,173, - 95,191,190, 95,101,226,170,146,107,179,220,244, 13, 27, 54,172,211,250,255, 33, 22,213,174, 40,239, 12,239,167,182,114,253, 37, -180,194,194,194,170, 87, 32, 20, 6,133,157, 62,118,191,187, 28,174,158,173,125,181,172, 67, 52, 34, 31,220, 3, 64,255,162, 83, - 87,248,253,140, 72, 6,243,151, 61,235,102,146,123,111,150, 32, 37, 61, 11,247, 46,254,130,108, 65,210, 33,128,158,139,196,208, -194, 15, 62, 18,245, 6,121,217,219,216, 90, 74,228, 52, 40, 26,192,123, 98,235,147,160, 85,227,198,141, 7, 71, 68, 68,216, 74, - 36, 18,222,157, 59,119, 74, 66, 66, 66, 50,228,114,249, 77, 0,119,213,109,162,178,179,179,135,168,133, 9,131,201,100,114,228, -114,121,117,190, 11,173,230, 79, 28,115,103,227,158,131,188,215,207,163,177, 61,244, 34, 10, 74, 74, 84, 55,179,196, 95, 3,208, - 40,250,235, 81, 57,226, 52, 26,180, 11,139, 36,192, 55, 97, 57,198,229, 73,120, 64,229, 67,178, 82,169,116,196,200,145, 35,249, - 26,145, 5, 0, 57, 69, 10,102,137, 84,193,232,212,204, 6,173,187, 13, 65,228,141, 83, 56,121, 59, 13,110,118,198,183,235,155, - 20,232,180, 71,179,179, 4,123,182, 6,239,221,186,113,229,124,206,188,190, 22,240,111,195, 2,143, 77,192,220,152,133,181, 59, -246, 43,162, 30,220,126,202,231,243,195, 0,124, 45, 16, 8,192,231,243,139, 1,188,100, 48, 24,137, 42,149,170, 50,167,238,229, - 0, 28, 14, 31, 62, 76, 42, 20,138,226,132,132, 4, 56, 58, 58,194,193,193, 1, 22, 22, 22,136,139,139,195,159,127,254,137,248, -248,120, 80, 20,133, 22, 45, 90,232,117,176,114,115,115,241,244,233, 83,244,237,251,213,220,236,236, 44,115, 43,107, 27,209,157, -240,219,155,106,195, 73, 81, 20, 1, 0,158,158,158,240,244,244,228,165,165,165, 57,135,133,133,217,175, 89,179,230,157,171,171, -235, 81,177, 88, 92,206,114,160,171,208,210,136, 11,141, 8,228,241,120, 96,179,217, 40, 44, 44, 68,102,102, 38,138,138, 74,131, - 54, 45, 45, 45, 63,137,208,170,194, 66,245,209,218,255,205,226,240,189,225, 78, 75, 75,203,145, 0, 22,234,184, 45, 80, 42,149, - 96,179,217,240,241,241, 65,112,112, 48, 30, 61,122,132,223,127,255, 29,117,235,214,197,216,177, 99, 65,146, 36, 94,188,120,161, -111, 23,169,136,136,136,133, 95,127,253,181,231,225,195,135,121,201,201,201,136,143,143,135,165,165, 37,130,131,131,185,147, 39, - 79,110,120,227,198,141,229, 40, 13,126,169, 30, 90,209,133, 34, 35,254, 80,111,111,239,247,154, 56, 58, 58, 90, 92,190,124,217, -190, 76,128, 85,140, 72,124, 31, 5,203,151, 47,223,234,225,225,177, 77, 61, 92,232, 11,192,132,166,105,191,208,208, 80, 2, 0, -252,253,253,105,130, 32, 52, 15,164,103,167, 78,157,234, 22, 23, 23, 71, 7, 6, 6, 26,124,180, 12,168, 74,139, 76,214, 92,147, - 85, 9, 40,125,132,154,182,197, 75,131,197,139, 23,123,174, 95,191,254,225, 7,138, 44,237, 55, 38, 90, 35,182,202, 30,166, 85, - 14, 25,150,217,190, 72,190,163,189,141,245,162,177,157, 64, 81,128, 82, 5, 40, 85, 52, 68, 37, 98,196, 62,127, 84, 2, 30, 17, -170, 83,119,184,156,160, 53, 63,204,105, 16,157, 74, 34, 61, 95,142, 91,103,247,210,217,130,164,193, 72, 60, 53,254,227,136,172, -161,222,142, 14,246,183,142,237, 93, 77, 62,122, 43,131,138, 42,213, 89, 20, 69,151,253,254, 4,112,180,179,179, 11,184,127,255, -190, 29,151,203,229,189,122,245,138, 58,117,234, 84,190, 92, 46,191,166, 37,178, 0,160, 83,155, 54,109,148,166,166,166, 16,137, - 68,114,185, 92, 46,169, 70,100, 57,251,181,106,126,123,227,158,131, 60,137, 76, 6,161, 88, 10,134,141,125, 69,145, 5, 0, 29, -187,185,215,169, 67,240,204, 64, 3, 72, 42,148,167, 87, 37,178, 0,128,203,229,246,152, 57,115,102,185,186,120,182,102, 44,165, - 49,151,165,186, 27,147, 67, 69,222, 56,133,240, 23, 57, 20,143,205, 80,217,209,111, 27,232,186, 3, 10, 82, 99,246,252,126, 46, -236,234,119,203,130,138, 75, 68, 69,112,115, 50, 66,113,145, 16,107,215,111, 84, 68, 68,132,223, 92, 56,119,106,135, 83,167, 78, -109, 64,169, 51, 56, 0,188, 60,117,234,212,152,101,203,150,253,138,191,210, 60, 84, 68,122, 64, 64, 64,106,179,102,205,132, 30, - 30, 30,194,220,220, 92,196,196,196, 32, 63, 63, 31,219,183,111, 71,108,108, 44, 52, 22, 65,157,124, 85,222, 23, 72,200,207,207, - 51,165,105, 26,249,121,185, 38, 63,252,240,131, 69,109, 56, 85, 42, 85,185,107,171, 78,157, 58,152, 54,109, 26,187,164,164,196, -242,221,187,119,230,218,243,116,229,148,201,100,208, 88,134,104,154,134, 76, 38,131, 80, 40,132, 76, 38,195,235,215,175,203, 68, -150,122,253,159,204,162,165,249,205,227,241, 50, 53,231,178,102, 8,142,199,227,101, 85,213,254, 67,160,181, 46, 90,253, 91, 95, -113, 88,227,246,232,120,220,193,102,179, 49, 97,194, 4, 60,124,248, 16, 9, 9, 9, 96, 48, 24, 16,137, 68, 40, 41, 41, 65,207, -158, 61,193,225,112,244,181,104,209,108, 54,123,228,146, 37, 75,120,137,137,137,200,201,201,209, 56,211, 67,165, 82, 97,238,220, -185, 70, 92, 46,119,164,190,166,123,129, 64,208,251,245,235,215,141, 43,126, 50, 50, 50,132,218, 62,133,181, 69,104,104, 40,225, -239,239, 79,251,251,251,211, 26,193,101,128, 1,149,161, 10, 45,178,175, 42,139,214,199,176,138,105, 44, 91, 80, 7,136,212, 2, - 26,145,213, 85, 75,120, 17, 26, 11,151,110, 67,135,110, 67, 91, 58,216, 88,223, 56,188,107,149,105,216,115, 2,169, 41, 73,200, - 22, 36,163, 77, 7, 63,196, 62,143, 6,165, 80,157,198,235,208,154, 61, 57,235,249,187,123,120, 52,157,222,181,131, 23,130,194, -138,241, 42,242, 50, 10,178, 5, 59,145,116,234,244, 71, 57, 66,174,254,205, 29,236,173,111,252,186,107,149,229,165, 24, 18, 41, - 41, 73, 56,251,235, 86, 90, 33,151, 22,160,124, 36,151,222,111,205, 70,148,140, 83, 92,144, 9, 89,145, 10, 60,178,132,167,231, - 32, 69, 6,128,240,173, 91,183,118,111,223,190, 61, 39, 32, 32, 32, 35, 63, 63,255, 44,128,251, 90,109,154,185,187,187,247, 13, - 14, 14,118, 72, 73, 73,193,181,107,215, 50, 80, 26,250, 95, 21, 82,111, 71, 63,223,253,231,175,251,231, 27, 53,104,130,237, 75, -190, 83,134, 62,138, 25, 0,224,146, 86, 27,143, 30,222,238, 97,107,190,159, 65, 82, 81,127,224,105,114, 38,222, 10,165,127, 86, - 69,152,147,147, 67,148,148,148,184, 90, 90, 90,106,159,144,224,155,136,164, 11,134,186,167,247, 92,120,199, 73, 34, 87,129,203, - 34,233,217, 3, 93,211, 31,158, 13,181,201,145,228, 16,154,104,196,154, 48,105, 88,143,129,187, 66,206,140, 14, 11,187, 48, 93, - 46,149,120, 53,105,210,152,126, 28,113,227,233,194,185, 83,251,212,242,136,155, 62,124,248,144,100, 48, 24,229, 4,186,182,133, - 72, 95, 75,145, 62,208,149,179,162,208,210, 64,169, 84, 18,181,229,148, 74,165,101, 66,171,226,195,189, 50,193,248,119,108,191, - 62, 22, 42,237, 33, 67,141, 63,157, 68, 34,177, 87,251,108, 57,124, 76,139,214,135, 68, 34, 86, 55,124,169, 79,255, 72,146, 4, - 69, 81, 96,179,217,104,209,162, 5,194,194,194, 96,109,109, 13,115,115,115,152,155,155,195,200,200, 8, 54, 54, 54,101, 66,139, - 36,117,142,210,161,165, 82,105,221,186,117,235,226,245,235,215,224,241,120,101, 31, 46,151, 11, 79, 79, 79,136, 68,162, 58,248, -148,182,123, 3, 12,248,123,239, 43, 97,218, 98,137, 32,136,176, 69,139, 22, 45,169, 45,223,162, 69,139,150, 84,102,225,250, 64, -193, 85,206,186,197,212, 86,144,149, 42, 73,181,200, 58,180,115,165,249,153, 39, 64,106,106, 34,174,158,220, 81,164,144,203,242, - 41, 74,225,250, 54, 62, 26, 32,241,139, 78, 93, 32,233,118, 3,251,118, 35,174,190,144,161,176, 32, 27, 47, 31, 95, 78,130,152, -179,248,163,137, 44, 7,219, 27,135,119,173,180, 60,255,156, 64, 74, 74, 18, 46, 29,219, 94,168,144,203,123, 32, 49,244,241,135, - 80,143,100,179, 7,178, 93,222,245,155,232,155, 14, 21,161,194,200,216,184, 47,179, 50, 48, 80,112,167,250,200, 48,109,100,103, -103,159,221,186,117, 43,241,227,143, 63,118,149, 72, 36,191, 1,208, 54, 81,122,185,185,185, 13,223,183,111,159,117, 74, 74, 10, -235,206,157, 59,162, 27, 55,110,208, 0,206,215, 96,113, 89,208,115,252, 52, 70,171,122,117,102, 70, 37,165, 13, 0,240,135,214, -108,207,126,173,155,221, 61,184,126,185,153,226,110, 40,138, 5, 41, 88,124, 55,181, 16,128,206,251, 91,161, 80, 64, 40, 20, 66, - 81,156,171,108,195, 23, 9, 3,135,216, 75, 51,243, 37, 76, 22, 85,162,244, 48,207,146,222,200,125,203, 48, 54, 54,214,107, 95, -238, 90, 63, 63, 4, 64,200,144, 33, 67, 14, 63,139,184,208,134,207,231, 95,240,240,240, 32, 0,160,138, 8,195,170,176, 10,192, -220,142, 29, 59, 18, 62, 62, 62, 15,182,109,219,118,165, 58,177, 82, 27,139, 86, 77,208,149,147,162, 40,178,138,253, 75,212,150, - 83,219,162, 85,147,208,250,148, 22,173,202, 68,139,182, 72,212, 22, 66,255,134,168,195,234,196,148, 62,253,211,248,201,177,217, -108, 68, 71, 71,195,197,197, 5,114,185, 28,102,102,102, 48, 51, 51,131,169,169, 41,138,138,138,192, 98,177,160,231, 54, 83, 60, - 30,239, 93, 76, 76, 76, 99, 59, 59, 59,168, 84,170,114, 98,235,213,171, 87, 48, 49, 49, 73,211,215,162,197,231,243, 47,171,163, - 14,203,193,209,209,209,226, 99,236, 87,109, 75,150,191,191,191, 97,136,208,128,106,173, 89, 85, 88,181,178, 43, 88,162,100, 90, -255,179, 81,154,195,173,159,250, 55, 42,249, 45,171,100, 90,238,250,245,235,111,104,249,119,101,127,224, 38,104, 82, 60,148,139, -112, 97,214,100,201,178,183,182,186,113, 96,123,160,249,201, 72, 32, 45, 37, 17,183, 78, 7, 11,149, 42,249, 23,160,104, 65,196, -181,211,161, 32, 80,130,183,161,183,116,187, 69,160, 85,171,166,174,248,253,133, 2,217,169,175, 64,211,212, 33,100,133,148,124, -240,209,113, 27,212,194,222,218,246,198,161,224, 64,139, 51,209, 4, 82, 83, 18,113,245,100,112,161, 82, 81,210, 29,137,167, 35, -107, 75, 59, 1,176, 98,152,240,118, 15,246,107, 53,212,213,205, 25, 20,173, 0,197,166, 49,104,129, 45,243,101, 84,201,239,225, - 60,225, 73,170,152,154,158,118, 95, 55, 7,186,226,226,226,223, 1, 60, 70,249,244, 10,205, 27, 53,106, 52,116,247,238,221,118, -169,169,169,188,168,168, 40,241,222,189,123,179, 40,138, 58, 3, 64,151,161,212,239,162,146,210, 14,160,124,190,156,230,243,199, - 7, 68, 4,140,155,200, 75,188, 22, 2,171,196, 88,124,127, 55, 93,245, 50, 95, 54, 66,109, 93,171, 20,182,182,182,116, 78, 78, - 78,114, 65, 65, 65, 99, 19, 19, 19,228,230,230, 34, 47, 47, 15, 66,161, 16,210,194, 60,165,141,170, 64, 68, 40,243,192, 98,177, -144,149,162,128, 74,165,202,208,213,154, 5,192,106,213,170, 85,147, 40,138,210,100, 68, 44, 23, 93,168,213, 78,115, 62, 52, 30, - 50,100,200, 97,173,168, 67,109,103,120, 77,122, 7, 66,157,222,161,253, 31,127,252, 17,215,167, 79,159,212,202,196, 10,151,203, -213,219, 81,186,170, 40,198,218,112, 86,101,209,170, 56, 93, 31, 78,205,240,165,198, 9,190,226,116, 13, 24, 12, 6, 40,138,130, - 14, 65, 21,127,171,104,209,142, 14,172,141,200,169,112,108,170, 77, 28, 90,203, 72,196,143,106,209,210, 28, 11, 54,155,141,115, -231,206, 97,220,184,113, 80,169, 84, 48, 54, 54,134,169,169, 41, 76, 76, 76,112,250,244,105,104,210, 63,232,163, 95, 21, 10,197, -145,245,235,215, 47,217,179,103,143, 17, 77,211,224,112, 56,101, 66, 43, 48, 48, 80, 44,151,203,143,232, 36,180, 52, 25,223, 41, - 58,198,196, 68, 89,109,212, 97,101,203, 84,225,175,101,185,106,213,170, 49, 20, 69, 13, 68,133, 20, 14, 21,218,149, 75,253, 96, - 72,239, 96,128, 14,247,147, 71,255,226,238,105, 4, 22,161,101,201, 42, 19, 92,100,117,226,197,206,202,242,198,254,237,129,230, - 71, 31, 17, 72,124,251, 22, 55,127,219, 81, 42,178,222,156,124,130,228,208, 76, 36,134,118,198,219,208,222, 58,191, 61, 17, 68, - 43, 39,123, 75,228,137, 40, 20,230,188, 3,104, 68,125, 12,145,101,103,101,119,227,231,224, 64,139, 83, 79, 72, 36, 38, 38,226, -234,201, 29, 66,165, 82,242,197,135,136,172,145,108,246,192, 70,238,206, 9, 75, 39, 13, 28,234,211,208, 17, 54,239,226,112,126, -236, 80,172, 62,254, 13,204,236, 24,104,215,215, 12, 19,214, 58, 14,229,123,114, 95,243, 59, 99,160, 30,212,218, 34,171, 85,253, -250,245,135,222,191,127,223,214,219,219,155, 23, 31, 31, 47,217,187,119,111,150, 88, 44,190, 2, 32, 90, 15, 78,109,145,213,106, -209,228,177, 17, 27,247, 31,230,145,108, 14,130,142,156,199,172,219,169,170, 11,201,133, 67, 80,126, 88,177, 82, 72,165,210,107, -193,193,193, 82,146, 36,145,151,151,135,156,156, 28,100,101,101,149,125, 23, 20, 20,128,193, 96,224,250,245,235,178,194,194,194, -251,186,118,240,222,189,123,245,211,210,210, 60, 4, 2, 65, 27,245, 39, 30,165,209,133,166, 90,211,218, 8, 4,130,174, 0, 30, -105,166,167,166,166,214,123,240,224, 1,191, 38,126, 51, 51, 51,176,217,236,114, 22, 45, 46,151, 11, 7, 7, 7, 40,149, 74,156, - 56,113, 2, 0,242,170,227, 96,179, 57, 2,146, 36, 64,209,148,148,199,227, 81,124, 62,191, 82,129,165, 15,167, 26,169, 95,126, -249,165, 36, 50, 50,178, 82,139, 86,109, 56,105,154, 46,233,213,171, 23,210,211,211,193,227,241,202, 30,214, 26, 65, 69,146, 36, -184, 92, 46, 50, 50, 50, 48,101,202, 20,208, 52, 93,242, 79,223,121,180,125,154,212, 98,136, 0, 64,168,133,208,123,126, 90,186, -250, 64,105,134, 6,105,154,134, 70,112, 85,152, 95,182, 46, 93,178,183, 87,240,233,154, 92, 80, 80,176,177,180, 59,244,222, 10, -223,251,244,120, 40,148, 9,173,216,216, 88, 28, 62,124, 24, 5, 5, 5,224,112, 56,200,207,207,199,193,131, 7, 17, 19, 19, 3, - 14,135, 3,205,190,208, 85,191,249,248,248,108, 12, 15, 15,143, 25, 49, 98,132, 56, 58, 58, 26, 98,177, 24,209,209,209,232,221, -187,183,228,238,221,187, 9, 98,177,120, 21,116, 25, 58,212,100,124, 87,151,215,145, 74,165,136,138,138,170,244, 83,213, 50, 21, -145,144,144,224,170, 82,169, 26,211, 52,237, 75,211,180, 57,212, 41, 28,212,255,181, 63, 95,170,231,153,211, 52,237,171, 82,169, - 26, 37, 36, 36,184, 26,228,132, 1,159, 41,110,105,137, 45, 90, 75,100,221,170,222,162, 69,145,193, 7,118,172, 52, 63,242,144, - 68, 74,114, 2, 30, 95,220, 45, 84, 81,138, 47,244, 44,135,211, 3, 90,185, 54,120, 70, 38, 94, 20, 81, 26,206, 92,152,147, 2, -208,140,218, 8,173,114,156,160,200,224,131, 59, 2, 45,142, 61, 38,144,158,242, 6,119,207,238, 18, 42,149,210,238,120, 27, 26, - 85, 27,206,145,108,246, 50, 22,131, 88,218,171, 83, 75,118,231,150,238, 48,201, 74, 66, 70,106, 58, 78,196,102,231, 37,228, 75, - 39,222, 37,228, 72,126, 35, 61,208,119,146,181,181,149, 35, 11,253,166,218, 88,223, 63, 95,248, 59,193, 18,201,105, 57,189, 94, -112,183,172, 44, 69,249,126,190, 15, 71, 51, 51,179, 17,143, 31, 63, 54,231,241,120, 70,143, 31, 63,166,246,238,221,155, 43, 22, -139, 47, 2,136,208,105,219,223,135,115, 91,119,183, 91,235,118,237,231, 21,139, 74, 32,146,201,193,117,224,171,206, 68, 60, 31, -140,170, 19, 96,150,227,228,114,185,199,142, 29, 59,214,183, 75,151, 46,174, 94, 94, 94,100, 94, 94, 30,138,139,139,203,156,171, -237,236,236, 16, 27, 27, 75, 37, 38, 38,166,115,185,220,227,186,246,179, 99,199,142,137, 36, 73,198,171,135,209,226, 81, 33,186, - 80,171,105, 99,129, 64,208,150,207,231,223, 2, 96,172, 21,117,168,205,169, 73,239,176, 4, 0, 73, 16,196,163,232,232,232,226, - 62,125,250,192,200,200, 8, 34,145, 8,117,235,214,133, 82,169,196,197,139, 23, 17, 25, 25, 41,162, 40,234, 86, 37,226,181, 92, - 63, 37, 18,113, 93, 0,164,184,164,164,197,152, 49, 99,186,206,155, 55,175, 92, 72,186,189,189, 61,172,173,173,245,226, 4,128, -188,188,188,166,127,252,241,199,156,232,232,232,239,250,246,237,107,177,100,201, 18,110,253,250,245,161, 82,169,200,218,114,230, -231,231, 91, 68, 69, 69,109,234,220,185,243,140, 62,125,250, 48,215,173, 91, 7, 11, 11, 11,168, 84, 42, 24, 25, 25,161,176,176, - 16,171, 86,173,194,157, 59,119,148, 52, 77,239, 18, 10,133,223,235,121, 46,225, 67,175,205,170, 44, 64, 85,165,100,168,162,253, -223,222,207, 10, 62, 93, 80,167,112, 88, 88, 69, 6,123,232,122,206,107,132, 22,131,193, 64, 82, 82, 18,246,238,221,251, 94, 30, - 45, 77,250,135, 42,184, 43,219,118,250,230,205,155, 42,130, 32, 58, 60,126,252,120,225,232,209,163, 39,138, 68, 34,103, 19, 19, -147,116,133, 66,241,139, 88, 44, 94,139, 82,127, 84,182, 62,247, 16,145, 72,148, 92, 89,212, 97,197, 54,128,101,181,156, 21,210, - 59,148, 75,225, 80, 97,153,114,169, 31, 42, 73,239,240,183, 31,119, 3,231,191,146,243,115, 23, 91, 85, 39, 44,125, 15,173, 38, -179, 88, 98,133,119,120, 2,241, 33, 34,235,125,107,137,164, 36, 97,249,177,119, 45,101, 82, 9, 68,194,204,151, 72, 58,145,245, - 65,155,165,238,231,237, 4, 2, 73,137,111,240, 48,108, 87,105, 63,223,134,214,186,159, 4,176,248,167, 75,161,108,194,194, 26, - 79,231,140, 67,122,129, 8,151,222,230,159,164, 75,164,211,143, 0,249,184, 3,144, 74,105,248,193, 31, 50,118,251, 14,178, 24, -106, 91,135,133, 45,243,127, 1,111,145, 13,187, 93,247, 46,250,212, 64,204,224,241,120,225,219,183,111,239,225,235,235,203, 29, - 50,100, 72,101, 14,242,250, 34,245,209,171, 55, 63, 93,216,179,121,190,141,119,123,236, 92,182, 64,117, 44,226,121,197, 40,196, -106,225,225,225,161,186,119,239,222,188, 41, 83,166,108,233,209,163,135,211,128, 1, 3, 56,117,235,214, 5,151,203,197,155, 55, -111, 16, 30, 30, 46,123,251,246,109,122, 73, 73,201,188,230,205,155,235,147,227, 44,127,249,242,229, 27,213,235, 32,212,195,133, -109,160,142, 46,212, 52, 82, 39, 45,109, 3,192, 56, 48, 48,112, 52, 0, 84, 17,246,189, 28,192, 30, 0, 76,154,166, 51, 66, 66, - 66, 58,156, 61,123,182,195,220,185,115,217,125,251,246,197,253,251,247,113,245,234, 85,185, 92, 46,143, 80, 11, 87, 93, 75,229, - 80, 0,162,148, 74,229,243,160,160,160, 14, 12, 6, 99,185,102, 70, 76, 76, 12, 14, 29, 58, 84, 27, 78, 37,128, 77,153,153,153, - 63,133,132,132, 44,191,118,237,218,248, 49, 99,198,152, 43, 20, 10,196,198,198,226,231,159,127,174, 21,167, 80, 40,156, 99,107, -107,187,244,226,197,139,191, 92,185,114,229,235, 81,163, 70,145,179,102,205, 66,112,112, 48,126,251,237, 55, 74,165, 82,157,101, -177, 88, 99,114,114,114, 68,159,226,174,163, 30,134, 75,215,179,214, 97,141,188, 31, 50, 52,168, 35, 4, 31, 74,160,217, 14, 63, - 63,191, 50, 43,163,198, 10,167,221,134, 32, 8,189,135, 14, 1, 88,210, 52, 77, 1,216,133,210,250,162,218, 89,225, 25,248, 43, -115,188,174,140,205, 4, 82,203, 24, 72, 17, 91,125, 81,105, 75,128, 70,179, 26,216, 10,150, 47, 95,190,117,197,138, 21, 91, 43, -166,112,208,110, 84, 49,245,195,202,149, 43, 97, 72,239, 96,192,127, 21,149, 11,173,168,125, 10, 69,131,193, 75,182,175, 91,176, - 66,169,144, 9,105,200,253,241,230,116,244,135,174,140,166,232, 69,215,143, 6, 6,131, 70, 62,173, 82, 46,252,224,222,255, 77, -253, 36, 44,172, 81,180,106, 26,126,123,145, 78,103,136, 20,223, 28,145,203,203, 89,131, 74,125,178,168, 97, 55, 36,249, 39,172, -156, 88,103,230,124, 97, 67, 92,200, 27,173,247,122,178,178,178,206,109,221,186,149,220,188,121,115,215,146,146,146,138, 14,242, -181,197,130,254, 51, 23, 49,218, 53,114,157,249,240,117,242, 64,232, 48, 92, 88, 17, 29, 59,118, 20,196,197,197, 5, 92,185,114, -101,196,237,219,183,123,136, 68, 34, 87,130, 32, 96,108,108,156, 44,149, 74,175,113,185,220, 99,122,138, 44, 0,192,138, 21, 43, -232,149, 43, 87, 18,113,113,113, 52,131,193,248, 19, 64, 34,131,193, 72,210,118,130,215,158,174, 89, 38, 48, 48, 80,151, 7,226, -237,226,226,226,200, 85,171, 86,117, 89,181,106, 85, 11,181, 85,232, 54,254,242,249,210, 23, 10, 0,183,217,108, 78, 58, 65, 16, -206,108, 14, 87,116,239,222,189,107, 31,200, 89, 34,151,203, 23,166,164,164,108,217,178,101,203, 90, 19, 19,147,182, 49, 49, 49, -127,126, 8,167, 90, 68, 13,182,182,182,118, 58,124,248,240,169,131, 7, 15,182,103, 50,153,247, 9,130, 24, 34, 20, 10, 63,105, - 81,105,117,129,232,149,122,212, 58,212,137,247, 99, 39, 41,253, 59,132,155, 74,165, 42, 94,186,116,105, 86, 69,225, 85,209,122, -165,249,175, 78,229,162,203, 62,213, 39,138,178, 6,225, 66, 20, 3, 64,105,237,194,210,178, 58,186, 22,149, 6, 32,174,233, 58, - 39, 73,242, 44,128,151, 36, 73,190,174, 24,232,162, 61,111,229,202,149, 53, 93,231, 6, 24,240, 89, 67,135, 59, 91, 32, 9, 4, -214,214,147,246, 31, 52, 87,126,156,126, 6,176,217, 43, 73, 96, 62, 0,130, 6,182, 28,145,203,127,168,110, 65,199,142, 88, 75, - 19,152,171,222,153,235, 50,238, 98, 77, 45,182,189, 14,116,168, 63,168, 39,103, 19, 84, 95, 80,246, 61, 78,127,127,127, 70, 21, - 15,243,114, 69,165,171, 66,104,104, 89, 22,255,170,250,169,125,190,153, 61,120,240,192,201,199,199, 71,128,242, 78,255,149, 77, -167,245,220,118, 6, 0,213, 71,222,159,159, 5,167,155,155, 27,231,205,155, 55,178,127,215,181,105,224,252, 87,114, 90, 54,117, - 1,129, 73,208,206, 29, 84,173, 69, 75, 75,160,209,244,207, 40,136, 77,169,162,159,154,235,220, 50, 33, 33,193,181, 97,195,134, -201, 0, 10, 42,244,163,178,121,180,225, 24,253,223,115, 86,134,201, 40, 95,138,206,128, 74, 14,132,129,211,192,105,224, 52,112, - 26, 56, 13,156, 6, 78, 3,103,109,133,214,103, 13, 18, 6, 24, 96,128, 1, 6, 24, 96,128, 1, 6,252, 45, 32,170, 81,165,250, -152, 4,107,163,108,175, 25, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,191,227,172,137, 91,123,249,207,117,232,240, 31, -235,183,193,172,106,224, 52,112, 26, 56, 13,156, 6, 78, 3,167,129,243, 67, 4,203,103, 13, 38, 12, 48,192, 0, 3, 12, 48,192, -128,207, 6, 61,220,193,103,170, 64,254,241, 70,167, 32,170, 26,209,199, 13,117, 0,224, 99,241,253,159,130, 15,224, 43,173,255, - 23,160,142,140, 55, 8,173,207, 23,141, 0, 44, 1,160, 93,139,236, 33,128,245, 21,218, 29, 5,160, 93,144, 80,132,210, 58,129, -175,245, 89, 25, 73,146,235,187,116,233, 50,253,206,157, 59,155,149, 74,229,170, 90,244,215,149,207,231,111, 36, 8,162, 53, 0, - 22, 65, 16,111, 50, 51, 51,215, 43,149,202, 15,137, 90,105,224,232,232,184, 1, 64, 75,146, 36, 89, 4, 65, 36,100,102,102,174, - 81, 42,149, 55, 63,128,211,204,193,193,161, 19, 77,211,142, 0, 24, 44, 22, 43, 55, 45, 45,237, 1,106,153, 91,201, 63, 48,150, - 93, 40, 82,178, 0,192,220,132,169, 8, 13,108, 42,215,117,154,225, 20, 55,192,128,255,111,208,165,145,201,229,208,219, 13,107, -105, 37,190, 87, 1, 68,175,250,216,113, 57, 17,223, 87,181, 60, 81, 73, 84,115, 69,206,222,110, 88,171,162, 75, 57,122,185, 97, -211,229, 55,168, 54,210, 94, 23, 78, 13,246, 1,228,100, 29,170, 20, 16,186, 69, 95,255,219,241, 21,202, 15, 21,150, 13, 29, 86, - 43,180,134,185,131,175, 98,130, 25, 26, 11, 77, 24,175, 25,128, 22,234,135,252,107,148,230, 42, 42,250,192,206,125, 46,156,255, - 54, 44,167,105, 58,160,220,201, 90, 73, 30,162, 47,190,248, 98,192,149, 43, 87,140, 53,245,238, 40,138,130,145,145,145, 18,192, - 88, 61,214,101, 63,108,216,176, 69, 7, 14, 28,192,208,161, 67,151,134,133,133,109, 5, 80,172,235,194, 86, 86, 86,254,150,150, -150,193,251,247,239,183,107,223,190, 3,193,225,112,240,230, 77,130,243,148, 41, 83,188,226,226,226,206,102,101,101, 77,212,119, -227,173,173,173, 71, 90, 90, 90,110,217,187,119,175,109,231,206,157, 65, 16, 4, 34, 35, 35,157,231,204,153,211,226,221,187,119, -199, 51, 51, 51,103,232,203,105, 99, 99,227,110, 97, 97,209,109,231,206,157, 70,157, 58,117, 2,143,199, 67,116,116,180,233,212, -169, 83, 29,211,210,210, 98, 51, 51, 51,111,233, 43,178,158, 69,158,255, 90, 41,151, 6, 1, 0,147,205, 93,208,126, 75,196,249, -103, 55,206,247,175,105,154,127, 96,236,239, 6,177,101,128, 1, 6,104, 99,164, 19, 28,105, 26,243,175,252,188,140, 4,128, 94, -227, 87,207, 26,233,132,205, 71,210,171,174, 97,171, 39,223,247, 99,234, 32,248,112, 26, 50, 63,164,159,251, 0,114, 14,147, 57, -171,157,143,143,237,183,119,239, 38,200,129, 95,254, 79, 14, 81,165,195,156, 85, 10,173,193, 77,177, 74, 89,106, 49, 33,250, 52, -196,241,171,137,140,240, 47,190,248,162,225,132, 9, 19,136, 86,173, 90, 33, 50, 50,210,253,248,241,227, 95, 93,184,112, 33, 65, -165, 82, 69, 2,120, 1,221,179, 90,179, 0,120, 50, 24,140,214,255,114,206,127, 51, 76,212,226, 42, 19,127, 37, 58,125, 47,225, -233,245,235,215,207, 49,153, 76,141, 69,171,157, 72, 36,114,168, 96, 5,211, 5,245, 20, 10, 5,226,227,227, 65,146, 36, 11, 64, -125,188, 95, 82,163, 42, 56, 27, 27, 27,239,142,120, 24,105, 67, 48,141,144, 47, 1, 32,145,131, 99,234,128, 3,135, 66,172,231, -205,158, 49,248,230,205,155,225, 69, 69, 69,191,234,209,159,250, 38, 38, 38, 91,159, 62,125,106, 99,108,108, 12,138,162, 80, 84, - 84, 4, 71, 71, 71,236,223,191,223,114,222,188,121, 1,133,133,133, 55, 37, 18,201,111,250,136,115, 11, 11,139,110,207,159, 63, - 55,210, 20,148,150,201,100,112,118,118,198,209,163, 71,185,179,102,205,106, 90, 80, 80,144, 42,147,201,222,234, 74, 88, 40, 82, -178,148,114,105,208,225, 93,129, 46, 0, 48,102, 70, 96, 16,167,200,252,162, 46,211, 10, 69,202, 11, 0, 12, 66,203,128,127, 26, -173,109,109,109, 67,115,114,114,110, 1,152,136,143, 99,105,112,231,241,120,205, 41,138,114, 36, 73, 18, 12, 6, 35, 67, 36, 18, - 61, 5,240,170,182,132, 54,110,126,253,193, 53, 30, 7,154,106, 65, 2, 32, 72, 50, 90, 37, 47, 57,148,251,234,230,249, 15,226, -228, 24,141, 7,232, 22, 36, 64, 17, 36,249,148, 82,150,236,207,137,191,121,233,223,114,112,238, 11,209,216,205, 81,247,194,152, - 31,131,111,120, 3,240, 73, 10,228,209, 36,221,135, 21,103, 2,125,103,207,158,237, 56, 99,250,116, 98,220,216,177,141,110,221, -185, 67,116,213,167, 90,193,231,137, 42, 29,223, 43, 21, 90,254, 77, 97, 69, 3, 11,143, 7, 47, 33,153, 12, 6, 49, 98,246,250, -128,131,187, 54,145, 61,251, 15, 41, 27, 62,241,245,245,133,175,175, 47, 17, 20, 20,212,232,207, 63,255,108,116,244,232, 81,101, - 68, 68,196, 83, 0, 39,170, 90, 89,111, 55,136, 41,128,199,102, 49, 69, 35,150,253,186,215,199,199, 7, 92, 46, 23, 31,194, 9, - 0, 61, 27,146,111, 89,214, 13,158,142,152,185, 60,185,125,251,142,244,199,224,252,140,240, 16, 40, 43,106,109,229,226,226,210, - 73,169, 84,242, 0,128,201,100, 74, 82, 82, 82,102,162,180, 54, 32, 0,156,165, 40,106,128, 30,220, 36,128, 21, 3, 6, 12, 88, -250,237,183,223,162,110,221,186,152, 53,107, 22, 20, 10, 69,228,165, 75,151,150, 3,216,128, 26, 46, 30,123,123,251,229,187,119, -239,182,102,114, 76,208,106, 97, 34, 4, 5, 74, 0,128, 41, 23, 56, 55,141,198,172, 89,179,204, 31, 63,126,188, 70, 31,161,101, -111,111,191,106,255,254,253,214,198,198,198,160,105,186,172, 22, 99,113,113, 49,138,139,139, 49, 99,198, 12,243,216,216,216,141, -250, 8, 45, 7, 7,135, 78, 59,119,238, 52,226,241,120, 40, 46, 46,102,203,229,114,162,168,168, 8, 37, 37, 37,180, 76, 38,147, -207,156, 57,147,251,226,197, 11, 63,129, 64,240, 22, 6,252, 91,192, 0,240, 13,139,197, 26,212,176, 97,195, 54,175, 95,191,126, -162, 84, 42, 79, 3, 56,253, 17, 94,166,186, 59, 57, 57,173, 77, 79, 79,223, 9, 32,228,255,101,135, 58, 56, 56,156,190,119,239, -158,203,238,221,187,199,110,222,188,249, 34,128,223, 62,128,142,205,102,179, 7,119,237,218,213,101,204,152, 49, 28, 7, 7, 7, - 72,165, 82, 36, 38, 38,154,159, 60,121,210, 53, 58, 58, 58, 85, 93, 17, 67,231, 23, 10, 27,247,142,166, 96,154, 31,239,208,177, - 83,231,161,131,191, 49,115,176,177,128, 88,166,194,235,100, 65,221, 63, 46,158,235, 26,199, 54,186, 39,151, 11,135,231,190,186, - 87,172, 47,103,183,110,221, 59,247,232,222,221,204,194,210, 2, 66,145, 28,111,146,210, 92,111, 92, 61,239,203,100, 26,221,166, - 8,197,168,172,231, 87, 75, 62,229,177,153, 5, 48, 69, 60,155,230, 45, 58,182,122,220,107,194,154, 54, 52, 77,131,164,177,163, -162, 53,107, 22,192,220, 81, 90,246, 75, 47, 62,208, 52, 77, 16,216,164,109,205,234,237,134,181, 52,141,239, 65,130,232, 93,195, - 48,165, 6,189, 0,174,165,181,181,207,212,201,147,137,162,194, 66, 68, 71, 71,151, 84, 20, 89, 91,235,128,125,155, 68,189,179, - 41,181, 23,219,255, 82,107, 86,165, 67,135, 58,231,209, 50, 54, 54,174,116,186,133,133, 5,186,117,235,134,245,235,215, 51, 1, -180,174, 48,187,124,145, 85,128, 27,182,103, 49, 44, 76,184,100,221,186,117,205,204,205,205, 63,152, 19, 0, 64, 83,245, 59,214, -165,191,124,244,235,146,177,215,142,110,241, 20, 21, 21,176, 42, 54, 49, 53, 53, 69,227,198,141,177,116,233, 82,221, 56, 63, 28, -255, 40,167,163,163, 99, 19, 95, 95,223,214,215,111,221,178, 76, 79, 79,231,166,167,167,115,175, 92,191,110,217,161, 67,135,214, -142,142,142, 77,202,118, 21, 77,235,211,207,213,187,118,237, 90,126,246,236, 89,210,215,215, 23, 86, 86, 86,232,214,173, 27, 46, - 94,188,200,220,188,121,243, 58, 0, 75,107,234, 39, 73,146,157,125,125,125, 9,208, 52, 50,132, 74, 60, 88,223, 4,209,155, 60, - 80, 36,161,145, 39, 44,132, 88, 44,129,177,177, 49, 15,165,195,189,186,110,123,199, 14, 29, 58, 16, 0,202,196, 85, 81, 81,233, -167,184, 88, 4,153, 76, 14, 46,151,107, 6,128,167, 43, 39, 77,211,142,157, 58,117, 2, 0,200,229,242,178, 55,188,130,130, 2, - 66, 40, 20, 66, 38,147,129,197, 98,177, 81,179, 95, 99, 25,167,185, 9, 83,193,100,115, 23,140,153, 17,152, 50,102, 70, 96, 10, -147,205, 93, 32, 51, 43, 84,233, 50,205,220,132,169,248,196,231,167, 29, 73,146, 63,187,185,185,197,146, 36,121, 24,128,227, 7, -114,182, 5,176,206,200,200,232,154,135,135, 71,138,177,177,241,117,181, 80,239, 80, 75, 78,142,177,177,241,245,117,235,214,157, -122,242,228,201,208, 63,255,252,179,254,179,103,207, 6, 7, 5, 5, 29, 55, 53, 53, 13, 71,121,191, 68,189,175,205,250,245,235, - 31,124,240,224, 65,219,142, 29, 59, 30, 0,192,253, 72,215, 59, 3, 64, 75,232, 84,145,227,147, 28,119,167, 86,173, 90,185,240, -120, 60,244,232,209, 3, 0,252, 62,132,147,205,102, 15, 94,186,116,169,219,178,101,203, 56, 2,129, 0,215,175, 95,199,195,135, - 15,161, 84, 42, 49,109,218, 52,238,152, 49, 99, 26,152,153,153, 13,214,171,159, 76,243,227,179,231,204,237, 51,127,214, 36,179, -167,239,228, 56,116,237, 29,126,143, 16, 32,171,132,131,254,131,199, 88,244, 30, 56,172, 55,135,107,113, 92, 95,206, 69, 11, 23, -246,153, 60, 62,192, 44, 70, 64,225,220,253, 12,220,143, 23, 66,201,178, 68,223,193, 19,173, 90,116,234,243, 21, 19,172, 95, 62, -245, 49,218, 15,180,159, 61,123,182,221,130, 77, 71,238, 58,181,253,102, 71,118, 62,124,181,133,143, 59, 96,105,109, 98,242, 77, -124,215,174,147,140, 74,235,197, 86,203, 89,142,175,245,192,224,172,124,116,209,246,207,234, 98,141, 70,234, 97, 69,198,149,159, -151,145, 52,129, 89, 35,157,202,221, 7, 42,237,231, 77, 96,232,236,185,115, 89, 22, 86, 86,216,181,107, 23,164, 34, 81, 57,159, -217,238, 46,232,115,205,152,153,218,192,195, 57,182,155, 43, 17,254, 31,124, 95,153, 92,165, 69, 43, 44, 44,140,238,215,175, 31, - 1, 0,161,177,200, 31,220, 20, 27,135,125,187,110, 41, 65, 18,116, 61,207,142, 49,117,220,154,137,108,108,108, 80, 82, 82, 2, -169, 84, 10, 54,155, 13,137, 68,130,119,239,222,225,254,253,251,176,178,178,210,171, 39,133,133,133, 48, 53, 53,133,169,169,233, - 71,225, 92, 60,182, 7,247, 77, 74, 54,247,242,253,155, 93,183, 79,255,173,189, 91, 75,191,103,221,135,205,122,110,110,231, 36, -121,246,236, 25,238,221,187,135,252,252,124,248,248,248,252, 87, 14,230, 67,181, 79,214, 67, 0, 86, 13, 27, 54,116,190,124,237, -182, 85,177,132, 50, 79,202, 84,176, 40,138,130,177, 49, 95,121, 34,244,156,112,232,224,254, 68, 70, 70, 70, 22,128,135,106,113, - 91, 83, 77, 69, 30,128, 38,254,254,254,139,166, 79,159,142,132,132, 4, 76,154, 52, 73,252,240,225,195,220,142, 29, 59,218,236, -223,191,223,104,222,188,121,184,117,235,214,138,176,176,176, 51, 0, 18, 1, 84, 90,171,141,166,105, 54,155,205,134, 82, 45, 27, -228, 42,170, 76,223, 23, 22, 22,130, 22,231,131,205,102, 51, 0,216, 65, 71, 63, 58,138,162,216, 44, 22,171, 76,100,189,203, 44, -196,187,172, 18, 20, 22,203, 32, 22, 43, 33, 19,211, 96, 24,219, 48,129, 36, 7, 0, 73, 80,170, 87, 0, 0, 0, 32, 0, 73, 68, - 65, 84,186, 90, 71,120, 60, 30,148, 74, 37,138,138, 74,187,161,177,148,201,100, 50, 8,133, 66, 48, 24, 12, 83, 0,230, 0,242, -116, 33, 84, 59,185,255,174, 30, 6,196,163, 35, 3,108, 95, 95, 88, 92,110,154,185, 9, 83, 17, 58,175, 41,195,198,185,197,157, -150, 67,127,241, 40,155,246,105,253,179,184,118,118,118, 55, 78,157, 58,213,180, 81,163, 70, 72, 76, 76,244, 24, 50,100,136,143, - 64, 32,104, 9,253,107, 50, 26,147, 36,185,113,204,152, 49,211, 71,140, 24, 65,184,187,187,131,201,100, 66,169, 84, 58, 39, 36, - 36,116, 59,121,242,228,194,131, 7, 15,238, 87,169, 84,223, 65,119,191, 63,146,195,225,156,216,187,119,111, 23, 31, 31, 31, 28, - 62,124, 24, 15, 31, 62,164,218,182,109, 75,142, 30, 61, 26,174,174,174, 62,163, 71,143,254, 93, 42,149,246,173,165,101,203,181, - 67,135, 14, 46, 12, 6, 3, 29, 59,118,100,223,187,119,175, 21,128,123, 31,184, 79, 77,157,157,157,111,249,249,249,181,188,118, -237, 90, 84, 70, 70,134,159, 30,219, 11, 0, 3,157,156,156,130, 44, 44, 44,172,244,184,199,150,164,165,165,125, 15, 32, 84,199, - 69,218,183,110,221, 26,201,201,201,104,210,164, 9,216,108,118, 7,185, 92, 62, 5, 64, 31, 0, 63, 0,136,213,163,191,238,221, -187,119,119,241,243,243, 35, 66, 67, 67,203,252, 67, 73,146,132, 82,169, 4,155,205, 70,251,246,237,201,200,200,200, 58,143, 30, - 61,114,135, 14,195,136, 54,110,126,253, 59,118,238,218,185,139, 79,115,114,115,232,107,168, 40, 21, 24,132, 18, 76,130, 2,165, -224,130,203,102,192,221,179, 13, 35,254,197, 83, 31,153, 84,222, 63,247,213,181,243,186,112,246,233,213,211,183,105, 19,119,114, -251,239,111, 80,144, 22,171, 74,139,187,157, 67, 50, 72, 52,109,253,133,173,123,179,150,140,150, 62,126,172,244,196, 23,221, 36, -146, 46, 61,242, 19,110, 95,251, 20, 23,228, 74,128,225, 92,199,246,155,126, 61,253,216,130,244,116,209,201,208,243,207, 75, 20, -184, 15, 0,183, 0,162, 47,208,220,187, 93,187,174,251, 55,108,176,225,243,249,172, 81, 35, 70, 40,247, 69, 69, 69,161,138,161, -223,149, 0,195,214,209,177,199,212,169, 83, 25,130,244,116,250,228,233, 11,207, 52,124, 40,125, 75,241,110,238,236,209, 15,162, -120,189,134, 41,251, 3, 28, 7, 71,199,166, 83,166, 76, 65, 70,122, 58, 14,135,132, 20, 75,128, 8,141, 21,235, 28, 3, 59,155, -185, 57,142, 91, 48,113, 0,225,194,183,197,212, 21,251, 58,116,147,103,185, 65,240,215,241,215,214, 34,159,177,200,154, 92,169, -208,170,136,223, 98,177,220,140,141,250, 39, 79, 30, 35,179,139,228,162,132,132, 4,216,218,218,130,207,231,195,194,194, 2, 49, - 49, 49,184,126,253, 58, 94,190,124, 9,138,162,208,162, 69, 11,189,122,147,147,147,131,167, 79,159,194,202,202,234,163,113,186, -185,216,225, 91, 23, 59,118,102,110, 33,251,218,195,151, 62,251, 22, 15,110, 70,122, 12, 62,168, 93, 36, 86, 38,147,225, 63,130, -178,232, 66, 23, 23,151, 78,135, 14, 29, 98, 75,149, 48,115,159, 18,241,163, 72,162, 50, 1, 0, 19, 30, 67, 20, 25,212,248,187, -213,171, 87,139,198,143, 31,239,145,146,146,178, 94, 7, 91,255,218,238,221,187,207,167,105,154, 53,123,246,108, 0,192,152, 49, - 99, 10,239,223,191,239, 14, 32,235,250,245,235, 78, 19, 38, 76,120,117,227,198, 13,227,185,115,231, 50,148, 74,101, 12,147,201, -164,195,194,194, 86, 1, 8,124,239,137, 72,146,143,163,162,162,234, 57,185, 54,134,171, 13, 9,223,165, 47, 75,111,112,198, 20, - 82,147,222, 32,238,217, 67, 56, 58, 58, 90,240,249,252,216,212,212, 84,121, 90, 90,218, 66,145, 72,180,187,134, 62, 70, 71, 70, - 70,242, 93, 93, 93, 81, 92, 92,140,212,236, 18,204, 58,109,140, 66,113,169, 17,131, 5, 49, 90,186, 52, 54, 51, 34,101, 15,179, -178,178,228, 50,153,108,153, 80, 40, 60, 84, 29, 39,139,197,202,125,246,236,153,105,221,186,117, 33,145, 72,232,188,188, 60, 66, - 36, 18,161,168,168,136,184,112,225,194,215, 2,129,160,109,253,250,245, 9,103,103,231, 85, 2,129, 64,156,150,150, 54, 73,151, -161, 73,181, 96, 82, 49,153,204,205,147, 39, 79, 30,122,230,204,153,199,161,129, 77, 7,106, 13,151, 88,120,122,122, 94,110,222, -188,153, 83,200, 38,239, 29, 0,126,252, 23,156, 91,227,150, 44, 89,210,212,218,218, 26, 83,167, 78,197,202,149, 43,177,124,249, -242, 70, 83,167, 78,157, 12, 96,171, 30, 60, 70,142,142,142,143,182,111,223,238,209,169, 83, 39, 92,188,120, 17,199,142, 29,195, -219,183,111,149,245,235,215,103,250,248,248, 96,197,138, 21,232,221,187,247,164,153, 51,103,118, 77, 79, 79,111,165,163,248, 24, -191, 98,197,138,129,157, 59,119,198,216,177, 99,165, 55,111,222, 28, 10,224,202,213,171, 87,191,184,117,235, 86,232,145, 35, 71, -140,214,173, 91,215, 99,222,188,121, 83, 1, 4,215, 98,251,191,238,210,165,180,134,114,231,206,157, 17, 20, 20,212,251, 3,133, - 22,199,198,198,230,194,225,195,135, 91, 54,110,220, 24,163, 70,141,106, 53,116,232,208, 11,249,249,249, 61, 1,232,116, 67,170, - 83,167,206,198,179,103,207, 54,172,106,100,161, 50, 72,165, 82,235,111,190,249,102, 67, 82, 82,146, 94, 66,235,232,209,163,248, -254,251,239,209,162, 69,139,230,237,219,183,223, 51,101,202, 20,248,251,251,119,143,137,137,113, 64,105,212,114,141,224,241,120, -205,135, 15, 31,206,121,240,224, 1, 0,192,211,211, 19, 45, 91,182, 68,114,114, 50, 30, 63,126, 12,169, 84, 10, 7, 7, 7, 12, - 26, 52,136,151,148,148,212, 60, 39, 39,167, 70,161, 69,114,141,199, 13,236,215,215,236,220,125, 1, 84,148, 18,109, 26,154,195, -199,195, 30,241,169,133,136,140, 77,133, 74,198,134,185,181, 13, 58,116,237,101,157,145,246,118, 92, 46, 80,179,191, 22,215,120, -220,160,129, 95,153,158,139, 72, 71, 65,122, 28,253,250,225,153,235, 10,137,104, 18, 0, 60,254,243,248, 30, 71, 27,163,158,238, -173,219, 48,252,122, 14,176, 58,125, 44, 99, 92,254, 63, 83,219,239, 61,220,114,193, 94, 87, 86,206,152, 5, 1,190, 52,203,202, -249,161,153, 66,177, 83, 51,175, 55,208,107,225,146, 37,237, 39, 78,158,204,163, 40, 10, 71,126,253,181,240,105, 84, 84,252,100, -128,154, 82, 5,223, 78,192,117,232,192,129, 92, 51,115,115,204,153, 53, 11,102, 10,197,141,178, 93, 2,116,159, 51,127,126,167, - 25, 51,102, 24,237, 89, 53,253,113,239, 9,107, 90, 83, 52, 77,104,134, 41,143, 86,111,138,107, 59, 97,224, 64,152,153,155, 99, -246,236,217, 32,228,242,203,101, 2,138,137, 27,227,191,246,245, 9,232,223, 25, 4, 8, 28, 11,187,131,215,201,217,207,110, 8, -240,230,115, 85, 85, 21, 80,165,143, 86,181, 67,135, 69,114,100,118,255,106,176,192,221,221,189,168, 81,163, 70, 69,185,185,185, -120,254,252, 57,242,243,243, 17, 28, 28,140,184,184, 56, 80, 20, 85,107, 1, 67, 81, 20, 62, 54, 39, 0, 56,216,152, 99, 84,223, -118, 76,169, 68,196,203,206,206, 46, 55,124,244, 31, 18, 90,101, 80, 42,149,188,250,245,235,131, 4, 8, 97,137,194, 52,227,104, - 23, 34,227,104, 23, 66, 88,162, 48,149,201,100,164,169,169, 41,164, 82, 41, 79, 7, 42,214,151, 95,126, 57,255,204,153, 51,172, -181,107,215,194,203,203, 11,114,185, 28,247,239,223, 79, 5,144,165,110,147,126,251,246,237,116,141, 16, 94,191,126, 61, 78,159, - 62, 77,244,232,209, 99, 97,101,231,147, 64, 32,216, 56,101,202,148,188,146,162, 60,236, 29, 38, 70,232,168,108,252, 60,240, 45, - 70,216,156, 66, 94,230, 59,236,219,183, 15, 87,175, 94, 35,174, 92,185,202,190,121,243,166,201, 87, 95,125,181,163, 78,157, 58, - 97,213,117, 50, 61, 61,125,237,140, 25, 51, 10,138,138,138, 80, 84, 84, 4,177, 88,130, 60, 17,240,108, 75, 83, 60,219,210, 20, - 18,202, 8,187,118,238, 38,159, 61,123,102,251,246,237, 91,167,254,253,251,111,225,243,249, 7,171,227, 76, 75, 75,123,240,237, -183,223, 74, 10, 11, 11, 33,147,201,228, 42,149, 74, 38, 22,139, 21,199,143, 31,159,107, 99, 99,211,225,226,197,139,172,171, 87, -175, 49,111,222,188,197,190,126,253,186, 69,183,110,221, 78, 56, 56, 56,252,162,139,165,140,193, 96,108, 11, 9, 9, 25,183,107, -215, 46, 7, 31, 31,159,102, 21,134,162,248, 61,123,246,172,247,235,175,191,214, 9, 10, 10, 90,136,210, 0,148, 79, 10, 91, 91, -219,153, 3, 7, 14,196,174, 93,187,112,254,252,249,121, 59,118,236,192,151, 95,126, 9, 39, 39,167,111,161,251,176, 23, 0,252, -184,117,235, 86, 15, 15, 15, 15,140, 25, 51, 70, 54,105,210,164,239, 14, 29, 58, 84, 63, 60, 60,156,253,203, 47,191,212,155, 58, -117,234,236,128,128, 0, 73,131, 6, 13, 16, 28, 28,220,144, 36,201,109, 58, 93,223, 14, 14,115, 71,140, 24,129, 77,155, 54,225, -230,205,155,131, 81,250, 64,149, 1,184,116,247,238,221,254,235,214,173,195,224,193,131,225,236,236, 60,187, 54,150,167,166, 77, -155, 46,235,211,167, 15,194,195,195,209,170, 85, 43,116,232,208, 97, 30, 0,219, 90,238, 78,210,212,212,244,196,161, 67,135,124, -235,213,171,135, 53,107,214,192,205,205, 13, 7, 15, 30,244, 53, 49, 49, 57, 1, 29,221, 55, 44, 44, 44, 76,141,141,141,177,112, -225, 66,122,240,224,193,121, 53,125,230,205,155, 71,115,185, 92, 88, 89, 89,233, 26,248, 98,196,227,241, 58,122,121,121,225,254, -253,251,184,122,245, 42,150, 46, 93,138,185,115,231, 34, 59, 59, 27,195,135, 15, 55, 6,224,175,199,118,219,219,217,217,161,176, -176,180, 46,188,151,151, 23,158, 60,121,130,236,236,108, 56, 59, 59, 35, 35, 35, 3, 54, 54, 54,104,220,184, 49, 40,138,178,215, -141,146,246,178,181,182, 64, 86,190, 20, 76, 40,209,218,221, 22, 55,158,231,226, 93,182, 12,246, 54,150,200,200,202, 70, 29, 27, - 30, 92, 92,234,130,166, 41, 47,157, 20, 48,131,108,205,229, 25, 33,175, 72,142,180,216,155,185,114,149,116, 74, 65,226,221,148, -130,196,187, 41,114,169,100,202,227, 59, 87,115,235, 57, 24,193,197,197, 5, 4, 77,181,251, 20,215,227,144,186,112, 49, 49, 98, -142,185,250,243, 50, 34,108,255, 98, 66,154,251,174,109, 31,135, 82,203,178, 29, 80,127,200,240,225, 29,191,251,238, 59, 94,102, -102, 38, 21, 48,108, 88,222,218,192,192,107,127,212,240, 98, 80, 12, 52,234,217,179, 39, 72, 0,127, 92,185, 34,202, 0, 82, 1, -192, 1,112, 25,240,205, 55, 93,150, 44, 90,100,148,147,155, 75,221, 79, 40, 62, 23,151, 69, 15,178, 86,161,190, 46,254, 89, 42, -192, 91,195,123,249,242,101, 90, 12, 60, 6, 0, 63, 23,124,219,171,147,167,207,232,129, 93, 32,200,202,199,236,181, 63, 99,207, -201, 91,151, 45, 20,244, 23,255,161, 71,241,228, 90, 9, 45,245,208,207,123,211, 74, 74,222, 31, 61,248, 80, 1,243,119,112, 86, -134,255,162,208,210, 64,161, 40, 29, 37,145, 41, 40,200, 20,148,230,173, 22, 98,177, 88,103,138,203,151, 47, 31,158, 53,107, 22, -182,108,217,130, 87,175, 94,129,205,102,195,203,203,139, 15,192, 84,115,207,111,221,186,181, 61, 73,146,136,143,143,199,230,205, -155, 49,126,252,120,250,222,189,123, 7, 81,121,190,148, 39,121,121,121, 59,167, 76, 26, 95,144,159,249, 14, 10,113, 62,178,210, -222, 64, 42, 42,192,154,245, 27, 81,162, 96, 34, 67, 40, 71,134, 80, 14,146,107,141, 61,251, 15, 49,154, 54,109,218,135,193, 96, -244,171,166,159,247, 51, 51, 51,247, 79,155, 54,173, 32, 35, 35,163,108,251,100, 10, 26, 50, 69,249,243,213,216,216, 24,219,182, -109,179,112,119,119, 31,200,100, 50,187, 85,195, 41, 72, 73, 73,137,155, 54,109,154, 44, 51, 51, 19, 66,161, 16,231,206,157,235, - 95,175, 94, 61,171, 13, 63,110, 33, 68,114, 38, 50, 10,228,200, 40,144,131, 99,106,143, 19,161,103, 24,141, 27, 55, 14, 96, 50, -153, 29,106, 18, 89, 71,142, 28, 25, 61,108,216, 48,179, 31,127,252, 49,239,236,217,179,187, 0,104, 31,144,248,109,219,182,157, - 60,113,226, 68,209,252,249,243,173,131,130,130,230,125, 98,177,213,109,216,176, 97, 77, 40,138,194,169, 83,167,158, 1,216,122, -230,204,153, 71, 82,169, 20,195,135, 15,175,175, 30, 70,210, 5,109, 3, 2, 2,166,251,250,250, 98,206,156, 57,242,107,215,174, -181, 6,176, 5,165, 67,185, 52,128,100, 0, 59,110,221,186,213, 98,230,204,153,210,118,237,218, 97,236,216,177,227, 1,248,214, -192,219,113,196,136, 17, 30, 20, 69,225,248,241,227, 79, 1, 92,172, 48,255,122,104,104,232,125,153, 76,134,145, 35, 71, 54, 0, -160,207,141,156,205,229,114, 79,173, 94,189,218, 50, 45, 45, 13,163, 71,143,150,198,199,199, 35, 48, 48,208,200,194,194,226,162, -214, 53,160, 51,184, 92,238,190,159,126,250,105,160,183,183, 55,166, 77,155, 38,219,189,123,247,172,233,211,167,203, 90,183,110, -141, 93,187,118, 13,228,112, 56,122,149,232, 72, 79, 79, 47,136,141,141,181,169,233,147,154,154,170,107,120,190,177,169,169,105, -132,167,167,103,161,151,151, 87, 27,165, 82,137,152,152,152, 55,135, 15, 31,166,188,188,188,176,115,231, 78, 4, 5, 5,161, 95, -191,126, 96, 48, 24, 58, 11, 45, 6,131, 1,185, 92, 14, 99, 99, 99, 48,153, 76,188,121,243, 70,147, 90, 6,108, 54, 27, 0, 96, - 98, 98, 2, 35, 35, 35,144, 36,169, 83, 52, 26, 65,128, 46, 44, 81,128,197, 34,193, 36, 41,196, 37, 11, 33, 87, 80,224,177, 25, - 96, 49, 9,128,166, 96,105,194, 2,143,195, 0, 73, 16,148,142,156, 16,138,228,224,176, 73,176,216, 28,130, 84,170,140,202, 30, -142, 76,149,145,145, 17,135,176, 53,231,130,199,254, 23,149, 5, 38, 74, 29,203,199, 1, 44,147,186,117,135,110,218,188,153, 83, - 88, 92,140,193,131, 7,231, 37, 61,122, 20, 34, 6, 30,117,173, 33, 72,137,100, 50,221,253,186,118, 69,100, 84, 20,138,242,243, - 95, 3,165,206,241, 28, 39,167, 97,219,182,109,227,136, 37, 18, 12, 30, 52,168,224,213,157, 59, 71, 82,138, 17,118, 60,185, 84, -136,213,120,220,217,108, 71, 13,175, 48, 63, 63, 31, 40, 77, 33,225, 96,103,186, 97, 70, 64,111, 20,149, 72,176, 96, 99, 8, 21, - 21, 39,248, 54, 60, 21, 95,157, 73,135,240, 63,246, 24,158, 92,225, 3, 64,135,132,165, 26,235, 82, 77, 98, 69, 42,149,126,116, - 1,244,161,156,149,137,196, 15,229,252, 55,130,201,100, 74, 94,190,124,201, 49,183,113,162,108,204, 88,249,245,198,223,177, 0, - 0,107, 83,166, 80,174, 82, 80,233,233,233,224,114,185, 18, 29,135, 27, 38,237,219,183,111, 13,128,102, 76, 38, 51,236,208,161, - 67, 68, 72, 72,136,213,136, 17, 35, 18, 98, 99, 99,211, 60, 61, 61, 93, 15, 29, 58,100, 14, 0, 59,118,236,160, 79,156, 56,209, - 27,165, 41, 51,170,204,227,146,153,153, 25,152,155,155,123,111,198,140, 25,193, 28, 14,199,202,196,196,196, 38, 60, 60,156,144, -200,105,180, 93,146, 92, 22,137,104,110, 68,226,246, 98,115, 76,158, 60,153, 17, 27, 27,187, 62, 45, 45, 45,172, 26,206,133, 5, - 5, 5,225,175, 94,189,218, 98,225,220,210,206,196,117,137,133,207,226,120, 0,128,171, 45, 11,164,250,190, 88, 80, 80,128,236, -236,108, 76,159, 62,221, 42, 33, 33, 97, 97, 90, 90,218,141,106,172, 90,183,114,114,114, 82, 95,188,120,225,199, 98,177, 56, 38, - 38, 38,109, 35, 34, 34, 8,137,140, 66,243,133,201,200, 43, 46,237,167,181, 41, 19,143, 87, 59,224,219,111,191,101,190,126,253, -122,163, 64, 32,232, 92,233,205,140, 36,131,180, 69,214,130, 5, 11,162, 1, 52, 0, 80,110,104, 84,165, 82, 17, 35, 71,142,124, - 14,192,107,254,252,249,214, 52, 77,207, 91,184,112, 97, 30,128,189,255,244,185,100,110,110,190, 97,202,148, 41, 56,113,226, 4, -242,243,243,183, 1, 64, 97, 97,225,214,163, 71,143, 30,159, 52,105, 18,126,253,245,215, 13,217,217,217,127,160,230, 80,237, 47, -135, 15, 31,142, 75,151, 46,225,207, 63,255, 92, 6, 32,166,138,118,175,194,195,195, 23,158, 61,123,118,251,136, 17, 35,240,243, -207, 63,247, 1, 80,157,131,108,207,222,189,123,227,226,197,139,200,205,205,221, 85, 89,131,130,130,130,221,231,206,157,107,223, -187,119,111,172, 95,191,190, 39,128,235, 58,108,186,135,133,133,197,161,237,219,183,183,245,246,246, 70, 64, 64,128, 68, 46,151, -247,153, 63,127,254,249, 99,199,142,153, 29, 62,124,184,205,228,201,147, 31,168,115,190,221,215,201,148, 69,146,235, 54,111,222, - 60,193,207,207, 15,243,230,205, 83, 94,190,124,121, 0,128, 43,127,252,241, 71,194,130, 5, 11, 46,108,222,188,153,177,105,211, -166, 9,179,103,207,206,166, 40,234, 83,137,235,213, 59,118,236,104,223,171, 87, 47,188,121,243, 6,247,239,223,135, 92, 46,255, - 53, 34, 34,226,118,163, 70,141, 86,203,100,178,243, 38, 38, 38, 99,204,204,204, 60, 91,182,108,249,197,227,199,143,141,161,155, -159, 94,102, 98, 98,162,165,133,133, 5,148, 74, 37,158, 61,123,134,186,117,235, 66, 46,151,227,237,219,183,240,246,246, 6,155, -205, 70,102,102, 38,180,172,229, 53,136, 34,242, 89, 66, 82,122, 3,107, 51, 19, 64,197,195,147,248, 84,216,217, 90, 65, 69,144, -200,200, 16,160,101, 19,103, 16, 4,129,130,220, 12, 16, 4,241, 92, 23, 78, 21, 77, 69,190, 75,207,170, 99, 99,198,133,119,251, - 94, 54, 17,127,100,135,152, 55,232, 52,153,201, 32, 24, 28,174,233,222, 9, 99,199,218, 82, 20,141,130,220, 76, 48, 73,242,225, -167, 56, 64,167,222, 33,165,171, 27,239, 73,175, 9,107, 90, 18, 52,104,177, 28,135,127,206, 68,190, 49,208,114,199, 15, 63, 88, -218,216,218, 34, 32, 32,128,202, 77, 75,187, 86,162, 99, 98,229, 6,141, 26, 57,152,154,153,225,238,221,187, 96,148,250,216,226, - 32,224, 17,180, 96,129,141,189,163, 35,198, 79,152, 64,101,190,123,119, 93, 12,164,235,211,215, 6,110,110, 44, 13, 47,169,230, - 21, 48, 48,107,254, 0, 95,174,137, 17, 23,235,246,156, 65, 74,142,232,120,132, 0,123,254,163,246,142,125,213, 90,180,170,114, - 62, 43,117,170, 54,174, 86,172,240,120,188, 50,107,138, 30,111,122, 31,157,179, 38,252, 29,156,159, 16,139, 1,156, 5,176, 56, - 37, 37, 37,110,194,132, 9,114,165, 92, 90,116,111, 77,131, 69, 81,235,235, 77,139, 8,228, 79,251,125,150,197,162, 18, 97, 94, -209,142, 29, 59, 20, 41, 41, 41,113,218,203,212,192,253, 14,192,197, 95,126,249,101,247,169, 83,167,224,229,229,133,152,152, 24, -123,145, 72,212,234,249,243,231,214, 30, 30, 30, 8, 9, 9,193,137, 19, 39,182, 0,184, 90,157,200,210, 64,169, 84, 94,203,200, -200,104,156,156,156,220,208,210,210, 82, 97,105,105,137,138,145,136,133, 98, 10,185, 5, 66, 88, 91,219,192,220,220,188,190, 14, -226,252, 98, 70, 70,134, 59,101,213,164,139,123,206, 54, 97,228, 58, 23, 68,174,115,193,197,133, 78,224, 91,114,144,159,159,143, -236,236,108,100,103,103,131, 32, 8, 40, 20,138,166, 58,112,190, 21, 8, 4, 7,222,189,123,119,214,193,193, 1,102,102,102,160, - 1,100, 20, 40, 16,189,201, 3,209,155, 60,144, 81,160, 64, 97, 81, 17,234,213,171, 7, 51, 51,179,170,134, 40,200, 58,117,234, -244, 29, 54,108,152, 25, 0,168, 5, 84,119,154,166,167, 85,242,153,170, 84, 42, 59,105,218,126,255,253,247,214, 0,122,255,195, -231, 19, 3,192,140, 73,147, 38,181,225,241,120,216,185,115,231, 91, 0, 71, 52,247,250,221,187,119,199, 3,192,172, 89,179, 60, - 1,204, 67, 21,153,160,203, 76, 67,108,118,235,166, 77,155, 34, 34, 34, 2, 0,206,212,176,238,208,123,247,238,161, 81,163, 70, -224,241,120,109,107,104, 91,223,197,197, 5,241,241,241, 0,240,164,138, 54, 79,226,227,227, 75,135,123, 8,162,190, 14,219, 62, -176, 87,175, 94,207,110,220,184,209,182, 99,199,142,152, 48, 97,130,236,193,131, 7,125, 1,220,126,242,228, 73,183,145, 35, 71, -138,220,221,221,113,235,214, 45,143,145, 35, 71,222, 35, 73,114,141, 14,156,227, 87,173, 90,181,248,235,175,191,198,170, 85,171, -232,147, 39, 79, 6, 0,184,162,158,119,249,248,241,227,163,215,174, 93, 75, 15, 26, 52, 8, 43, 87,174, 92, 12, 96, 90,117,100, - 34,145, 72,168, 82,169, 32, 18,137,116, 50,201,235,218,222,214,214,246,203, 94,189,122, 97,233,210,165,168, 83,167, 14,206,159, - 63, 79, 3, 8, 3, 16, 46,147,201,186, 0,216, 44, 18,137,126,143,136,136, 64,207,158, 61,217, 40, 95, 98,164,186,245, 63, 59, -122,244,168,212,194,194, 2,174,174,174,104,208,160, 1, 50, 50, 50,144,148,148, 4,111,111,111,180,110,221, 26, 74,165, 18, 7, - 14, 28,144, 20, 21, 21,233,148,147, 79, 41, 19, 29,190,122,225,180,208,198,140, 11,103,123, 11,212,171, 99,141,226,130, 28,100, -103,164,163,117,211,186,232,218,186, 30,114,132, 50, 92, 14, 59,157, 95, 84, 84,114, 88, 39, 19,190,180,228,208,181, 63,206, 11, -173,204,216,104,220,196, 19, 35, 39,204,106,217,178,149,207,213,118,237, 58, 93,254,113,195,186,230,221, 59, 52, 37, 82,115, 36, -184, 20,118, 38, 95, 88, 88,120,232, 83,220,232, 87, 2, 12,137,133,251,237, 93,103, 35, 15, 52,235, 51,233, 64, 92, 42,182, 1, -128,130,193,240,232,251,229,151, 72, 77, 77,197,233, 83,167, 4, 37,192, 83, 93,249,140,140,140, 72, 0, 16, 10,133,224,170,253, -238,148, 64,147,175,190,250, 10,217, 57, 57, 56,122,228, 72,246, 37, 32, 74,159,126,246, 7, 56,198, 70,165, 6, 65,161, 80, 8, - 2, 40, 4, 0,130,137,190,237,188, 26, 33, 59,175, 16, 55, 30,198, 21,215, 19, 99,122,117, 60,159,177, 35,124,237,124,180, 0, -228,204,155, 55, 15, 92, 46, 23,124, 62,191, 76, 28,105,196, 10,135,195, 1,159,207,135, 82,169,196,241,227,199, 1, 32,167,218, - 55, 60, 64, 58, 96,218,122, 74,170,160, 75, 88, 44,214, 71,225, 84,191, 57, 74, 7, 47,248,153,250,227, 94,229, 65, 49,181,225, -252, 12,208, 78,157, 19,171, 29,128,252,164,164,164,212,161,131, 7, 8,147, 19, 94,100,136, 10,210, 5,133,185, 41,130,148,183, -207, 51,150, 44,156, 39, 76, 77, 77, 77, 65,105, 46,173,118,233,233,233,154,101,116,193,188,161, 67,135,254, 52,105,210, 36, 58, - 58, 58, 26, 0, 16, 25, 25,137,177, 99,199,210,163, 71,143,222, 6, 96, 81, 45,250, 45, 18,139,197,229,172, 33,114, 21, 85, 54, -228, 87, 88, 88,136,244,244,116,200,100, 50,157, 21,241,171,203,155, 94,230, 37, 61, 86,120,186,154,192,211,213, 4, 30, 46,198, - 32,148,197,101, 34, 43, 59, 59, 91,243,230, 44,209,163,159,133, 82,169,180, 92, 63,181,135, 38, 11, 11, 11,145,145,145, 1,149, - 74, 85,213,131,140, 74, 75, 75,187,124,226,196,137, 34, 0,248,241,199, 31,243, 8,130,248,147, 32,136,159, 42,249,236, 97, 50, -153,119, 53,109, 55,109,218,148,135,247,135,196,254, 78,124,237,237,237,157,191,120,241,226,157,179,103,207,198,158, 61,123, 32, - 16, 8, 22,225,175, 92, 60, 84, 78, 78,206,130, 93,187,118, 97,220,184,113, 88,190,124,249,166, 86,173, 90, 21, 2, 24, 89, 21, -161,157,157,157, 51,147,201, 68, 84, 84, 84, 33,128, 55, 53,172, 63, 35, 42, 42, 42,147, 32, 8,240,249,124,183,234, 26, 90, 91, - 91, 55, 52, 51, 51, 67, 90, 90, 26,160,126, 99,174, 4, 73,233,233,233, 52,135,195,129,147,147, 83,163,154, 54,222,202,202,106, -193,129, 3, 7,152, 47, 94,188, 64,247,238,221, 83,111,221,186,213, 19,128, 38, 36, 61, 42, 50, 50,210,183, 91,183,110, 47,175, - 94,189,138,141, 27, 55, 18, 45, 90,180,152, 86, 19,167,171,171,235,212,241,227,199, 35, 56, 56, 24,123,247,238,157, 6,224, 84, -133, 38,199,118,237,218, 53,107,239,222,189,152, 48, 97, 2,234,215,175, 63,178, 58,190,228,228,228,133,126,126,126,145,175, 94, -189,210,169,226,129,142,237,187,249,248,248, 52, 20,139,197, 56,116,232,208,155,134, 13, 27, 62, 58,117,234,212, 60,188,255,192, -254,253,244,233,211, 24, 53,106, 20, 90,180,104,113, 8,192, 8, 93, 46,203,216,216,216,148,235,215,175, 83,108, 54, 27,174,174, -174,232,215,175, 31, 2, 2, 2,208,188,121,115,200,229,114,156, 62,125,154,122,254,252,121,170, 76, 38,211, 41,151, 82,238,171, -155,231, 19, 19,255,199,222,121,135, 71, 81,181, 81,252,204,246,190,155,222, 8, 9,161,165,210, 2,132, 94, 2, 33, 8,132,142, -162, 82, 68, 20,144, 34, 10, 40, 22, 64, 69,154,244, 34, 82,196,130, 8, 8,136,180,208, 4,252, 64, 58, 9, 16, 18, 72, 66, 72, -175,155, 94, 54,219,119,231,126,127, 36,193, 16, 83,118, 19, 84,208,249, 61,207, 60,155,220,217, 57,123,167,221, 61,251,222,123, -223,137,191,114,251,198, 37, 35,135,205,130,135,171, 29, 70,135,116,194, 27,227,122,161,179,111, 51,164,230,106,112,225,194,175, -198,228,228,196,107,150,204, 56,172,210,140,189, 31,117, 53,230,246,101, 19,151, 67,193,215,167, 45, 22,125,244,190,237,242, 79, - 22,218,180,109,229,129,168,164, 18,252,122,246,148, 49, 43, 35,253,183,127,106,198,225, 69,128, 39, 21, 80, 18, 54,139, 5, 51, - 75, 80,206,174,156, 72,211,206,223,223,219,217,197, 5,225,225,225, 96, 89, 49, 35,244, 34,192,147, 74, 43,122,193, 85, 42, 21, -170,244, 90,251,248,248,120,120,122,226,100,120, 56,216, 52,253,160,159,149, 9, 70,227, 42,186,161, 31,235, 82,128,118,102,115, -200, 90, 55,119,242,177, 85, 72,112, 35, 42, 1, 58, 35,185,249, 99, 17,254,209,124,100,127, 33,211,208,200,174,195, 53,219,183, -111, 15,218,181,107,215,160,121,243,230, 73, 39, 79,158, 12,161, 80, 8,181, 90, 13,119,119,119,152,205,102,156, 62,125, 26, 17, - 17, 17, 42,154,166,127,197,159,211, 6,132,160,218, 44,141, 51,137, 16, 85,248, 45,117,208,209, 23, 95,124, 42,154, 0, 32, 77, -160,229, 5, 45,244,123, 54, 31,188, 60,102,239,153,219,212, 59,175,244, 99,117,246,105, 14, 0,112,118,118,134, 92, 46,183, 90, -243, 41,240,151,107, 86,239,214,205,201,201,137,203,201,201,201,125,243,205, 55,125,171, 6,190, 11, 4, 2,109,101, 36,171,168, -182,109, 44,168,167, 1,192,204, 93,187,118, 29, 43, 41, 41, 57,243,222,123,239, 97,249,242,229, 56,126,252,120, 31, 0, 87, 26, -185,239,230,162,162,162,226,155, 55,111, 58,183,241, 11, 68, 75, 39, 46,250, 46,126, 8, 66, 8,236,197, 4,101,197,133,184,115, -231, 54,202,202,202,110, 88, 83, 79,131,193, 80,156,155,155,235,224,228,228,132,194,194, 66,228,231,231, 63, 54, 89, 69, 69, 69, - 40, 44, 44, 36, 20,245,167,156, 45,245,105,150,231,230,230,170, 99, 99, 99,249,206,205,219,160,149, 19, 15,221, 62,138, 3, 8, -129,135, 29, 11,101,165,197,184,118,237, 26, 74, 74, 74,254, 87,151, 38, 77,211,243, 39, 76,152,192, 6, 48,233,189,247,222,179, - 3,208,241,253,247,223,255, 21, 53,102, 22,114, 56,156, 13,123,246,236,105, 87,213,197,184,112,225,194,245, 0,118,253, 93,215, -146,189,189,253,252,240,240,112,153,193, 96,192,230,205,155,177,126,253,250,111,240,231, 68,149,225, 95,126,249,229, 86, 22,139, - 53,107,246,236,217,152, 62,125,186,184, 75,151, 46,243,178,179,179,127,172, 77, 51, 51, 51,115, 81,231,206,157,151,228,230,230, -174,176,200, 44, 63,124, 56,173,115,231,206,139,114,115,115, 87,215,119,142, 36, 18,137,196,108, 54, 35, 57, 57,185, 8,168,115, -124,135, 54, 57, 57, 57,211,108, 54,187,139,197, 98,187,134,174,207,162,162,162, 21, 93,186,116,249, 84,169, 84,158, 5,176,172, - 22, 67,126, 55, 59, 59, 59, 96,238,220,185,115, 86,173, 90, 53, 38, 39, 39,103,127, 67,154,169,169,169, 43,130,131,131, 23,199, -199,199,127,143,186,187,128,191,252,236,179,207, 12,123,246,236,121, 43, 57, 57,121,101, 3,154, 39,242,243,243, 79, 88,113,126, -235,122,255, 99, 77, 54,155,253,254,170, 85,171, 88,219,183,111, 7, 33,100,173,217,108,174,171,158, 81, 71,142, 28,217,221,171, - 87,175,201, 7, 15, 30, 20, 6, 4, 4, 76,215,233,116,251, 26,186, 62,213,106,245,225,131, 7, 15,142,137,138,138,114,159, 60, -121,178,208,219,219, 27, 6,131, 1,217,217,217,216,190,125,187, 54, 58, 58, 58,163,184,184,248,176, 53,109,136, 73, 95,250,202, -213, 11, 71,247,165, 60,140,238,209,255,133,145,182,122,131, 59, 4, 5,108, 20, 23,228,224,244,137,195, 69,201,201,137,215,212, -234,226, 87,172,209, 52,232, 74, 94,190,246,219,177,253, 25,201,177,221,251, 6, 15,181,213,234, 61, 33,224,177, 80,160,204,196, -233,240,163,133,201,201, 73,191,107,141,186,215,254,169,118,158,237,133,101,236,156,136, 55,103, 12,239, 4,145,173,251, 29, 46, -176,185, 23, 32,114,112,118,230, 85,222, 59,144, 86,140,121,180, 72, 83, 9,240,219, 84,246, 82,169,213,106,112, 1,253, 20,128, -235,232,232, 40, 2,128,248,248,120,136, 43,122, 53,172,170,167, 10,144,136,171,233,178, 0,117, 1, 7,205, 90,203, 37, 20, 0, -100,228, 20, 64,111,172,247,123,227,121,103,103, 53,195,181,179, 49, 2, 60, 0, 33, 82,169,116,249,146, 37, 75,214,222,184,113, - 99,109, 88, 88,216, 90,129, 64,176,188,242, 96,243,234, 57, 17,127,155,102, 87, 55,216, 5,183,162, 46,133,182,166,232, 25,125, -108,205,175,117,147,232, 7, 12, 24,176,181,137,245,108,202,205,242, 87,106, 30, 53, 26,141, 4, 21,221,118, 71, 81,119,151,224, -135,213,214,231,164,165,165,145,202,191,173,169,167,195,248,241,227,233,178,178, 50,242,210, 75, 47, 17, 52,252, 8,159,122, 53, - 5, 2, 65,112,223,190,125,141,202,188, 66, 18,151,148, 73,174, 71,222, 39,103, 46, 92, 37,251, 15,135,147, 45, 91,119,144, 14, - 29, 58,232, 1,120, 90,163,201,225,112, 6, 4, 7, 7, 23, 40,149, 74, 18, 27, 27, 75, 46, 93,186, 68, 14, 29, 58, 68,118,236, -216, 65,182,109,219, 70,154, 55,111,174, 4,224,108,141,166, 72, 36, 26, 57,100,200, 16, 99,113,169,154, 36,103, 22,144,123,177, -201,228,202,205,123,228,244,133, 43,228,199,125, 7,137,191,191,191,214, 2, 77, 54,155,205,222,178,127,255,254, 82, 66, 8, 25, - 57,114,100, 6,158, 76,164,218,114,254,252,249,185,132, 16,178,122,245,234, 2,212, 62, 16,254,175,190,150, 94,104,214,172, 89, - 28,143,199, 11, 7, 48,169,129,237, 94,230,112, 56,199, 93, 92, 92,110, 1, 24,253, 15,220, 71, 97, 78, 78, 78,215, 1, 52,244, -132,131,170,247,141,250,151,220,239,127,133,230, 0, 14,135,115, 9,168,255, 33,194,213,218,235,207,217,108,246, 73, 0, 3,173, -172,103, 91, 7, 7,135,151,108,109,109,223,177,181,181,125,199,201,201,233, 37, 62,159,223,182, 41,251,110,223, 54,100,184, 71, -224,136, 35,205, 59, 14, 75,245,232, 20,150,234,213,121,228, 17,251,182, 33,195,155,170,233,217,121,228, 81,143, 78, 97,105, 30, -157,134,167,180,236, 58,242,136,131, 79,200,144,127,242, 28, 77,106, 6,183, 65, 45, 97, 34,151, 22, 19,114,105, 49, 9,105, 9, -186,135, 13,252,131, 0,217,224,144,144,117,196,108, 94, 55,102,212,168,117,109, 0,123, 2,176,107, 46,181,105, 6, 2,242,199, -219,142, 28,185,174, 21,224, 48, 8, 16,247,235,211,103, 45, 49,155,215, 77,120,249,229,117, 30,128, 75,109,122,117,105, 18,128, -221, 12,112,171,174,235, 0,180, 30,231,133,128, 15,135,123, 17,114,105, 49,249,236, 69,111,210,217, 25,147, 26,208,172, 43, 82, -244, 92, 71,180,172, 69, 82,217,184,174,172,124,149, 60,133,139,240,169,107,118,119,133,119, 72,107, 42,118,168, 15,167, 16, 21, - 83,146, 37,255,194, 70,242,123,189, 94, 79,180, 90, 45, 81,171,213, 68,165, 82,213, 52, 80,143, 13, 89, 86, 86, 22,201,200,200, - 32,105,105,105, 36, 37, 37,133,224,143,177, 55, 22,215, 83, 46,151,239,122,241,197, 23,205, 92, 46,119,203,211,216,119, 59, 59, -187,149,221,186,117, 51,108,218,180,137, 28, 57,114,132,124,253,245,215,100,246,236,217,164, 93,187,118, 58, 27, 27,155, 87, 26, -163,233,226,226,178,200,199,199,167,224,155,111,190, 33, 63,254,248, 35,217,184,113, 35,249,248,227,143,205,238,238,238, 57, 50, -153,108,112, 99, 52,157,156,156,118,246,238,221,219,176,115,231, 78,242,235,175,191,146,189,123,247,146,249,243,231, 19, 95, 95, - 95,157, 68, 34, 25,107,161, 38,155,195,225,172,155, 49, 99, 70,142,155,155, 91,120,141,117, 98,127,127,255, 91, 19, 38, 76,200, - 2,176,240, 95,116,125, 50,154,140, 38,163,249, 23, 24,173, 87,221,208,140, 0,108, 49,143,247,114,191, 62,125,214,242,128,151, -173, 53, 69, 66, 54,123, 92,175,110,221,214,242,128, 87,170,222, 43,100,179,199,245,235,211,103, 45,151,205,158, 88,151, 94,125, -154, 4, 96,243, 56,156,133,189,122,244, 88,199, 1, 62,170, 42, 27,208,146,122, 48,255,133,230,164,143, 39,149, 48,209, 9,226, -127,177,209,122,234,112,254,130,139,240,121,209,124, 86,110,234, 54,149,134,233,168, 21, 17,173,163,168,120,138,122,155, 70,214, - 83,244,148,247,189,189,131,131,195,169, 54,109,218,228,181,104,209, 34,203,214,214,118, 31, 0,247, 38,106, 6,184,184,184,252, -224,236,236,252,208,213,213, 53,202,193,193, 97, 3, 42,178,206, 55, 90,147,203,229,118,115,118,118,254,159,151,151, 87,177,167, -167,167,210,193,193, 97,127, 45,145, 44, 75, 52, 93, 81,123,163,194,171, 92,199,124,233, 48,154,140, 38,163,249,132,129, 9,109, -133, 85,131, 90,194, 52,168, 37,204,161, 94,216, 80,221,160,132, 1,162,198,154,162,215, 0, 65,205,247, 55,164,215,144, 38, 1, -216, 61, 1,105,205,109,134,186,195,223, 66,205,231, 61,162, 85,213,206, 91,151,222,161, 14, 76,127, 65, 37,159, 23,205,103,133, - 4,212, 51, 24,185, 26, 43,159,226,103,106,158,242, 62,220,203,207,207, 31,146,159,255, 84,231, 38,196,228,228,228, 76,122,154, -130, 70,163,241,134, 82,169,236,255, 20,164,234,154,122,109,128,133,211,178, 25, 24, 24,254, 59, 80,128, 25,137,248, 32,164, 45, - 54,115,204, 96,157, 78, 66,102,141, 41,121, 26,170, 49,154, 21,152,191,175,165,141,167, 26, 91,207, 63, 80,253, 73, 35, 3,247, -169,255,206,105,203, 70,197, 24,173, 38, 27, 45, 6, 6, 6, 6, 6, 6,134,191,129,115, 15,153, 31, 98,207, 1,225,120, 50,250, - 22, 94,205,136,214, 25,250,180,102, 38, 69, 99,194,167,231, 24, 77, 70,147,209,100, 52, 25, 77, 70,147,209,252,207,105, 86, 81, -215,179, 83,227,106,252,223,168, 89,124,255, 21,152,126,118, 70,147,209,100, 52, 25, 77, 70,147,209,100, 52,255,237, 52, 58,143, - 22, 3, 3, 3, 3, 3, 3, 3, 3, 67,253,212, 25,117, 99,140, 22, 3, 3, 3, 3, 3, 3, 3, 67,211,112, 69,197, 35,170,194, -241,199,163,170,118, 2, 13, 63,130,231, 9, 86,173, 90,197,106,211,166,141,148,207,231,183, 75, 76, 76,100,205,156, 57,179,201, - 19, 9,214,110,216,194,242,244,244,148, 2,104, 87, 80, 84,198,122,253,141,247, 40,230,124, 49, 48, 48, 48, 48, 48, 48, 60, 71, - 12,171, 52, 86, 85,175,143, 35, 92, 86, 69,180,150, 45, 91, 6,163,209, 40, 1, 48, 62, 32, 32,224,115,173, 86,171, 61,112,224, - 0, 85,153, 45,188, 81,124,180,112, 62, 12, 6,131, 4,192,120, 39, 7,155,207,205,102,179,246,224,241,203,212,139,195,123, 19, -230,188, 49, 48, 48, 48, 48, 48, 48, 60, 39, 76,171,241,186,211,106,163,197,225,112,216, 44, 22,171,149,209,104, 28, 34, 20, 10, -207,106,181,218, 75, 77, 49, 89, 85,154, 20,139,213,202,100, 52, 14, 17, 8,132,103,213,234,242, 75,140,201, 98, 96, 96, 96, 96, - 96, 96,120,142,176,108,102,228,137, 19, 39,234, 52, 56,124, 62,159, 21, 16, 16,208,219,211,211,243,138,159,159,159,222,221,221, -253,144, 88, 44,150, 52,177, 98,172, 54,222,190,189,221, 92,157,175,116,106,229,170,119,114,114, 58,196,229,114, 37,204,249, 98, - 96, 96, 96, 96, 96,248,111, 82,159, 23,121,134,169,154,105,248,167,167,124, 88, 51, 70,171,163, 82,169,220, 58,106,212,168,238, -115,231,206,229,177,217,236,230, 18,137,164,157,131,131,195, 19, 81,177, 41, 83,166, 80, 86,105,230,100,111, 93, 62,174, 99,247, - 43, 31,117,229,113,217,104, 46,145, 72,218,201,229,242, 39, 52, 39,188, 62,157, 25,183,197,192,192,192,192,192,192,240,172, 82, - 53, 46,107, 24,172, 73,239,208,181,107, 87, 65,122,122,122, 39,141, 70,227,196,227,241, 22,142, 24, 49, 34, 96,204,152, 49,184, -115,231,142, 57, 32, 32,192,173,160,160, 96, 78, 81, 81,209,185,242,242,242, 59, 52, 77, 7, 8, 4,130, 11,251,246,237,147, 2, -120, 88,151,102,251,142, 93, 4,233,169, 73,143, 53,103,140, 27, 16, 48,105,222, 16,208,167, 54,155, 7,116,240,112, 75,205, 87, -207,201, 5,209,176,198, 0, 0, 32, 0, 73, 68, 65, 84, 45, 40, 57,167, 46, 87,221, 49,211, 36, 64, 32, 16, 92,248,241,219, 29, -245,106, 50, 48, 48, 48, 48, 48, 48, 48,252,131, 84, 25,171,112,212,120,164, 26, 7,168, 8,211,133,133,133, 61, 17, 53,226,243, -249, 95,197,199,199,247,178,179,179,107,197,229,114,205, 47,191,252,178, 96,194,132, 9,200,203,203,163, 85, 42, 21, 59, 48, 48, -208,249,214,173, 91, 67, 76, 38, 83, 31, 27, 27, 27,117,113,113,177,131, 78,167, 75, 0, 48,167,158,138,124,245, 48, 46,186,151, -189,173, 93, 43, 62,151,109,158, 61,117,130,224,163,133, 47,128,210, 69,210,230,220, 2,246,231,157,109,156, 55, 92, 45, 31, 18, -111, 48,247, 41, 87, 8,213, 57, 37, 58, 75, 52, 25, 24, 24, 24, 24, 24, 24,158,115,106,243, 34,207, 17, 13,230,209,234, 95,217, - 39, 90,253,193,185,187, 29, 29, 29, 93,164, 82,169,223,180,105,211, 88, 14, 14, 14,136,136,136,160,203,203,203, 89, 92, 46, 23, - 92, 46,151, 61, 96,192, 0,169,201,100, 18,159, 60,121,146,122,244,232, 81,158,209,104,252,188,160,160,224, 86, 61, 21,217,221, -218, 70,224, 34,178,225,251, 29,127,175, 47,203,177, 77, 1,112,230, 51,154,168,114, 89, 28,154,192, 65, 66,179,215,245,161,164, - 57, 10, 47,241,236,253,121,212,239,143,138,243,140, 70,227,231,101,101,101,183,152, 75,144,129,129,129,129,129,225, 95, 77,109, - 94,228,121,161,122, 30,173, 39, 34, 90,117, 58, 71,103,103,103, 74,171,213,186,120,121,121, 77,115,116,116,156, 40, 22,139,157, -251,246,237, 43, 50,155,205, 32,132, 64,161, 80,208, 45, 90,180,160,247,237,219,103,186,124,249,114,198,219,111,191, 61,106,214, -172, 89, 15,134, 14, 29,202, 58,121,242, 36, 93,155,166,141,173, 29,101, 82,151,186,120,180,242,155,214,222,145, 76,244, 82, 24, -156, 23,143, 16,139, 56,201,249, 32, 14, 28,192,201,139,102,181, 11,165, 87,174, 59,107,250,250, 92, 82,198,251,139, 87,142,122, -107,234,248, 7, 33,161, 67, 89,231,206,214,174,201,192,192,192,192,192,192,192,240, 15, 51, 13, 21, 81,173,170,215,134,141, 86, -175, 94,189,168,152,152, 24,202,211,211, 83, 92, 80, 80,224, 15, 96,195,130, 5, 11,130, 8, 33,102,145, 72,196, 22,137, 68,230, -223,126,251, 77,253,243,207, 63, 95, 54, 26,141,147,244,122,125,145,151,151, 23,149,156,156, 92,231,108,129,174,221,123, 80,247, -163,238, 80, 30,158,173,196, 5,249, 74,127, 10,100, 67,230, 71,110, 65, 92, 85,145, 25,110,142,108,200,156,204,107, 15, 23,169, - 63,250,229,238,101,163,209, 48, 9, 64,145,187,155, 43,149,145,149,205,164,123, 96, 96, 96, 96, 96, 96, 96,120,150,141, 86, 77, -234,207,163,117,229,202, 21, 2,128,100,102,102,154,141, 70,163,188, 95,191,126,182,108, 54, 27,246,246,246,108,181, 90, 77,151, -151,151,179, 29, 28, 28,178,184, 92,238,143,229,229,229, 69,163, 70,141,162,142, 28, 57, 82,175, 33,186,117,253, 26, 1, 64, 50, - 50,210,205,180, 81, 43,159,217,187,133, 45,199,100, 0, 29,216,139,173, 42,163,104,169, 38,153,237,235, 42,200,226,241,184, 63, - 26,141,134,162,209, 97,195,168, 95, 78,132, 51, 38,139,129,129,129,129,129,129,225, 89,166,206, 49, 90, 13,166,119, 80,171,213, -182, 60, 30, 47, 36, 40, 40,168, 69,121,121, 57,189,108,217,178,244, 77,155, 54,237, 73, 72, 72, 48,218,216,216,180, 18,137, 68, -239,140, 31, 63,222,225,200,145, 35,164, 79,159, 62, 53, 35,100,181, 62,221, 91,163, 81,217, 10,120,220,144,119,186,201, 90,164, - 27,108,105,191,119,110,166,247, 91,114,117,207, 47, 49, 28, 99,123, 59, 77, 43, 59, 62,245,206,248,241, 47, 57,252,114, 34,156, -244,232,209,221, 34,205, 38,194,104, 50,154,140, 38,163,201,104, 50,154,140,230, 63,171,249,188, 51, 13, 53, 82, 59, 0, 22,100, -134, 23, 8, 4,125, 61, 60, 60,122,199,196,196,152,175, 93,187, 86,194, 98,177,182, 13, 29, 58,244,208,225,195,135,187,217,217, -217, 57, 53,111,222,220,249,252,249,243,193, 0, 14,252,254,251,239, 22, 69,159, 68, 2, 94,223, 78,238,138,222, 59,239, 18,243, -183, 17, 15, 75,204,108,193,182, 1, 99,199, 30,122,123,207,222,110,110, 14, 50,167, 78,174,114,231,147, 39, 79, 7, 3, 56,112, -237,218,117, 38,162,197,192,192,192,192,192,192,240,172,155,172,157,181,253, 95,111, 68,139,207,231, 55, 99,179,217,254, 25, 25, - 25,169, 39, 79,158,140,233,218,181,235,144,212,212,212, 85,132,144, 20,177, 88, 60, 45, 61, 61,253, 97,122,122,186, 94,163,209, -204,176,162, 50,205,192,226,249, 71,100,105, 82,191, 56,127, 63,166,125,143,193, 67,114,114,178, 86,153, 9, 73,225,139,229,211, -226,211,242, 30, 94,207,213,233,181, 90,171, 52, 25, 24, 24, 24, 24, 24, 24, 24,158, 57, 26,138,104, 25,204,102,243, 26,157, 78, -103,251,203, 47,191,100,134,134,134,234, 0,224,171,175,190,162,167, 78,157,122, 57, 49, 49,113,224,131, 7, 15,134,184,184,184, - 92, 0, 64, 37, 37, 37, 89, 18,125, 50,208,180,121,141, 94,175,179, 61,255, 91,100,102,223,222,237,117, 0,176,253,203,205,244, -203,211,230, 94, 78,140,141, 25, 24, 31,125,123,136,139,139,203, 5,179,137, 67,101,231,164, 48, 17, 45, 6, 6, 6, 6, 6, 6, -134,103,153,170, 25,135,213,255,111,216,104,233,245,250, 60,189, 94, 15, 0, 69,161,161,161, 79,172,251,230,155,111, 8,128,114, - 0, 7, 11, 10, 10,172,169, 76,158, 70,163, 1,128,162,190,189,219, 63,177, 98,255,206, 77,143, 53, 85,101,165,204,105, 99, 96, - 96, 96, 96, 96, 96,120,158,204,214,159, 96, 49,199,133,129,129,129,129,129,129,129,161, 73, 76,171,235,127, 10,117,207, 28, 56, -103,197, 7, 52,102,246,193, 57, 70,147,209,100, 52, 25, 77, 70,147,209,100, 52,255,115,154, 13,105,159,195,243, 71,157,131,225, -255,106,152,169,175,140, 38,163,201,104, 50,154,140, 38,163,201,104,254,219,113,197,147,233, 29, 92,171, 86,112,152, 99,195,192, -240,124, 67, 14,130,141, 34, 31, 47, 16,226, 6, 54, 63, 27,217,247, 18,169, 79, 65, 55, 89, 83,233,239, 9,145,209, 25, 38, 97, - 30,148, 81, 73, 77,213,100, 96, 96,248,247,225,210,115,230,104,138,197,222, 70, 17, 26, 26,101,172,128,167, 73, 17,231,102,167, -254, 23,189, 69, 54,234,136, 96, 49, 70,139,129,225,121, 39,207,215, 27, 28,172, 4, 11,174, 32,134, 71,112,244, 95, 9,220,143, -110,178, 38,143, 94, 6, 51,203, 29,196, 16, 15, 39,159, 85, 64,220,125,230, 96,255,251,152, 51,251, 45,242, 32,250, 6,210,210, -178,208,170,181, 43,188,125,123, 98,211,230,173, 20,115,100, 24, 44,251, 85, 70,237, 12, 25, 62,193, 78, 36,150, 1, 0,104,147, - 17,223,204,235,244,171,201,100,218, 13,224, 8, 0,205,127,253, 16,253,237,131,225,185, 92,174, 18, 0, 45, 20, 10, 15,163, 90, -104,141,129,225, 47,192,181,242, 58,163, 43,175, 59,107,144,114, 56,156, 37, 98,177,248, 55,129, 64,144, 43, 16, 8,114, 37, 18, -201,111, 28, 14,103, 9, 0,233, 51,211,198,253,208, 78, 12,150,121,136,222, 72, 55, 59,125,175,216, 73,173, 51,123,131,101, 26, - 74,190,105, 43,109,146, 38,135, 10,213, 26,104,143, 31,111,170,157,203,245, 38, 63, 16, 52, 73,179, 26, 54, 60, 30,239, 52, 0, - 7,230,242,124, 54, 72, 77,138,198,201, 19,235,176,108,233,100,124,183,115, 6,226, 30, 92,111,146,158, 31,208,165, 11,135,179, -192, 23, 24,128,122,158,167,203,240, 47,129, 34,211,206, 29,255, 49,239,248,190, 47,243,126, 90, 55,131, 28, 93, 25,134,205,155, - 55,135, 76,158, 60,249, 71, 15, 15,143, 60, 0, 47, 50, 70,235,111,198,104, 52, 58,229,231,231, 83,187,119,239, 30,161, 80, 40, - 30,113, 56,156, 15, 1,240,254, 43, 7, 92, 42,149, 94,149,203,229, 74,133, 66,161,148,203,229,183, 27, 42,255,151,226,237,232, -232,152,106,103,103, 23, 95,189,208,177,195,232,158,109,122, 77,250,196,222,127,100,191, 38,234,243, 56, 28,206,135, 10,133,226, -209,238,221,187, 71,100,102,102, 82, 70,163,209,201,138,237,251,218,218,218, 62,184,113,227,198,226,252,252,252,126,233,215,191, -113,204,185,177,195, 49,245,127,235,250, 71,156,220,178,216,198, 70,113, 31, 64,223,103,226, 72,106,105,103,176,216,193, 49,217, -106,113,118,169,209, 57, 50, 69, 45, 3,216,253,161,111,194,143,152, 18,218, 25, 32, 3,238,102,104, 36, 87, 11, 29,157,127, 79, -212,201,193, 98, 5, 67, 75,185, 52,185,193, 97,177,222,162,105,122, 16,143,199,123,135,249,134,122, 54, 16, 8,120, 0, 33,144, - 74,132, 0, 8, 88, 77,180, 70,124, 22,171,215,213, 17, 35,150, 45,236,208, 97,142, 47, 48,188, 14,179, 69, 1,120,219,215,215, -247, 20,128,151,159,226,238,124,225,227,227,147, 9, 96,238,211,106,151, 58,119,238,220, 51, 56, 56,248,147, 78,157, 58,245,123, - 90,154,255, 38,114,174,126,245, 75,246,229, 45, 78, 89, 87,182, 58, 21, 39, 93,122,219,213,217,150, 78, 74, 74,194,176, 97,195, -240,229,151, 95,138, 3, 2, 2,246, 0,112,251, 15,220, 74,129, 85, 63,240, 81, 99,140,150,197, 70,107,156, 23,122,189,210, 18, - 23, 95,242, 66,217,248,150, 80, 77,108,137,203, 99,189, 48,160, 49,181,177,183,183, 71,223,190,125,217,153,153,153,162,249,243, -231,127, 34, 20, 10,147, 1, 12,110,140,150, 72, 36,138, 16,139,197,233, 28, 14,231,137,186,136,197,226, 8,137, 68,146,206,225, -112, 6, 86, 47,151,201,100, 87,229,114,185, 82, 38,147,221,174,195, 8, 69,200,229,114,165, 84, 42,141,168, 94,206,225,112, 6, - 74,165,210, 12,153, 76, 86,179,124,128, 76, 38, 75,175, 89, 94, 23, 92, 46,215, 61, 61, 61,221, 41, 35, 35,195,137,207,231, 59, - 87, 47, 79, 75, 75,115, 74, 79, 79,127,162,220, 26, 56, 28,206, 0,137, 68,146, 46, 22,139, 35,106, 43,175,185, 79,117, 81,237, -216, 13,176,164,220,218,134, 39, 52, 52,244,114,118,118,182,135,141,141,141, 77,245, 21,118, 10,155,193, 63,124,179,117,222,200, -161,161,111, 57,250,141,106,223, 72,253,193, 66,161, 48,121,254,252,249,159,100,102,102,138,122,244,232,193,102,177,172,250, 61, - 17, 50,114,228,200,163, 74,165,178, 89,199,142, 29,217, 38,147, 9, 49,199,150, 64, 28,245, 14,132,201,219,209, 92,148,199,121, -244,235, 42,247,208,254, 93,142,226, 31, 30, 12, 74, 14,250,241, 64,209,125,105, 66, 28, 31,100,106, 29,135,141,120,145,115, 39, - 93,227,104, 52,155,237, 0,118,127,242,157,167,160, 81,154, 28, 99, 31,154, 16,231,243, 41, 92,199,224,151,230,176, 47,164,112, - 28,141,102,179, 61, 88,232,215, 24,205,234,151, 63,155,205,158,183,110,221, 58, 22,128,217, 0,248,255, 37, 67, 19,228,134,102, - 3, 90,179,111, 6,186,162,215, 83,148, 13,168,188,223,189,155, 42,180,235,187, 83,152, 58,125, 39,218,250,118,111,146,142,158, -166,227,246, 39, 37,157,153,216,186,117,216,194, 14, 29,166,212, 98,182, 40, 0, 11, 87,173, 90, 53, 41, 38, 38,198,177,101,203, -150,211,159,210,143,254,141,171, 86,173,122, 63, 38, 38,198,205,203,203,235, 51, 43, 53,235,108,151,108,109,109, 7,239,218,181, -107,222,176, 97,195,222,234,220,185,115,251,167,161,249, 47,230,203,187,119,239,122,172, 91,183,238,131,169, 83,167,150, 2,192, -192,129, 3,121, 0,122, 52,185,189, 35,132, 79, 8, 9, 38,132, 12, 35,132, 12, 36,132, 4, 85,254,221,181,114, 25, 70, 8, 9, -169,241,218,181,114,219,170,245,221,234,208, 24, 86,115,187,106,219,212,252,255,137,191,107, 49, 90,195, 80, 49, 86,107,216, 19, - 59,112,226,196, 9, 82,253,181, 38,227,189,240,233,156,158,205,212, 15,142,239, 37,170,244, 36, 82, 20,123,135,220,217,185,130, -204,233,234,168,126,181, 37,190,176,254,120, 17,114,229,202, 21, 18, 19, 19, 67, 84, 42, 21,121,248,240, 33,233,214,173,155, 70, - 44, 22,159, 7,224,101,141,152, 76, 38, 83,158, 63,127,158,132,134,134,150, 72,165,210,181, 85, 55,151, 92, 46, 87, 94,185,114, -133,132,134,134,150,200,100,178,141, 0,216, 0, 48,118,236,216, 92, 66, 8,113,116,116,204,170, 77,111,228,200,145, 69,132, 16, -162, 80, 40,170,186,154,216, 50,153,108,227,172, 89,179, 84,183,110,221, 34,182,182,182, 85,229, 44,185, 92,190,118,246,236,217, -170,200,200,200,234,229,245, 98,103,103,151,110, 54,155,201,241,227,199,137,147,147, 83, 86,181,155, 57,221,108, 54,147,163, 71, -143,214, 89,183,250, 2, 5, 82,169,116,205,196,137, 19,203, 82, 82, 82,136,189,189,189,178, 90,249,218,201,147, 39,151,165,165, -165, 17, 7, 7, 7,139,234,104,111,111,175,188,122,245, 42, 25, 51,102, 76,105,245, 99,106,111,111,175,188,118,237, 90, 85,249, - 26, 75, 26, 50, 55, 55,183,233, 78, 78, 78, 89, 78, 78, 78, 89, 54, 54, 54,203, 93, 93, 93,115,242,242,242, 8, 33,132,180,106, -213, 42,183,122, 36,203, 41, 96,196,187,219, 15, 94,187,113, 41,186, 32,175,195,160,183,214, 40, 58,140, 84, 88,113, 12,188,196, - 98,241,249,126,253,250,105,210,211,211, 73,121,121, 57,137,138,138, 34, 87,174, 92, 33, 9, 9, 9, 4,128, 37, 79, 24,144, 73, -165,210, 76,157, 78, 71,235,116, 58, 58, 47, 47,207,156,155,155,107,142, 93,235, 74,200,183,220,199, 75,241,209,225, 36,231,210, - 74, 90, 46, 21,103, 0,144,253, 99, 70,107,171,191, 59,217,225,179,255,254, 18,143,216, 75,171, 94, 48,146,148, 11,100,239, 20, - 71,227,197,119,155, 61, 34,219,124,127, 38, 59,252,154, 55, 74,115,155,223,222,168,143, 61,226,182,124,246,182, 49, 53, 53,149, - 44,152,252,130,233,236,156,102,137,100,187,239,193,198,104, 86,227,149,209,163, 71,171,210,210,210,136,191,191,127, 57,155,205, -158,250, 95, 50, 89, 33,222,252,204,168, 31, 23,208,195, 3,196, 5, 79,201,108, 5, 56, 57, 57,229,127,255,253,247, 68, 38,147, -229, 54,214,108,141, 27,213,159,104, 74,206,147, 81, 97, 65,245,222, 35, 47,189,244, 18, 9, 14, 14, 38,115,230,204,105,232, 94, -162,124,129, 17,187, 59,116, 56, 74,143, 27,103,222,221,161,195, 81, 95, 96, 68,165,193,162, 0,124,176,122,245,234, 72,163,209, - 24,249,221,119,223, 69,142, 24, 49, 34, 18,192,130, 38, 30,139, 77, 95,124,241, 5, 49, 26,141,228,187,239,190, 35, 35, 70,140, - 32, 0, 54, 55,165, 93,170,138,100, 5, 6, 6,190,123,228,200,145, 27,113,113,113,121, 97, 97, 97,107, 58,116,232,160,104,172, -230,179,136, 84, 42,109,211,190,125,251, 61,254,254,254,105, 29, 59,118,212,251,249,249,105,189,189,189, 83, 2, 2, 2,190, 23, - 8, 4, 94,141,148,237,222,171, 87, 47,243,197,139, 23,201,232,209,163, 73, 53, 19, 82, 47,245,121, 17, 66, 72,208, 7, 31,124, -240, 33, 0,242,193, 7, 31,124, 72, 8, 25, 86,233, 39,134, 85,255,187,230,107,149,121,170,250,191, 54,141,170,165, 54,205,218, - 62,163,198,231,160,142, 72,214,180, 63,237,220,137, 19, 39,250,157, 56,113,226, 98,205,157,123,177, 37,122,206,233,217, 76,163, -201,203, 38,209, 43,222, 33,191, 5,187,147, 43,253, 93, 72,252,188,209, 36,251,199,141,100,102, 39, 91,245,184,150, 8,182,214, -104, 69, 70, 70,146,200,200, 72,114,251,246,109,146,156,156, 76, 74, 74, 74,200, 79, 63,253,100,182,183,183,215, 8, 4,130, 85, - 0, 68,150,136,201,229,114, 37, 33,132,232,116, 58,178,124,249,114,109,101,164,202, 89,161, 80, 40, 9, 33,164,184,184,152,172, - 90,181, 74,171, 80, 40,162, 0,184, 57, 56, 56,164, 39, 37, 37, 17,103,103,231, 90,205,140,173,173,173, 50, 46, 46,174,202, 56, - 53,179,181,181,141, 62,118,236,152,129, 16, 66, 50, 50, 50,136,157,157,157, 18,128,179,189,189,253,157, 19, 39, 78, 24, 8, 33, - 36, 43, 43,171,170,220, 34,163,165,209,104,200,217,179,103,159,168, 67, 85,249,169, 83,167,158, 48, 96, 22,224,172, 80, 40, 34, -127,250,233, 39,189,217,108, 38,209,209,209, 85, 38,209,217,198,198,230,246,193,131, 7,245,102,179,153,196,198,198, 90,108, 6, - 91,180,104,145, 75, 8, 33, 38,147,137,108,223,190, 93, 87,117, 76,171,202,245,122, 61,249,234,171,175,116,114,185, 60, 18, 64, -189,209, 55, 7, 7,135, 44,189, 94, 79,138,139,139, 73,183,110,221, 84, 87,174, 92, 33,165,165,165,132, 16, 66, 90,180,104,145, - 11, 0, 62,253,166,126,126,227,161,170,244,245,247,183, 30,240, 10,122,117,197,153,155,153, 25,187,142, 68, 68, 58, 4,140,124, -193,146,160,166, 64, 32, 88,229,234,234,170,253,253,247,223,205, 6,131,129,164,165,165,145,219,183,111, 63,190,198,238,221,187, -103,145,209,226,112, 56, 75,110,220,184, 97, 48,155,205,116,126,126,190, 57, 55, 55,215,156,155,155,107,170,105,180,200,183, 92, -146,127,234, 77, 18,190,115,174,158,199,227, 45,249,103,162, 89, 96,147, 29, 62, 35,201, 14,159,200,239, 39, 58,228,151,221,222, - 71,200,175,115, 73,226,231, 45,201,146, 23,100,101,244, 14,159, 72,178,195,119, 28,249,180, 31,199, 42,205,157,126,195,201, 14, -159,200, 47, 94,244, 44,184, 19,121,139, 92,188,120,145,124,181,113, 53,153, 19,210,172,156,222,225, 19, 73,182,249,141,177, 70, -179, 58, 2,129,224,225,229,203,151,201,165, 75,151,200,103,159,125, 70,196, 98,113,218,211,136,234,145,109,222,158,228,107,239, -126,228,155,182,174,228,127,253,158,185, 9, 62, 65,110,104, 54,200,155,159,145,127,231, 8, 33,133, 9, 36,103,173, 63,121,193, -135,219, 84,179, 21,224,228,228,148,151,146,146, 66,114,114,114,200,250,245,235,137, 92, 46,111,148,217, 26, 55,170, 63,209, 20, -159,171,215,104,141, 28, 57,146,108,216,176,129, 24,141, 70,210,189,123,119, 75,126,180,252,201,108,249, 0, 35, 1,124,184,102, -205,154,199, 38,107,235,214,173,145,247,238,221,139,244,240,240, 56,217,132, 99,177,121,205,154, 53,143, 77,214,214,173, 91,201, -189,123,247,136,167,167,103,122, 83,218,165, 65,131, 6,125,158,156,156, 92,186,104,209,162, 3,125,251,246, 93,113,231,206,157, -140,240,240,240,200,192,192,192, 23, 26,171,249, 20,162, 58,156,202,200, 14,159, 16,194, 37,132, 84,153, 87, 14, 0,110, 85, 64, -193, 18, 38, 78,156, 40,238,217,179,103,228,132, 9, 19,212,223,127,255, 61, 73, 73, 73, 33, 81, 81, 81,100,205,154, 53,228,147, - 79, 62, 33,223,126,251, 45, 25, 51,102, 76,121,183,110,221,110,140, 27, 55, 78,104, 69, 53,253,189,188,188, 74,142, 30, 61, 74, -246,238,221, 75,120, 60, 94,184,165, 27,214,231, 69,234, 50, 83,117, 25,172,154,235,234, 49, 98,245, 26, 54, 11, 62,239,207,166, -170,102, 36,164,218,223,255, 11, 11, 11,235,247,167, 47, 31,130,165,211,230,127, 46, 76,254,126, 61,148, 63,125, 9,118,177, 18, -220,178, 2,232, 46,135,195,120,249, 24, 38,245,232, 33, 18, 81,212, 50,107, 47, 24, 62,159, 15, 62,159, 15, 30,143, 7,181, 90, -141,172,172, 44,244,238,221,155,117,251,246,109,225,244,233,211,231,138, 68,162, 52, 0,163, 26,188,155,169,138,136,244,213,171, - 87,241,230,155,111, 10,246,236,217,211,209,209,209,241,174,217,108,230, 3, 64,108,108, 44,198,143, 31, 47,216,183,111, 95, 59, - 55, 55,183,219, 6,131, 65, 44, 16, 8,192,102,179,235,212,227,243,249, 48, 26,141,130,182,109,219, 70,221,189,123, 55, 32, 44, - 44,140,155,154,154,138,164,164, 36, 24,141, 70,190,183,183,247,189,219,183,111,119, 28, 54,108, 24, 55, 61, 61, 29,169,169,169, -143,235, 97, 73,125,245,122, 61, 4, 2, 1,170,119,105, 81, 20, 5,157, 78, 7, 62,159,111,177, 22,135,195, 25,224,235,235,123, -239,238,221,187,129, 35, 71,142,228,221,186,117, 11, 25, 25, 25, 48,155,205,124, 63, 63,191,123,119,239,222,237, 52, 98,196, 8, - 94, 84, 84, 20,148, 74, 37, 44,237, 66,171,122,223,221,187,119, 49, 97,194, 4,254,233,211,167, 59,185,186,186, 70,153, 76, 38, - 62, 0,220,187,119, 15,227,199,143,231,159, 57,115, 38,176,121,243,230, 81, 13,116, 37,178, 1,192,104, 52, 98,250,244,233, 18, -185, 92,142,244,244,116,208, 52, 13,179,217, 12, 0, 40, 40, 42,184,119,247, 94,116,236,164, 87, 94,236,167, 49,232,116,215,110, - 70, 60,104,213,194,211,157,162, 72,139, 6,170, 58, 74, 34,145,164,173, 93,187,246,221,148,148, 20,129,175,175, 47, 43, 49, 49, - 17,101,101,101,224,241,120,143,175, 49, 75,247,155,207,231,247,247,247,247,231,104,181, 90,208, 52, 13, 0,132,197,170,125,196, -138,176,248, 50,252,156, 77, 92,145, 72,212,255, 31,249,246, 46,245,183, 7,141, 65,169,121,122,129,192,198, 93, 38,117,245, 6, -210, 46,161,165,163, 0,108, 22, 91,120, 43, 73, 45, 1,200, 32,120,228,219, 91,167, 73, 15, 74,202,213, 11,140,118,237,164,110, -238, 30, 40, 40, 40, 64,243, 86,190,208,242, 29,249, 87, 19,202,165,160,172,212,252,131, 62,109,219,182,117,105,211,166, 13,242, -243,243, 17, 24, 24, 8, 91, 91, 91, 91, 0,131, 26,253,165,243,157,167, 0,165,232, 5,176,214,194, 76,125, 6, 35,103, 37, 18, -242, 2,201,142, 64,238,179,100,178,228, 82,254,245,125,251,127,106,102,239,225, 7,132,191, 14,103, 27, 1,190,121, 43,208,206, - 81, 33, 56,218, 72,179, 21,224,236,236,124,225,198,141, 27, 14, 66,161, 16,183,111,223,134,191,191, 63,214,175, 95,239,104,107, -107,123,169,113,145, 45, 2, 66,213,109,178,250,246,237,139,217,179,103, 99,207,158, 61,176,179,179,195,132, 9, 19, 26, 50, 91, - 36, 22, 56,254, 69, 84,212,119,123, 30, 61, 58, 49,177,117,235,176, 9,222,222,203,103,188,252,242,212,183,223,126, 27,171, 87, -175,198,209,163, 71,209,171, 87, 47, 76,155, 54,205,152,150,150,182,187,177, 93, 85,107,215,174,157, 51,119,238,220,154,154,134, -212,212,212, 47,154,212, 46, 21, 20,220,139,138,138,138,125,229,149, 87,250,105,181, 90,221,205,155, 55, 31,120,121,121,185, 3, -104,209, 88,205, 38, 24, 44,138, 16, 34, 4, 32,174, 92, 36, 0,196,251,246,237, 83,140, 28, 57, 82, 94, 89, 38,170, 92, 26,236, -222,247,247,247,119,127,248,240, 97,230,188,121,243, 2,247,236,217, 35, 18,139,197, 40, 46, 46,198,215, 95,127,141, 15, 63,252, - 16, 20, 69,129, 16,130,111,191,253, 86, 60,101,202,148,160, 71,143, 30,101,122,122,122, 90, 50,164, 69, 32,149, 74, 15, 46, 95, -190, 92, 78,211, 52, 22, 46, 92,152,111, 48, 24,102, 87,174, 91,100, 99, 99,115, 29, 21,134,187, 62,106,245, 34,213,190, 43, 79, -212, 56, 54, 97, 53,203,106,174, 35,132,132,213,167, 97,229,185,168,237,243,194,235, 51, 91,213,191,129,250,215,234, 34,129, 14, - 46, 94, 62, 40,249,245, 32, 68, 28, 10, 34,118,229,194,161,192, 74,188,135,230, 66, 46,140,132, 4, 52,214,104, 85, 45, 92, 46, - 23,106,181, 26,102,179, 25, 31,126,248,161,224,236,217,179,246, 44, 22,235,231,134,116,170, 27,166,248,248,120,248,249,249, 81, -199,143, 31,119,158, 61,123,182,168,234,115, 74, 74, 74,208,166, 77, 27,234,212,169, 83, 78, 31,127,252,177,180, 62, 51, 67, 81, - 20,120, 60, 30,230,206,157, 43,186,121,243,166,157,155,155, 27, 18, 19, 19, 81, 88, 88, 8,169, 84,138,185,115,231,138,110,220, -184,225,232,230,230,134,148,148, 20,148,148,148, 64, 42,149, 90,109,180,120, 60,222, 19,219, 80, 20, 5,131,193, 96,149, 49, 80, - 40, 20,123, 35, 35, 35, 29, 21, 10, 5,162,162,162, 96, 50,153,160, 80, 40, 48,103,206, 28, 81,100,100,164,163,141,141, 13, 98, - 99, 99, 65, 8,129, 92, 46,183,170,142, 0, 64,211, 52, 98, 99, 99,209,162, 69, 11, 92,186,116,201,105,198,140, 25,194,170,242, -132,132, 4,184,187,187,227,210,165, 75, 78, 18,137,100,111, 93, 90, 52, 77, 35, 59, 59, 27, 49, 49, 49, 72, 76, 76, 68, 94, 94, - 30,242,243,243, 81, 86, 86, 6,147,201, 4, 0, 16,151,149,134,239, 59,112,252,174, 72, 36, 18,251,123,183,245,184, 23,125, 63, - 87, 36, 18,137, 61, 61, 60,188,129, 79, 89,245, 24,194,159, 83, 83, 83,237,167, 76,153,194,203,201,201, 65, 81, 81, 17, 56, 28, -206,159,174, 45, 62,223,178,161, 64, 38,147,201, 79, 40, 20, 82, 6,131,225,113, 4,140,207,231,227,221,189,106,248, 47,193, 19, -203,203, 27,115, 65,204, 70,232,245,122,191,191, 61,154, 5, 80,160,244,109, 65, 81,129,215, 19,203,237,250,132,189,194, 67,210, -105,128, 54, 2, 44, 14,250,119,112,231, 28,189, 87,238, 12,130, 14,208,193,151,144,134,103,126, 17,128, 2, 12,109, 0,170,203, -217,135, 38,251, 94,163,223,226,101,102,102,130,199,227, 65, 32, 16, 32,112,192, 88,206,190,187, 70, 23, 80,232, 8, 3,124, 44, -209,124, 34,236, 40, 18, 45,254,228,147, 79, 36,213, 53,167, 78,157, 42, 81, 40, 20,159, 52,218,100,149,139,123,192, 68,230,198, -100,170, 91, 44, 15,207,241,123,148,171,241, 1, 33,243, 0, 99,167,167, 96,182,250, 11, 4,130, 36, 0,189,155,100,178,100,252, -107,251,247,255,212,204,174,121,133,201,130, 73, 11,112, 69,112,113,180,193, 55,239, 6,219, 57,218,136,172, 53, 91, 1,206,206, -206,231,175, 95,191,238, 32, 20, 10, 17, 25, 25, 9, 30,143, 7,161, 80,136,246,237,219, 99,199,142, 29,142,118,118,118, 86,155, - 45, 2, 82,107,204,119,212,168, 81,164,111,223,190,152, 53,107, 22,118,239,222, 13,189, 94,143,229,203,151, 35, 53, 53,213, 34, -217, 88,224,248,170,168,168,239, 87,198,196,196,127, 16, 16,224, 59, 74, 34,177,155, 53, 97,130,226,227,143, 63, 62,113,236,216, -177,239,134, 13, 27,150,127,243,230,205, 13, 0, 14, 90,121,120, 41, 0, 91,215,173, 91, 55,171,202,184,125,252,241,199,223, 30, - 59,118,108,229,176, 97,195,178,111,222,188, 57, 15,192,214,166,180, 75, 52, 77,135,255,252,243,207,119, 69, 34,145,216,199,199, -199, 35, 58, 58, 58, 87, 36, 18,137, 61, 60, 60,188,251,245,235,199,106,140,102, 99,112,114,114, 26,120,253,250,117,127, 84, 76, - 26, 19, 84, 25,173,232,232,104,155,210,210, 82, 27,169, 84,106,227,234,234, 42,171, 50, 91,163, 71,143,182,225,112, 56,245, 94, -183, 42,149,234,216,162, 69,139, 20,163, 71,143,174,250, 31,151, 47, 95,198,238,221,187, 33,145, 72,158,120,239,136, 17, 35,240, -230,155,111,218,234,245,250,159, 45,168,238,228,233,211,167,251, 56, 59, 59, 99,241,226,197,186,204,204,204,129, 0, 82, 1, 40, - 66, 66, 66, 62,143,142,142,238, 22, 20, 20,116, 0, 64,231,250,238,189,218,188, 72,117,163, 99, 73, 89, 99,223,111,169,217,170, - 81, 84,103, 14,173, 39,140, 86, 88, 88,216, 69,212, 49,147,202, 80,168,132, 0,102,136,216, 20,196,236,106,102, 11, 52, 56, 37, -185,160, 26, 49, 75,165,182, 47, 67, 62,159, 15, 54,155, 13,189, 94, 15, 75, 31, 84, 93,101, 10,228,114, 57,164, 82, 41, 52, 26, - 13, 76, 38, 19,132, 66, 97,149, 25,129, 92, 46, 7,151,203, 5,151,203,133, 80, 40,252, 83, 52,169,102, 52,135,199,227, 65, 34, -145, 32, 59, 59, 27,169,169,169,160,105, 26, 82,169, 20, 18,137, 4,124, 62, 31, 89, 89, 89,200,202,202, 2, 33, 4, 18,137, 4, - 18,137, 4,214, 12,184, 54,155,205,181,126,249, 27,141, 70,171, 34, 90, 38,147, 9, 15, 30, 60, 64, 90, 90, 26,132, 66,225,227, -125, 21, 8, 4, 72, 72, 72, 64, 78, 78, 14,196, 98, 49,228,114, 57, 20, 10,133,197,186, 85,251, 34,147,201, 32, 18,137, 80, 84, - 84, 4,181, 90,253,248,152,202,229,114, 72, 36, 18,148,148,148, 32, 55, 55,183,222,125, 55,155,205,200,202,202, 66, 94, 94, 30, -210,211,211,145,159,159,255,184, 1,170,140, 26, 53, 45,176, 83, 90,138,130,130,130,199,145,200,186, 22, 75,160,105, 26,101,101, -101,184,126,253, 58, 69,211, 52,138,139,139,233,188,156, 28,243,204, 44, 62,142,126,186,141,252,116,250,142,118,223,201, 72,205, -225,243, 49,154,173,135,239,105,132,221, 62, 51,225,159,224,171, 0, 5,140,220,208,124,149, 81,144,103,224, 41,156, 3, 66,128, -164, 83, 0,139, 3, 8,109,209,189, 93, 75,164, 22,153, 37,113, 74,189, 16, 20, 6, 99,171,183,173, 69,154,102,238,160,188, 50, -163, 32,197,224, 40,247,235,208, 25, 74,165, 18, 2,129, 0, 2,129, 0, 93,122,133, 32,169,192, 44,190,159,169, 17,131, 32,212, - 34,205, 63,104, 37,149, 74,123,244,238,221,155,170,174, 57,116,232, 80, 80, 20,213, 30,128,175, 85,141,220,230, 86,124, 24,196, -221,193, 33,115,239,103,171,221,142, 70,107,189,135,143, 26,107,183,233, 92,174,223,131, 28,157, 23,136,113, 62,136,161,115, 19, -204, 86, 63,153, 76,118, 98,203,150, 45, 94, 66,161,240, 20,128, 62,141, 17,145,138,216,219, 23,207,122,165,153,109,149,201, 50, -170, 1,142, 8,224,138, 0,142, 8, 46, 78, 14, 88,246,230, 32, 59,177,144,123,216, 10,195,186,111,235,214,173,142, 53, 77, 86, -213, 18, 24, 24,136, 37, 75,150, 56,218,217,217,237,181, 68,111,237,154,213,164,184,164, 4, 32, 64,105,169, 10,107,215,172, 46, -170, 90, 55,122,244,104,210,167, 79, 31,204,154, 53, 11, 43, 87,174,196,201,147, 39,209,189,123,119, 76,155, 54, 13, 65, 65, 65, - 13, 73,135, 42, 20,138, 61, 33, 33, 33,215,179,100,178, 55,179, 59,119,230,159, 87, 40, 74, 6,150,148, 40, 60,163,163, 13, 62, -192, 61, 0, 95,101,100,100,188, 96,133,201,122, 89, 46,151, 71, 14, 28, 56,208, 32,147,201,210,214,175, 95, 63,115,246,236,217, - 88,189,122, 53, 22, 45, 90,244, 53,128, 55, 0,124,148,145,145,225, 86,159,201,250,171,218,165,191,170,173, 51,155,205,233, 7, - 15, 30, 12, 50, 24, 12,238,149,221,131,130,226,226, 98,121, 97, 97,161,204, 96, 48, 72,104,154,150,216,216,216, 72, 1,136, 39, - 77,154,196,185,127,255,190,159,201,100,202,172, 79, 51, 39, 39,231,213,133, 11, 23,230,231,231,231, 3, 0,218,183,111,143,226, -226, 98, 44, 88,176, 0,239,188, 83, 49, 33,184, 83,167, 78, 32,132, 64,169, 84, 98,237,218,181,202,156,156,156,215, 44,168,110, -235,182,109,219, 34, 58, 58, 26, 15, 30, 60, 56, 7,128, 70,197, 56,214,146, 59,119,238,220,205,203,203,195,222,189,123,121,205, -154, 53, 59,134, 58, 82,188,212,231, 69, 26, 3, 69, 81,225,141,217,174, 42,114, 85, 91, 68,172, 14,234,143,104,133,133,133, 81, -213, 95,159,136, 24, 81,136, 74,139,184, 4,187,128,206, 79, 68,179,196,108, 10, 34,185, 2, 73,233,169,224,129,138,121, 90, 70, -171,168,168, 8, 51,103,206,212,188,250,234,171, 5, 52, 77,143,181,212, 20, 40, 20, 10, 40, 20, 10,220,191,127,159,140, 25, 51, - 70,185,126,253,122, 77,117,163, 21, 31, 31, 79, 66, 67, 67,115, 63,249,228, 19, 85,125, 70,171, 42,162,181,106,213, 42, 77,255, -254,253,243, 98, 98, 98, 72,149,153,146, 74,165, 88,187,118,173, 38, 56, 56, 88,121,235,214, 45, 82, 85,102, 77, 68,139,197, 98, - 61, 54, 90,213,183, 97,177, 88,160,105,218, 42,163, 85, 94, 94,254,234,176, 97,195,148,177,177,177,164,106, 63, 21, 10, 5,214, -175, 95,175, 25, 52,104,144, 50, 38, 38,134, 84,149,201,229,114,139,205, 96,213,231,203,100, 50,200,229,114,220,191,127,159,132, -134,134, 42, 55,111,222,172,173, 94,254,224,193, 3, 50, 98,196, 8,101, 89, 89,217,171,245,153,151,170,238, 60,147,201, 4,173, - 86,139,252,252,124,164,167,167, 63, 14,167,107, 36,242, 23, 94,121,105,120, 71,141, 70,163,190, 31,255, 48,173,125, 59,127, 39, -141, 70,163, 78, 77, 75,139, 7, 62,165,235,209, 30, 27, 16, 16, 80, 48,115,230, 76, 77, 81, 81, 81,147,141, 22,159,207,143,229, -112, 56,164, 79,159, 62, 68,175,215,147,244,244,116, 99,126, 81,145,201,119,197, 10, 18,243,238,187,148, 40, 34, 66, 32,149, 74, -169, 74, 77, 86, 98, 98, 34, 45, 18,137, 98,255,118,163,197,162, 93, 64,145,222,191, 63, 84,217, 12, 26, 62,158, 79,229,220, 4, - 12, 42, 64, 96, 11, 8,108,193,145,216, 99, 72,159, 78,236,239,175,151,186,128,208, 61,193, 19,184, 55,168,201, 37,206, 0,221, -231,215,120,173,109,239,113,115,248,133,133,133, 96,179,217,143, 77,145, 88, 34,193,192, 81,147, 88,223,222,212,185, 0,164, 23, - 40,182,187, 21,247,250,251,139, 23, 47,230, 21, 21, 21,129,197, 98,253,161, 41, 22, 99,198,140, 25, 2,185, 92,190,200,226,198, -239,160, 31, 15, 92, 65,119,128,188, 19,151,163,117, 59,118, 79,227, 51,127,213, 55,162,128, 78, 65,152,222,223, 73,180, 42, 60, - 55,224,110,186,166, 37, 96,126, 23, 38,125,151, 70,152,173, 62, 50,153, 44, 60, 34, 34, 66, 60,116,232, 80,172, 93,187, 86, 34, - 18,137, 78, 53,166,225, 47, 87,153,103, 47,221,252,131, 50,106,195, 96,192, 80, 94, 97,176,170, 45,185, 42, 26, 75,190,185, 80, - 98, 52,146, 87, 44,213,212,104, 52,147,223,120,227,141,130,195,135, 15,255,201,100, 9,133, 66, 36, 39, 39, 99,249,242,229,133, -133,133,133, 13,126, 41,174, 95,183, 54, 50,250,238,111,248,246,235,165, 0, 8,182,172,127, 11,215,126,223,111,211,191, 95, 95, -210,162, 69, 11, 18, 20, 20,132,153, 51,103, 98,217,178,101,136,139,139,131,131,131, 3,222,122,235, 45,244,235,215, 15,235,214, -173,171,175,145, 10,157, 61,123,246,242,140,140, 12,159, 95,127,253,149,147,151,151,231,180,110,215,174,146, 67, 37, 37,133, 43, -163,163,227, 62,106,215,174,237, 7, 29, 58,188, 86, 79,234,135, 90, 77,214,172, 89,179,246,101,100,100, 4,158, 59,119,142,155, -151,151,231, 62,107,214, 44,172, 89,179, 6,139, 22, 45,218, 1, 96, 58, 44,155,240, 98,113,187,196,102,179, 95, 24, 59,118,108, - 71,141, 70,163,142,139,139, 75,107,215,174,157,147, 70,163, 81,167,165,165,197, 95,188,120,145,110,140,102, 99, 40, 40, 40,120, -180,119,239,222,248, 57,115,230, 4,102,100,100,248, 1,176, 47, 43, 43,147,148,149,149, 9,244,122,189,200,214,214,214,182, 83, -167, 78, 14,211,166, 77,147,222,185,115,199, 47, 35, 35, 67, 85, 25, 69,170, 19,131,193, 16, 87, 84, 84, 20, 54,120,240,224,226, -162,162, 34,116,232,208, 1,195,135, 15,135,139,139, 11,220,220,220, 48,114,228, 72,120,123,123,163,160,160, 0,175,188,242, 74, - 97, 94, 94,222, 96, 0,137, 22, 84,247, 81, 78, 78, 14,122,246,236,137,165, 75,151,134,189,248,226,139, 49,125,250,244, 41,109, -215,174,157,218,221,221,221,119,211,166, 77,104,214,172, 25, 14, 30, 60,232, 42, 16, 8,246,214, 98,178,234,244, 34, 0,242, 42, - 13,143,190,198,107, 94, 3,235, 44,221,182,214,191, 45,120, 95, 77,179, 85,125,249, 83,215, 97,237, 39, 4, 88,178,251,224,247, - 90,190, 71, 27, 40,124, 58, 66, 44, 20, 66,196,231, 67,100,107, 15, 29, 77, 99, 87,114,142,186,156,144, 69,214, 94, 60, 53,191, - 8, 41,138,194,151, 95,126,105,234,209,163,135,246,194,133, 11, 91, 52, 26,141, 7, 42,178,202, 90,108, 10, 54,111,222,172,158, - 59,119,238,221,220,220,220,142, 66,161, 80, 95, 85,190,101,203, 22,245,164, 73,147,162, 51, 50, 50, 2,197, 98,177,186,174,241, - 89,213,141,150, 64, 32,208,229,230,230, 6, 77,157, 58, 53,246,171,175,190, 42, 23,139,197,144, 72, 36, 16, 8, 4,250,220,220, -220,142, 51,103,206,188,187,102,205, 26,181, 72, 36,130, 68, 34,177,170, 91,142, 16,242, 39, 67, 85,189,220, 82, 76, 38,211,133, -220,220,220,142,115,231,206,189,179,105,211,166,242, 42, 3, 84,189,142,235,214,173, 83, 75,165, 82,171, 34, 90, 85,239,147, 72, - 36,216,184,113,163,122,206,156, 57,119,115,115,115, 59, 10, 4, 2,125,181,242,242,217,179,103,223,201,205,205,237,104, 50,153, - 46,212,243,107,204, 92, 90, 90, 10, 14,135,131,232,232,104, 29,143,199, 3,139,197, 66, 66, 66,194,227,198,199,206,206,206,191, - 99,251,118,190, 63,236, 59,120, 81,196, 19, 8,122, 4,117,241, 75, 76, 73,205, 32,132, 74,105,160,170, 71, 52, 26,141,199,133, - 11, 23,182,244,232,209, 67,251,229,151, 95,154,234,138,108, 89,130, 78,167,187,120,251,246,109,163, 80, 40,164,178,179,179, 77, -108, 54, 27,102,179,153,232,130,130,116,237, 55,109, 34,247, 63,248,128,146, 75, 36, 28, 30,143, 7,177, 88, 76,157, 62,125, 90, -175, 86,171, 47,254,253, 70, 11, 98, 80, 16, 61,204,213,201,132, 44, 19,133,248, 35, 21, 38, 75,104, 3, 8,109, 1,161, 45,154, - 53,115,199,205,100,181, 12, 44,240, 97,182, 32,135, 24, 33, 18, 80, 16, 71, 43, 33,227,242, 69, 84, 78, 78,206, 99, 67, 84,181, -120,181,241,195,237, 84,149, 20, 20, 17,128, 13,107, 82,144,132,217,219,219,115,178,179,179,255,164,233,239,239,207, 54, 26,141, -150,167,118,201, 50,187, 2,244,172,248, 28,173,235, 47,119,203,125,222, 93,249,173, 72,100, 46, 6, 34, 54, 35,160,149, 27,222, - 29,215,137,255,241,177,188,128, 91, 41,234, 86, 96,147,204, 47, 15,255, 0, 0, 32, 0, 73, 68, 65, 84,233,160, 85,142, 86,212, -179,183, 76, 38, 59,117,235,214, 45,177, 76, 38, 67, 98, 98, 34,130,130,130,176,115,231, 78,177, 88, 44, 62, 9,192,170,241,120, - 55,148, 72, 85,149,153,123,188,127, 48, 45, 39, 42,219,244,132,201,202, 43, 39,120,227,139, 99,197, 69,165,218,177,215,211,235, -190,127,106,225, 78,113,113,113,232,162, 69,139, 10,242,242,242,158, 48, 89,169,169,169, 85, 95,138,253, 1, 52,248,227,247,127, -191,157, 9, 92,177,108, 46,110, 69,196, 96, 72,216, 59,184, 29,245, 8, 31, 45, 28, 5, 27,185, 8, 23, 46, 92,192,232,209,163, -177,116,233, 82, 36, 36, 36,224,167,159,126,162,118,238,220, 73, 93,191,126,157,250,226,139, 47,168, 6,134, 52, 76, 88,185,114, - 37,110,221,186,133,161, 67,135,226,210,165, 75, 40, 44, 44,196,254, 83,167, 30,238,125,248,240,163,170, 49, 91,117,164,126,168, - 21,185, 92, 62,127,229,202,149,136,136,136,120,172, 89, 80, 80,128,149, 43, 87,102, 0,120,203, 26,147,101, 77,187,212,161, 67, - 7,223,125,251,246, 93, 20, 10,133,130,160,160, 32,191,228,228,228, 12, 0, 41,141,208, 44,109, 74, 79, 85,126,126,254,213,157, - 59,119, 94, 31, 48, 96,128,120,242,228,201,142, 71,143, 30,181, 87,171,213,110, 2,129,192, 73,175,215,243, 31, 60,120,192, 62, -116,232,144,203,253,251,247,147,181, 90,237, 77, 75,142, 71,110,110,238,205,184,184,184,193, 29, 58,116,120,176,101,203,150, 12, - 87, 87, 87,122,218,180,105,120,227,141, 55,224,232,232,104,222,184,113, 99, 90,159, 62,125,162, 31, 61,122, 20,162, 86,171,239, - 89, 88,215,239, 86,172, 88,113,101,223,190,125, 24, 62,124, 56,190,248,226, 11,236,223,191, 31,191,253,246,155,232,247,223,127, -231,239,220,185, 19, 60, 30, 15,221,187,119, 71,104,104,232,192,202,238, 78, 75,191,151,110, 81, 20, 21, 78, 81,212,185, 26,175, -183,234, 91,103,197,182,117,253, 93,239,251,106, 84,115,103,141,197,114, 38,180,194,167, 51,218,201,212, 87, 39,118, 39, 57,211, -122, 19,229,120, 63,114,185,159, 29,153,218,154, 42,159,220,200,244, 14, 26,141,230,241,114,248,240, 97,226,226,226, 82, 46,147, -201,172, 78,239,224,226,226,162, 44, 45, 45, 37, 93,187,118, 45,116,116,116,124,156,138,192,213,213, 85, 89, 94, 94, 78,186,119, -239, 94,232,228,228,244, 56,189,131,187,187,123, 58, 33,132,120,122,122,102,213,165,103, 50,153,136,139,139, 75,213, 12, 61,174, -157,157,221,182,110,221,186, 21, 42,149, 74,226,234,234,250, 56,117,130,163,163,227,218,160,160,160,154,229, 13,213, 55, 61, 35, - 35,131,100,100,100,144,230,205,155,103, 85, 47, 79, 77, 77, 37,169,169,169,196,221,221,221,234,244, 14,142,142,142,107,106,169, - 75,163,234,232,225,225,161,212,104, 52,164,103,207,158, 79, 28, 83, 15, 15, 15,165, 86,171,173, 42,183, 40,189,131, 72, 36,154, - 46, 20, 10,179,132, 66, 97,150, 64, 32, 88,222,162, 69,139,220, 3, 7, 14,144,141, 27, 55, 86, 77, 73,135,163,255,136, 30,109, -122,190,246,145,163,255,200,249, 77, 73,239, 32,147,201,206,187,184,184,148, 31, 62,124,248,137,235, 75,163,209, 88,156,222, 65, - 36, 18,101,168, 84, 42, 90,169, 84, 26,175, 92,185,162,142,136,136, 80, 71, 71, 71,171,147,147,147, 53, 5,185,185, 6,165, 82, -169, 41, 41, 41,209,221,189,123, 87, 39, 22,255, 51,233, 29,200, 78,239, 54,100,155,239,177, 71, 75,189,238,207,237, 43,214,222, - 91,214,145,144,159, 71, 19,114,242, 13, 66, 46,188, 79,110,238,152, 70,122,122, 9,204, 87, 22, 52,143, 39,219,125,126,177, 36, - 37, 3,217,217,190, 13,217,230,123,242,225,103, 94,247, 39,247,113,211,238,250,106, 35,185,113,227, 6,137,142,142, 38,137,137, -137,228,228,145, 3,164,103, 43,113,133,230, 54,223, 99, 86,166,121,232, 37, 16, 8, 84,235,215,175, 39,215,175, 95,127,172,121, -236,216, 49, 34, 22,139,213,128,101,179,150, 9, 64,145,109,254,163, 76, 95,249,252,254,241, 32,105, 89,193,137,247, 9,185,247, - 61, 33, 59, 3, 8,249,174, 27, 33, 7,134, 17,114,252, 53,114,125,227, 56,210,203,139,103, 36,219,125, 46,145, 29,254, 22, 15, -182,231,114,185,165,135, 15, 31, 38, 89, 89, 89,228,210,165, 75, 36, 34, 34,130,196,198,198,146,180,180, 52, 18, 30, 30, 78,184, - 92,174, 22,141,120,108, 89, 55,103,120,134,180,229,101,223, 93,213,139,144,163,175,144,188,189, 19, 72, 88, 59, 89, 97,247,230, - 77,202, 71,215,201,222,222, 62, 63, 60, 60,156, 36, 39, 39,147,139, 23, 47, 18, 39, 39,167,124, 0, 22,143,151, 13, 27,210,135, - 16,253, 93, 18,220,183, 29,233,208,161, 29,233,215,171, 45,201,124,180,153, 4,117,110, 65,182,109,219, 70,148, 74, 37,105,209, -162, 5,177,182, 98, 33, 33, 33, 55, 8, 33,145, 67,135, 14,141, 4,112, 58, 36, 36, 36, 50, 41, 41, 41, 50, 40, 40,232, 58,234, - 79,253, 80, 39, 3, 7, 14, 52, 16, 66,200,208,161, 67, 9,128,172,144,144, 16,146,148,148, 68,130,130,130,244,141, 57,120,150, -180, 75,129,129,129, 61, 6, 12, 24,240, 81, 96, 96,224,124, 75,210, 59, 52,160,249,180,146, 80,179, 81,145,252,211, 31, 64,151, -202,197,175,178,140,221, 4,205,215,184, 92,238, 46, 59, 59,187,223,108,109,109, 47,176,217,236,157, 0, 38,162,113,249,205, 88, -149, 17,198,179,142,142,142, 9, 29, 58,116,208, 12, 30, 60,152, 12, 25, 50,132,204,154, 53,139,208, 52, 77, 14, 28, 56, 64,150, - 46, 93, 74, 90,219,219,155, 54, 2,249,219,129, 41, 96,168, 72, 88, 58,165, 21,117,241,213,150, 40,123,165, 37, 84,175,183,166, - 44, 73, 88, 26, 82,151,209,162,105,154,196,199,199,147,224,224,224,114,137, 68,146, 9,203, 19,150, 62,161,233,224,224, 16,225, -228,228,244,167, 36,154,213,202,159, 72, 88,234,228,228,116,213,213,213, 85,233,232,232,120,187, 54, 77, 7, 7,135, 8, 87, 87, - 87,165,131,131,195, 19,201, 61,217,108,246, 80, 7, 7,135,204,154,229, 28, 14,103,128,147,147, 83,122,205,242, 58,246, 29, 46, - 46, 46,233, 89, 89, 89, 36, 47, 47,143,120,120,120,100,213, 52, 96, 57, 57, 57, 79, 24, 48, 75, 52, 27,170, 75, 61,117,172, 85, -211,130, 99,218,152,243, 94,133,119,179,102,205,114,215,173, 91, 71,164, 82,233, 19, 83,158,125,250,190,190,248,198, 67, 85,233, - 27, 11,183, 29,168, 37, 97,169,165,201, 65, 7, 75, 36,146,204,224,224,224,242,248,248,120, 66,211, 52,161,105,186, 46,163, 85, -155,230, 11, 93,186,116, 41,200,207,207, 55,151,149,149,153,210,211,211,117, 73, 73, 73,154,101,203,150, 25,242,242,242,180, 42, -149, 74, 31, 21, 21,165,115,117,117,205, 3,240,130,181,231,168,145,132,212,236, 62, 35, 59,252,122,145,237,126,225,177,159,120, - 62,120,173,155, 68, 23,185,110, 40, 33, 23,222, 39,215,183,189, 65,122,120,241, 43, 12,209, 14,223, 83,228, 91,239,190,100,115, - 43,190, 69,154,187, 90,247, 33, 59,124, 79,221, 95,226,249, 96,116,103, 71,253,190,239,119,144,132,132, 4,114,236,208, 94,210, -189,101,165,201,218,238,119,150,108,243, 11,182, 68,179, 54,179,245,205, 55,223,144,132,132, 4,242,203, 47,191, 88,106,178, 66, -106, 51, 90, 31,134, 72,139,223,232, 38,212,189,210,137,175, 31, 25,192, 51,132,182,225,153,122,122,114,204, 29, 93, 89,180,159, - 35, 72,168,143, 72, 71,182,251, 92, 34,219,253, 6, 91, 90, 79, 62,159,159,134,106, 57,117,106, 46, 2,129, 32,175, 30,163, 21, -210,160,217,242, 22,100,159, 95, 58,128, 12,239, 32, 43,176,208,100, 53,116, 45,117,114,112,112,200,255,238,187,239,136,179,179, -115,158,133, 38,235,177,230,136,176, 80,146,250,232, 36,249,229,192, 74, 18,220,215,143,236,249,102, 46,185,113,233, 19, 50,108, - 72, 48, 9, 9, 9, 33,249,249,249,100,192,128, 1,196,218,122, 42, 20,138, 61, 42,149, 42,242,204,153, 51,145, 33, 33, 33,145, -123,246,236,137,188,124,249,114,164, 88, 44,222, 83, 21,156,168,105,182,252,254,220,254,135,212,136,104, 69,150,149,149,145, 51, -103,206,144,144,144, 16,178,103,207, 30,114,249,242,101, 34, 22,139, 35, 27,123, 31, 89,218, 46, 13, 26, 52,104,113,114,114,114, -233,146, 37, 75, 14,212,146,176,212, 82,205,132,167, 84,207,167,210,134,252, 3,154, 50,145, 72, 20,121,247,238, 93, 82, 84, 84, - 68,218, 57, 59,147, 21,108, 54,201,224,241, 72, 22,143, 71,182, 1,133,255, 2,155, 52,173,174,174,195,191,154, 90,141,150, 86, -171, 37, 11, 22, 44,208, 11,133, 66, 53,143,199,179,246, 17, 60,207,245, 69,232,224,224,112,213,217,217, 89,233,236,236,252,132, -217,171, 94,238,224,224,112,251, 95,126, 3,122,243,120,188, 84, 46,151,251,228, 35,120,252, 71,244,104,221,107,242, 34,231,128, - 17, 67,154, 88, 79, 30,143,199,251, 80, 40, 20,170, 23, 44, 88,160, 87,169, 84,214, 24, 45, 0, 24, 36, 22,139, 51,119,239,222, -173,121,248,240,161,177,176,176,208,116,227,198, 13, 99, 68, 68,132,254,211, 79, 63, 45, 19,139,197,153,168, 59, 45,193,223,114, - 60,201,230, 86,252, 42,179,117,111,145,103,236,240,118, 98,195,206,121,161,164, 71,139, 26, 38,171,238, 76,238,181,107, 86,154, -173, 59, 31,123,196, 6,123, 75, 77, 43, 23,189, 75,186,183, 20, 61,105,178,172,208,172,105,182,196, 98,113,217, 39,159,124, 98, - 77, 36,235, 73, 67,184,203,199,131,236,240,221, 83, 97,162, 26, 88,182,249,124, 77,190,244,241,120, 86,238,163,110,206,240, 28, -232, 45,136,177, 34,146,101, 73, 61, 59,217,218,218, 62,176, 34,146,245, 88,243,203, 47,183,144, 9,227, 7,145, 71, 15, 14, 19, - 85,193, 73,114,251,218,122, 50,102, 68, 32,233,222, 61,136,236,216,177,131,196,197,197,145,174, 93,187,146, 70,212, 51,116,198, -140, 25,145, 73, 73, 73,145,137,137,137,145,151, 47, 95,142, 28, 53,106, 84, 36,128,208,234, 61, 65, 85,102,203, 48,102,140,174, - 19,139,245,110, 3,154, 47,207,152, 49,131, 36, 37, 37,145,196,196, 68,114,249,242,101, 50,106,212, 40, 2,235, 30,223,211,168, -118, 41, 48, 48,176, 71,112,112,240,162,206,157, 59, 15,121, 90,154,255, 65,163, 37, 25, 61,122, 52,109, 54,155,201,144, 33, 67, -204,155,128,226,157, 20,165,220, 73, 81,202, 29, 64,222,191, 61,162,245, 87, 63,240, 51, 4,192,185,234, 5, 66,161, 80,169,213, -106, 29,165, 82,233, 17,149, 74, 53, 7, 21,211, 34,155,164,249, 87,212,147,209,252, 87,104,186, 74,165,210, 45, 42,149,106,148, - 80, 40,204,211,106,181,206, 86,104,218, 8, 4,130,119,133, 66, 97,176, 90,173,246, 6, 0,137, 68, 18,175,211,233,126,211,104, - 52, 27, 0, 20,255,211,251, 78, 54,183,226,131,207,239, 2,130, 15, 34,211,202, 91,174, 60, 83,232, 57,111,128,109, 90,207,214, -146,100,112,233, 47, 64,233,110, 82, 83, 82,117, 86,107,138,168, 32,152,185, 31,220, 76, 81,183,248,226,215, 50,207,249,193,210, -180,158,173,164,105, 32,248, 2, 2,245, 53,107, 53,107,154, 45,137, 68,178,187,188,188,252, 77, 0,191, 89,187,239,228,160, 31, - 15,229,198,102, 48,178,219,129,212,243, 8, 31, 66,212, 96,177,163,145, 3, 37,245,233, 3, 3,115, 31,213,174,249,213, 87, 91, -201,185, 95, 79, 66,167, 46, 68,118,110, 41, 38, 76,124, 29,157, 58, 5,194,193,193, 1, 43, 86,172, 64,155, 54,109,176,116,233, - 82,170, 17,245, 12,149, 74,165, 19,124,125,125, 91,221,191,127, 63, 81,173, 86,255, 8,224,108,205,239, 31, 95, 32, 88,204,225, -116,212,152, 76,151, 30, 0, 17, 13,104,190, 44,149, 74,231,251,250,250, 6,220,191,127, 63, 70,173, 86,175, 3,176,159,105,235, -158, 15, 77, 22,139,181,193,211,211,115, 76,114,114,242, 7, 0,246,225, 63,196,223,110,180, 24, 77, 70,243, 57,212,172,186, 79, -200,179, 86,207, 63,204, 22, 61, 7, 20, 90,130, 80, 25,224,209, 27, 27, 48, 89, 13,107,138,168, 32,152, 56,239,128, 66,115, 16, -228,128,176, 54, 52, 96,178,254, 94,147, 9, 80,248,180,158,246,235, 83, 16,170,238,243,197, 92,243,181,176,120,241, 98,114,250, -244,105,136,197, 98,104, 52, 26, 12, 30, 60, 24,159,127,254, 57,197,180, 33,140,230,223,168,249,175,132,195, 28, 2, 6,134, 6, - 33,207,106,197,168,183, 19,245,228,160,223, 45,228,179, 23,128,133,150,128, 41, 21,229,166, 28,234,237, 84,125, 19, 53,111, 32, -159,154, 11, 54,188,193, 55, 61,130, 74,159, 67,189,213,120,205,191,224, 23, 34,193,167,207,238,121,121, 30,169,105,170, 34, 34, - 34,152,131,194,192, 96, 57,211,240,228, 76,195,199,255, 51, 70,139,129,225, 57,135,122,241,129, 1, 64, 70,229,242,204,106, 50, - 48, 48, 48,252, 7, 13, 23, 40,212, 61,160,205,154,144, 96, 99, 6,218,157, 99, 52, 27,165,201, 6,160, 0, 96,131,138, 28, 36, - 85, 83,122, 27, 74,179, 49, 4,128,145, 57,158,140, 38,163,201,104, 50,154,140,230, 63,172,217,144,246,243,216, 37, 89,219, 44, -195,157,127,199, 7,135, 48,154, 79,149,193,255,154,125, 39,232, 8,130,141,149, 75, 71,230,188, 51,154,140, 38,163,201,104,254, -231, 53,255,149, 48, 93,135,207, 23,194,231,182,230,132,184, 2,168, 74,114, 25, 13, 45,229, 11, 33,230, 2, 0,202,112,155, 16, - 60, 4,208,174,114,125, 58, 69, 89, 61, 27,149,129,129,129,129,129,225,159, 34, 16,192,109, 0,174, 0,134, 1, 8, 71,101, 86, -133,127,212,104,137,236,219,186,130,195,234, 64,209,196, 23, 0, 8,139,138,133,137,142,210, 20, 60,108,242,151,172,212,205,219, -142,128,127,144,130,254, 69, 85, 86,124,147,147,161,181,243,150,143,113,118,144, 77,200, 41, 40,217, 29, 19,167, 58,106,205,182, - 10,133,167, 66,104,103, 59, 78,103, 48,182,227,243,120,105,134,226,210,157, 69, 69,137,101,141,168,134, 93,125, 43, 63,253,148, - 80, 39,178,111, 83, 60,177,129,101, 47,231, 81, 42,168,136, 42, 91, 74,123, 21, 39,147, 67,135, 94, 36,214,158, 27,138,133,254, - 18,153,172,179, 64, 40, 14, 18,203,108,219,210, 4, 40, 84,102,166,232,141,166,203,102,189, 58,146,208,248,159, 21,231,106, 18, -128,149, 0,128, 1, 3,206,161, 29,228,216, 80, 85,113,188, 53,224, 30, 38, 93,184,128,170,228,178, 31, 2, 88,197,220,183, 12, - 12, 12, 12, 12,207,153,209, 26,134,138, 46,195,134, 7,195,123,250,247,190, 37, 20,138,188, 0,128, 38, 4, 52, 1,202, 75,139, - 35,115, 18, 35, 6, 3,128, 67,139,192, 51, 92,161,188, 51, 77, 42,214,155,105,192,100,208, 38,151,166,222,232,106, 73,141, 36, -142,222,163, 7,132, 12, 28, 19, 22, 54,204,167,125,187,246,173, 1,224, 94,244,189, 71, 39, 78,132,199, 93, 56, 71, 29, 46,207, -139,255,165, 73, 1, 20, 8, 63,239,210,165, 83,239,136,136,219, 75, 1,204,106,234, 17,180,183,151,206, 57,251,243,130,190, 3, -199,172,149, 0,214, 25, 45,161,157,237,184,145,195, 95,232,244,222,219, 51, 88,111, 44, 88,225,117,235,202,255, 86, 75, 93, 3, -138, 9,109, 60, 91,174, 28,255,123,125, 15, 78,174,233, 31,235, 50, 88, 63, 22,158,102,109,252,174,135,173,166,240,209,120, 66, -155,199, 83, 20, 5, 54, 95,124,200,177, 85,239, 3, 54,253,231, 21, 1,176,120,198,152,220,213, 63,196,201,213,253,240,248,215, -223, 21,138, 21,206, 28,176,121, 0, 40,100,165, 60,192,133,253, 43,109,223,249,236,155,192, 43, 81,169,166,243, 63,111,213, 82, - 60,238, 24,117,246,253,134,251,211, 83, 83,109,224,233, 89,241,247,215, 95, 47,134, 87,203,123,168, 24,107, 6,172, 71,201, 15, - 89,104, 7, 84, 24,173,148, 20,216, 50,247, 44, 3, 3, 3, 3,195,115, 68,120,165,185, 10,175,185,162, 78,163, 37, 20,138,188, -174,255,239,132,221, 47,151,211, 1, 0, 33,129, 46,248,104,217,150,208, 61,155, 35,226, 0,160,199,128, 48,239,165, 31,190,141, -171, 49,185, 32,132,160, 83, 27,123, 12, 25,249,162,101,198,195,217,175,235,184,113, 99, 95, 93,176, 96,254,136,132,132,132,148, -125,251,246,253, 14, 0,125,250,246,109,179, 98,197,138,151,214,218,218, 9,126, 58,244,115,166, 86,249,224, 86, 99,246, 86,232, -214,170,153, 79,219,150, 19,126,250,118, 11,171,255,224,177,175,164,160,124,165, 54, 43, 49,211,146,109, 29, 28, 28,230,114,185, - 92, 5, 80,241, 52,246, 42, 12, 6,226, 2, 0, 38, 51, 45,179,117,243, 41, 99,243,132,102,129,128,119,191, 76,165,218, 93,154, -249, 96, 87,125,154, 58,163, 49,224,157,183,166,176,238, 36, 22,192, 43,160, 15,123,227,202,143, 65,155,141,182,239,126,184,108, - 92,196,141,159, 80,174,196, 69, 11,119,141, 91,179,160, 89,179,238,236,207, 87, 74, 7, 81, 20, 94,243,236,241,250,168,165,223, - 31,226,118,105, 35,135,206, 72,227, 84,100, 65,143,109, 27, 62, 95,115,101,219,176,227, 0,118, 0, 56, 15,160, 65, 83,103,103, -111,247,227,220, 69, 27,164,229,250, 63,102,123, 87,154, 44,124,189,251, 32,238,166,211,240,245,241,229,184,204, 93, 45,221,177, -108,218,247,234,138,231,108,213,102,119, 91, 1,232, 5,196,218, 97,250,103, 3,241,195,170,229,112,114, 42,135, 76,150, 6, 10, -206, 0,218, 86,190,241, 33, 63, 31,233, 0, 62,204,205,133,100,233, 12, 12,190, 3, 44,236, 8,228, 2,184, 66, 89,246,212,120, - 6, 6, 6, 6, 6,134,127,138,108, 60, 57,248,125,103,131, 70, 11, 0,164, 34, 14,226,146,114, 0, 0, 54, 34, 96,206,244,201, - 40,200,207,243,214,155,104,188, 62,121, 34,110,199,102, 35, 46, 57, 15,132, 16,120,187, 91,252, 16,110,176, 65,119,121,125,234, -235,253,206,156, 61,123,115,241,162,197, 63, 80, 20,174, 1,192,142,157, 95,247, 88,242,201,146, 55, 39, 78,158, 56,232,208,161, - 67, 49, 0, 26,101,180, 56,148,108,203,154, 85,203,249, 25,249, 90,237,220, 5, 31,208,243,231,205,221, 8, 96,172, 69, 78,134, -203, 85,100,100,100, 72, 89,172, 39,159,165,249,197,242, 15, 46, 13, 26,179,246, 97, 74, 90,241,157, 51,199,142,117,245,247,247, - 71, 70,102, 78,175,213,155,182,119, 60,117, 70, 52,165,172, 84, 51, 70,157,255,160,214,135, 54, 11,184,220,152,207, 86,111,235, - 68,219,180, 97,125,244,230, 80, 4,180,118, 67,102,110, 49,250, 14, 30,193,137,188,117, 43, 20,176,216,104,213, 76, 30, 56, 78, - 79,231,118, 92,177,251,198,192, 81, 61,221,186,176, 88,108,168, 52, 70,228,149,232, 96,166,129, 62,126, 10,188,176,103, 19,167, -176,220, 56,122,217,207,233,163,175,109, 14, 83,106, 75,178,102, 3, 56, 92,255,199, 16, 59,119, 39, 57,226,210,203,106, 53, 89, -229, 90, 19, 0,128,199, 54,131, 2,177,175, 71,168, 23,128,239, 0, 95,224,215,217,175,194,217,121,159,179,179,243, 56, 39,103, -151, 72,239, 87,167, 80,205,188,252,100, 42,141, 1,247, 99,238,149,249,119,142, 38,101,133,185,239,106,203,139, 14, 61, 0,162, -125,129, 3,149, 26, 83,192, 24, 45, 6, 6, 6, 6,134,103,155, 58,103, 29,114, 0,224,196,137, 19, 36, 44, 44,236, 79, 25,128, -205,102,130,184,228,138, 33, 56,108, 54, 27,195,122,183,193,198,213,159, 65,163, 55,225,110, 82, 9,126,185,154, 14,125,121, 49, - 8, 33,200, 15,112,170,237,131,159,232, 82, 90,187, 82, 20,200, 22,112,199, 95,185, 33,105, 97,103,107,107,251, 48,230,135,242, - 37,243,148,126, 28, 98,136, 92,246, 69,155, 36,158, 29,167,231,193,131, 7,252,135,135,133,241,165, 82,217,251,132,211,209,157, - 91, 78,230,151,148, 68,149,212,165, 89, 19,145,147,239,136, 17,195, 94, 24,224,226,226, 76,191,186,226, 70,236,150,217,129, 30, -109,219,180,237, 21,103,212,140,208,228, 62, 60, 86,199,102,143, 53,105,154, 6,139,197,130, 82,169,132,217,108,134, 78,167,131, -209,104, 68,122,122,138,146, 38,196,221, 12,154,229,234,234, 14, 14,135, 15,175, 22,158,216,182,113,165,120,207, 79,199,130, 22, - 46,254,252,168, 58, 31,221,241, 71,114,203,199,154,218,194,162, 67, 39, 79,159,117, 36,184,224,246,209,155, 67,217,185, 69, 42, - 92,184,149,128,219,247,211,173, 61,145, 53, 83, 56,180,200, 76, 77, 40, 93,187,118, 45,123,233,169,132,244, 1, 67,198,154, 61, - 91,119,104,161, 51, 19, 0, 20, 4, 60, 14,120, 28, 22, 60, 29,133, 56,242, 65, 59,220, 24, 25,229, 28, 26,232,184,129, 16,114, -184,190,227,169,211, 25,205,189,125, 37,236,142,173, 20,136,122, 84,132,155,167,174, 97,238,162, 13,136, 72,210,161, 76,165, 6, -101,214,129, 77,116,200, 79, 77,132,201,108, 38, 13,157,247, 10, 2,139, 0, 64, 32, 16,124,248,203,241,211,110, 58, 90,136,156, - 98, 29,148, 69, 58,180,233, 62, 70,146,154,153,135,239, 62,123,233, 67, 0,135,124,129, 50,203, 52,155, 12,163,201,104, 50,154, -140, 38,163,249,140,104,214,229, 69,158, 19,234, 76,229,192,170,111,171, 71,233,133,136, 75,202, 65,103,223,102,104,221,194, 21, - 55,227,139,240,227,133,116,124,115, 38, 21, 23,238,230,129,230,200,144, 83, 10, 60, 76, 81,226, 97,106,126,131,249,179,217, 2, -238,248,119,222, 41, 89,208,222,191,180,251,255, 78,205, 65, 51,199,135,254, 11, 23, 22,207, 97, 11,184,227,109,155,203,246,125, -176,224,221, 9, 50,177,152,175,215,233,209,170,165,167,240,237,217,115,166, 80,182, 2,139,159,137, 36,107,230,103, 43, 16,137, -118, 45,251,244,125,193,134, 95, 30,166,149,235, 81,126,248,154, 50,113,254, 7, 75, 10, 57, 92,225, 54, 89, 51, 63,139,199,254, - 24,141, 70,232,116, 58,232,245,122, 24, 12, 6,100,166, 63, 24,113,254,151,247, 6,183,108,110, 55, 88, 32, 20,130, 0, 40,213, -152,144,148,173, 70,240,192, 65,236,206,129,129, 1, 82, 87,191,169,181,105,149,148,164,150,208,132, 45, 59,113,100, 47,251,192, -175,119,240,195,137, 91, 56,250,219, 29,220,188,120,202, 68,104,227,227,231,127, 73, 93,219,120, 75, 93,219,167, 74,221, 58, 40, - 31, 47,205,218,213,155,158,153,205,102,145,224,129, 33,231,166,207,122,251,127,234,178,130,220, 93, 91, 62,203,204,203, 74,121, - 32,224, 81, 38,177,128, 13,149,214,132,239,207,103, 97,220,202,187,184,159,166, 2, 33,164,193, 7,120,211,192,188,241, 83,223, - 51, 27, 13, 6,248,120, 72,177,119,231, 42,140, 8,238,136, 1,237,109,209,181,181, 4, 98,142, 14, 49,177,113,216,191,247,123, - 19, 77,179,230, 55,112, 35,190, 80,185, 68, 2,128, 74,165,122,111,225,251,243,243,244, 38, 26, 6, 35, 13, 67,229,235,249,253, - 95,228,153,181,234,247, 42,183,139,172,182, 29,243,136, 7, 6, 6, 6, 6,134,231, 33,162, 85,181,184, 86, 95, 81,103,215,161, - 86,171, 73, 30, 59,126, 34, 92,157, 92,164, 35,251,191,198,139,124, 84,140,188,236, 84, 36,196, 71, 67,173, 53,130,103,219, 18, - 16,186,160,133,151, 39,162,226,142, 26, 54,175, 9, 87,209, 38, 93,114, 93,122, 35, 70,184,186, 39,196, 82,172, 53,171, 61,174, -199,199, 21,117,222,187,232, 59,188,250,170,212, 97,205,106,143,235, 41,137, 18,150, 88, 72,122, 78,153,252, 10,197,162, 8, 22, - 46, 92,128,145, 97, 47,224,245, 41,147,168,221,187,191,239, 94,108,225, 94,210,224,126,249,225,199,159,241,149,197, 38,253,205, -120,149, 78, 44, 17,137,174, 60, 84,149, 7,120,121,136,134,142,121, 45, 43,252,224,174, 13, 0, 38, 91,162, 85,101,176,140, 70, - 35, 12, 6, 3, 0,152, 1,128,197,170,120, 45, 40,211, 35,183, 88, 7,101,177, 14, 38, 51,141, 49,227, 39,139,110, 69,220,157, - 12,160,142,241, 90, 52,109, 52, 25,113,248,215,219,200,188,117,136,166, 88,236,146,106,131,225, 33,117,109,227,237,226,226,113, - 41,108,204, 36, 71,190,176,162, 27,182,172, 92,135,221,219, 87,215, 91, 79, 22, 69, 17,218,108, 42, 54, 25,141,229,173, 90,182, -202,244,245,239, 40,188,252,191, 51, 35,174,156, 59,172, 50,181,154,100,243, 40, 37, 27,108,174, 0,108,158, 16, 58,131,101, 19, - 15,149, 9,215,183, 2,160,166,206, 92,176,241,221,247, 62, 98,207,219,252, 59,244, 90, 53,116,154,114,148,150, 20, 65,196, 49, - 34,230,234, 49, 19, 49, 27,223, 45,207,190,179,181,110, 37, 42, 11, 64, 86,245,146,194,194,194, 11, 87,127,191,116,252,198,213, -223, 95,119,105,213,153,165, 55,210, 72,136,190, 65,103, 62,140, 56,174,211,149, 94, 0, 0, 10, 40, 0,112,134,185,111, 25, 24, - 24, 24, 24,158,195,136,214,180,234,101,117, 26,173,212,251,151,187, 2,128,119,151,208, 2,169,144, 99,199, 97, 81, 80,102, 60, -194,238,181,115, 65,211, 4, 67,223, 92, 3,153,151, 11, 68, 60, 54,116,170, 2, 85,225,163,139,245,141,213, 1, 69, 25, 7,109, -221,145,233, 53,243,173, 86,242,189,123, 85, 92, 0,216,187, 87,197,125,107, 70,115,249, 87, 59,146,189,186,245,238, 12, 98, 54, - 35,108,228, 88,140,127,121, 60, 82,114,212,248,249, 82, 26,202, 53,122,139,102,203,137, 28,124, 59, 58,216, 59,190,240,206,107, - 47, 72, 56,108,138,106,235,169, 96,167,231, 25, 77,108, 54,215,124,252, 86, 73,214,152, 49, 47, 59, 92, 56,121, 96,128,217,193, -183,163, 38, 63,246,110, 67,122, 58,157,238,137,174, 67, 59,135,150, 39, 7,141, 93,155,145,157, 83, 22,158, 83,164,237, 86,110, - 52, 65, 89,172, 67,110,177, 14,197,229, 6,184,200,108, 97, 50,234,219,215,165, 71, 8,249, 97,212,216,137,147, 0,176, 40,150, -233, 59, 85,118,108,124,197,154, 63, 76,214, 11, 35, 95,117,188, 20,249, 8, 9, 17,167,138, 8,109,170,200,226, 78,209, 25,245, - 31, 87, 16, 54, 5,154,199,161,140,108, 22,139, 54, 24, 84, 70, 39, 39,199, 11, 23, 47,156, 30,174, 53, 37,130,205, 19, 60,126, -175, 70,111,182,248,138, 81, 38, 92,255, 18, 0, 54,109,222,184,174,231,160, 87,121, 23,111, 39, 67, 99, 4,122, 4,122,227,200, - 79, 95,235, 8, 49,190, 87,158,125,231, 75, 43, 46, 66,155,230,205,155,207,229,242,249, 3, 68, 98, 89,115, 71, 87, 15,150,193, -100,134,193,104,134,196,190, 25, 75, 32,181, 27, 68,179,120,151, 77, 6,253, 5, 67,121,222, 38, 0,197,204,125,203,192,192,192, -192,240,156, 69,181,128,106, 57,180,158, 48, 90, 39, 78,156, 32, 0, 80, 91,255,104,166,178, 16,246, 82, 14, 28,221,188, 48, 97, -238, 58,252,176, 97, 30,204,102, 35, 8, 1, 76,102,203, 50, 19, 16,194,253,117,214, 91, 94,190, 45,188,216,142, 19, 94, 21,107, -126,220,171, 22, 77,120, 85,172,105,215,222,190,100,214, 91, 94,201,101, 90,143, 94, 38,179, 25, 87, 98,114, 17,157, 92,130,232, -148, 82, 72, 69,150,167,249, 98,243,121,111,173, 94,181,146,199, 97, 83, 84, 76,170, 74,149, 81, 96, 82,177,185, 92,131, 88,196, - 39,122,194,209,165,228,147,130,129,163,166,104,142,239,217, 52, 21,192,236, 58,163, 98,149, 51, 13,171, 34, 89, 85,175,132, 16, - 66, 1, 52, 77,153,205, 25,249, 90,168, 12, 70, 40,139,254, 48, 90,148,169,238,158, 83,169,107, 27,111,185, 76,122,154,205,102, - 11, 8, 1,140, 6,211, 75,112,109, 51, 88,149,157, 16, 95,221,100, 93,143,201,194,163, 59,231,148,102,131,122,162, 58, 55,238, -188,165,251, 78, 81, 32,108, 54,104, 54,139,162, 41, 10, 52,151, 69,244, 32,132,174, 89, 35,181, 21, 70,171,202,108,241,185,236, - 69,103,247,111,112,122,125,152, 31,126,186, 84,225,249,180,101,121,165,229,153, 86,153, 44,216,219,219, 79,126,255,253,247, 63, - 25, 49,246, 85,148,104, 41, 40,139, 42,162,129,122, 35, 13,158,196, 1,131,102,125,219, 60, 59,175,180,121,194,205,227,189,242, -239,236, 45, 49,106, 75, 54, 50,247, 44, 3, 3, 3,195,127,139,250,188,200,115, 20,213,250,115, 68,171,190, 29, 34, 4,120,152, -154,143, 22,238,142,112,111,209, 26,241, 15,162,254, 88, 7,192,100,182,172, 59,234,216,177,236,140,117,235,228,244,188,121, 37, - 61, 86,175,246,184,246,214,140,230,138,118,237,237, 75,222,127, 63,173,199,250,245,138,107,191, 94,231,154, 73,101,190,174,170, -220, 92,132, 88,147, 99,147, 21,212,209,191, 37,251,179,189, 15,211,206,223, 43,203,229,241,120, 70, 23, 91, 33, 37,147,242,217, -108, 22,151,175, 51,178,116,222, 1,129,236,227, 44, 42,176, 62,149, 42,163, 85,179,235,176, 32,239,209,136,179, 63, 47,104,215, -127,212, 26,187,204, 60, 13, 74,244,236,199, 93,135,108, 22,133,123, 15, 82, 1, 54, 47,186, 54, 77,185,204,238,204,190, 31,127, -240, 88,191,122, 57, 12, 38, 51,102,205, 91,140, 41,147, 39,158,129,107,155,193, 30, 94, 62,145,191, 31,255, 78, 60,120,198, 54, -164,198, 69,228,152,116,165,251,173, 49, 89,143,205, 22, 64,204,132,102, 21, 22,149, 74,117, 38, 8, 81,139,239,211, 25,232, 70, - 93, 57, 42,141, 9,199,111,228,224,196, 47,251,161,144, 73, 26,165,161, 80, 40,252,250,246,237, 7,138,195,135,222,168,131,222, - 68, 67, 95,109,140,150,193, 72,195, 72,184, 16,187,118, 64,225,253, 35,126,208,150, 48, 45, 14, 3, 3, 3,195,127,136,231,120, - 32,124,117,115, 85,119, 68,171, 62, 60,221,157,113, 35, 58, 25,237,125, 91, 66, 33,151,253,159,189,243, 14,143,162,106,219,248, - 61, 51,219, 75,122,178,105,132, 18, 74, 66,239, 16,122,135, 72, 21, 20, 41, 34, 40,210, 44, 40, 2,138,138, 74,135, 23,105,130, -136,210, 68,122,239, 85, 8, 85,233, 53, 1, 18, 72, 37, 61,187,105,219,235,204,124,127,108, 2, 1, 82, 54,128,223,171,190,231, -119, 93,123, 37,179,217,189,115,166,157,185,207,115,158,115, 14,238,199,167,129,161,133,160, 41,192,238,112,221, 12,241, 54,251, -246, 37, 75, 60,144,146,164,160,127, 90,149, 84,227,195, 9, 53,146,150, 44,241,184,200,219,236,219, 1,140,224,121,192,105,182, -156,134,139,173,132, 47,224, 57,123,136,191,183,156,185,150, 96,200,165,105,198,226,227, 33,229,124, 60, 36,180,143,155, 88, 40, - 18, 50,156,131,167,109, 85, 84, 53,204, 60,199,185,178,174,222, 83, 93,135, 44,203,130,162,104,182,200,136, 41, 82,115, 77, 40, - 52, 51,200, 46,176, 32, 95,103, 67,157, 96, 5, 78, 70,237, 50,178,118,211,150,210,180, 24,161,200,163, 86,141, 42,248,106,246, - 18,152, 44, 44, 30,164,235, 33,146, 72, 2,252, 3, 26,220, 26,241,193, 52,201,196,213,241, 24,221,213, 7,159,157,143, 79, 55, -102, 75,167, 85,230,204,178, 44, 11,147,217, 42,202,214,228,123,105,117, 6,119,153, 84, 98,242,243,246,208,148,246, 89,115, 37, - 35, 90,197,200,165, 2,244,139, 8,128,217, 54, 12, 38,139, 3,127,158,218,243, 34, 50,161,254, 65, 85,160,183,150, 48, 87, 69, -102,171,164,233, 18, 42,253, 0, 80,161,164,202, 33, 16, 8, 4,194, 63,136, 50, 71, 29,186,100,180,148,114, 41,120, 70,138,243, -215,227, 17, 94,191, 49, 54, 28,184,130,218,141, 34,144,169,115,128, 7, 93,225,104,195, 98,166,124,105,186, 1,224, 70,255,254, -242, 42, 3, 7, 6,247,224,121,225,239,171,126,209,166, 1, 64,104, 67,167, 12,199,241,224,121,128,231,156,134,203,245,144,142, - 32, 37, 41, 83, 91,189, 70,128, 2,119,211,108, 22,133, 68, 68,123, 41,196,140,159,135, 88, 36, 18, 8,192,242,148, 37, 51, 51, -222, 66, 1,201,174,200, 61,219,117, 40, 87, 6, 30,233,246,250,247,234,228, 71,133,215,234,228, 25,155, 20,218,196,224,121,160, - 78,176, 2,209,151, 14,179,217,233, 15, 31,152,178, 99,127, 46, 77,139,227,192,216, 28, 28,110, 37, 20,162,192, 96, 71,129,222, -134,118, 93,250,137,218,117,239,143,243,209, 26,112, 14, 59, 22,174, 57,172, 99,121,251, 16,224,158,189, 18, 59, 77, 95,190, 17, - 83, 69,157,111,144, 8, 5,130,130,186,181,171, 37,138, 69, 66,135, 86,171, 21, 63,253, 41, 6, 10,153, 24,121,122, 59, 0,216, - 43,123,245, 20, 26,236, 56,112, 41, 11, 7,247,108,133, 76, 38, 3,255, 2, 87,160, 72, 36,242, 20,138,164,176, 25,156,221,133, -197, 47,219, 51, 47, 90, 32, 1,104,129, 39,185,103, 9, 4, 2,129,240, 15,162,228, 26,135,125, 74,154, 47,218,165,168, 9,199, -195,215,199, 27, 82,133, 59,146,178,109,208, 81, 42,228, 27,121,176,172, 51,162, 85, 78,224,169,212,213,189, 15, 28,200, 76,219, -191, 95,179,238,192,129,204, 18,137,222, 79, 34, 89,143,127,114,188,203,154, 20,207,158, 60,112,244, 76, 97,255,214,126, 94, 52, -195,152, 68, 66,218, 34, 16, 49, 54,145,128,182,139, 4,180,213,223, 93,200,156, 57,184, 77,204, 83, 56, 83,145,166,217,108, 70, -247,238,221,209,187,119,111, 12, 24, 48, 0,131, 7, 15, 70, 88, 88, 61, 21,205, 80, 86,158,226, 56, 63,177, 14,181,252, 40, 8, -204,169, 56,181,237, 63,198,232, 63,246,221, 98, 45,230,126,120,218,114, 62,209,228,121, 46,175,208, 2,179,141, 69,190,222,134, -124,131, 13, 14,191, 54,216,247,103, 6, 76, 86, 22, 41,215,119,153,212, 89,105,159, 88,114, 30, 38, 85,112, 42,190,120,122,147, - 79,123,255,189,145,106, 55, 41,253,176, 67,219,150,106, 95, 31,111, 7, 69, 61,137,188, 82, 20, 5,169,187, 10, 94,158,110, 72, -186,113, 20, 39, 22,118, 51, 1,248,218,149,227, 89, 18,119,185, 0,253, 91, 7,160,223,160, 97,104, 20,209,203, 21, 99,253,156, -166, 92, 46,151, 21, 71,175, 74, 78,235, 96, 45, 17,213, 98,139,206, 55, 45,144,200, 92, 61,239, 47, 9,209, 36,154, 68,147,104, - 18,205,191,143,230, 63,153,226, 53, 14,139,127,186, 54, 51,124,177, 1,170, 25,168, 64,237, 96, 5,204, 54, 21,204, 86, 22, 6, - 51, 11,173,209, 6,173,209,142,164, 44, 35,162, 15,188,124, 9,157, 81, 44,231,212,231,188,115,190, 77,176, 28,239,114,244, 68, -108,179,206, 94,188,112,222, 91,219,154, 53,181, 78,236, 19, 24,114, 59,201,154, 65, 81,180,137,102, 4,118,111, 55,129,240,254, -253,219,234,139,231,142,116,148, 58,216,119,140,229,232, 56, 28,142,194,224,224,224,162, 72,212, 19, 11, 89,175,150,108,192, 31, -135,191, 8,237,212,127,161,223,210,185, 83,140, 52, 35,226, 40,129, 40,154,181,155,182,154,178, 99, 87,161, 28,251, 65,139,164, -247, 46,223,188, 27,225,233, 29,130,135,233, 6, 24,204, 14,216, 28, 28,188,148, 34,164,221, 57,110, 75,186,127,109,135, 62,227, -246,134, 23, 56,108, 91,226,238, 69, 87,137,140,236,245, 70, 68, 68, 27,230,219,111,191, 65,120,120, 56, 76, 38, 19,104,154, 70, - 72,245, 90, 72,138,187,137, 75,135,103,179,198,220,228,159, 1,204, 2,160,174,236, 63,209,104,173, 56,122, 45, 7,135,247,110, - 7, 35, 20,191,200,233,165,101, 50,153,180, 52,115, 85,210,116, 61,254,176, 80, 44, 45,106, 4,112,228,222, 37, 16, 8, 4,194, - 63,132,177,207,252, 92,237,146,209, 50,155,205, 73,237,187,247, 3,199,241, 96,121,128, 99,139, 34, 79,220,147,232, 19,107, 55, - 39,189,108,233, 56,142,189,242,227,234,117,189,155,181,234,196,212,175,170,132, 54, 55, 11,151,254, 56,237, 0,199, 95,116,229, -251,185,185, 15,244, 50,255,218,111,188,245,230,192,157, 35,223, 27, 95,208,177, 75, 23,133, 74, 21, 96, 73, 75, 79, 51,174,223, -180,217,126,252,200,254,142, 28, 28, 67,115,115, 31,234,203,211, 41, 44, 44,252,161,180,247, 37, 98,101, 59, 0,161,140,128,178, -154,212, 15, 42,149, 17,174, 73, 79, 29, 52,111,246,140,228,225, 99, 38,137,107, 6,215, 66, 78, 33,131,164,180, 44,220, 63,183, -223,146, 30,119,117,175, 54,237,198,104, 23,165, 50, 75,121, 47, 13,192,210, 75,151, 46, 54,136,140,140,236,213,181,107, 87,126, -236,216,177,224,121,224,212,234, 9,124, 94,210,165, 93,112, 70,177, 18, 94,240,188,164,156,187,120,211,123,112,199, 22, 2, 31, -183,209, 88,183,253,136, 29, 60,151, 82, 73, 25,255, 42, 85,171, 11,156,221,133,206, 41, 29,158,125, 89,237, 79,242,199, 68, 74, -127,129, 17,209,254,101,236, 47,129, 64, 32, 16, 8,127, 55, 94, 60, 71, 43,245,158,115, 62,173,191, 26, 93, 86,206,136, 13, 27, - 54,206,217,184,105, 91, 59,179,213, 26,204, 67,148,202, 58,172,103,245, 44,190,117, 85,195,148,253,240,154,143, 79,157,134,235, -215,252,248,245,250,117, 63,117, 2,199,214,165,128,100,158,194, 25,169,157, 29, 89,145,201, 42,215, 44,105,116,191,244,120, 99, -145, 41, 55, 87,191,177,178,223, 53,229,198,102,209,140, 45,228,151,101,179,191,167,105,166, 39,203,114, 66,142,181, 63,100,109, -230,255,152,212,177, 7,224,114,150, 27,242,202,249, 91, 12,128,152,168,168,168, 14, 81, 81, 81,173, 0,252, 0,231, 26,138,215, - 94,230,188, 88,114,117,221,166, 78,153,122,106, 50,168,106, 28,199,195,193,114, 41, 34,147,177, 91, 37,101, 66,106,214,172, 37, -183,217,217,231, 18,224, 75, 38,194, 63, 54, 90, 30, 85,228, 0, 66,136,209, 34, 16, 8, 4,194, 63,132,177,120,126,210, 82,215, - 34, 90,255, 95,228,231, 39,232,144,143,137, 47,171,147,155,251, 64, 15,224,185,145,123,198,151,212,141, 59,240,254,158, 0, 0, - 32, 0, 73, 68, 65, 84,126,160,221,141, 7,218,221, 47,250,125, 67, 78,162, 26, 72, 28,249,146,197,112, 37,145,253,124,209,235, -149,160,209,220, 51, 64,131,214, 47,123, 90,182,108,222,116,127,219,182,237, 66,158,102,132, 28,207,136, 28, 60, 37,116,112,148, -208,110,231, 96,177,217,237, 54,135,195, 14,214, 97, 3,199,218,121,206,102,135,115,118,120, 2,129, 64, 32, 16,254,201,134,235, -239, 99,180, 8,255,106, 18,226, 31,198, 69,144,195, 64, 32, 16, 8,132,127,185,201, 42,249, 19,128, 51,247,188,172,145, 3,149, - 89,204,247, 69, 70, 31,156, 36,154, 47,173, 41, 4, 32, 6,160, 4, 80, 81,151,102, 47, 20,173,215, 72,142, 39,209, 36,154, 68, -147,104, 18,205,255,162,102, 69,218, 39, 65,248, 75, 13, 24,209, 36,154, 68,147,104, 18, 77,162, 73, 52,255,247, 52,255,201,140, - 45,229, 5,128,116, 29, 18, 8, 4, 2,225,127, 16, 31,159, 58, 74,224,113, 94,111,133,200,125,235,249, 3,128, 81,115, 47,155, - 28, 61, 66, 41,148, 92,231,240,169, 28, 45,250, 5, 5,133,180, 64, 60, 85,238,230,115, 79,225,225,147,254, 63,126,112,169,176, -234,138,143,123,116,172,177, 47, 60, 84, 54,160, 50, 95,148,251,133,253, 26, 80,171,245, 35,133, 42,236, 99, 4, 54,147,189, 76, - 33, 20,170, 80, 63,101, 72,139, 63,220,130, 27,188,246, 23,236,163,164,126,253,250,109,234,215,175,223, 6,128,228, 85, 8,202, - 85, 97,195,170,212,142, 56,167,170,217,244,180,194,191,206,155,175,186,192,202,192,218, 62,202,144,230,187,149, 65,141,243,149, -129,141,181,202, 42,205,207,186,249,214,171, 89,209,247, 66,250,207,171, 59,115,107,244,214,144,254,243,234,150,246,119,175,200, -229,110,223,109,123, 48,215,167,223,127,148,164, 94,121, 49, 66,218, 13,243, 12,236, 52,217,167,178,223, 11, 14,139,136,169,222, -160, 67, 78, 80,157,214,209,174,126,167, 74,120,155, 27,213,234,183,203,174, 18,214,230, 26, 57,242,174, 33,245, 11,109, 35,245, -170,122, 88,226, 85,245,136,196, 59,180,203,203,234, 5, 6, 6,202,234,214,173, 27, 25, 17, 17, 49,174, 91,183,110,159, 54,109, -218,116,108,181,106,213,122,254, 55, 27,250,114, 85,216,151, 22, 33,165,177, 8, 41,141, 92, 21,246,101,197,245,107,248, 28,138, -102, 51, 40,154,205, 80,168,194,231,252, 93,206,149,196, 63,172,154, 92, 21,182,196, 45,160,254, 21,153,170, 78,191,202,126,223, -203,203,171,167,159,159,223,235,197, 47, 47, 47,175,158,228, 14,120, 97, 74, 70,177, 94, 58,162,197, 8, 37,242, 11,195,223,251, -176,225,130, 25,211,164,203,214,237,195,178,185, 83,238, 90, 12, 5,245,255,142,123,238, 27,218,234, 26, 67, 51, 85, 74,190,199, -114,108,154, 38,241, 74,139, 87,161, 31, 94, 93, 54,250,235,207, 71,124, 54,236,173,238,213,186,247,253,132,138, 77, 52,237,119, -221,162,161,201,142,221,123, 67,206,157, 57,189,124,221,186,213,179,212,142,240, 37, 66,137,224, 71,109,106, 76, 65,101,202,224, -238, 87, 51, 84,160,240, 61,215,126,192,135, 1,215, 79,110,222,192, 90,185, 30, 70, 77,137,213,191, 95, 28,191, 90,181,106,181, -100, 24,198,231,227,143, 63, 22, 1,192,210,165, 75,107,179, 44,155, 27, 31, 31,127, 21, 47, 48,249,169,211, 96,134,143,248,225, -251,153, 27, 95,123,173, 55, 50, 52, 6, 44, 92,178,178,243,177, 67, 59, 6, 27,178, 31,236,122, 21,231,196,211,179,134, 59, 68, -110,119, 62,249,124,150, 42,178,115, 75, 70,111,118,224,216,185,155, 29, 54,175,156,117, 5,168,215, 74,167,185, 87,230,156, 98, -156,177,112,186,191,146,143,228,140,133, 0, 48,236,185,135,189,210,222,221, 79,198, 70, 6, 74, 4, 55,115,129, 10, 23,125,244, -172,222,238,184, 80, 34,169, 70,211, 52,104, 10,160,105, 10, 12, 69, 57,215, 9,181,153, 82,210,239,159,239,245,119,184, 79,220, -170,182,202, 2, 35,240,161,169, 39,229,163,232,162,159, 60,175,205,122,112,193,231, 21,252, 27,143,134,181, 61, 27,180,171,109, - 88,127, 54, 49, 79, 33,232,248,233, 97,138,167,127,122,116,126,201, 45,151, 12,128, 84,234,117,240,224, 65,191,200,200, 72, 15, - 85,131, 1,103, 93,249,142,152,209,215, 63,116,232,128, 40, 50,178, 87, 37,174,207,176, 30,160,233, 77, 20, 32,228, 56,126, 41, -195,241, 59,244,185,113,241, 64,229, 86,159,146,169,194, 71,211,224, 93,174,103, 56, 80,215, 76, 57,177,235, 94,244,224, 10, 36, -238,221,132, 34,209,167,161, 97,141,154,165, 39, 63,188,102,208,235,150, 56, 44,133,103, 43, 45,100,119, 76, 61,121,254,250,107, - 2,161,144,138,236,214,154,177, 0,167, 95,230,164,251,251,251,191,190, 98,197,138,154,109,218,180, 1, 0, 56, 28, 14,247,157, - 59,119, 6,204,158, 61, 91, 17, 23, 23,183,231, 5,101,131,253,252,252,170,138,197,226, 96, 0,176, 90,173,233,106,181,250, 17, -128, 10, 27,254, 10,255,154,190,224, 49,235,252,185,115, 2, 0,232,208,161,227,156,170,237, 63,242, 98, 68, 74, 83,169,135,195, -170, 83, 20,196,159,158,116,233,242, 69, 10, 0, 34, 90,183,153, 38,247,173,247,227,127, 51,178, 37, 85,133,183,166,129,207, 34, - 58,116, 31, 52,100,232, 8,186, 65,157,170,232,217,163,235, 23, 38,224, 96,165,174, 25,129, 64,118,229,202,149, 90, 52, 77, 51, - 14,135,195, 28, 17, 17,241,232,101,202, 21, 20,214,230, 79, 10,116,136,205, 97, 93,163, 78,184, 54, 7,207, 79, 58,205,120,132, - 52,251, 26,140, 96, 12,199,113,169,186, 71,215,218,254, 11, 35, 90,207, 31,231,202, 42,209, 2,241,167,195,222,253,160,225,164, -201, 95, 73, 63, 89, 22,133,195, 43,167,105,254,174, 38, 11, 0, 24,154,169,114,252,196,113,149, 92,204, 0, 0,244,102, 7, 94, -139,140,172,248,137, 80,189,213, 25,154,162,194,139, 23,180, 97, 29, 54,169, 64, 40, 54, 83, 78,131, 4, 10,128,111, 80,245, 40, -127,199, 5,249,176,183,186, 87,219,180,237,247,180, 71,105,185,149,174,212, 40, 70,132,136,142, 61,209,189, 71, 47,143, 43,151, -255,156,181,250,231, 85, 95, 58,108,246, 85,156,157, 91, 98,206,123,152, 81, 97,101, 30, 80,167,185, 88,233,123,108,208,184,217, - 62,102,218, 27,223,206,253,193,247,220,209, 45,103,211, 83,155,112, 41, 41,169,102,158,162,238,230,231,101,126,106,200,138,143, -117,245,144, 41,149,202,154, 74,165,178, 73,227,198,141,165, 83,166, 76, 17,118,238,220,249,137,101, 31, 59, 86,116,230,204,153, -192, 69,139, 22,245,190,125,251,182, 89,175,215,223,210,235,245, 9,168, 68,162,125, 64,128,223, 71,111, 12,236,135,174,131, 62, - 4,203, 81, 24,251,193, 36, 28, 63,186,103, 60,128, 87, 98,180,236,114,247,217, 99,198, 77,241,139,104,217,148,153,181, 37, 22, - 50,177, 0,189, 90,132, 83,239,126, 60,221,115,221,242, 89,107,161, 65,167,210, 34, 89,156,177,112,122, 67, 95,235,208,254,109, - 66,113, 96,171,117, 40,186,125, 14, 90,238, 49, 39,245,192, 87,247, 1,160,102,228,199,110, 18, 86,189, 34,200,147, 81, 73, 88, -245,138,154,145, 31,159, 76, 56,182, 66, 87, 94, 89,132, 18, 73,181,173, 91,182,212,241,114, 19, 65, 64, 83, 96, 24, 10, 2,134, -134,217,202, 98,240, 91, 67, 95,217,101, 46, 83,213,233, 77, 3,239, 58, 31,216,248,213,148,243,224, 72,101,206, 9,197,136,124, - 14, 29,216, 43, 80,121, 72,192, 48, 20, 24, 26, 96,104, 10,201,217, 38,140, 30,253,174,199,203, 26,246,215,218,169, 90, 78, 29, - 18,222, 43,162,161,119,227,237, 23, 41,143,136,215,134,248,104,204,242, 81,219,246,159, 30,202,119,152,116,153,231,185,239,211, - 46,252,112,162, 60, 17,139,197,146,221, 43,242, 53,119, 74,160,144,159,220,183,161,163,128,166, 96,103,121, 56, 88, 30,108,209, -218,168, 84, 81, 11,134,166, 41,240, 28,143, 49, 99, 70,163, 87,228,107, 70,206,193,165,185, 94,201,209,155,142,157,252,195,207, - 98,231,176,104,197,186, 89,134, 66,245,172,196,251, 62,201,250, 66,205, 36, 83,206, 3,151,215,193,160,193,183, 72, 77,136, 30, -183,229,208, 37, 52,172, 95, 15, 44,231, 44,103,120, 21, 5,182, 28,190,132,186,225,117,157,229,230,120,132,133, 40,209,178, 69, - 75, 0,120, 33,163, 37,144,184,125,219,169,207,136,153,125, 7,191, 7,149,159, 31,104,222,222,247,228,225, 45,125,127,253,233, -251,169, 14,179,118, 81,165,196,120,246,241,115,129,231,184,151,142, 58, 5, 5, 5,249,181,108,249,100, 58, 70,135,195,129, 26, - 53,106, 32, 61, 61, 61,252, 69,218,105,129,129,129,125,190,251,238, 59, 85,239,222,189,133, 1, 1, 1, 0,128,172,172,172,224, - 99,199,142, 53,251,238,187,239,114, 50, 51, 51, 15,163,156, 25,125, 88, 59, 45,162, 5, 96,164, 82,185,115, 31, 65,209, 83, 62, -122,167,177,127, 96,144,165,180,207,171,213, 89,226,207, 63, 60, 77, 9, 4,162,162,207,131,230,121,142, 42, 39, 74,212, 93, 40, - 20,150,218, 67, 97, 99,220, 35,120,161,199,251, 52, 67, 59, 47, 86,135, 93,157,255,232, 70,189, 74, 68,226, 26, 8,197,162, 85, -111, 12,121,175,237,155,131, 6, 32,208,207, 3, 39, 47,220,198,248,143, 62,179, 59,108,246, 37, 47, 84,121, 48,140, 32, 39, 39, - 39,217,203,203, 43,224,229,159,183, 84,232,239,199,143,170, 78,158,138,154,182,120,217,242, 9, 54,171,195,206,241,252,227,117, -140,101, 50,137,176, 71,223,183,220, 85,181, 34,164,203,191,123, 95,248, 47,140,104,173,126, 37, 70, 75, 44,115,123,235,155,207, - 63,150,206,222,124, 9,135, 87,142,215, 24,181, 26,191,199, 45, 5,119,207, 27, 6,109, 65,179, 23, 41,161,210, 47,172, 13,197, - 8,198, 81, 12,163,160,104, 74,204,177, 92,170,195,106,157, 99,202,125,240,210,147, 86,114, 28,143,221,127,230, 84,206, 0,241, -168,189,105,251, 94,149,191,167, 4,102, 27,139, 33,195, 70, 96,227,198,141,110,126, 30, 98,152,173, 14,124,191,120,177, 78,159, -124, 88,149,156,154,159,222,189,223,103, 39, 18,146,114,162, 31,101,154,119, 84,182,108, 22, 27, 11,173,209, 1,163,133, 70,157, - 6, 45,241,253,146,186,210, 71, 41,137,159,109,248,117,237,196,187,119,153,141, 28, 67,207, 52,103,222, 75, 45,245,166, 11,104, -216,203,221,203,103,235,192,113,115, 61, 31,228, 8,192,195,134,120,119, 41,222, 26, 53,209,189,102,128, 12, 10, 41,227,153,152, -146, 30, 56,101,234,212, 11, 9, 44,223, 74,171, 78, 72,172,168, 60,213,171, 87, 31,212,183,111, 95,249,228,201,147,133, 33, 33, - 33,248,117,203,206,106, 29,122, 13,238,151,145,153, 29,194,243, 60,252, 85,170,212, 49,239, 14, 62,120,228,200,145,148,212,212, - 84,225,194,133, 11, 91,239,221,187,183,126, 86, 86,150,203, 45, 83,150,231, 97,182,176, 96,139, 30,144,234, 66, 75,165,253,105, -112,112,176, 36, 61, 61,221, 82, 34,202, 64, 61, 9, 20, 82,189,186,117,106, 45,248,229,104, 18,244,102, 22, 10,169, 16, 73,217, - 70,180,104,218,136, 90,195, 58,154,148, 38, 56,250,173, 62,211,253,149,124,100,255, 54,161, 80,121,201,177,254,199,185, 56,112, - 49, 49, 50, 91, 79, 97, 5,207,140, 11,148, 8,122, 40,184,204, 21,157, 91,212, 10,232,218,188, 26,174,182,168, 21,112,238,122, -108,156,108,240,226,143,211,245,194,147,249,199, 38,234, 74,175,120,104,120,187,137,176,238,120, 10,228, 82, 1, 20, 82, 1, 20, - 18,231, 79,154,166, 94,174, 85, 27, 88, 47,132,225,216,209, 12, 35, 24, 61,244,173,193, 65,195,135, 14,230,193,208,216,185,251, -224,128,205,155, 55,101,218,109,214,181, 44,205,172, 43,235,250,121,234,128,210,128,202, 67,140,169,107,163,225, 46, 19,194, 77, - 46,132,187, 92,136,174,141,253,192,208, 47, 92, 68,175,241, 3,106,246, 30, 63,176,122,151,240,170,202, 58,183,226, 11,239,142, -158,115,109,217,153,130, 46,159,254,184,180,190,143,190,192, 42,248,118,202, 24, 65, 90, 70, 70,151,157, 7,207,118,101,173,239, -197, 58,108,134,175,212,183,119,150, 26, 21, 78,139,189,216, 44, 56,226, 77,169, 77,111,191,115, 43, 54,173, 86,190, 69,130,152, -100, 45, 20, 82, 1,148,197,199, 86, 42,128, 66, 42,132, 82, 42, 64, 70, 90, 18,242, 12,204,133,116, 31,186, 11,206, 94,116, 84, -166,224,102, 27,139,155,137,122, 84, 15,111,138,192,192, 32, 88,123,191, 93,253,114,212,238,253, 87,206,238,155,111,204,186,255, -149,171, 58, 91, 14, 93,194,180, 73,227,174, 83,192,141,162,135,116,179,111, 23,172,108, 62,107,218,135, 79,189, 55,101,230,242, -230, 47, 30,201,114,155,222,117,224, 7, 51, 59,244, 24, 8, 93, 94, 54,254, 60,177, 3,189,250,190,129,183,223,251, 4,158,158, -190,223, 47,153,243,249, 45,135, 69, 27,245, 92,157, 27, 80,183,125,163,134,245, 54, 7, 7, 5,133,112,156,115,149, 15,158, 7, -244,186, 66,124,254,233, 24,112, 60,143, 38,205, 90,117,149,118,232,193,243, 69,171,129,104,114, 53,134,216,251,119,187,155,115, - 98, 47,187,124, 44,205,102,187, 90,173,198,205,155, 55, 17, 23, 23,135,152,152, 24,228,230,230,194,195,195, 67,111, 48, 24, 42, - 21,188,111,220,184,241,240,168,168, 40,169,151,151,215,227, 55,173, 86, 43,220,220,220, 48,124,248,112, 97,207,158, 61,131,251, -244,233, 51, 50, 58, 58,122, 11, 0,109,169,229,201,123,152,225,230, 31,254,115,167,206,157, 38, 0,128,204, 61, 48,113,197,175, - 7, 99,202,109,208,122, 4, 85,107,219,182, 93, 45,240, 60, 40,240, 63, 24,115,227,178,202,137, 18, 41, 46, 93,186, 84,147, 97, - 24,193,147,103, 16,135,159,214,111,175,251,251,249, 59,131, 22,124,191, 72,234,174,144, 64, 93,104,197,251,111, 15,116,249, 25, - 44,243, 15,239,221,182,109,199,253,179,102,126, 35, 80, 42, 20, 56,113, 57, 1, 31,127, 58,213,156,153, 28,189,136,231,132, 43, -141,234,184,156,151,124, 84,242,120, 5,212,169,162,132, 91,255, 94,210,241,239,244,151, 90,237, 44, 10, 12,118, 88,108, 44, 88, -142, 71,161,193,142,187,143,116,240,117,175,252, 82,110, 60,207,183, 4,224, 7, 64, 77, 81,212,213,146,219,197, 13,186, 98,111, -252,204,182,166,232,249,224, 3,192, 10,231, 72,253,199,151, 79,209,118, 89,239, 23,127,255, 46,128,122, 69,154, 44,128, 43, 20, - 69,229,151, 97,182,158,139,114, 9, 14, 29, 58,196,247,237,219,247,113,141,255,236,246,179, 72, 68,194, 32,133,135, 31,120,254, - 30, 74, 46, 96,172, 10, 8,206, 93,180,100,153,247, 71, 31,140, 75,209, 22,228, 85, 43,122,251,164, 43, 15, 11, 1,197, 44,233, -212, 46,162,231,132, 15, 62, 64,120,205, 42, 34,150,101,249,232,184, 68,251,134,117,235, 71,157,187, 40, 94,166, 77,139,158, 94, - 34, 4, 89,169, 97,159, 44,199,166, 61, 27,193, 98, 57,246,217,214,237,115,154, 20, 5,120, 42,197,248,249,104, 18,120, 30,160, -192,195, 67, 33,196,182, 51,105, 72,188,190, 71,219,183,137,214, 48,124,193,140,174, 93,122, 79,140,186, 27,111,222,145,147, 99, - 62, 14, 32,171, 60,205,210, 43,116, 14, 22, 27, 11,187,195,129, 93, 7, 15, 34,178,107,107,180,109,219, 26, 29, 59,180, 21, 92, -187,126,251,189, 15, 38,140, 9,193,147,209, 29,143, 53,165,254,181, 91, 42, 61,124,119, 12,154,176,208,237, 78,154, 3, 2, 6, - 8, 13,144,193,219, 77, 4,171,131, 66,178,218, 86,116,231,120,226,227, 41, 51,189,167,125, 54,225,136, 86, 45,110, 8,220,179, -149,183,239, 70,163, 81, 60, 98,196, 8,161,221,110,183, 13,127,255,147,158, 89, 89,234, 1, 63,253,240, 31,137, 74,229, 15,163, -217,129,235, 49, 15,235,205,154, 53, 51,244,224,177, 51,251,102, 76, 29,191, 63, 50, 50,210, 99,251,246,237, 92, 69,199,243,169, - 22, 98,182,230,199,245,155,119,109, 92,186,104, 30, 98, 83,242,177,238,151,149,224, 89,199,207, 21, 28,170,146,154,252,136, 17, - 35,100,251,246,237,171,146,150,150,166, 53, 26,141,234,167,226, 17, 52, 37,200,206, 51,194,215, 77, 12,145,128,134,191,151, 20, - 42, 15, 9,132, 12, 64, 83, 20, 91,154,230,186, 29,135,231,112,198, 66, 28,216,106, 29,186,254,199,185,120,239,163,175, 17,173, - 17, 31,163,229, 30,115, 62, 28, 58,104,154,159,140,141, 12,242,164, 85, 93,155, 87,135, 66, 42,194,151, 19, 71,160,213,245,100, - 85,122, 1,247,181,218,196, 52,157,121,236,241, 98,221, 39,159, 14,142, 56, 35, 88,110,114, 33,142,109,254, 62,199, 80,168, 46, - 44,238,146,179, 90,204, 41, 46, 94,198, 39, 75,105,217, 78,107,218,168,193,220, 9, 99, 71,211,237,218,180,226,105, 90, 8,141, -206, 74,241, 60,240,233,199,227,241,225,248, 49, 1,169, 25, 57,223,174, 92,249,243,244,168,223,249,217, 6,245,253, 25,229,105, -210,148, 51, 10,164,148, 10,160,148, 57,141,139, 82, 42,128,217,202,130,162,192,120, 86,109, 86, 72, 57, 35,185, 25,121, 41,101, -182,192,159,210,244,174,218,224,212,239,137,110,117,243,119,228, 95, 76,202,136,153,115,253,118,246, 21, 0,121, 33, 29, 61, 71, -218, 28, 60,244,102, 7,146,178,141,112,216,120,234,189,215,170,161,198,155, 84,248,188,245, 55, 54, 30,189, 13,247, 18,149,254, - 83,154,233,151,118,153,125, 26, 14, 28,178,116,249, 47, 87, 23,205,253,154,209, 20, 90,193,241, 60,164, 98, 6, 50,177,160,232, -197,192,100, 40,196,202, 85,107,178, 28,160, 6,225,236, 89, 71,101,174, 79,112,252,219, 3,123,119,220, 70, 1, 98,138, 22,165, - 5, 85,171, 94,173, 91,191, 81,210,110,253, 71,128,117, 88,167, 93, 63,207,159, 54,230,196,158,114, 69,179, 97,253,122,160,128, - 27,134,156,184,241, 0,160, 80,133,253, 92, 55,188,110,243,103,223,171, 93, 59,188,185, 43,231,253,113,164, 84,234,246,145,151, -183,223,215,225, 13,154,170,178,243, 45,148,155, 79, 21, 36, 61,184,137,173,171,190,221,196,153,173, 51, 79, 29,222, 49,119,217, -186,189,111,117,139, 28,136,245, 63,253,231,203,220,204,199, 70,235,100,137,104,213,219, 27,214,174, 14, 17,138, 37,176, 59, 56, -216, 89,222,249,211,193, 34, 47, 47, 31,118, 7, 7,169,220, 13, 14,142,130,157,229, 96,119,112,176, 88, 29,138,241, 35,250,124, - 96, 6, 46,151, 86,206,224,186,157,142,139, 36,146,106, 60,156,107,215,242, 60,143,164, 44, 19, 29, 24, 24,184, 5, 0, 36, 18, - 9, 36, 18, 9, 56,142,195,245, 88,245, 71,190,225, 97, 19, 80,100,240, 88,155, 53,165, 32,249,143, 94,101,237,123, 64, 64, 64, -191,103, 77,150,217,108,134, 94,175,199,249,139, 87, 61,214,110,220, 21,153,148,146, 86,147,227, 61, 44,110,170,154,189,116, 57, - 9,253,202, 58,158,186,236,216, 15,220, 35,198,208,147, 63, 28, 89,123,249,134, 67, 87, 30, 30,159, 83,110,158, 86,141,110, 95, - 88, 39,143,123,163,197,130, 31,214, 61,200,255,227,231, 73, 21,157, 35,129, 64, 32, 84,171,213,143,239,239, 21,107,182,182,184, - 17,155,254,250,178,165,203,164,215, 19,116,184,147,148,129,145,221,171, 58, 91, 56, 46,156,119,133,127, 77,223,208, 90,181,182, -172,252, 97,129,224, 65,134, 25, 63,238,185,130,168,253, 63,159,207,202,185, 28,137,236, 76,211,139,212, 33,175,192,104,149,169, -121,250,182, 6,122,179, 3, 22,171, 3,118,142,135,214,104, 71, 78,129, 21, 90,163, 13,122,147, 3, 35,123, 84, 45,245,123, 21, -248, 17, 63,138,162, 14,241, 60,223,151,231,249,238, 0,196,197,219,206,103, 54,117,168,200,144, 61,181, 61,109,218,180,175,230, -207,159, 31, 83,252,217,226,247,139, 63, 91,222,251, 37,190,239,243,229,151, 95, 54, 92,176, 96,193,188, 54,109,218,108,251,243, -207, 63, 19, 1,228,187,218,125, 40, 40,185, 51,135, 14, 29,170,232, 64,215,180,217,109, 18,119,153, 16,161, 53,170,226,221,175, -214,251,254,182, 96,116,142, 84, 44, 96,142, 30, 61,234,157,107, 85,130,166, 25,151,155, 40, 74,191, 58,109, 69, 34,241,225,197, -139, 23, 99,104,191, 14,178, 71, 26,187,254,246, 35, 83,182,193, 10,135,202, 47, 76, 60,103,222, 2,229,130,133,223,127,120,232, - 0, 87,160,207,190,251,125,233, 93,124, 45,174, 49, 84,137, 28, 44,138, 2,207,177,105,249,201, 87, 91, 0,192,203,228, 98,233, -205,118, 48, 69,185, 53, 20, 5, 24,205, 14, 48, 12,149, 83, 16,187,227,238,240,217,115,186,110,218,246,123, 6, 79,123,234, 12, -134, 36, 57,156,107, 14, 86, 26,179,149,133,197,206, 34,230,214,117,116,140,168,143,182, 45,234,194,104,102, 97,180, 56, 80,163, - 86, 56, 0,248,150,122,226, 24, 58,145,103,237,102,158,103,221,250,182,244,131,202, 83,140, 64, 47, 9, 36, 98, 1,236, 14,192, -100,229, 96,182,178, 72,206, 49, 65,103,146,161, 81,167,193,161, 62,129,215, 44, 89,201,178,125,121,143,174, 13, 42,215,156,178, - 44, 54,108,217, 85, 59, 35, 35,123,192,145,125,155, 37,106,173, 29,183,147, 13,200, 41,176, 0,140, 31,190,155,247,163,228,139, - 73, 99, 95,223,176,117,119, 74,183, 14,173, 83, 42,187,207, 70,117,236,166, 29, 59,119,253,220,183,239,235,178,152,203, 71,240, -224,230,169,185,134,156, 74,229,103,209, 77,154, 52,113,140, 29, 59, 86, 55,111,222,188,144, 3, 7, 14,212, 80,171,213, 55, 1, -216, 61, 61, 61,235,134,213,174,118,235,196,177,163,193,125, 94, 31, 44, 76,211,152,224, 33, 23,161,154, 74,142,139,231,143,219, -197, 98, 97,169,249, 38, 69,221,131,195,208,237,115, 28,184,152, 24, 25,147, 43, 61, 51,102,244,200,148, 19,231, 98,115, 87,108, - 60,241,159, 96,165,253,166,148, 83,175,184,214,162, 86,192,180,143, 71, 96,254,242, 77, 56,123, 61, 54,199, 64, 7,206,205,180, - 56,126, 47, 59,148, 14, 8, 24, 10,110, 50, 33, 12, 90,117, 97,252,141, 99, 97,175, 40, 76, 61,242,196,190, 77,116,158,206,142, - 84,141,153,202,200,211,129,229,120,120,202, 69,112,112, 60, 10,242, 52,212,230, 77, 27,113,245,234, 69, 26, 12,253, 62,128, 25, -229, 30, 80,202,217, 85,168,148, 10,157, 17, 33,153,243,167,157,229, 16, 94,187, 22, 86,175, 88,226,238,171,242, 71,251,142,174, -231, 70,187,249, 84,107,178,237,215, 21, 56,243,231,141,206,103,151,253,216, 82, 25,228,183,156,162,216, 69,224, 97,182,216, 88, - 20, 22,228, 67,108, 77, 69,171, 96, 53,188,229, 44,146,181,129,136,206,122,160,172,168,194,207,141,222,123,147,226, 95,159,190, -235, 96,212,252, 94, 61, 58, 35, 58, 89, 11,153, 88, 0,169,152,129, 84,204, 64, 72,177, 88,178,234,103,123,126,161,174,111,110, -204,126,205, 11, 92,159, 39,139, 90,191, 78,115,199,234,253, 54, 45,159,254,219,152,207, 23,246,138, 28, 56,138,138,190,122,250, - 43, 35,112,202,181,134, 30,239,210,123, 28,231,250, 51, 78,234,230,251,195,196, 47,230, 76,236,217,119, 48, 24, 70, 0,187,221, -142,221,219, 55,225,215, 31,191,187,111,213,231,142, 2,192, 89,115,152,177, 59, 54,173, 26,252,249,183, 75,168,134, 77, 90,181, - 62,157,249,252,114,180, 28, 67,253,242,206,232,113, 67,252,253,253,221,158, 68,180,120,132,133,215, 71,239,254,111,224,248,254, -189,184, 27,115, 27, 28,239, 52, 76, 28,199,163, 32, 63, 55,203, 97,183,110, 40,179,199, 67, 42,173,182,254,215,141,117,104,154, -122,188,128,252,164, 15,222,181,142,255,244,171,246,189,123,118,138, 17, 51,208, 38, 63,202,244,188,120,227, 94, 35, 78,168, 12, - 25, 61,101,137,200,108, 97, 81,104,180,227,200,186,178,189,142,212,171,106,155,234,205,123,143, 30,255,205,106,137,132,161,109, - 13,194, 66, 18, 59, 69, 52, 72,173, 26,228,171,155,181,224,199, 86, 23, 46,223,232,253,214,240,209,210,145,117,155, 83, 65, 62, - 50,183,119,135, 15,108,204, 58,108,239, 24,243, 82,203,156, 95, 80, 40,247, 42,168, 90,163,182,241, 73,196, 40,108, 15,197, 35, -244, 41,231, 65, 33,209,148, 29, 55, 8, 0, 2,131,170,154,133, 18,119, 93, 37, 34, 48, 60, 0, 44, 95,179,181,197,173,184,140, - 49, 75,151, 46,147, 95, 79,208,225,102, 66, 33, 36, 34, 26, 54, 59, 7,202,197,160, 54,199, 51,227,190,254,114,154,123,190,129, -197,153,219,106,196, 92, 59,205, 91,245,230,225,114,135,251, 32,168,220,222, 1, 80, 11, 64, 60, 69,241,191, 24,178, 3,246, 3, -103, 29,149,189,238, 57,206,217, 94,118,247,171, 25,202, 10, 36,189,133, 98, 69, 27,138,226, 27, 80, 60,188, 0, 62, 61,175,232, -153,234,170, 83, 51,100,199, 97,225,188,111,241,195,218,189,200,200, 53,195,131, 77,197,254,117,115, 48,121,254, 22,152, 44,101, -103, 53, 84,228, 71, 74, 51, 70,207, 26,174,226,223,139, 63, 55,127,254,252,190,207,156,155,190,101,156,179,231, 62, 87,252,253, - 5, 11, 22,204, 43,241,119,163,171, 38,235,177,209, 42,222,169, 10,204, 86,152, 95, 96,181, 63,247,239,219,227,149,175,183, 65, - 42, 98, 80,181, 70,109,204, 88,177,223,239,181, 22,190,208,216, 60,176,117,245,162, 60,179, 81,183,221,165,202, 66, 21,222, 90, -166, 84, 28,217,179,123, 47,106, 86, 85,137, 54,159,207, 75,186,145,104,122, 28,234,213,170, 83,196, 53,220,141,130, 65, 3, 7, -202, 79, 69,157,254, 84, 15,148,106,180, 24,138,169,178,102,227,110,149,155, 76, 8,138, 2,116, 38, 7,198,188,243,198,203, 63, -198,120,142, 25, 61,106, 36,168, 34,147,165,205,205,194, 87, 95,124, 96, 86,216, 31,220,125,148,252, 40,189,123,191,201,167,180, -122,202, 60,100,196, 7, 87,239,198,205,207, 55, 26, 95,108,145, 31,139,149,133,197,198, 33, 33, 33, 30,147, 70,246,128,144,161, -193, 48,156, 51, 89,218, 81,246,197,168,207,136,203, 67,128,232,205, 77,139, 63, 90, 19,228,175,242, 81, 42,100,188, 82, 46,161, - 26,212,173, 35,138,136,104, 43,174, 17,222, 88,116,254,158, 9,143,212, 38, 36,102, 20, 66,226,223, 84, 48,180,235,107,216,180, -108, 74,231,188, 71,215,104, 60,159,164,248, 20,191,159,185,212,111,237,170,165,146,236, 2, 27,238, 63,210, 35, 43,223,140,204, -124, 11,178,242,204, 80,202,132,232,216,127,172,228,240,254, 95,250,117,235,208,122,249,139,236,119, 98, 98,210,225,228,244,204, -193,141,155,181,194,166,223,126,237,224,233, 89,195,189,160, 32, 73,235,234,217,153, 51,103,142,120,193,130, 5,130, 21, 43, 86, -104, 35, 34, 34, 2,190,252,242,203, 94, 57, 57, 57, 87,170, 87,175, 30,126,124,207,134,168,166, 29, 7,180, 4,103,243,235,208, -169,139, 72,194, 9,112,226,208, 33,219,142,237,155,115, 77, 38,221,248,114, 13,135,220, 99, 78,182,158,130, 95,112,112,140, 82, -204,246, 16,208, 5,113,249,199, 38,110,204, 7,246,212,140,252,248,228,233,107,177,113, 45,174, 39,171,162,174, 63,204,201, 51, -218,194, 18,142, 77, 46,183,226,101, 40, 10, 66,134,134,155, 76, 0,186,168, 86, 85, 6, 53,126, 8,138,242, 43,142,156, 82,160, -138,126, 2, 20,133,140,252, 71, 55, 93,200,217,160,120,142, 7, 98,211, 12,208,155,157,161,249, 42,190,114,168,179,211,240,211, -242, 13,184,113,237, 42,122,190,214, 31, 43,215,108,198,152,119, 6,155, 43,106,253,208,116, 81, 68,171, 68, 52, 75, 41, 19, 0, -160, 80, 96,176, 99,247,133, 84,212, 10,165, 93,126, 48, 0,128,155, 82,142, 66,157, 9,180,200, 13,241,215,143,200,143,158,190, -252,229,244,217, 75,167,230,103,222,126,244,240,206,121,132,251, 22, 34, 52,216,134,152, 44,119, 92,203,173,129,240,218, 53, 65, -139,174,186,164,173,137,105,180,112, 63,189,187,111,139,166,245,219, 84, 83,121,194,100,101,139,162, 90, 12,126, 93,191, 17,201, - 73,105,163,115,239,238,191,241, 42, 28,173, 33, 39, 81, 45, 81,213,254,240,206,229, 83,137, 3,135,127,136,192,224,170, 77, 10, - 30,221,116, 57,109,193,149,247, 88, 23,141,150, 72,238,249,229,164,175,255, 51,177,103,159, 55,113,233,252, 41,220,140,137, 71, -235,214, 45,241,218,235, 67,161,211,230,213,221,185,113, 89, 15,135, 81,119, 92, 32,113, 76,108,213,182, 43,197,177, 44, 30,220, -143,142, 47, 77,203,148, 25,123,243, 98,102,172,251, 83,221, 83,190,117,155, 40, 61,188,111, 90,108, 44,210,211,211,240,199,159, -103,154,153, 50, 99,111, 86,230,120, 73, 68, 12, 78,220,200,129,173,104, 13,211,142,157,122, 88, 69,180,165,195,220,165,235, 35, - 50, 51, 50,105,133,187, 47,231, 29, 92, 79, 20, 40,177, 89,110, 37, 20,138,108,118, 14, 53,131, 20,229,106,250, 5,213,158, 55, -101,202,164,122,140, 72, 6,157,193, 98,205,204, 72, 15, 88,189,245,180,254,222,253, 59,193, 85, 84, 30,238,255, 89,246,139, 72, -107,166,144, 83,104, 65,158, 78, 75, 13, 31,247,121,208,218, 31,231,191, 93,158,209, 42, 37, 93, 36,244,240,137,243,117,189,220, - 68,148,222,236,224,114,181, 54,118,248,235, 47, 55,232,178,200,100,141, 93,186,100,153,252, 70,130, 14,183, 18, 10, 33, 21, 49, - 16,139,104, 88,237, 28, 92,188,157,232, 0, 85,192,248,182, 45, 26,225,248, 77, 13, 24,134,134, 73,151,111, 20, 32, 55,174, 69, -231,158,242,230,173, 34,208,165,115, 39, 60,140,139,173,122,232,192,238,110, 23,255, 56,155,229,176,133,125,100, 80,199,237,173, - 84, 96,193,104,100,236,226,128,119, 3,131,171,183, 27, 52,244, 93,143,106, 85,131, 41,149,175, 15, 28,188, 0, 99,223,121,195, -229, 59,223,105,204,129, 5,179,191,132,197, 98,133,159,167, 24, 60, 15,172, 95, 62, 3, 86,171, 21, 65, 62, 18, 20, 26,202, 94, - 77,174, 34, 63, 82, 86, 20,170, 82,185, 39, 37,204, 88,121,239, 83, 20,117,104,218,180,105, 95, 1,224,167, 77,155,246, 85,241, -246,252,249,243, 77, 0, 50, 42,232, 58, 92,253,148,209, 42,222,185,178,239,110, 81,184,175, 79,224,197, 19,199,143,121,236,187, -197,225,210,222,107,232,211, 58, 16, 34, 1, 13,185, 71, 16,110, 37, 21,226,240,158, 85, 5,251,183,253,146,110,177, 88,190,175, -184,175,185,118, 11,165, 92,113,252,183, 77,219, 57, 95, 31, 31,250,167, 19,234,132, 92,157,227,113,151, 86,220,229, 3,220,181, -227,171, 3,121, 80,199,164, 82,105,109,171,213,234, 85,209,137, 93,127, 34,165, 40,137,151,122, 21,117, 43, 40,134, 97, 55,109, -222, 4, 95,119, 49, 44,118, 14,211,166,126, 98, 26,217, 83, 89, 48,252,173,161, 93,187,244,158, 24, 37, 84,212, 57,213,182, 89, - 29,190,105,211,166, 5, 12,195,184,148, 74,161, 82,169,102,208, 52, 61, 76, 44, 22,187, 89,173, 86,157,149, 51,203, 13,102, 43, -204, 54,192,104, 52, 67, 40,114,154, 69, 33, 67,193,100,182,194,104,178,150,127, 99,100, 69, 95, 0, 16,166, 45, 17, 83, 58,117, -175,166,120,203,206,253,159,188,249,214,144,233,193, 77, 94, 87, 38,101, 22, 66, 68,217,208,178, 94, 32, 78, 31,219,203,167, 37, -199, 77,170,200,100, 1, 64,142, 58, 47,196,207,207, 31, 55, 18,245, 72,207, 53, 33,171,200,100,101,230, 91,160, 51,233,208,184, - 90, 16, 10, 10, 11, 67, 94,248,248, 2,123,143, 31, 63, 62,184,247,128, 33,152, 56,117,102,251,117,171, 22,221, 86,136,133,239, - 25,178, 31,156,113,197,104, 69, 71, 71,231,125,241,197, 23,181,214,172, 89, 67,191,253,246,219,166, 70,141, 26, 73, 71,140, 24, -209,126,227,198,141, 82,185, 92,106,186,117,254,192,244,247, 63,158, 54, 96,245, 15,115,154,228,231,231, 83, 14,187,253,168, 45, - 63,127,154,190, 2, 51,151,122,224,171,251,223, 37,216, 70,245,232,224,119,192, 91, 78, 55,144,240,214,161,168, 55, 99, 59,238, -205,176, 37, 28, 91,161,147, 13, 94,252,113, 70, 1,247,181,153, 86,205,173,200,100, 1, 0,205, 80,176, 58, 88,184,201,132,160, -105,186,216,196, 7,254,186,253,168,220,207, 67, 12, 33, 67, 67,192, 80,208, 26,237,208,104,109,248,240, 93, 87,103, 8,225, 57, - 7,203,195,100,117,192, 88,212, 58,212,105, 53,248,114,234,103,120,173,223, 64,188, 63,254, 51,228,155,128,107,137, 58,216,236, -246, 10,111, 10,154,162, 97,180, 56,240, 94,207,106,200,211,219, 96, 48, 57, 96,117,112,144,139, 5, 16, 10,104, 40,164, 2,184, -203,133, 0,207,139,138, 43, 19,161, 80,104,182,219,237,155,202,105,209,163, 70,136, 63, 76,118, 26,173,134, 44, 66,247, 54, 97, -136,185,176, 91,112,246,210,157,208, 79,167,126,141, 79,198,244,195,174,251,181,224,173,170, 6,165, 66, 6, 59, 79, 3,224, 93, - 76,216,155,193,209,182,129,195,126, 94,179, 62,118,214,183,211,164, 5, 6, 10, 18, 17,131,168, 83, 39,113,241,242,181, 31, 52, -119,247,111,194, 43, 68,200,211,254,238,238,238,144,138, 25, 88,109, 22,171,235,169, 11, 60,120,160,153, 66, 21,246,115, 81,139, -191, 25,203,161,148,247, 42, 54, 90, 2,169,251,180,143,166,206,154,215,179,207,155, 56,113,104, 23,118,238,218,206,182,137, 28, -205,108,254,117, 21,218,119,239,143,246, 61,135,224,232,222,141,159, 25, 56,170,254,216,137,211,103,119,236,218, 27, 39, 14,239, - 66,118, 86,218, 98, 87,203,203, 8,169,137, 93,123,244,131,217,202,162, 67,183,190, 56,118,112,239,199, 40, 26,100,225,250, 67, -236,153,250, 25,180,227,179, 73, 19,133, 57, 5, 86,161, 90,107, 69,154,218,136,164,108, 35,246,111, 91,199,187, 94, 95, 88, 91, -118,108, 92, 69, 56,118, 97, 84,106, 72,149, 64,139,208, 98,146,197,197, 39,212,125,255,221,145,194,208,218,117,233,156, 66, 11, -212,133, 22,104, 10, 45,208,155, 29,168, 93,165, 14,109,119, 80,109, 42,123,158,125, 61,196,194,149, 7, 19,225,174, 16,162,109, -221, 23, 31,104,203,113,220, 19,147,181,212,105,178,110, 39, 22, 66, 34, 98, 32, 17,209,144,136, 24, 56, 88,222,165,134,139, 76, - 21,214,251,195,143, 62, 8,178, 58,128,220, 66, 43, 4, 12, 5,149,175,151,162,101,147, 97, 88,191,232, 99, 0,192,152, 47,126, -194,251,239,141, 64,189, 6,141, 80,144,159, 31, 48,236,205,222, 75, 1,236,117,181,172, 71, 78,156,169,122,226,220,141, 47, 62, -156,242,157,242,173,126, 93,152,155, 9,133,200,204,179, 32, 62, 78, 87,169,200, 27, 0, 56, 88, 14, 60,120,108,216,126, 8, 50, -177, 0,234, 66, 27,120,158,199,156, 21, 59,224, 38, 19, 34, 51,223,217,221, 95, 30,229,250,145,114, 34, 82,149,136, 54,246,133, - 51,151,203,207,213,136,214,252,249,243, 99,230,207,159, 95,106,132,172,132,201,122,177, 69,165, 69, 34, 69, 93,119, 31,223, 75, - 39,142, 29,113,219,123,139,197,233, 91,185,120,179, 67, 21,232,243, 30,225,251,169,111,229, 81,224,173, 52,195, 20, 88, 76,198, - 61, 38,147, 97, 46, 0, 91,185, 23, 77, 64, 88, 51,133, 84,121,114,229,234,223, 28,190, 42, 21, 54,157,207, 75,203, 55, 56,236, - 79,186,173,236,212,181,227,171, 67, 29,156, 61,210,156,253,240,106, 69, 45,113,142,135,104,254,170,253, 0,120,112, 28, 7,158, -227, 32,148, 42, 21,190, 53, 35,178,139, 42, 58,169,128,166,204, 37,107, 0,158,115,164,105, 18,203, 15,131, 82, 0, 60,228, 66, -108, 63,155, 14, 0,217,140,238,250,189,225,111, 57,187, 11,205, 86,169,182, 65,173, 90,124,203,150, 45, 11,100, 50,151,166,191, - 98,252,253,253,175, 76,159, 62,189,238,251,239,191, 47, 17,139,197,112, 56, 28,222,191,172, 94,205,173,158, 59, 6,131, 62, 94, - 9,145, 88, 2,147,217, 6,161, 80,128,252, 66, 61, 10,180, 70,232,140,246,202, 95, 65, 9, 9, 86, 53,176,112,223, 94,241,192, - 94,202,198,173,196,180, 8,205,195, 3,113,250,248, 62,254,210,177,245, 99, 76, 57,113,191,185,120, 33, 66,111,182, 35, 35,215, -140,244, 92, 51,178,242,205,200,202,179, 32, 43,223, 12,138,162, 96,182, 58, 94,234,193,101,200,137,221,185,233,183,181,253, 45, - 54, 12,237,216,115, 32, 62,251,110,101,181, 77, 63, 47, 56,153,200,211,237, 92, 76,180,101, 99, 98, 98,146,223,125,247,221, 38, - 91,183,110,101, 26, 54,108,104,186,119,239,158,188,200, 68,218,148, 74,185,108,221,143,243,143,183,106,213,106, 91,122,220,253, -168,162,254,244, 10, 43,246,106,157, 70, 73,100,182, 27, 99,171, 42,218,246,170, 25, 32, 71, 85,133,174, 87, 93,229,173,239,115, -187,126, 50, 79, 29,245, 67, 78,166,197,241,187,218,196, 52, 77,215, 11, 93,202,193,179, 91,204, 41,131,222, 28, 10,134,162, 97, - 51, 27, 83,138, 47, 46,149,135, 24, 51, 54,223,135, 82, 42,132,155, 76, 0,165, 76,136,246,245,189, 81,137,250,140,183,179, 28, -140, 22, 22, 38,139, 3,102,171, 3,190, 33, 94, 88,179,105, 39, 30,229,152,176,255,170, 6,177, 41, 58,212,169,162, 0,207, 87, - 92, 77,114,172,221,208,239,141,183,221, 24,154, 2, 67, 83,116,253,186, 97,200,211,219, 32, 18,208, 16, 73,101, 80, 72, 4,112, -151, 9, 33, 18, 9,145,147,147, 3,139,197,130,170, 85,171, 74,203,183,130, 60,220,148, 50,212, 9, 13,130,205,238,192,145,115, -119, 49,119,210, 32,244,232,216, 2,148, 80,137,251,150,102,112,243,118, 3, 71,211,176, 57, 56, 88,109, 44, 0,218, 92,150, 94, - 72, 72, 72, 87,133, 66, 45,234, 42,153, 0, 0, 32, 0, 73, 68, 65, 84,161, 48, 26,141,186, 71,143, 30,157,201,138,221,251,136, -101, 6,140, 61,118, 34,106, 83,223,215,122,224,198,237, 24,236,218,123,224,188,198,167,112, 74,241,119, 26, 52,104, 16,225,235, -235,171,204,205,205,213, 70, 71, 71, 95,121,209,118, 1, 79,211,159,182,105,223, 25,250,130, 28,100,167, 38,185,220,138,174, 87, -205, 13,223,204, 95,217, 60, 60, 44,188, 57,203, 59,141, 87,253,170,110,152,252,221,242,230,181,234,132, 53, 47, 30, 16, 82,175, -106,249,211,178, 9,228,110, 61,223,121,255,179,249,253,223, 28,133,168, 19, 7,176,100,238,212, 77, 10, 15,191,122,222, 94, 30, - 77, 27, 70,244,196,249,147, 7, 32,117, 11,128,151, 79, 64,251,183,223,251,168,251,155,111,143,195,197,243, 39,241,195,130,175, - 54,178, 22,221, 22, 87,202,170, 80,133,250, 53,105,214,106,184,155,183, 63, 10, 10,117,112,243, 82,161, 94,227,150,195,239,222, -178,124, 97,200, 73, 84,191,176,233,224,121, 88,108, 60,242,245, 54,164,170, 77, 72,206,114, 26, 45,142,171, 68, 78, 16,203, 81, - 74,169, 64,224,109,127, 88,245,206,201, 40,190, 90,136, 63,181,112,246, 84,198, 6, 41,212, 5, 78,147,165,214, 90,161, 46,180, - 66,111,182,195, 91, 33, 0,199,114,149,110,117,231,235,109,112,147, 11,225, 33, 23,185, 28,101, 44,141, 85,191,110, 15,191, 21, -151,241,250,146, 37,203,228, 55, 19, 75,152, 44,161, 51,154, 37, 17, 49, 96, 57, 14,112,225,142, 23, 10,132, 19, 7,244,238,142, - 84,141,201, 57,106,153,166, 80,167, 81, 43,248,202, 56,116, 27, 50, 13, 0,208,175,183, 51,181, 45, 49,211,128,131,151,212,192, -211,137,221,229,215,197, 38, 19,179,122,243,225, 79,119,238,216,230, 97,102, 5,248,229,104, 50,140, 22, 7,164, 34, 6, 18, 17, - 3,153,136,121, 42, 31,187, 98,163,229,204,185,123,164,177,195,104, 54, 67,107,178,131, 7,112,229,161, 30, 38,171, 3,133, 6, - 59, 34,234,122,189, 92, 32,132,162, 14,243, 60,223,231, 89, 67,244,172, 89, 42, 17,145, 42, 77,227,106, 73,141,226,207,151,101, -228, 74,230,108, 1,168,212, 8, 46,193,179,206,177,228,182, 72,225, 85,207,195,205,227,210,177,163,135,148,123,111,113, 56,115, -219,105,178,236, 38, 13, 22,127, 49, 44, 77, 91,160,233, 2, 32,193,213,127, 38,247,173,215, 88, 42,150, 68,253,103,217, 47, 54, -149,127, 48,183,231, 82, 65, 78,161,145,125,202, 77,176, 22, 11,205,115,188,200,156,253,208,165, 62, 4,154,166,108,223,125, 60, - 16, 28,207, 99,198,178,157,152, 55,101, 8,148,178,183,229, 20, 69,201, 13,102, 7, 38,205, 92,139,197,223,140,118,147, 75, 4, -160, 40,103, 78,212, 59, 67, 7,186,118, 1,154, 29,136,191,188, 85,175, 75, 60,116,175,100,119, 97,235,246,175, 93,107,221,186, -117,129,151,151, 23,100, 50,217,147, 72, 69, 25,248,251,251,127,243,221,119,223,133,143, 31, 63,254,241,100,159, 2,129, 0, 31, -126,240, 1,205,178, 60,142, 30, 93, 15,191,234,205,112,224,247, 75,136,236,218, 18,122,163, 25,121, 5, 58,112, 96, 94,248, 66, -212, 21,104,162,178,146,239,180,106,215,165, 31,206, 28,223,199, 95, 58,186,110, 76,101,230,232,241,242,246, 74,189,126, 39,190, - 30, 69,121, 59, 35, 90, 69, 38,203,106,231, 80,205, 95,142,212,228,120,120,122,120,164,186,170, 39,243, 11, 31, 64,209,252,120, - 10,252,122, 67,246,131,157, 0,120, 67,230,189, 97, 59,183,172,190, 29, 19,125,115,110,223,225, 19, 5, 61,223,252,128,249,121, -254, 71, 95, 1,112,117,226, 61, 91,108,108,236,221,209,163, 71,183,189,120,241, 34, 11,192, 72, 81,148,157, 97, 24,185,213,106, - 21,117,233,210,165,240,254,253,251,103, 81,122,210,226, 83,180,127,119,167, 47, 37,209,189, 38,230,108,195,170,185,233,122,116, -233,208, 6,109, 26,132, 32,181, 67, 27, 0,152,152,162, 87,134,155,107,173,221,110,119,200,142,252,252,235,193,121, 99,134,116, -159,180, 73, 48, 99, 73,230,161, 25,229, 38,162,166,222, 59,219,171, 52, 27, 47, 96,104,184,201,132, 80,202, 4,112,147, 9,225, - 38, 21,194,238,224, 43,211,114,228,237, 14,206, 25,209,178, 58,160, 55, 57, 16,117, 51, 27, 89,133, 86, 20,232,108, 48,217, 88, -240,224,157,173, 81, 23,106,115,245,195, 63, 60,139,159,164,158, 85,155, 21,174, 94,177,200,125,247,133,180,199, 35,250, 60,228, - 98,184,201,157,163,177,207,157, 59, 7, 31,159,138, 91,251, 28,199, 97,215,177, 43, 88,178, 33, 10,199,214,127, 14,169,136, 65, -227, 1, 51, 49,234,245,214,224,120, 14,241,177, 49,217,117,234, 55,241,167,105, 25,104,138,130,197,206, 1,224,203, 60,158, 86, -171,213,231,209,163, 71,218,218,181,107, 7, 4, 5, 5,189,201, 48, 12, 15,221, 77,203,190,109,121,198, 83,135,182,200, 13, 38, - 11, 43,119, 20,174,175,157,105,234,131,218,181, 65, 81, 20,239,238,238, 46,138,138,138,210, 55,106,212,200,239, 5,111, 37, 90, -166, 10,251,225,253, 9,159,190, 89,171,102, 77,236,220,178, 30, 60, 79,237,118,245,203,155, 15, 94,196,236, 47,159, 30, 97, 56, -249,187,229,205, 23,207,156,248,212,123, 19,190, 92, 82,238,168, 67,153, 68, 57,101,208,176,177,184,118,229, 79,124, 63,115,242, - 54,139, 62,111,148,221, 97, 31,156,151,153,184, 45,180,126,107,240, 54, 29, 78,236, 88,132, 33, 35,198, 72,122,246,125, 19, 23, -207,159,196,188,175, 38,108, 54, 22,228,188, 11, 23,147,156, 57, 94, 56,190, 75,175,215,133, 38,139, 13,203, 23,126,139,113, 83, -230, 34,162,107, 63, 97,244,205, 75,227, 1,204,114, 57, 29,194,198,162, 75, 35, 95,167,121,182,115, 56,144,200, 8, 74,187, 2, - 5, 12, 69, 55,173,233, 9,147,213, 1,109, 5,141, 74,129, 72,152, 85, 80,168,173,254,227,188, 79, 25,131,217, 1,117,161, 21, - 57,133, 22,104, 10,158, 24, 44, 77,161, 5,234, 66, 43,132, 2, 10,113, 9, 41,160,133,130, 74,231,231,229,235,237,104, 21,230, -229,188, 71, 95,176,119,196, 46,112,111,125,236,236,173, 65, 75,150, 44,149,222, 74,210,225,118,162,182, 40,146,197, 64, 34,164, - 33, 46,250,157,229,156,185,145,229,225,238, 87, 51,116,228, 59,111,119,115, 87,202,144,241, 32, 7, 2,198, 57, 69,140,135, 42, - 4, 30, 18, 51, 62,154, 48, 22,190, 62,158,120,164,177,224,135,189,113,184,125,247, 33, 56, 83,229,118,123,249, 47,219, 34,223, -255,112,178, 39, 45, 20, 99,227,241, 36,103, 57, 25, 22,247, 47, 29, 52,103,196,223, 49,232,181,185, 60,120,214,197, 28,100,138, -119,176,206,203,109,222,140,105,216,182,225, 39, 28,191,158,243,248, 10,188,176,123, 49, 62,253,114, 14, 52, 90, 43, 74,187, 46, -203,243, 35, 0,212, 37, 34, 81,207,109,151, 48, 71,165,109, 83, 69,219,214, 50, 52,172,207,152, 43,235, 51,239, 91,159,209, 43, -109,238,191,213, 21,118, 29, 62,103,138, 60,253, 26,202,165,138, 63,143, 30, 61,168,216,119,155,127,108,178,108, 70, 13, 63,119, - 98,191, 52,109,129,186,103,165, 76,150, 95,157,134, 18,185,228,236,244, 57, 63, 88,252,131,171, 59,142,220,212,230,234,204,172, -227,249, 28, 4, 5,171,240,240, 51, 11,196,146, 37, 66,147,245, 91,141,230,158,161,162,200, 19,199,243, 56,116, 57, 11, 60,239, -108, 34,237, 56,151,142,162,150, 57, 88,206,217,173,242,251,205, 28, 8,138,242, 80, 92, 13,127,175,250,229, 39,109,159, 70,133, -134,225,243,102, 60,238, 46,140,104,226,140,100,185,187,187,195,211,211, 19, 74,165, 18, 21,117, 29, 82, 20,245,206,251,239,191, -255, 92,235, 63, 39, 39, 7,221,187,117,193,138,159,214,160, 73,183,145,248,253,143,227,176,217, 57, 52,174, 95, 19,213,131,188, -144,154,173,123,161, 27, 93,225, 31,254, 97,171, 46,175,127,213,190,107, 63, 68, 29,219,195, 95, 58,246,235,216,202, 78,132,216, -167,123,219,131,179,103,207, 8,157, 62,247, 71,137,155, 84,128,123,122, 43,104,138, 66, 53,127, 57,124, 20, 52,206,236,219,104, - 30,210,175,173,203,147,227,133,132, 4,111, 90,188, 98,181, 98,241,130,153, 93,174, 93,167,162,244, 25,113,121, 0, 96,204,142, - 93,120, 31,184, 91,229,207, 19, 71,154,116, 26, 8,255,160,154, 61, 18,179,239,187,108, 54, 0, 24, 19, 18, 18, 18,167, 79,159, - 30,190, 96,193, 2,158, 97, 24, 14,128,100,217,178,101,198, 7, 15, 30,220,132,115,104, 46, 42,122,216,116,235,209, 96,146, 82, -204, 70,120,203,233, 6, 53, 3,228,104,211,192,217, 43, 58,164, 79,123,132, 84,173,138,132, 44, 99,211, 60, 35, 39,212, 91,153, -154, 43,127,185,125,181,134, 47, 51,198, 97,178,222, 5,176,191,178,231,135,194,147, 4,249,226,104,150,155, 76, 8,206,121,173, - 84,202,104, 89,108, 44, 76, 22, 22, 38,171, 3, 6, 43, 11,163,149, 5,199, 59,239, 9,138,162, 96,115,112,112,169,217,252,204, -181,239,238,237,139,154, 53, 40,184,203,157,101,115, 47,154,238,129, 2,224,227,227, 3,149, 74,229, 82, 84,212,106,115,222,226, - 86, 59,247,184, 91,223,106,115,128,231,121,196,197,197,126,158,156,152, 56,160,118,157,218, 29,235, 55,110,226, 45,151,208, 0, - 80,166,209, 50, 26,141,172,155,155,155,202,219,219,155, 78, 79, 79,127,108,158,107, 55,237,226,216,187,103, 55, 6, 13, 26,168, -191,119,229,214,227, 33,238, 38,147,137,106,215,174,157,123, 72, 72, 8,109,177, 88,180,149, 61, 77, 10,191,176,215,189,124,188, -231,190,243,238,184,176, 46,221, 35,113,250,212, 9,236,223,179,245, 55,163, 58,238,132,171, 34,225,225,117,159, 27,117, 88,171, - 78,216,115,163, 14,171,135,214, 41,215,104,213,111,220,178, 53, 79, 9,112,252,208, 14,222, 76,219, 38, 0,224, 88,179,110,199, -246, 85,223,204, 26, 54,254,203, 90,189,251, 15,195, 59, 35, 70, 65, 32, 96,112,230,247,131, 88, 60,243,179,195,250,194,156,145, -174,164, 9, 56, 67,111,245, 68,193,178,144, 79,170,214,106,136,235,151,206, 35, 62, 46, 58,230,214,213,139, 13,106, 55,138,128, - 95, 80,181, 79, 82,124,153, 5,184,119,207, 86,145,140,213,108, 78, 25, 53,114, 4, 74,142, 58,108,211, 44,220,135,122,246, 6, - 0, 96,212,229,216,214, 45,154,244,160,120,212, 33,103,179,166,148,165, 91,152,175,222,117,230,143,203, 83, 6,244,137,164, 53, - 90,171, 51,130, 85,104, 45,122, 89,160, 41,254, 93,107, 65,157, 32, 37, 98, 99,174,115,230, 66,205,238, 74,222,151,230, 81,131, -123,221, 45,190,118, 57,142, 7, 5,152, 43,221, 45, 37,116, 31,187,240,251, 37,210, 91,137,122,220, 78,210, 58,187, 10,133,140, -211, 96, 9,233,199,166,203, 57,154,189,130,232, 16,197,204,123,111,228, 80,104,180, 54,112, 28, 32, 96,232,162,151, 8,143,116, - 20, 82,117, 70,104,242,213, 72, 76, 78, 65, 65, 86, 60,104,154,134,111, 80,152,203, 51, 73,179,188, 56,208,104,229, 27,189,217, -167,163, 96,207,159,153,144, 75, 4,176,232,178,113,116,251, 34,181, 69,175,157,107, 50,234,247,184, 50,159,227,147, 20, 4, 74, -173,213,155,253, 37, 66, 6, 59, 55,252,136,193,163, 38, 60, 85,251,126,254,245,108,128,166,144,151,175, 3, 69, 81,234,202,213, - 75,212,213,242,182, 95, 48, 50,246,210, 26,165,152,173,231, 27, 10,101,183, 70,249,163, 39,142, 29, 84, 92, 72,150,224, 74,108, -102,145,201, 82,115,115, 62,238,147,166, 43,204,235, 5, 32,174,114,237, 66,186,215,144,247,166,196,212, 12,171,111, 57, 29,173, - 79, 42, 48,216,203,204,115,104,243,230,244,152,107,135, 87,244, 46,180, 39,124,160, 8,172,207,114, 14,199, 66,147, 58,110,102, - 25, 93,135,226,153, 63,236,124,220,109,248,197,130,141,206,223, 89, 22, 44,207,129,231,128,143,190, 89, 5, 7,199,130, 99, 89, -112, 44, 15, 59,203,203, 43, 42,174, 42,168,250,158,252,251, 59,234, 14,159,245,124,119,161,167,167, 39,124,124,124,224,227,227, - 3,119,119,247, 10,141,150, 80, 40, 84, 10, 4, 79, 31,234,148,148, 20, 36, 39, 39,195,221,221, 29, 60,103,135,213, 14, 52,140, -232,137, 59,241,209, 56,121,225, 38,120,142,133, 66, 89,249, 85, 94, 20,254,225, 31,180,236, 60,224,199,174,253, 71,227,247, 61, -191,240, 87,207, 29, 28,103,202,137, 91,235,114,132,158,101, 41,187,221,142, 62, 61, 59,167,220,136,121,120,236,235, 41,227, 35, -219,246, 29, 39,105, 19, 30, 12,179,149, 69, 90,114, 60,206,236,251,213, 28, 22, 26,120,188, 91,135,214, 41,118,187, 29, 44,203, - 86,248, 32, 55, 91,109, 26, 70, 40, 83, 12, 29, 58, 92,120,245,202,149,221, 10,191, 58, 59, 89,138,190, 69,241, 92, 99,138,231, - 7, 53,110, 92, 15, 54, 59, 7,163, 81,155, 95,217,125,214,233,116,137,235,215,175, 15, 29, 57,114,164,188,126,253,250,194,248, -248,120, 44, 94,188, 56, 87,167,211, 37,186,170,113,226, 92,236, 50, 1,149,255,160, 56,162,245,168,125, 27, 12,237,219, 30,219, - 14, 95,192,153,243, 23,145,162, 87,222,212, 59, 4,251, 82, 83, 50, 44, 13,188,181,187,251,183,169,206,236,220,144,191, 59,166, -243,180,183,120, 94,114, 66,115,118,134,193,245,155, 27,208,153,236,112,151, 59,231,123, 42,142,108, 49, 20,229,178, 35,162,128, -196,243, 23,175, 55,108, 81,167, 62,110, 36, 22, 34,167,192, 2,147,197, 1,142,227,193,129,135,143,155, 24, 82, 17,141, 71,201, -137,224,120, 91, 82, 37, 31, 21,234, 78, 29, 59, 9, 0, 10, 20,197, 11,132, 2, 1,120, 56,231, 87,148,201,100,122,149, 74,229, - 82, 68,203,230,112, 96, 80,100,107, 68,180,108,140, 1,227,156,115,102,158,250,109, 26,188,148, 66,108,219,180, 22,169,231,150, -109, 10,109, 51,254, 68,244,157,152, 55, 98,110,252, 57,252,181,230,178,166, 1,130, 12, 81, 89, 97, 82,131,193,176, 27,128, 88, - 36, 18, 69,118,236,216,209,123,247,238,221, 5,190,190,190,156, 88, 36, 82,247,239,215,151, 19,138, 68,121,197,159,253,227,143, - 63,132,227,198,141,115,203,207,207,127,148,157,157,125, 17,128,189,252,134, 96,120,119,208,216, 10,138,146, 42,101,242,148, 26, - 53,106, 6,181,140,104,237,241,250,160,193,144,136, 37,248,253,196, 49, 44, 95,186, 96,135, 62,243,222,123,149, 57,146,175,106, -212, 97,218,163,164, 68,163,201,210,168, 97,139,206,212,249, 19,251, 38,218,224,187,148,145,216, 22,117, 31, 52,161, 86, 98,134, - 30,203,231,127, 14, 47, 15, 5,146,226,239,155, 30,220,187,179,202,110,214,126,238,178,201, 2, 32,207,101,223,104, 51, 34,210, -203, 98, 99,113, 46,234,176,153,115,112,145, 23,207, 30,137,175, 18,214, 82,218,176,101, 55, 47,205,254,181,131,140,192,182,138, -116,210,239, 63, 31,193,229,173, 5, 73,167,162, 78,122,248, 87,107,192, 80,160, 96,179,152,161, 78,184,234, 48,102,223,215,106, -211,163, 93, 26,133,155,155,138,111,190,252,238, 63, 31,180,108,209, 66,193, 67,250, 84, 4,171,216, 96,105,180, 86,248,186,137, - 97,210,170,241,224,234, 49,179, 81,205,148, 59,223,153,195,106,144,107,114,178,197, 79,210, 25,226, 34,202,251,188, 38, 39, 91, -236,176, 26,228, 21, 63,234, 24,184, 43,196,184,147,148,254, 56,241, 93, 34,116,230,102,137,133,204,227, 60,173,226,186,160, 2, - 58,139,164,158, 72,207, 53,131, 2, 15,142,117,192, 97,183, 66,167,213, 34, 61, 35, 11,217, 89,217,208,233, 10, 32, 87,122,161, - 97,211, 86,112, 83, 72,113,235,204, 14,240, 60,239,210,188,134,118, 74, 24,222, 50,162,131, 36, 58,217,153,139, 37, 21,242, 56, -184,117, 65,174, 94,155,211, 65,159,249,224, 65,101,235, 98, 7,203,158,188,125,247, 65,131, 42,129, 53,168,155,241,133,216,180, -102, 5,172, 69,145, 77,187,157, 69,244, 35, 3, 50,243,140,120,148,112,143,231, 88,246, 36,254, 71, 16,148, 29, 0,132,160,113, -195,122,232,249,246,235,248,233,167, 85, 72, 72, 76,230,230, 78,236,253, 72,175, 43,120,173, 18, 38,171, 59,138,230,218, 48,102, -199, 46, 52,121,181, 76, 59,112, 35,143, 54, 89,249,114, 19,124,164,126,213,208,225,189,197,199, 77,186, 60, 49,107, 49, 10, 14, -110,122,111,107,105,154, 78, 7, 13,235,220,201, 67,160,148, 9, 64, 81, 20,138,187, 11, 87,206, 30, 11,185,196,217,183,108,178, - 56,240,246,164, 37,216,180,228, 51,240, 0,134, 13,190, 96, 44,171,156,112,174, 93,248, 81, 32,174, 84, 73, 73,206, 73,239,222, -111,242, 41,179, 77, 98,233, 59,112,228,181, 22, 45, 90, 20,200,100, 50,200,100, 50,184,187,187,195,203,203, 11,158,158,158, 21, -238,187,221,110,215, 91,173, 86, 31,177, 88, 12,142,227,144,148,148,132,164,164, 36, 20, 22, 22, 66,173, 86,195,160,215, 58,174, -156,218, 41,104,216,166, 55,130,106, 54, 66,181, 58, 77, 32,100, 40, 8, 4, 52,206, 28, 88, 83, 86, 57, 75, 55, 89,157,250,175, -236, 54,224,125,252,190,103, 53,127,245,220,193,241,166,156,184, 53,174,158,163,162,238,158, 91,131, 6, 13,106, 52,110,220, 56, -209,119, 83,198, 29, 63,124,226, 76,220,206, 67,171,251,229,231, 23,132,240, 60, 15, 79, 15,143,212, 33,253,218, 30,236,210,174, -101,202,169, 83,167,184,173, 91,183, 90, 40,138,186, 83,158,166,179,146,202,249,237,212,201,168, 25, 29, 58,117,198,218, 13, 91, - 59,197,220,189,215, 41, 62,254, 1, 66,170,213, 68,141,208, 58, 48, 82, 94,136, 58,123, 30,250,130,156,223, 92, 41,231, 51, 81, - 45, 42, 63, 63,255,207, 33, 67,134,244,188,112,225, 2, 61,100,200, 16,163, 70,163,249,163, 68, 20,139,175, 72,243,226,207, 3, -213, 0,126,171,214,105,212,142,116, 91,193, 39, 0, 22, 84,173, 86, 21,103,206, 95,196,197, 11,151, 87,105,228, 85,103,190,247, -246,187, 99,171,247,103,222,239,223,166, 58,163,242,146, 99,203,234,197,204,129,139,201, 75,146,115,217,181, 11,206,206,152,237, -202, 57,122,252,224,208,217,208,174,158, 55,236, 44, 15,142,119, 86,184,110, 82, 97, 89, 21,239,115,154, 2,171,228,189,241,227, -198,197, 55,108,220,244,211,183,223, 29, 47,106, 90, 51, 4, 87, 30, 22, 0, 20, 5,239, 0, 5, 50, 51, 51,113,110,215,106, 71, -126,250,253, 85, 12,195,205,170,196,241, 68,126,202,205,218, 37, 54,199,106, 52, 26,156, 57,115, 6,197, 6,203,207,207,175, 44, -163,245,148,102,110,118,198, 31,179,191,255,165,221,152,119, 6,162,111,231, 6, 56,123, 53, 30,214,162,249,154,138,135,146, 39, - 94,252, 89,252,201,144,154,214, 15, 6,133,105, 77,118,113,242, 55, 73,133,231,224, 92,131,149, 43,163,156,214,188,188,188, 3, -177,177,177,237,155, 52,105, 82,253,200,145, 35,121, 49,151,143, 79, 44, 89,136,201,147, 39, 43,127,250,233, 39, 57,207,243,127, - 88,173,214, 4,151,246,157,198,150,235,215,174,249,216,236, 28,206, 95,190, 85,175, 91,187,166,224,120,224,234,213,171, 88,187, -110,173,249,206,237,155,139, 12,217, 1,179,202, 49, 47,165, 30, 79,246,229, 70, 29, 62,214,204, 76, 79, 94,244,251,225, 93,155, - 90,118,234,135,225, 31,205,154,117,230,240,214, 25,205, 59,244,165,235,181,236,137,235, 23,163,112,242,200,177,255,216,244,121, - 51, 80,113,238, 72,169,229,148,200,228, 31,215,111,222, 9,143, 82,146,145,244, 32,250, 55,115,222,195,140,148,120,230,183,140, -180,148,241,161, 13,218,225,194,241,109, 19,203, 49, 90,229, 94,243, 33,126,178,213, 71, 14, 29, 24,154,150,246,115,128,193,100, -150,240, 60,111,150,136, 5, 89, 74, 90,183, 93,235,114, 57,239,217,212, 25,213, 7, 13,126,123,252,225,229,203,151, 10,253, 61, -229,200,202, 55, 67,107,178, 65,103,180,129,166, 40,212, 14, 82,192,168,203,195,217, 93,223,219,173,250,252, 33, 64,188,173, 44, - 77,133, 42,124, 78,254,195,168,143, 38, 79, 56, 13,177, 71, 72, 80,141,174, 95,150, 27,173,211,165,223,236, 55,121,194,193,112, -158,231,187, 41, 84,225, 58, 67, 78,236,244,178,246,157,162,156,247,247,240, 46, 33,176, 57,156,243,143, 57, 56,128,229,184,162, - 40, 31,192, 63,238,207,167, 42,216,119,138,219,126,248, 15,100,100, 23,192,100,181,195, 98,117,192,102,103, 65, 51, 12, 60,189, - 60, 81,167, 70, 51,120,120,186, 35, 59, 43, 3, 23, 79, 29, 64,220,237,179,127, 80, 60,102,154,212, 15, 78,185,114,142, 68, 50, -207,240,192,160, 0, 58, 83,107,133, 76,204,224,230,217, 35, 54,187,213,178,200, 69,147,245,156,102, 65,110,222,146, 79,167, 76, - 29,246,235,250, 13, 1,141, 66,221,145,166, 49, 33, 77,109,134,206,108, 47, 50, 98, 28, 44,122, 13,110, 71,109,200, 98,205,186, - 37,248, 31,161, 76,163,229,176,153,117,187,143, 93,241,153, 54,227,123,230, 97,124,130,125,206, 39,125,210, 76,122,109,239, 74, - 71,178, 74,240,235,135,161,219,254,138,157,120,174,187,144,231,192,241, 60, 14, 94,206,122,220, 93,200, 21,101, 94,222,136, 47, -127, 25,193,146,107, 23,118,238, 61,241,247,219,177,186,205, 38, 83,182,199,253,135,139,242, 1,128, 97,152,199,175,226,220, 44, -179,217,108,173,160, 11,101,227,154, 53,107,190, 24, 63,126,188, 36, 53, 53, 21,241,241,241, 40, 40, 40,128, 84, 42,197,177, 99, -199,236,224, 28,139,110, 95,216,155, 20,123,253,196,183,225, 45,122, 86,105,212,166, 55,228,114, 5, 4,188,235,201,152,114, 85, -216,208, 22,157,250,255,216,237,245, 49, 56,185,119, 13,127,245,236,129, 9, 38,117,220,234,202, 30,203,130,130,130, 24, 0, 15, - 22, 45, 90,212,116,237,218,181,161, 83,166, 76, 73,216,248,227,140,229, 0,144,155,155, 11, 0,184,113,227, 6, 63, 97,194, 4, -139,217,108, 78,204,207,207,191,142, 10, 6, 64, 0,128, 73, 45,159,183,118,229,130,134,169,233,153, 3,107, 54,108, 5,191,208, - 86, 8,168,221, 26,249, 58, 27,174, 60,204, 64,194,189, 83,184,119,126,215, 17,163,210, 49, 3,149,156,223,184, 73,147, 38, 33, - 52, 77,215,208,235,245, 1,245,235,215,111,162, 80, 40,110, 52,105,210,164,153, 64, 32, 72,187,118,237, 90,114,101,180, 82,206, -110,176, 84,235, 52,234,135, 20,157, 91,151,132, 44, 99,179, 20,157,219, 13,163,196,227, 51,117,212, 15,150, 95,153,224, 37,188, - 77, 19,179,115,131,118,247,150,213,139,153,183,199, 78,102,163, 11,189, 62, 17,200,196,191, 87, 46, 92, 77,103,126, 48,114,192, -147,233, 29,138, 34, 89, 69,191,187, 20,166, 47, 44,188, 93, 8,224,139,219,119,133, 63, 70,127, 50,110,118,227,150,237, 70,116, -124,109, 8,237, 16, 41,113,124,239,207,124,226,237,168,157, 2,158,253,218,228,194,106, 0, 21,118, 7, 89,173,174,152,172,231, -203,152,170,232,188,115,235,186, 81,187,247,238,153,255,122,255, 1, 62, 43,191,121, 11,223,255,178, 15, 10,153, 4, 60,199,225, -173, 46, 33,111,126,251,126,221,126, 33,254,210,224,221,167,211,206,125,180, 52,250, 11,163,209, 22,231, 66, 36,134,215,104, 52, -231,149, 74,165,186,125,251,246, 17, 18,137,132,210,104, 52, 2,149, 74,229,240,240,240,176,166,165,165, 25, 45, 22,203,110, 0, -149,154,118,220,102,231,144,148,109,198,254, 61,187,113,235,242, 41,220,187, 23,171,187,119,247,222, 10, 74,192, 47, 53,100, 63, -200, 3, 42,221,192, 7, 87,234,168, 67,190,210,163, 14, 89,139,110,203,198, 85,115,186, 26,205,150, 81, 77,218,246, 65,245,122, -237,104,155,157,197,157,171,167,113,122,215,210,239,109,250,188,105, 47,115,142,131,170,132,214,225, 25, 49,254, 60,115, 24, 60, -199,173, 2, 0,158,227, 86,221,184,112,100,124,235,222,239,195, 91, 85,189, 73,193,163, 27, 20, 94, 96,246,112,145,128, 54, 28, -221,253,235,222,164,164, 36,220,191,127, 31, 15, 31, 62, 68, 94, 94, 30,182,108, 73,170,212,249, 49,230, 39,255, 30,119,151,238, -245,198, 91,195, 15,190, 57,244, 29,105,104,157, 70,116,120, 21, 47,248, 40, 5,136,125,152,140,184,107,183,185,216, 43, 71,204, - 54,109,206,235,166,252,228, 50,141,159,220,183,158, 63,192, 78, 43, 94,187,176, 77,155,118,225, 83,231,206,143,240,241, 83,149, - 90,143,231,170,115,196,159,127,116, 32,252,226,165, 63, 93, 90,235,144, 99,217,220,177,163,134,112,140,115,161, 80, 60,142, 83, - 23, 29, 61,103, 99,202,249, 62,207, 57, 42,140,224,191, 59,176, 3, 28, 28, 7,131,201, 6,173,193,130, 66,157, 25,153, 57,185, -184,117,251, 54,206, 30, 60,128,248,216, 91,137,118,171,245, 4, 77, 83,187, 76,217,113,103, 43,215,211, 36, 8,245,241,246, 70, - 98,158, 30, 82,177, 0,201,113,215, 44, 6,109,225,230, 23,189,142, 76,185, 15, 50,115, 24,170,231,144, 33, 67,143,117,237,213, -223,163,101,219,238,114, 95,119, 79,136, 4, 60, 30, 36,101,224,250, 31,199, 12, 9,183,206,105,237, 86,125,228,171, 88,245,229, -111, 78,197,163, 14,109, 22, 67,191, 97, 3, 58,237, 97, 24,129,152,227, 28, 22,155,213,242,198,203,152,172,191, 10,158,103,211, - 70, 13, 27,248, 84,219,192,193,241,178, 97,131,143,155, 74,182, 21,236, 44, 47, 31, 54,248, 15,163,179, 2, 41, 59,177, 47, 48, -208,187, 79,241,218,133, 41, 41,185, 87,243,242, 44,167, 1,164,153,205,230, 23, 46, 99,118,118,246,236,185,115,231,246, 53, 26, -141,117, 59,119,238, 44,113,119,119, 71,110,110, 46, 78,156, 56, 97, 63,116,232,208,221,156,156,156,111,129, 28,135, 9,205,126, -187,109,222, 59, 50,246,218,137,111,235,182,232, 85,165, 81,219,222,174, 87,102, 18,217,152,174,253, 71, 83, 39,247,173,225,175, -156,217,247,129, 73,253,224,151,151, 56,172, 54,179,217,124,217,108, 54, 71,127,253,245,215, 45,253,253,253,253,191,253,246, 91, -169, 86,171, 21,174, 92,185,210,172,209,104,178,180, 90,237, 69,148,147, 79,243, 60, 55,236,133,233, 24,116,116,247,154, 46,252, -238, 53, 61, 60,125,131,123,122,248, 85,169, 85,160, 78, 79, 44, 84,103,156, 0,112,178,104,162,200, 74,209,180,105,211,154, 20, - 69, 13, 1,208, 80,161, 80,212, 86, 42,149, 18,158,231,235, 82, 20, 21,195,113,220,237,250,245,235, 31,186,123,247,110,165, 38, -147, 77, 57,187,193, 18, 18,222,110,107,158,145, 19, 89,105,209,214,148,179, 27, 44, 0,144,243,251, 84, 35,128,253,119, 59,127, - 49,232,192,197,228,229, 49,249, 30, 19,213,103,230, 31,168,108,153, 11,211,110,213,126, 85,215,191, 57,243,110, 26,128, 81,183, -175, 97,241,157, 27, 23,191,163,120, 8, 89, 56,230,152,114, 30, 94,123, 21,250, 66,161,208, 28, 28, 28, 92,234,232, 66,137, 68, - 98,182, 88,202, 11,160,156,117,232, 51,177, 22,232,180, 97,207,142, 13,163,246, 29,216, 63,191, 99,183,215,125,164, 85,170,160, -134,138,194,134,105,205, 39,158,186,161,190,210,127,234,185,159, 18, 50,204,183, 81,201,124, 24,189, 94, 31, 7, 32, 95,175,215, - 15,224,121, 62,149,162,168,144,252,252,252,155,118,187,253, 78,165, 13, 1,135,225,109,218,180,218, 66, 81,148,128,119,112, 11, - 47, 10,153,173,230,204,123,105,120,201,101, 73, 26,213,112,199,164,111,127,104, 94,171,118, 88,243,226,181, 14, 27, 84,119,195, -184, 47, 22, 55,175, 30, 90,167,249,147,245, 15, 43, 76, 19,224,237,198,252,247,246,172, 91,120,238,198,165,211, 95,249, 6, 86, -175,158,149,150,112, 47,245,225,205,217,172, 89,187,231,101,207,115,210,195,152,165,107, 23,125, 49, 37, 51, 61,113,173, 81,253, - 32, 26, 0,140,234, 7,209,247,174,227, 27, 77, 86,218,148,220,156,132, 69, 47,122, 44, 12, 6, 67,198,230,205,155, 61,219,181, -107, 71,251,251,251, 67,173, 86,227,244,233,211, 28,199,113,233,149,214,202, 75, 60,109,200,163,188,127,251,229,199,133, 34,133, - 91,111,135,195, 17,196,243,128, 64, 32,200,180, 26,181,199,116,180, 98, 42,242,147,205,229, 63, 51, 56, 10, 0, 93,188,118, 33, -199,113,212,194,229, 27,146,133, 82,183, 82, 39, 67,180,155,117,114,142,227, 92, 94,235,176,224,209,245, 90,175,234,254,166,120, -126,102,147, 22, 17, 95,217,237, 54,115,209,253, 97, 6, 96,230,121,228,210, 52,117,150,225,236,199,181, 47,209,152,162, 40,184, -243,148, 0,110, 50, 1, 40, 80,208, 23,230,241,149,201,201, 42,213, 16,231,196,197, 24,115, 58, 85, 59,106,221, 49, 50,234,247, - 35,131, 89,150,173, 81, 20, 51, 72,178,152, 12, 59,245,153, 94,191, 1,215, 28,248,247,115,184,216,108, 81,127,241, 63,114,169, - 27,229,239,164, 25, 30, 42, 27, 80, 37,216,127,100, 82,114,206,149,132, 84,227,111,120,122, 89,157,151, 41, 39,227,239,239,255, - 13, 69, 81, 35,196, 98,177,210,106,181, 26,120,158,223,152,157,157, 61, 27,207, 45,254,219, 76, 40, 83,153, 70,138,165,242,233, - 54,179,225, 79, 99, 78,220,240,138,246, 93,238, 23,214, 83,170, 80,124, 97, 54, 25, 54, 26,179,227, 54,188,226,227,233, 33,145, - 72,154, 41,149, 74,161, 70,163,185, 12,160,240,239,116,222,155, 52,105, 82,149,166,233, 26, 28,199,249, 3,240,128,115, 84,136, - 70, 32, 16,164, 23, 69,180,248,202,106,182,127,119,167,111,183, 30, 13, 38,157, 56, 23,187,172,168, 91,241, 49,193,111, 46,145, -142,232,221,101,242,111,123,246,151, 54,234,240, 31,119,205,255,255,105,118, 18, 40, 3, 53,163,104,177,199,156,110,225,102,163, - 38, 35,125,194,249, 59,234,203, 0,116, 47, 83, 78,145, 72,244,182,205,102,147,137, 68, 34,147,205,102,219,252,119,217,119,153, - 42,124, 52, 13,222,229,149, 41, 56, 80,215,158, 25,180,242,111,185,150,152, 70,141, 26,117, 16,137, 68, 85, 89,150,149, 91,173, - 86,163,201,100, 74, 74, 78, 78,254, 19,101, 47,124,254,151,150, 83,161,170,179, 84, 36,146,124, 2, 0, 54,155,229, 7, 67,206, -131, 73,229,125,177,156,207,255,163,207,145,111,141, 22, 15, 4,140,208, 15, 69, 19,115,115, 14,135, 58, 59,241,106,157,255, 98, - 57, 9, 47,120,114,137, 38,209, 36,154, 68,243, 89,104,114, 60,137,230,127, 83, 83, 26, 88, 47, 68, 26, 88,207,229, 73,151,203, -248, 60, 57,158,132, 98,198,150,242, 2,224,194,132,165, 4, 2,129,240, 23,192,145, 67, 64,248,111, 98,206,188,151,250, 87,126, -158,240, 63, 71,153, 57,209, 84, 57,174,180, 50, 33,193, 23,113,182, 39,137, 38,209, 36,154, 68,147,104, 18, 77,162,249, 63,167, - 89,145,246, 63,177, 75,114,236, 51,219,135, 1,252,191, 36,252,147,176, 42,209, 36,154, 68,147,104, 18, 77,162, 73, 52,255,215, -120,108,188,104,114, 44, 8, 4, 2,129, 64, 32, 16,254, 26, 72,142, 22,129, 64, 32, 16, 8, 4,194,203, 81, 90,215, 33, 49, 90, - 4, 2,129, 64, 32, 16, 8,175,128, 50,147,225, 73,215, 33,129, 64, 32, 16, 8, 4,194,203, 81, 28,209, 10,196, 51,211, 59, 16, -163, 69, 32, 16, 8, 4, 2,129,240,106,200, 68,105,209,173, 67,135, 14,241,165,253, 78, 32, 16, 8, 4, 2,129,240,255,193, 63, -220,139,148,140,100,141, 45,218, 6, 80, 34,162, 69, 12, 22,129, 64, 32, 16, 8,132,191,139,217,250,135, 81, 28,201, 42,126,101, - 62,103,180,250,246,237, 75, 17,179, 69, 32, 16, 8, 4, 2,225,191,197,191,209,139,208,207,238, 32, 57,205, 4, 2,129, 64, 32, - 16,254,155,102,235,223,180, 63,100,122, 7, 2,129, 64, 32, 16, 8,132,151, 35, 16, 64,159, 18,219,255,111, 75,240, 16, 8, 4, - 2,129, 64, 32,252,219, 25, 91,214, 54,137,104, 17, 8, 4, 2,129, 64, 32,188,122,179, 69, 32, 16, 8, 4, 2,129, 64,248, 39, - 67, 86, 54, 39,154, 68,147,104, 18, 77,162, 73, 52,137,230,191,157,226,121,180,128,178,230,209, 34, 16, 8, 4, 2,129, 64, 32, -188, 16,125,224,156, 63,107,108,209,207, 62,196,104, 17, 8, 4, 2,129, 64, 32,188, 90,158, 91,126,135, 24, 45, 2,129, 64, 32, - 16, 8,132, 87,107,176, 86, 19,163, 69, 32, 16, 8, 4, 2,129,240, 23, 67,140, 22,129, 64, 32, 16, 8, 4,194, 95, 4,133,178, - 71, 14,156,172,132,206,139,140, 62, 56, 73, 52,137, 38,209, 36,154, 68,147,104, 18,205,255, 57,205,138,180, 79,226,159, 71,241, -204,240,135,241, 36, 17,126,245,255,199, 63, 38, 67, 95,137, 38,209, 36,154, 68,147,104, 18, 77,162,249,111,103,236, 51, 63, 31, - 67,186, 14, 9, 4, 2,129, 64, 32, 16, 94,173,217, 34, 75,240, 16, 8, 4, 2,129, 64, 32,188, 34,202,236, 38, 36, 17, 45, 2, -129, 64, 32, 16, 8,132,151,163,204, 69,165,137,209, 34, 16, 8, 4, 2,129, 64,248,107, 12, 23, 49, 90, 4, 2,129, 64, 32, 16, - 8,175,208,100,141, 45,245,175,135, 14, 29,226,201, 49, 34, 16, 8, 4, 2,129,240,223,226, 95,235, 69,138,119,140,152, 45, 2, -129, 64, 32, 16, 8,196,139, 84,154, 64, 60, 25,109, 56,182,104, 27, 0, 25,117, 72, 32, 16, 8, 4, 2,129,240,178,244,193,211, - 35, 15,199, 22,111, 19,163, 69, 32, 16, 8, 4, 2,129,240,242,140, 45,247,175,164,219,144, 64, 32, 16, 8, 4,194,127,147,127, -163, 23,161,200,105, 37, 16, 8, 4, 2,129, 64,120, 41, 74,139,102,173, 38,135,133, 64, 32, 16, 8, 4, 2,225,175, 53, 92, 4, - 2,129, 64, 32, 16, 8,132,191,194,100,253,213, 19,150,146,149,205,137, 38,209, 36,154, 68,147,104, 18, 77,162,249,191, 98,178, - 74, 78,241, 0,128,140, 58, 36, 16, 8, 4, 2,129, 64,120, 89,200,162,210, 4, 2,129, 64, 32, 16, 8,127, 17,100, 81,105, 2, -129, 64, 32, 16, 8,132,255,103,195, 69,140, 22,129, 64, 32, 16, 8, 4,194, 43, 52, 89, 79,153, 45,146,163, 69, 32, 16, 8, 4, - 2,129,240,114,148,153,163, 69,161,236,145, 3, 39, 43,241, 15, 94,100,244,193, 73,162, 73, 52,137, 38,209, 36,154, 68,147,104, -254,207,105,254, 31,123,231, 29,214,212,217,254,241,111, 22, 25, 36,144,176,195, 86, 25,226, 2, 69,235, 22,247,170,184,169, 91, -235,174,213,106,245,181,110, 5, 90,181,142,186,107, 91,251,186,234,168,187, 86,113, 83, 7,110, 37, 40,130, 34, 32,136,128,236, -145, 9, 36, 33,201,243,251,131, 81,106,153,218,190,191,142,231,115, 93,185, 32,201,201, 55,207, 57,231, 57, 39,223,115,159,231, -185,239,186,180,195,241,247,103, 6,254, 71, 9, 75,233,212, 87,170, 73, 53,169, 38,213,164,154, 84,147,106,254,219,160,233, 29, - 40, 20, 10,133, 66,161, 80,254,104, 99,245, 38,212,104, 81, 40, 20, 10,133, 66,161,188, 27, 52,143, 22,133, 66,161, 80, 40, 20, -202,159,132, 35,202,162, 90, 21,127,253,169,209,162, 80, 40, 20, 10,133, 66,249, 99, 24,132,178,168, 86,197, 95,106,180, 40, 20, - 10,133, 66,161, 80,254, 64,170,205,163,197, 0,128,176,176, 48, 82,254,188, 71, 96, 96,224, 13,186,173, 40, 20, 10,133, 66,161, -252, 47,249,167,122,145,202,136, 86, 96, 96, 32, 3,192,117,186,171, 41, 20, 10,133, 66,161,252,127,240, 79,244, 34,204, 55,156, -100, 15,186,155, 41, 20, 10,133, 66,161,252,127,240, 79,244, 34,236, 55, 92, 36,133, 66,161, 80, 40, 20,202,255, 11,127, 99, 47, -226,136,178,129,240,231,202,255, 2,229, 41, 31,104, 30, 45, 10,133, 66,161, 80, 40,148,119,163, 98,182,225,239, 74,239,208, 40, - 22,133, 66,161, 80, 40, 20,202,187, 81, 93,102,248,239,233,102,161, 80, 40, 20, 10,133, 66,249, 19,161, 17, 45, 10,133, 66,161, - 80, 40,148,119,167,106, 84,235,127, 22,205,162,149,205,169, 38,213,164,154, 84,147,106, 82, 77,170,249,111, 50, 89,191,121, 78, - 51,195, 83, 40, 20, 10,133, 66,161,252, 73,208, 89,135, 20, 10,133, 66,161, 80, 40,239, 70,197,140,195,170,207,169,209,162, 80, - 40, 20, 10,133, 66,249, 3,205,214,239,160,183, 14, 41, 20, 10,133, 66,161, 80,222,141, 25, 53,189, 65,141, 22,133, 66,161, 80, - 40, 20,202,159,100,184, 24,168,121,230, 64,120, 3,132,223,102,246, 65, 56,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,117, -154,117,105,135,227,239,199,255, 91,194, 82, 58,245,149,106, 82, 77,170, 73, 53,169, 38,213,164,154,255, 90,232,173, 67, 10,133, - 66,161, 80, 40,148,191,128,209,178, 99,179,217,203, 4, 2,193, 55, 2,129, 96, 23,155,205,254, 10,128, 85, 67,191, 80, 40, 20, -206,149, 74,165,113, 82,169, 52,221,205,205,237,188,133,133,249,167, 30, 60, 4, 0,224,252, 65,235,227, 3,224, 83,129, 64,240, -140,207,231,167, 0, 56, 8,224, 83, 0,182,239, 34,252,133, 19, 70,198,204, 27,122,250, 11, 39,140,124,227,173, 65, 14, 14, 14, - 55, 1,244,251,163,118,202, 24,115,244, 9, 18, 34, 53, 72,136,212, 49,230,111,127,213, 96, 97, 97, 49,193,209,209,241,174,141, -141,205,107, 71, 71,199,219,124, 62, 63,168,129, 18,246, 14, 14, 14, 27, 93, 93, 93,227,157,156,156,182,162,172, 58,249, 95,150, -110, 60,116,235,200, 67,110, 39, 46, 84, 93,184,248,166, 19, 23,125,251, 2,230,111, 41,215, 21,192, 9, 75, 75,203, 71,108, 54, - 59, 12,192,136,242,254, 53,130,205,102,135, 89, 90, 90, 62, 2,112,162,124,185,183,233,167, 27, 1,188, 6,176,182,252,249, 39, -174,174,174, 42, 63, 63,191, 20, 63, 63,191,125, 94, 94, 94, 19,235, 43, 14,106,110, 21, 0, 0, 32, 0, 73, 68, 65, 84,102,110, -110,222,215,213,213,245,164,155,155, 91, 74,167, 78,157, 10,156,157,157,159,187,184,184,236,231,241,120, 61,232, 41,142, 66,161, - 80,254,250, 12, 6,240, 37,128, 29,209,209,209, 50, 66,136,140, 16, 34,139,142,142,150, 1,248, 6,192, 58,212, 28, 66,252,205, -235, 54, 54, 54,161,171, 87,175, 46,201,204,204, 36,185,185,185, 36, 62, 62,158,108, 89,177,216,212,223,154, 77, 60,236,172,138, - 28, 29, 29, 95,184,187,184, 28,105, 41, 98, 46, 6,224, 89, 31,205, 42, 88, 9, 4,130,251, 43, 86,172, 80,223,188,121, 83,173, -211,233,212, 38,147, 73,157,145,145,161, 14, 15, 15, 87,119,233,210, 69, 13, 96, 62, 0, 86, 3, 52, 43,249,220, 9, 55,200,158, -149,228,115, 39,220,168,250,122,179,102,205,158,154, 76, 38, 50,114,228, 72, 45, 0,231,134,104,190,137, 51,192,111,105, 9, 73, -144, 8,217,134,253, 95, 16,178,115, 33, 9, 18, 34,245,109, 52,237,237,237,127,158, 59,119,174,242,245,235,215, 68,171,213,146, -212,212, 84, 50,115,230, 76,133,189,189,253,161,122,174,187,141,175,175,111,246,221,187,119, 77,114,185,156, 92,191,126,221,212, -170, 85,171,236,122,154,173, 62,111,180,229,123, 39, 39,167,243, 13,121,216,219,219,239,110,232, 62,234,192, 67,170, 94,118,141, -144,135,151,201,153,145,157,200,150,118, 46,100,132, 53, 87,222,149,139, 79,186, 87,159,202,164, 38,205, 15,186,119,239,174,121, -242,228,137, 49, 63, 63,159, 60,125,250,212, 52,125,250,244, 18, 0,177,211,167, 79, 47,121,250,244,169, 41, 63, 63,159, 60,121, -242,196,216,189,123,119, 13,128,105, 13,104, 39, 19,192,222,144,144, 16, 66, 8, 33,171, 87,175, 38,126,126,126,164, 87,175, 94, - 68,173, 86, 19, 66, 72, 10, 33,100,159,193, 96,248,176, 62,154, 98,177,120,194,220,185,115,213, 69, 69, 69,164, 2,147,201, 68, -228,114, 57,217,177, 99,135, 70, 42,149,158,175,225, 34,131,222,242,160,154, 84,147,106,254,213, 52,255,206, 56,162,108,156, 86, -197,163,222,129,137,177,139, 23, 47,174, 48, 85, 23,186,118,237,250,224,195, 15, 63,148,125,248,225,135,178,174, 93,187, 94, 7, -112, 41, 50, 50, 82,182,104,209, 34, 25,128,177,117,236, 8,171,206,157, 59,203,179,178,178,136,183,183, 55,105,212,168, 17,201, -202,202, 34,132, 16,242,240,131,182,228,151,230, 32,105, 17, 23,200,229,159, 78,144,233,142,108,210,205, 81, 92,234, 40,149,230, -219,218,218,174,193,111,107, 50, 86,183,115,135, 55,111,222, 92, 21, 27, 27,171, 78, 72, 72, 80,135,134,134,170,123,245,234,165, -246,245,245, 85,143, 24, 49, 66,189,125,251,118,181, 94,175, 87,239,222,189, 91,109,105,105, 25, 91,141,217,122,107,163,197,102, -179,183, 69, 71, 71,147, 23, 47, 94,144,242, 40, 69, 77,154, 98,137, 68, 50,192,202,202,106,190, 68, 34, 25, 0, 64, 12, 0,222, -128,168,181, 24,110,159,180,246,104, 22, 54,182,143,231,142, 62,239,181, 13,178, 96,202, 75,191, 94, 72,200, 72,183,183, 50, 90, - 98,177,120,194,167,159,126,170,210,106,181,164,168,168,136,168,213,106, 82, 84, 84, 68, 84, 42, 21, 25, 59,118,172,146,207,231, - 15,175, 75,211,214,214,246,139,136,136, 8, 67, 86, 86, 22,137,136,136, 32,231,207,159, 39, 59,119,238, 52,217,219,219,111,110, -232, 1, 40,149, 74,175, 92,190,124, 89, 22, 21, 21, 37,187,127,255,190,172,180,180, 84,166,215,235,101,122,189, 94, 22, 22, 22, - 38, 59,117,234,148,236,232,209,163, 50,157, 78, 39,211,233,116, 50,173, 86, 43,107,210,164,201,197,134,238,163,246, 60,164,233, -110,158, 33,100,243,108,162, 88, 63,139,200, 23,188, 79,114,102, 6,144,111,222,115, 33, 1, 2,156,197,239,107,123, 86,171,201, -225,112,110,164,164,164,152,150, 46, 93,170,107,209,162,133, 98,202,148, 41, 37, 90,173,150, 16, 66,136, 86,171, 37, 83,166, 76, - 41,105,209,162,133, 98,233,210,165,186,151, 47, 95,154,216,108,118,120, 3,218,185,174,194,100,221,184,113,131, 84, 69,173, 86, -147, 94,189,122,165,248,249,249,237,107,220,184,241,184,186, 52, 69, 34,209,208, 37, 75,150,168, 73, 53,148,150,150, 18,149, 74, - 69, 94,190,124,105,106,212,168, 81, 6, 0, 27,122, 50,167,154, 84,147,106, 82,163,245,167, 49,163,142,231,213,111,196, 69,139, - 22,201, 8, 33,178,229,203,151,203,202, 35, 91,102, 0, 68,229, 15, 54,128, 49, 75,150, 44,145, 17, 66,100,139, 23, 47,174, 88, -166,166, 29, 49,248,248,241,227,250,173, 91,183, 18, 7, 7, 7, 34,149, 74,201,182,109,219,136,201,100, 34, 89, 97,135,200, 47, -205, 65,158, 45,155, 68, 8, 33, 36,126,205, 28,242, 75,115,144,164,111, 63, 39,227,199,143, 47, 50, 55, 55, 31, 91,203,206,181, -110,219,182,173,170,184,184, 88,189,127,255,126,181,185,185,249, 67, 0, 45, 80,118, 43,146, 81,222,214,137, 45, 90,180, 80,198, -196,196,168,127,252,241, 71, 53,128,208,122,118, 24, 79, 0, 61,133, 66,225,136, 37,206,156, 4,178,103, 37, 89,226,128, 39, 0, - 90, 1,176, 43, 95,198,105,241,226,197,132, 16, 66, 92, 93, 93, 35,106,208, 20,251,250,250, 46, 78, 72, 72, 8, 46, 45, 45, 13, -142,138,138, 10,110,218,180,233,210, 33, 77, 28, 59,157, 30,219,215, 95,241,249, 44,127,178,105,129,239, 87, 3,219,247, 57, 50, -186,199,216,201,141,109,111, 78,177,231, 23,141, 18,179, 84,111,220, 58,172, 87,199,118,118,118,190,159,154,154, 90,105,174, 84, - 42, 21,121,253,250, 53, 73, 78, 78, 38, 55,111,222, 36,142,142,142,191,212,165, 41,149, 74,159,166,166,166,146,111,183,108, 33, - 35, 91, 53, 35, 1, 18, 11,210,221,202,130,180, 19,241, 53,205,129,118, 13, 53, 90,143, 30, 61,146, 1,144, 1,144,229,231,231, -203,242,243,243,101,133,133,133,149,175, 1,144, 41, 20, 10,153, 66,161,144,233,116, 58,153,135,135, 71,131,141, 86, 23, 62,186, -116,224,163,160, 19, 15,197,131,157,109, 51,102, 53,177, 53,222, 27,219,137, 20,206,238, 69,182,250, 59,147,174, 92,124, 82, 79, -205,193, 92, 46,247, 58,128,133,229,166,124,210,128, 1, 3,138, 8, 33,100,192,128, 1, 69, 0, 38,149,191,254,105,185,201, 26, - 80,207,118, 50,189,188,188, 52, 21,145, 44, 0,119,188,188,188, 52,126,126,126,196,207,207,143,184,186,186,170,202,181,235,117, - 66,243,244,244,140, 47, 46, 46,174, 52,128,114,185,156,100,100,100,144,164,164, 36, 18, 27, 27, 75, 30, 62,124, 72, 82, 82, 82, -200,177, 99,199,140, 18,137,228, 28, 61,153, 83, 77,170, 73, 53,169,209,250, 83,141,214,155,143,223, 18, 22, 22, 70,222,120,105, -125,100,100,164,108,201,146, 37,178, 58,156,217,140,229,203,151, 87, 68,189,190,172,229,199,127,119,124,124, 60,153, 52,105, 18, -241,241,241, 33, 62, 62, 62,228,195, 15, 63, 36, 10,133,130,168, 19, 99,200, 47,205, 65, 30,142,106, 71, 8, 33, 68,245, 44,138, -252,210, 28, 68, 54,190, 51,121,252,248, 49,113,113,113,185, 92,203,247,159,189,125,251,118,238,161, 67,135,178, 80, 54, 30,139, - 3,160, 35,128,109, 2,129, 96, 47,202,110, 23, 54, 2, 96,229,237,237, 93, 80, 84, 84,164, 30, 57,114,164, 26,128, 91, 45,154, -221,125,124,124, 94,236,222,189,155,228,228,228,144,130,130, 2,178,161, 75, 83, 66,246,172, 36,171,219, 53, 50,125,251,237,183, -218,133, 11, 23,106,172,173,173,195, 0, 56,141, 28, 57,210, 64, 8, 33, 1, 1, 1,217,213,137, 73, 36,146, 1, 9, 9, 9,193, - 37, 37, 37,193,114,185, 60,184,160,160, 32,248,204,233,211,193,253, 91, 53,157,164,248,124,150,255,233,177,125,253, 7, 58, 91, -141,216,220,239,189,143, 94, 47,157, 54,114,121,231, 22,207, 74,214,205,187,246, 65, 19,135,141,111,179,183,237,236,236, 50,181, - 90, 45, 1,240,187,199,139, 23, 47,136,141,141, 77,106, 93, 26,214,214,214,203, 63, 29, 51,218, 56,188,145, 51,121,177,117, 5, - 41,189,242, 35, 41, 61,191,159, 36,174, 95, 64,134, 72,109,149, 29,205,152, 75,234,219, 30,169, 84,122,229,254,253,251,191, 49, - 90,133,133,133,213, 26, 45,165, 82, 41,211,233,116, 50, 47, 47,175,139,239,218,235, 59,114,225,209, 93,192,122, 24, 53,169, 27, -201,157,213,139, 12, 16,115, 82,222, 65,110, 12,128,235, 0,198, 55,240,115, 76, 0,235, 42, 12,213,250,245,235, 9, 33,132,120, -121,121,105,240,110,147, 81,196,205,154, 53, 75,158, 54,109,154,161,121,243,230, 57, 93,186,116,145, 63,120,240,128,220,184,113, -131,156, 63,127,158,156, 56,113,130,196,196,196,144,215,175, 95,147,248,248,120, 50,104,208, 32, 57,128,238,244, 92, 72,161, 80, -254,202, 84,227, 69,254,246, 48, 43, 86, 44, 48, 48,144, 81,101, 5,197, 0,248,237,218,181,203, 93,183,110,221, 38,148,229,130, - 96,248,178,240, 65, 47, 1,251,113, 47, 1,251,177, 47, 11, 31,148, 71,140,190, 95,179,102,205, 23,126,126,126,153, 0, 4, 0, -164,213,125, 17, 33,164,155,141,141, 13, 82, 83, 83, 33, 22,139, 33, 22,139,145,154,154, 10, 66, 8, 12, 4, 40, 37,128, 86,175, - 71,113,113, 49, 74, 76, 4,197, 38, 64,169, 86, 67, 42,149, 66,175,215,123,212,208,254,214,163, 70,141,242,240,245,245,205, 93, -180,104, 81, 6,202,198,202,236,157, 58,117,234,149, 59,119,238,248,170,213,234,130,216,216,216,146, 86,173, 90, 13, 0, 32, 77, - 72, 72,152,176, 99,199, 14, 76,154, 52, 9,181,252,232,180, 26, 52,104,208,249,152,152, 24,143,241,227,199,227,250,245,235,216, -176, 97, 3,242,242,242, 8, 0,104,181, 90, 98, 52, 26,245,157, 59,119,214,111,221,186,181,125, 64, 64,192,253, 38, 77,154,176, - 0, 32, 57, 57, 57,177, 58, 65, 6,131,209,212,221,221, 29, 90,173, 22,185,185,185,136,137,137,129,133, 88,140,232,140, 60,135, - 30,155,191,205, 95,118,250, 10,103, 76,123, 95,235,249,125,187,104,215, 94,190,238,221,194,201,193, 65,167, 47,149,198,103,102, -103,188,205, 78, 53, 51, 51, 75,205,203,203,131, 78,167, 67,113,113, 49,148, 74, 37,242,243,243,145,151,151,135,140,140, 12,152, -153,153,189,168, 75,195,178,160, 32, 34,249,246, 13,198,177,239,214,195,195, 80, 0,246,201,109, 96,255,252, 13, 60,117,185,216, -181, 98,166,133,206,198, 46,196,210,194,162, 80, 34,145,124, 15,192,171, 46, 61,127,127,127,228,231,231, 35, 63, 63, 31, 54, 54, - 54,176,178,178,130,149,149, 21,228,114, 57, 20, 10, 5,148, 74, 37,188,189,189,209,186,117,107, 28, 56,112,224, 15,233,220,247, -116, 72, 50,192, 56,235,202,243, 12,152, 9,133,104, 98, 37,114,127, 79, 4,235, 90, 62,210,139,195,225, 28,183,182,182,190, 12, - 96, 54, 0, 33,128,217,214,214,214,151, 57, 28,206, 48, 0,171, 1, 28,106, 96, 51,214,134,132,132, 44, 78, 72, 72, 48,127,252, -248, 49, 22, 45, 90,132,208,208, 80, 36, 38, 38,126, 13,192, 84,190,204,199, 54, 54, 54, 97, 76, 38,243,191, 0,222, 7, 48,192, -209,209,177,119, 29,186,195, 22, 46, 92, 88,210,182,109,219,248,103,207,158, 13,187,125,251,118,187, 5, 11, 22, 40, 94,189,122, -133,248,248,120, 56, 58, 58,194,213,213, 21,106,181, 26,133,133,133, 24, 54,108,152,216,210,210,114, 44, 61,141, 83, 40,148,191, -178,201,122,195,139,252,221, 34, 90,213, 62,175,246,138,218,220,220, 60, 68, 38,147,117,242,243,243, 99, 3, 56, 6, 0,190, 44, - 4, 13,235,220,102,239,233,239,215,251,157,218,186,194,175,191,159,247, 94, 95, 22, 42,102,177,133,181,107,215,206, 74, 38,147, -117,230,241,120,159,212,208, 8, 2, 0, 86, 86, 86, 16,139,197,144, 72, 36,176,178,178,130,201,100,130,186,168, 4, 26, 35,160, - 42,209, 65,161, 80, 64, 85,254, 92,173,213, 67,163,209, 84,126,182, 26,122, 76,155, 54, 45,119,199,142, 29, 57,153,153,153,235, - 1,180,154, 52,105,210,208,237,219,183,227,234,213,171, 37,239,251,120,218,172,233,214,230,139, 22,153,137,193, 62, 28, 76, 7, - 16, 17, 17, 17,129,206,157, 59,131,193, 96,140,174, 78, 80, 32, 16,124,115,228,200, 17, 65,108,108, 44, 60, 61, 61, 99, 71,143, - 30,253,193,250,245,235, 61,132,234,130, 91, 0, 96,200,207,138,157, 51,103,206,202, 53,107,214,228,230,230,230,234,139,138,138, -236,135, 12, 25,130,212,212, 84,188,126,253,250, 78, 13, 38, 51, 62, 42, 42,138, 40, 20, 10, 36, 37, 37, 33, 42, 42, 74,176,114, -229,202,246, 70, 38,115,104, 58, 44, 38, 79,234,210,174,253,248,142,109,112,232,238, 99,179,155,207,147, 37,237, 26, 57, 91, 61, - 74,203,108, 92,202,192,139,183,217,219, 42,149,106,219, 23, 95,124,161, 86,171,213, 72, 79, 79,199,147, 39, 79,240,236,217, 51, -164,164,164, 96,195,134, 13,234,130,130,130,237,117,105, 56,241,217,255,217,184, 96, 42,131,253,244, 14,240,248, 6, 80,164, 2, -138,213,208,198,201,176, 47, 46, 11, 59, 79,254,196,125,149,154, 42, 57,122,244,232, 52, 55, 55, 55, 25, 0,239,218,244, 8, 41, -219,133, 76, 38,243, 77, 19, 10, 38,147,169, 2,144, 37, 20, 10,211, 44, 44, 44,210,152, 76,102, 22, 33, 68,243,135, 92, 73, 24, -160, 7,139, 5,112, 5, 96,114,106, 45,237,249,193,232,209,163,143,164,165,165,245, 79, 74, 74,234,180,125,251,246, 47,248,124, -126,244,246,237,219,191, 72, 74, 74,234,148,150,150,214,127,244,232,209, 71, 0, 76,108,200,247,123,121,121,205, 9, 14, 14,198, -134, 13, 27,208,186,117,107,120,123,123, 23,133,132,132,108, 3,176, 2,192, 39, 94, 94, 94,183,230,204,153, 51, 37, 39, 39, 71, -154,158,158,222,250,235,175,191,158,185,109,219,182,247, 50, 50, 50,248,117, 72,119,237,215,175, 31, 46, 92,184, 0, 0,153, 0, -146,242,243,243, 13, 25, 25, 25,104,214,172, 25,218,183,111, 15,181, 90, 13,181, 90, 13,185, 92, 14,119,119,119,152, 76,166, 78, -244, 84, 78,161, 80, 40,255, 83,195, 85,189,209,226,243,249, 86,254,254,254,104,210,164,137, 21,202,103,107,217,112,217, 75,231, - 79, 27, 99, 46,146, 93, 4, 35,234, 23,140,238,214,210,220,134,203, 94, 90,254, 17,182,187,187, 59,207,223,223, 31, 66,161,208, -185,134, 47,191,158,149,149, 5,127,127,127, 72, 36, 18,136,197, 98,248,251,251, 67,175,215, 67,161, 82, 65, 99, 4,138, 74, 77, - 80, 40, 20, 40,200,205, 70,145, 17, 48, 88,216, 32, 37, 37, 5, 44, 22, 43,185, 6, 77, 71, 79, 79,207,220,232,232,232, 92, 0, - 17, 0, 62, 10, 13, 13,197,146, 37, 75,176,106,213,170, 35,230,153, 47,251, 29,185,240,179,205,225,144,143,237,188,185,140, 49, - 0,244,105,105,105,144, 72, 36, 16, 10,133,213, 26,131,128,128,128,182, 66,161, 16,251,247,239, 39,233,233,233, 93, 80, 54,133, - 63,153,193, 40, 51,123, 2, 38, 20, 0,182,201,100,178, 14, 43, 87,174,124,222,167, 79, 31, 78,199,142, 29,177,122,245,106, 0, - 8,171, 78, 83, 46,151,223,155, 56,113,162,238,218,181,107,136,139,139, 19,158, 62,125, 58,104,245,234,213, 45, 95,189,122,197, - 59,123,254,226,192,131,105,202,160,245,151,111,242,215, 92,186,126,207,214, 82,216,162,177,173, 53,162, 94,189, 54, 51,178,240, -160,174, 61,218,129,195,154,214,131,207,142,234,198, 99,102,246,224,179,101,239,113, 88, 83, 85, 42,213,209, 51,103,206, 92, 90, -176, 96,129, 58, 39, 39, 7, 22, 22, 22,200,207,207,199,218,181,107,213, 81, 81, 81, 39,117, 58,221,217,186,116,141, 38,210,214, -181,145, 27,240, 34,186,242, 53,189,137,224,129,206, 12,129, 31,205,131, 79,179,102,208,233,116,104,213,170, 21, 35, 52, 52, 84, - 40, 22,139, 63,171,211,244, 48,127,215,221, 12, 12, 6, 35,139, 16,242, 90,173, 86,167, 11, 4,130, 87,102,102,102,175, 10, 10, - 10,210, 9, 33,217,127,132,207, 34, 76,252,167,115, 43, 47,128, 39,192,171,124,117,198, 67, 53, 10,170, 91,208,194,194, 98,234, -206,157, 59,249,123,246,236, 41,157, 51,103,142,118,230,204,153,156,226,226, 98,251,153, 51,103,114,230,204,153,163,221,179,103, - 79,233,206,157, 59,249, 34,145,104,196,219, 52,164,180,180, 20,209,209,209,235, 19, 19, 19,133, 40, 75, 55, 50, 47, 36, 36,100, - 82, 66, 66, 2,127,199,142, 29, 56,113,226, 4, 78,156, 56,129,161, 67,135, 98,238,220,185, 8, 14, 14,174, 77,206,220,207,207, -207,223,198,198, 6, 55,110,220,200, 0,240, 10, 64, 91,145, 72,100, 49,116,232, 80,244,239,223, 31, 37, 37, 37,208,235,245,149, - 70,139,197, 98, 65, 34,145,216,208,115, 32,133, 66,161,252,233, 38,235, 55,102,139, 13, 0, 21,161,186,192,192, 64, 70,109, 63, -140,198,194, 28,200, 53, 69, 72, 81, 20, 33,181,208,244,155,247, 76, 38, 83,173,223,158,145,145,113,246,238,221,187, 83,253,253, -253,217, 25, 25,101,119,196,252,253,253, 81, 84, 84,132,140,199,247,161, 49, 1, 66, 79, 95,104, 52, 26, 20, 62,123, 4,145, 95, - 39,216, 12, 26,143,205, 59,118,104,243,243,243,191,171, 78,147,203,229,114, 92, 92, 92,114,147,147,147, 13, 0, 10,196, 98,113, - 63, 55, 55, 55, 92,191,126, 29, 0, 14, 17, 96, 35,162,174, 1, 55, 78,129,148,133, 84, 68,238,238,238,200,201,201,129, 90,173, -190, 94,157,230,221,187,119, 19, 74, 75, 75, 91, 13, 25, 50,132,241,195, 15, 63, 28, 83, 42,149,171, 0, 60,209,154,192,122,156, -150, 13,141, 17,124, 0,125,173,172,172, 62, 13, 14, 14,238, 61,103,206, 28,156, 57,115, 6,151, 47, 95,214,163,108, 44,216,221, -106,100, 21, 73, 73, 73,187, 22, 46, 92,216,145,201,100,126,116,229,202, 21,131,183,183,183, 82,175,215, 27,155,250,248, 48, 87, -133,126,110, 54,251,163, 25,146,252, 34, 60,237,223,212,177, 51,131, 1, 60,125,157,243, 42, 81,141,252,218,182,105, 0,151, 21, - 54,172,139, 95,192,212,209,131, 69, 66,207, 22,208,196,220,151,238, 58,126,126,179, 32, 42, 33,240, 70, 78,206,208, 51,103,206, - 4, 93,191,126,125,182, 78,167,107,194,227,241, 94,200,229,242,173,106,181,186, 78,147,197, 98,177, 6,105, 29, 93,172,228, 5, - 5,224,151, 71,162,148,165, 38,228,105, 13,136,147,120, 99,172,139,107,229,109,208,172,172, 44, 72,165, 82,134,209,104, 28, 92, -155,230,229,203,151, 17, 24, 24, 88, 97, 60,193, 96, 48,192, 96, 48,242,124,124,124,178,121, 60, 94,190,153,153,153,114,227,198, -141, 37, 37, 37, 37, 96,179,217,124,163,209,200,122,151,222,222,222, 28,246, 60,194,248,102,230,144,158,125, 90,183,104, 70, 34, - 30, 62,102, 20, 22,149,236,171, 37, 10,248,181,151,151, 23,187,160,160,224, 44,128,184,210,210,210,195,199,142, 29,227, 79,152, - 48,161,228,248,241,227,227, 0,120,108,218,180, 41, 72,173, 86, 55,168,164, 66, 98, 98,226,215,107,214,172, 89,188,124,249,114, - 28, 56,112, 96, 78, 98, 98,226,146,242, 72,215,208,224,224, 96,108,220,184, 17, 7, 14, 28, 48,197,197,197,157, 55,153, 76,137, - 11, 22, 44,240,115,112,112,200,203,204,204, 76,172, 69,182,221,128, 1, 3,180,183,110,221,226,170, 84,170,155, 0, 62,157, 53, -107,214,180, 14, 29, 58, 40, 71,143, 30, 45, 42, 40, 40,144,155,155,155,115,119,239,222,109,197,102,179,161,209,104,192, 96, 48, -160, 82,169,116,244, 60, 72,161, 80,254,170,212,228, 69,254, 38,212,248,219,192,174,110, 5,139,138,138,178, 83, 83, 83,155,189, -126,253,218, 0,192, 0, 0,249, 58,195,151,107,118,159,218, 51,162,163,151, 48,179,180, 20,167, 31,198, 22,229,235, 12, 21,131, -223, 13,175, 95,191, 86,189,122,245,202,162,184,184, 88, 93,195,119,221,249,230,155,111,138,175, 93,187,102,145,148,148, 4,163, -209,136,182,109,219, 34, 62, 62, 30,133,113,209, 16, 54,107, 11, 97,247, 64,196,202, 30, 34,234,114, 56, 94,170,117,134,231, 43, -214, 40,212, 26, 77,176, 94,175, 63, 93,157, 32,135,195, 41, 0, 64, 8, 33, 70, 0, 80, 42,149, 79,212,106,117, 55, 7, 7, 7, - 60,125,250, 84,168, 49, 98,110,208,210,205,219, 9, 33, 70,179,178,217, 92,243, 71,143, 30,141,200,200, 72, 0,136,172, 78, 83, -169, 84,206,153, 62,125,250,181,253,251,247,179,147,146,146,250,239,217,179,167,255,243,231,207, 9,163, 32,213,120,171,136, 3, -143, 73,115,223,251,214,221,231,114, 96, 96, 32, 28, 29, 29,177,123,247,110,108,221,186,181,244,227,143, 63, 78,216,186,117,235, -123, 57, 57, 57,135,107, 88,127,133, 92, 46,191,104, 99, 99, 51,187,101,203,150, 42,141, 70,131,252,252,124,100,100,100,192,218, -198,134,105, 0,179,179,157, 68,114,248,108,150, 74,200,190,120, 15,247,211, 51,107,141,102,117,228,176, 38,142, 8,104, 19,240, -201,242,165, 34,220, 58, 13,198,244, 96,144, 61, 95, 96,222,135, 65, 22, 37,218,195,221, 53,143, 83, 38,200,148,202,131, 74,165, -242, 68, 3, 59,203,128,206,157, 59, 31, 89,179,102,141, 96,217,134, 53,216,212,204, 25,134,252,124,228,106,141,200,211, 26,160, - 44,140,195,211,167,177,176,177,177,197,203,151, 47, 81, 82, 82,130,103,207,158, 17, 22,139,117,182,174,136, 78, 5, 85,110, 23, -202,121, 60, 94, 62,135,195,201,102,179,217, 5, 73, 73, 73,154,146,146, 18, 48,153, 76,161,209,104, 20,212,163,173, 46,182,182, -182, 11, 80,150, 76,244,140, 42, 47,111,155, 63, 7, 18,176,209,195,221,214,102,224,138,153, 19,108,221,156,236,229, 73, 9, 47, - 74,191,187,116, 59,175, 68, 91,243,100, 13, 0, 97, 5, 5, 5,149, 17,201,227,199,143,207, 59,126,252,248, 52, 0,123, 81, 86, -119, 43, 92, 46,151,127,251, 22, 7,223,138,147, 39, 79, 46, 94,190,124, 57, 4, 2, 65,101,242, 84,129, 64,192, 7,128, 31,127, -252, 17, 79,159, 62,237,128,242,241, 90, 38,147,233, 72,102,102,102, 93,154, 30,190,190,190, 73,167, 78,157,226, 2,112,154, 53, -107, 86,167,237,219,183,227,195, 15, 63,204,141,141,141,237, 8, 32, 25,128,199, 71, 31,125,244,224,192,129, 3, 86, 38,147, 9, -133,133,133,208,233,116,201,244, 84, 78,161, 80,168,217,250, 83,240, 7, 16,133,178,252, 89,131, 0,156, 67,217,176,142, 26,113, - 45,119,103,151, 0, 12,169,248,125,172, 97, 48, 60, 80, 54, 35,235, 34,128,255, 2,112,168, 73,212,198,198,230,179, 73,147, 38, -149,166,167,167,147,172,172, 44,114,226,196, 9, 50,127,234, 36, 99, 95, 79, 39,147,167,147,131,198,206,206, 46,222,209,214,122, - 95, 27,115,204, 7,224, 82,143, 21,155,244,252,249,243, 25,147, 38, 77,154, 90,254,189, 83,143, 28, 57,162,190,114,229,138,154, -197, 98,133,161, 44,181, 67,133,161,156, 56,120,240, 96,181, 86,171, 85,251,248,248, 20,160,108,224,126, 77, 4,245,232,209,163, -240,194,133, 11,196,104, 52,254, 46, 71, 81,110,110, 46,185,124,249, 50,233,210,165,139, 28,192,132,222,189,123, 95,191,125,251, -246,245,174, 93,187,158,172,171,193,182,182,182, 75, 31, 63,126, 28,153,146,146, 34, 59,119,238,156,236,240,225,195,178,143, 62, -250,232,137,159,159, 95,113, 66, 66,130,201, 96, 48,144,199,143, 30, 17,159,166, 77, 53, 0,220,107,210,233, 37, 96, 63, 80,238, -254,130,148,172,254,144,148, 12,115, 37, 0,136,106,243,103, 36,123, 78, 31, 18, 63,123, 32,233,201,103,221,125,155,158, 98,109, -109,125, 41, 50, 50,146,168, 84, 42, 18, 19, 19, 67, 38, 6,246, 39,119,167,245, 33, 23,251,123,145, 3,221, 27,147,205,253,252, - 72,255,238,221,200, 55,223,124, 67, 78,157, 58, 69,150, 46, 93,106,178,181,181, 85,161,150, 49, 90, 82,169,244,202,177, 99,199, -100, 0,100, 44, 22, 75,166, 84, 42,101, 42,149,234,108, 90, 90,218, 78, 31, 31,159,197, 45, 91,182, 28,215,172, 89,179, 94, 61, - 27,187, 47,238,109,193,139,239, 99,201,127,209, 84,100,190, 25,191,207,123, 85,137, 24,112,247,244,240, 80,221,184,113,195,164, -213,106,201,205,155, 55, 77,205,155,122,151,108, 26, 53,224,228,203,221,235, 78,150, 92,248,225, 82,209,207,223,223, 62, 62, 57, - 48,186,135, 57,243,135, 78,194,202,116, 28,111,203, 24, 0,167,241,235,172,195, 73, 0,126, 70,237,179, 16,153, 0,246,174, 94, -189,186,234, 76, 67, 0, 96,250,249,249,201, 8, 33, 50, 63, 63, 63, 89, 67, 27, 98,110,110,190,224,204,153, 51, 33,110,110,110, - 27, 70,143, 30,189, 91, 46,151,159, 27, 55,110, 92, 52,202, 38,131, 48, 80, 86, 29, 97,176,139,139, 75,110, 84, 84, 20,185,126, -253, 58, 25, 57,114,164,202,204,204,108, 60, 61,141, 83, 40, 20,202,159,194,140, 26,254,214,202,154,232,232,232,138, 28, 90,179, -106, 19, 95,178,100,137, 44, 50, 50, 82,134,178, 44,241,181,194,102,179,127,250,248,227,143,137,131,131,131,218,222,222,254, 39, - 14,139, 53,205, 85, 0,127,188,221, 84,247,110, 7, 15, 30, 28,250,245,215, 95, 15, 2,208, 1, 0,199,217,217, 57, 35, 43, 43, - 75,125,251,246,109,117,151, 46, 93,212,182,182,182, 57,190,190,190,234, 77,155, 54,169, 75, 75, 75,213, 11, 22, 44, 80,227,247, -249,190,170,131, 15, 96, 54,151,203,253,169,121,243,230,209, 43,134,244, 42,221, 48,119, 26,153,228,101,167, 6,240, 53,128,143, - 1, 72, 0,112,130,130,130,126,121,246,236,217, 37, 95, 95,223, 93,245,208,117,106,217,178,229,213, 35, 71,142, 68,158, 58,117, - 74,246,217,103,159, 69,218,216,216,164, 39, 36, 36,152, 74, 74, 74, 72, 97, 97, 33,145,203,229,228,220,185,115, 70,107,107,235, - 29, 53,174, 56,143,149, 73, 46, 31,170, 54,133, 67,218,242,241,164, 11,151,249,250,109,122,138, 80, 40, 44,200,207,207, 39, 89, - 89, 89, 36, 41, 41,137,156, 60,121,146, 12,232,220,158, 28,253,104, 4, 57, 52,117, 40,217, 56,160, 61,233, 96,193,215, 72, 45, - 68,145, 22, 22, 22, 57,245,153,117, 40,149, 74,175,104,181,218,202,244, 13, 46, 46, 46, 50, 31, 31,159, 83,190,190,190,155,207, -156, 57, 51,111,203,150, 45, 67,123, 54,118, 95,188,182,127,231,226,162,240,227, 68,117,236,107,178,164,173,119, 73,185,153,175, - 22,103, 27,235,131, 55,174, 95, 55, 85,152, 95,131,193, 64, 78,255,244, 19, 25, 53,176,111,180,226,226,143,255,189, 25, 60,231, -200,130,182,222,167,187,240, 49,166, 54,195, 86,121, 41, 34,130, 77,128, 37,115,231,251,110,214,153,221,196,204,175, 59, 90,252, -166,188,212, 40,111,111,239, 36, 66, 72,102,179,102,205,146, 0, 28,106,214,172, 89,213,231,147,107,144,173, 76, 78, 26, 18, 18, - 66,202,143, 15, 38,128, 85,107,214,172,145, 17, 66,100, 94, 94, 94,183, 0,160,181, 16,182,221,197,204,255, 14,241,112,200,239, - 46,102,254,183,181,176,250,146, 81,238,102,104,218,205,206,252,230, 80, 47, 71, 85, 15,103,113,196,161,125,123, 54,188,255,254, -251,187, 1,236, 0,240,133,141,141,205,205, 49, 99,198, 60, 61,112,224,192,211, 77,155, 54,233, 19, 18, 18,200,148, 41, 83, 52, - 60, 30,239, 11,122, 30,164, 80, 40,148, 63,141,138,204,240,142, 13, 49, 90,131, 23, 47, 94, 44, 35,132, 84,228,210,154, 80,205, - 50, 67,150, 47, 95, 46, 35,132, 84,100,135,127, 51,129, 89,117, 9,205, 66,118,238,220, 73,120, 60,222,127,223,114,101,170,106, - 74,135, 13, 27,214, 81,169, 84,190,231,224,224,240, 94,121,228,202,213,214,214, 54,233,240,225,195,234,226,226, 98, 53, 33, 68, -109, 48, 24,212,145,145,145,234, 30, 61,122,168,171, 92,245,215,213,206,223,176, 76,138, 91, 15, 87, 76, 37,203,164,184,245,198, - 91,227,247,238,221,123, 33, 57, 57,249,172,165,165,229,162,122,106,186,218,217,217,173,178,182,182,190,100,107,107,187,204,218, -218, 58, 83,175,215,147,194,194, 66, 18, 31, 31, 79,174, 95,191, 78,238,222,189, 75,172,173,173,211,107,106,103,111, 1,251, 94, -225,134,217,196,180,119, 13,209,109, 95, 74, 0, 16,249,150, 37, 36,239,155, 80,242,112,122,127,210,131,207,186,243, 22,219, 19, - 18,137,228,251,159,126,250,201,148,152,152, 72,194,194,194,200,185,115,231,200,220,185,115, 73, 83, 39, 71,109, 71, 46, 51,187, - 27,143,125,233,109, 18,150,106,181, 90,153, 82,169,148,169,213,106, 89,243,230,205,101,237,219,183, 63,213,177, 99,199,205,199, -143, 31,159,183,118,237,218,161,189, 45,120,241, 69,225,199, 9,249,108, 32, 33,179,187,146, 23,211,122,144, 94, 2,246,227, 26, - 53, 29, 28,210, 43,178,181,107, 52, 26, 18, 17, 17, 65,174, 94,189, 74,164,182,182,202, 0, 1,107, 70, 23, 30,186,119,177,132, -164,190,237,236, 41,102,238,187,247,205,151,198,226, 11, 7,200,143,147, 6, 26,122, 72,152, 59,171, 44,119,148, 16,146, 57,114, -228,200,151,132,144,204,147, 39, 79,166, 17, 66, 50, 71,140, 24,241,146, 16,146, 9,224, 72,117,154,111, 36, 39,221, 91,110,178, -102,135,132,132,200, 8, 33,178,144,144, 16, 25, 80,150, 68,181,187,152,185,255,254,174,141, 38,237,185,253,228,248,148, 65,198, -238, 98,230,254,106,219, 41, 97,159,141,218,187,133,232, 46, 29, 34, 63,205, 29,103,236, 42,181,188,225,237,237,189,113,222,188, -121,167,238,222,189,251,196,104, 52, 62, 77, 74, 74,122,186, 99,199,142,167,157, 58,117,186,101, 99, 99, 19,205,229,114, 63,174, -107, 31,253, 65, 80, 77,170, 73, 53,169, 38,229,205, 0, 83, 45,239,157, 93,191,126,189,144, 16,178, 32, 40, 40, 8,235,214,173, - 27,213,178,101,203, 49,206,206,206,118, 0,144,145,145, 81, 20, 19, 19,163, 12, 10, 10,194,170, 85,171,176, 97,195,134,205, 40, - 27,203,242,191, 36,235,244,233,211, 46,115,230,204,201, 89,187,118,173,105,202,148, 41,205, 0,196,228,229,229, 53, 29, 55,110, -220,108, 54,155, 29,228,238,238,238,155,153,153,153, 91, 92, 92,124, 8,192, 46,212,113,207,180, 38,120, 76, 24,219, 53,114,196, - 37, 38,140, 85, 94, 30,184,106,213,170,209, 35, 70,140,208,111,217,178,197,160, 84, 42,207,212, 83, 46, 45, 55, 55,247,243,138, - 39,214,214,214,210,199,143, 31,127,108,111,111,207, 76, 74, 74,130, 86,171, 69, 98, 98,162, 9,101,183,166,170, 69,109, 32,219, -190, 61,121,197,103,193,248, 64,203,162,184, 71, 48, 99,177, 80,202,225, 34,235,222, 37,236,141,136, 83,106,244,216,254, 54,235, - 41,151,203,191,154, 59,119,238,184, 69,139, 22,241,221,221,221, 25,119,238,220,193,177, 99,199,180, 57, 57, 57, 3, 0,220,248, - 53,245, 83,195, 48,153, 76,224,114,185, 0,128, 37, 75,150,128,201,100,114,114,114,114,184, 12, 6,131,199, 96, 48,204, 25, 12, - 6,171, 52,249, 41, 76,202, 66,100, 23,202,145,150, 45,175, 85,207,104, 50, 29,187,127,255,254,252, 54,109,218, 48, 31, 62,124, -136,220,220, 92, 36, 38, 38, 18, 35, 33, 71, 34,138,141,101,131, 18,181,245,111,159,185,181,205,176,214, 86, 60, 38,119,223, 42, - 4,232,152,172,239, 76, 24,137,178, 92, 90, 0,176,151,193, 96,152, 1,200,111,222,188,121,207,103,207,158, 9,154, 55,111, 94, - 28, 23, 23,119,129,193, 96, 56, 3,216, 95,157,166, 64, 32,200, 3,144,119,242,228, 73, 0,152,142,178,141,215, 54, 56, 56, 56, - 51, 34, 34, 2, 33, 33, 33,217, 0,118, 2,128,200,202,102,136,175,216,140,193,253, 33, 4,157,180, 96,110, 55,145,106,163,174, - 34,123,135, 94, 45,133, 76,112,246,172,196,123, 82, 31, 38,215,160,111, 21, 26, 26, 26,161, 86,171,181, 71,143, 30,213, 77,158, - 60,153,149,144,144,240, 0,192, 77, 0, 39, 81, 62,198,146, 66,161, 80, 40,127, 42,111, 70,176,234, 28,163,245,166,107, 93, 7, -224,219,231,207,159, 87, 22,149,126,254,252,185, 12,192,119, 40,203, 6, 63,184, 1,142,119, 69,121, 68,107,215, 91,174,204,155, -154,124,127,127,127,193,179,103,207,204, 80,125, 17, 71,198, 91,104,254,142,234,106, 29,122,123,123,111, 45, 45, 45, 61,245,221, -119,223, 29,103,177, 88,227,222,193,237,187,123,121,121, 21, 30, 62,124,216, 20, 22, 22, 70, 86,172, 88, 97,116,116,116, 44,196, -239,199,104,253, 70, 51,128,203, 58,177,176,153,179, 50,114, 66, 87,242, 98,222, 16,114,115,124, 15, 50,195, 89,164, 12,224,179, -142,189,227, 85,137,151, 88, 44,222, 43, 16, 8,148,150,150,150, 87, 0,116,126,151,125,100, 99, 99,115, 64, 42,149, 94,169,250, -112,112,112, 56,101,103,103,247,181,173,173,237, 10,137, 68, 50,211,131,207,221, 50,175,169, 83, 73,244,176,230, 36,188,139, 29, - 25,111,203,125,243,214,225,155,237,116,244,240,240,200, 63,120,240,160,233,236,217,179,100,233,210,165,166, 70,141, 26, 41, 81, -203,184,182, 90, 35, 90, 18,214,177, 19, 35, 58,154,178, 7, 57,147,117,205, 44, 76, 61,173, 88, 53,205, 80, 28, 95,110,128, 39, -213,165,233,233,233,249, 29, 33,100,223,234,213,171,247,225,215, 90,160,125, 67, 67, 67,131, 9, 33,193,161,161,161,193, 0,250, - 3, 64,128,152,121,240,208,208,118,198,140,247,157,200,151,205, 68,198, 0, 49,243, 96,181,145, 76,107,246,233,159,167, 13, 50, -101, 78,235, 66, 86,121, 9,141, 29,173,121,191,112,185,220,121, 40,139, 56,183, 7,192,165, 87,205, 84,147,106, 82, 77, 26,209, -250,203, 25,175,122, 33,181,182,182,222,219,164, 73,147,227,238,238,238,199, 69, 34,209,102,148, 13,154,111,232,142,240, 88,179, -102,141, 82, 44, 22,183,254, 3,119,174, 61, 0,103,252,190,112,238, 31,214, 97, 62,119,196,156,132, 69,163, 30,127,238,136, 57, - 85, 94,110,223,172, 89,179, 47, 81,150,205,251, 93, 59,161,187,181,181,245, 14,107,107,235,244,242,177, 89,238,245,209,108,199, - 98,141,235,201,103,221,233,204,101,102,245,228,179,111,191,199, 98,141,253,155, 30,128,181, 77,182,168, 73,211,197,214,214,118, -139,181,181,117,134,173,173,237,142, 6,154,172,223,104,182, 22,192,177,151,132,117,186,179, 5, 67,211, 75,204, 58,217,206,188, -230, 73, 29, 13, 88,119,255,144,144,144, 15, 9, 33, 31, 58, 57, 57, 5, 85, 49,254,190,171, 86,173, 10, 36,132, 4, 86,100,128, -111,111, 14,251, 30, 18,214,225, 46,150, 12,121, 15, 9,235,112,123,115,216,215,212,206,158, 18,214,177, 46,150, 12,121,128, 37, -243,176, 27, 15,141,232,201,156,106, 82, 77,170, 73,141,214, 63,195,104,209, 14, 67, 53,169, 38,213,164,154, 84,147,106, 82, 77, -106,180,170, 55, 86, 85, 31,149,119,216,216,116,219, 80, 40, 20, 10,133, 66,161,188, 19, 53, 38, 44,101,212,226, 74, 27, 50,176, -253,109,156,109, 56,213,164,154, 84,147,106, 82, 77,170, 73, 53,255,117,154,117,105,255,175, 39,214,253,173,161, 97, 85,170, 73, - 53,169, 38,213,164,154, 84,147,106,254,107, 97,210, 77, 64,161, 80, 40, 20, 10,133,242, 78,248,151,255,125, 51,113,105,245, 99, -180,216,237, 87,103, 27, 12, 6,123, 0, 96,179,217, 57,165, 15, 86, 56,214,166,206, 1,122, 27,202,202,239,128, 13, 76, 55, 0, - 87,170,209,188, 98, 48, 24,172,202, 53, 11, 75, 31,172,232, 95,171,102,251,213,151,170, 46,111,120,176,162,239,155,203, 16,128, -197,105,191, 58,227,141,182, 58,213,119,171, 48,240,155,156, 88,127, 90, 59,255, 46,154,255,102, 56, 29, 86,103,151,150,150,245, - 35, 14,135,157,163,191, 95,123, 63, 50,235,176, 58,163,234,242,165,247, 87, 56,212,166,105, 46,224,229,123, 58,219,109,174, 77, - 51, 41, 35,111,129,166,168,196,166, 54,205,134, 30,155,174,142,142,189,141,229,199, 38, 11,152,158,158,153,121,229, 47,214,151, -218, 1, 88, 1,192,178,202,107,209, 0, 62,165,189,146, 66,161,252,205,140, 86, 20,202,234, 28,126, 95,110,182,190,175,209,104, - 25, 12, 6,123,217, 79,193,208,104,129,222, 19, 87,219,123, 12,219,245,187, 66,201,134,146, 66,174, 60,246,168, 47,171, 84,105, -101,199,214, 91,102,100,100, 48, 0,128,193, 96,252, 23,128, 91, 53,154, 86,178,159,130, 81,164, 3, 2,198,132, 90,185, 1,150, -185,102,102,255, 17, 8,133, 61,139,139,139, 91, 2,128, 64, 32,136, 45,214,104,174,217,233,245,155,222, 92,190,166, 53,171,218, -214, 94, 19, 86,219, 55, 27,182,107,174,209,100,226,190,126,248, 93, 64, 73, 94, 2,155, 99,208,238, 92, 6, 92, 8,174,198, 84, -213,160,247,235,247,126,176,212,134, 3,244,226,242,249,173, 37, 86, 86,221, 76,132, 52, 55,153, 76, 12,163,193,240, 84,169, 80, -220, 52, 25, 12,143, 13, 58,141,141,236,204,151,166,218,218,249,230,186,124, 0,176,127, 2,130,132, 34, 81, 79, 22,135,211, 25, - 0,140,165,165,119, 52,106,245,181,225,192,137,250,172,123,125,183,207,219, 46,255,111,163,180,212, 96,159,124, 41, 24,218, 82, -192,127,228,151,246,126,227,126, 56, 12, 0,186,156,199, 14,234,132, 51, 29, 0, 64,232, 25,120,159, 39,245,207, 6, 0,246,171, - 76,251,248,176,229,208,150, 2,205, 3, 67,237,235,210,156,188,234,152,205,162, 25, 35,120, 0,112,249,228,215, 77,175,158,250, -118, 32, 0,244, 26, 49,235, 66,191,145,115,226, 1, 96,195,247,167,108,142,124, 57,170, 86,205,250, 29,155, 10, 51, 69, 79,238, - 8,153, 0, 0, 32, 0, 73, 68, 65, 84, 66,152,151, 78,153, 41,113, 21,178,165, 9, 9, 9, 76, 0,112,114,114,170,215,177,233, - 2,136, 51,129,217, 76, 22,171,155,167,151,151, 63, 0,146,244,226, 69,148,209, 96,184,229, 8,236,252,131,251,210, 92, 66,126, -155,156,149,193, 96,208, 14, 73,161, 80,254,110,156, 43, 55, 87,231,126,119, 49, 91,211, 39, 52, 90,224, 70, 34,208,189,163, 31, -102,140,123, 95, 84,245,189, 19,187, 66,221, 18, 30,254,220,108,207, 15,155,152,126,126,126, 72, 78, 78,174, 87, 43,138,116,192, -245, 4, 0,242,103, 22,133, 66,225,139, 45, 27, 55, 90,246,237,219,151,237,228,228, 4, 6,131,129,172,172,172,142,225,225,225, -237,230,207,159,255, 17,228,207, 10,139,116, 80, 93, 79,168, 91,183,162,173, 45,155, 54,194,138, 57,163,196, 0,176,108,226,206, -118, 15,159,103, 91,191,120,241,162,247,226,197,139,243, 89,215,174,125,107, 11,236,203, 6,210,234,211,206, 3,103,239,243,197, -153, 63,122,140,159, 51,231,164,151,151,151,200,221,221,157, 97, 97, 97, 1, 22,139,133,194,194, 66,183,152,152,152,129, 15, 30, - 60,208,132,223,248, 47, 55,242,193,144,164, 28,126,135,146,122,173,123,113, 6,255,178,133, 69,236,132,225,195, 93, 70,141, 26, -197,247,244,244, 4, 0,188,120,241,194,251,196,137, 19, 99, 78,158, 60,185, 10,197, 25,134, 34, 29, 74,234, 90,247, 74, 77, 0, -124,160,179,196,222,126, 60,139,195,105,105, 48, 24,156,203,163, 13,175,141,165,165,177,242,156,156, 67,111, 46, 79,249, 61,218, - 82,224, 89, 38,208,167,155, 63, 38,140,232, 35, 4,128,197,163,215,116,124,245, 50,209, 76,167,211,161,169, 79,243, 46, 95,124, -185,249, 18,152, 76, 28, 60, 21, 94,185,124,125, 52,163,159, 37, 35,248,139, 45,200,120,114,162,163, 81,145,216, 83,165, 84,176, - 0,192, 82, 44, 30,113,226,232,143,215,156,124,131,238, 37,230,233,235,165, 89,219,177,121,241,232, 14,199,244,152,107, 45,190, -185,188,151,227,230,230,134, 39, 79,158, 52,236,216, 84, 60,183, 48, 57, 58, 62,221,244,217,103,210,128,128, 0,136, 68, 34,176, -217,108, 24, 12,134, 62,183,110,221,234, 19, 28, 28, 60, 11,138,231,154,250, 30,155,245, 96, 19,131,193,232, 57,121,198, 92,199, -247,135, 6, 97,196,128, 46,180, 35, 82, 40,148,191, 27, 21,209,171,170, 51, 15,191,175,213,104,177,217,236,156,190,147,214,218, -119,235,208, 10, 15, 31,199, 43, 82, 82, 51,213, 21,239, 21,196,158,104, 58,180,139,115,139,136,136, 27,208,106,181,184,115,231, - 14, 30, 63,126,140,151, 47, 95, 98,230,204,153,218,242, 91,135,213,105, 22, 6,140, 9,181,130, 34, 65,228,205,125,222, 56, 60, - 46,142, 85, 82, 82,130,136,136, 8, 20, 22, 22,130,203,229,194,197,197, 5,253,250,245, 99,199,197,197, 89,247,238, 59, 64, 28, - 48, 96,108, 50,196,222,106, 54,155, 93, 88, 83, 29, 17, 54,155,157,211,123,226,106,251, 22,222,141,240, 34, 37, 67,177,226,203, - 61,106,147,137,176,147, 94,190,210,223,184,113, 3,254,254,254,184,114,229,138, 77, 65, 65,193,202,157, 59,119,174,224,172,255, -102, 91,169, 46,127, 33,106,214, 43, 12, 24, 19,106,101,147,115,220,253,234,197,211,102,177,177,177,102,223,125,247, 29,242,243, -243,193,229,114, 33,145, 72, 32,149, 74,209,180,105, 83,198,178,101,203, 68,129,129,177,248,100,122,144,187,222, 99,218,243,154, -218, 89,185,238,234, 87,230,182,202,203,158,167,206,157, 99,118,237,218,245, 55,151,237, 77,154, 52, 65,255,254,253,249,227,199, -143,247, 28, 53,102,156, 41, 96,208,228, 23, 16,185, 23,213,169,169, 73, 19,216, 20,221,117,234, 51,102,204,153,208,208, 80,137, - 84, 42,133, 80, 40, 4, 0, 40, 20, 10,151,148,148,148,142,171, 86,173, 26,121, 63,250, 40, 59, 32, 48, 45, 3, 66,215,226,218, -182,231,191, 21, 14,135,157, 83, 17, 69,178, 16, 10, 10,211,210,179, 53, 0,160,211,233,160,211,233,160,213,106,241,241,172,153, -172,233, 35,219,123,185,119,155,251,232,229,235,236,130,230,225,247,172, 43, 62, 91, 90,135, 38,187,232,165, 92,158,250,203,244, -224,207, 62,147, 58, 56,252,122, 71,240,224,129, 3,172,130,130,130, 62,193,193,193, 45,136,121, 15,121,243,192, 80, 73,109,154, -181, 29,155,242,248,115,141,191,152,211,191,245,174, 47,195, 96, 52, 26,113,247,238, 93, 68, 68, 68, 96,243,230,205,228,194,133, - 11, 10, 75,161,112, 58,106, 61, 54,159, 91,116,117,204,242, 88,191,254, 36,131,199,227,225,231,159,127, 70, 92, 92, 28,152, 76, - 38,252,252,252, 48, 97,194, 4,244,233,211, 71, 58, 99,198, 76, 18, 48, 96,116, 18,196, 62,170,119,236, 75, 76, 0,115,151, 6, -175,119,156, 56,109, 54, 54,124,177,140, 26, 45, 10,133,242,119,142,102,213,152,226, 1, 97, 97, 97,164,252,209, 29, 0, 8,192, -108, 50,108,215,145,227,145,166,115, 77,134,237, 58, 66, 0, 38, 1,152,150, 64,163, 54,109,218,148,202,229,114,242,224,193, 3, -242,241,199, 31,107,182,109,219,118,237,220,185,115, 39, 12,122,253,110, 39, 71,199,175, 72, 13, 3,236, 9,192,116, 7,196,230, -230,230,185,169,169,169,228,252,249,243, 36, 36, 36,132, 28, 58,116,136, 92,184,112,129,132,135,135,147, 11, 23, 46,144, 35, 71, -142,144,232,232,104, 18, 31, 31, 79,132, 66, 97,174, 59, 32,174, 69,147, 69, 0, 86,211, 97,223, 45, 60,249,176, 52,212,103,216, -174,249, 4, 96, 89, 1,205,218,180,105, 99, 60,113,226, 4, 57,120,240, 32,249,225,135, 31, 72,116,116, 52,201,203,203, 35,108, -158, 48,183,226,115, 53,181,147, 0, 76,103,103,231, 92,185, 92, 78, 92, 93, 93, 9,151,203, 37, 14, 14, 14,164,105,211,166,164, - 99,199,142,100,224,192,129,100,220,184,113,100,229,202,149, 68, 46,151, 19, 62,159,159, 93,241,185,154, 52,253, 1,129, 80, 40, - 76,149,201,100,164, 38,138,139,139, 73, 94, 94, 30,185,116,233, 18, 17, 10,133,169,254,128,160, 54, 77, 1,208,214,215,215, 55, - 55, 47, 47,143,232,245,122,146,154,154, 74, 98, 98, 98, 72, 92, 92, 28, 73, 77, 77, 37,197,197,197,149,218,241,241,241,196,195, -195, 35, 87, 0,180, 37,116, 18, 68,141,125,233,205,135,155,131,195, 64,169, 84, 90,124,242,228, 73,242,250,245,107,178,127,255, -126,194, 4,214,188,185, 92,109,154, 92,160, 95,215,174, 93,141,119,239,222, 37,143, 30, 61, 34, 75,150, 44, 33,253,251,247, 39, - 3, 6, 12, 32,193,193,193, 36, 61, 61,157,164,167,167,147,129, 3, 7, 26,185, 64,191,186,250,103,117,199,166, 24,112, 11, 12, - 12, 44,214,235,245, 36, 41, 41,137,180,108,217, 50,157, 5,140, 23, 2, 45,186, 3,188,186,250,167, 51, 96,229,232,232,152,121, -247,238, 93,114,234,212, 41,226,238,238,158,203, 2, 38, 91, 2, 77, 44,129, 38, 44, 96,114,147, 38, 77,114,239,222,189, 75,242, -243,243,137,155,155, 91,166, 51, 96,245, 14,125,137, 9, 96,239,210,224,245,228,121,186,134, 44, 13, 94, 79, 0,164, 18, 66, 8, -170, 25,227, 73,161, 80,254,249,188,233, 69,254, 41, 84,158, 36, 3, 3, 3, 25, 0,174,215,182,112, 49,139,181,118,195,134, 13, -236,146,146, 18,236,217,179, 71,245,193,200,145,199,187,119,235,150,212,216,221, 93,206, 96, 50,235,172, 54,156,203,227,205,219, -176, 97,131, 68,167,211, 33, 50, 50, 18,237,218,181,131, 84, 42,133, 72, 36,130, 72, 36,130,189,189, 61,124,124,124,144,147,147, - 3, 11, 11, 11, 44, 90,180, 72,156,203,227,205,171, 75,215,100, 34,108, 0, 48,154, 76, 92, 51, 96,134,199,123,239, 69,174, 90, -181,138,105, 99, 99, 3,107,107,107,136, 68, 34,196,197,197, 65,167,211,193, 92, 96, 94,175, 36,173, 76, 38,147, 41, 18,137,112, -245,234, 85,204,157, 59, 23,157, 59,119,134, 68, 34,129,133,133, 5, 90,182,108,137,126,253,250, 97,250,244,233, 72, 74, 74, 2, -163, 30,131, 74,158,178,217,179,167, 79,159,110,239,239,239, 95,237,251, 37, 37, 37,144,203,229,200,205,205,133,139,139, 11,130, -130,130,236,159,178,217,179,107,210,179, 1,164, 46,222,222,103, 30, 60,120, 96, 43, 20, 10,113,240,224, 65,156, 62,125, 26, 23, - 47, 94,196,249,243,231, 17, 22, 22,134,159,127,254, 25,185,185,185, 0, 0,111,111,111, 28, 59,118,204, 86,100,111, 31,102, 3, - 72,233, 33, 93, 63, 94,101,103, 95,110,153,149,101, 59,126,220,184,155,106,181, 26,227,199,143,199,218,117,235,150,113,128,249, -245,249,188, 15, 32,182,118,116,220,183,126,253,122,102, 86, 86, 22,134, 15, 31,158,183,105,221,186,169, 81,151, 46,121,202, 46, - 94,244, 92, 27, 26, 58,181,123,247,238,121,233,233,233, 56,112,224, 0,211,193,205,109,159, 15, 32,110,104, 59, 85,192,220,173, - 91,183,242, 75, 74, 74,208,183,111,223, 36, 83,108,172,143, 1,248, 81, 13,196, 93, 7,244,117,125, 62, 19,152,189,104,209, 34, - 41,143,199,195,127,254,243,159,188,162, 87,175, 90, 25,128, 31, 20, 64,138, 2, 72, 49, 0, 63,168,146,147, 91, 77,156, 56, 49, -143,199,227, 97,203,150, 45,210,204, 95,139,110,215,151,118, 0,206, 0,184, 1, 32, 99,242,140,185,147,253,219,119,194,129,221, - 59,241,101,232,226,125, 0, 62, 96, 48, 24,135, 0, 44,164, 61,143, 66,249,119, 82, 31, 47,242, 23,165,198,146, 59,236,170, 78, - 18, 64,143,218, 84,172,108,108,218,181,106,213, 10, 17, 17, 17,240,245,245,125, 32,145, 72, 12,102, 60, 30, 56, 28, 14,136,169, - 78,159, 5,129, 80,216,187, 79,159, 62,236,123,247,238,193,195,195, 3, 2,129, 0, 28, 14,231, 55, 15, 51, 51, 51, 56, 58, 58, - 66,169, 84,162,119,239,222,156,237,219,183,247,134, 86,251, 69,157, 63,136, 9, 49,162,220,123,235,199,253,119,255,190, 38, 1, - 1, 1, 80, 40,148, 48,153, 76, 48, 55, 55,135, 78,167, 3,155,205, 46,187, 5, 84, 74,148,245,217, 98, 70,163,209,200, 98,177, -224,225,225,129,181,107,215,162,164,164, 4,102,102,102, 0, 0,165, 82, 9,185, 92,142,152,152, 24,164,164,164,160,252, 42,188, - 86, 44,196,226,247, 71,141, 26, 85,109,193, 95,173, 86, 11,133, 66, 1,133, 66, 1,185, 92,142,146,146, 18,116,234,212,137,123, - 46, 44,236,125,228,231,111,170,246, 51,124,254,200, 3, 7, 14,216,115,185, 92, 20, 23, 23, 67,165, 82, 33, 45, 45, 13,175, 94, -189, 42,201,201,201, 49, 88, 88, 88, 48,221,221,221,153, 60, 30,143, 55,108,216, 48,134, 82,169, 4,131,193, 64, 96, 96,160,205, -225,131, 7, 71, 65,167,219, 76, 15,233,250,113, 25,208,182,213,233, 6,119,104,223,254,234,131,135, 15,253,231,205,155,135,232, -232,232,245,230, 71,143,222, 40, 2, 30,215,246,217, 36, 96,246, 87, 85, 12, 12,121,245,202, 87, 15,228, 86, 89, 36,197, 61, 57, -249,226,196,137, 19,159, 68, 71, 71,219,110,217,178, 69,250,193,240,225,179, 1,172,105, 72, 27, 45,196,226,247, 28, 29, 29,113, -225,194, 5,164,190,124,185,216, 0, 20, 55,232,138,139,197,234, 26, 16, 16,128,159,127,254, 25,233,175, 94, 45, 54,252,182,141, -101, 23, 74, 64, 46, 59, 41,105,241,190,125,251,246, 78,153, 50, 5, 44, 54,187, 43, 12, 13,186,113,248,187,129,239, 83,102,206, -195,190,239,183,239, 3, 48, 13,128, 9,192, 3,218,227, 40,148,127,119, 84,171, 46, 47,242, 55, 50, 91,223, 55, 56,162,101,111, -111,239, 44, 18,137,144,145,145,129,230,205,154,229,240,120, 60,112, 57, 28,240,185,220,122,181,160,168,168,200,215,201,201, 9, - 10,133, 2,182,182,182, 48, 51, 51,171,124,112,185,220,202,255, 45, 44, 44,192,100, 50,225,230,230,134,162,162, 34,223, 58,117, -179, 99,236,143,110,159,245,241,221, 27, 23,154, 12, 31, 62, 2, 86, 86,214,112,117,117,129,189,189, 61, 4, 2, 1, 92, 93, 93, -225,233,233, 73, 54,109,218, 4,115,123,191,122,157,200,171,154, 39, 54,155, 13,163,209,136,236,236,108, 60,127,254, 28,209,209, -209,184,123,247, 46, 30, 61,122, 4,149, 74,133,122,248, 44, 20, 21, 23,183,102,179,217,213,154, 44,185, 92, 14,185, 92, 94,105, -180,114,115,115,145,146,146, 2,181, 70,211,166, 22,211, 59,162, 85,171, 86, 44, 0, 16, 8, 4,104,211,166, 13,118,237,218,101, - 56,123,250,244,232, 22,119,239, 90,187, 94,186, 36,249,239,119,223,141, 14, 10, 10, 50,222,187,119, 15, 74,165, 18,207,158, 61, -131,157,157, 29,155,203,231,143,162,135,115,195,144, 1, 26, 91,149,106, 64,231,206,157,147, 21, 10, 5, 54,110,220,200,228, 88, - 88,124, 31, 90,195, 45,190, 74, 88,172, 46, 1, 1, 1, 56,115,230, 12, 50, 94,189, 90,242,170, 26, 3,243, 10,200, 77, 77, 74, - 90,178,111,223, 62,244,235,215, 15, 12, 54,187,193, 3,149, 58,118,236,216,202,100, 50,225,201,147, 39,144, 0,247, 27,250,121, - 79, 47, 47,255,138,200,175, 16,184, 89,211,114, 66,224,102, 84, 84, 20, 4, 2, 1,154,183,104,209,182,129, 95,179,137,193, 96, -100, 78,153, 57, 15,167, 46,222, 6, 0,236,251,126,123,118, 21,147, 69,161, 80,104, 68,235,239, 26,209,170, 48, 86, 85, 31,248, -141,209,170,167,249, 0, 0,112, 56, 28,112,121, 60,112,185,220, 50,131,196,227,213, 91,131,193, 96,128,207,231, 87, 26,171,170, - 6,171,234,255,230,230,230,245, 50, 48, 0, 80,152,120,177,219,180,169, 83,184, 60, 30, 15, 58,157, 22,132, 16,240,120,124, 72, - 36, 18,120,120,120, 64,169, 84,162,115,151,238,218, 52,185, 89,152, 77,243, 97,209,111,179,245, 12, 6, 3, 52, 26, 13, 10, 11, - 11, 81, 80, 80, 0,165, 82,137,226,226,226,122, 79, 69, 55,153, 76,172,180,180, 52,252,248,227,143,200,207,207, 7, 80, 54,208, -186,194, 92, 85,252, 77, 78, 78,198,193,131, 7,241,242,229,203, 6,237,159,110,221,186, 33, 44, 44,140,213,163,119,239,221, 87, -220,221, 51,174,184,187,103,244,232,221,123,247,153, 51,103, 88,206,206,206, 72, 73, 73, 65,100,100, 36, 10, 11, 11, 65, 8,161, -243,231,223,130, 23, 64, 97, 81, 65,193,148,101,203,150, 17,145, 72,132,141, 95,125,213,122, 13, 48,182,190, 6, 70, 92,139,129, - 17,191,155,129, 1, 33, 4, 38,147, 9, 70,163,241,173,214,141,193, 96, 48, 56, 28, 78, 67, 83, 43, 52,100,225,202,129,239,139, - 86,174,197,249,159, 79, 84,188,158, 64, 77, 22,133, 66,249, 7, 80,227, 64,120,118, 21, 7, 89,249,183, 38,178,179,179, 95,107, - 52,154, 38,238,238,238, 72, 79, 79,183,119,115,115,123,197,229,112, 96,198,229,130,193,172,219, 19,152,155,155, 63,201,200,200, -232,226,236,236, 12,131,193, 80,105,170,222,188,117, 88, 17,165,121,244,232, 17,204,205,205,159,160,164,214,204, 9, 48,234, 10, - 27,181,109,219,182, 50, 50, 36,145, 72, 32,145,136,193,227,241,177,124,249,114,211,150, 77,155,118,186,245, 10, 85,124, 56,127, - 25, 89,182,102,247, 31,186,101,235,251,195,100,110,110,254,196,213,213,181,147, 88, 44,198,169, 83,167,144,146,146,130,194,194, - 66, 20, 21, 21, 65,171,213,162,168,168, 8, 58,157, 14,124, 62, 31, 45, 90,180,128,165,165, 37,194,195,195,159, 64,171,173,222, - 92,230,231,159,122,242,228, 73,167,246,237,219, 87, 70, 84,122,246,236,201,232,217,179,167,109,101, 20,173,168, 8,121,121,121, -120,240,224, 1,194,195,195,193, 96, 48,144,144,144, 96,212, 22, 23, 31,161,199,196,219, 81, 2,220, 97,237,219,183,247,163,143, - 62,154,218,165, 75, 23, 24,129,129, 0, 14,254, 63, 26, 24, 0,192,221,187,119, 99,140, 70, 99,151,166, 77,155, 66, 14,116, 0, -240,115,131, 76,100, 98, 98,148,193, 96,232,221,186,117,107,156, 58,126,188, 27,128,148,234,150,211, 0,221,252,253,253, 81, 92, - 92,140,103, 79,159,202, 26, 96,178,118, 47, 13, 94, 63,121,226,180,217, 56,176,123, 39,246,125,191, 61,109,239,174,109,174,168, -199,248, 49, 10,133,242,175,138,102,213,233, 69,254,162,204,168,201,124,177, 27,162,162, 40, 44,148, 69, 69, 69, 53,105,219,182, - 45,118,239,222,221,190,115,167, 78,175,205,184, 92, 3,215,204, 12,204,122,252,144, 20,107, 52,191,252,242,203, 47, 29,134, 13, - 27,198,190,119,239, 30,164, 82,105,165,209,170,248,203,102,179, 65, 8,129,185,185, 57,126,250,233, 39,125,177, 70,243, 75,157, -209, 34,163,201,200, 44, 55,122,132, 16,200,229,114,152,153,153, 97,243,230, 45,216,177,105,211, 56, 35,112,194, 91,104,247, 25, - 0,254,255,219, 15,116, 81,209,213,243,231,207,183, 91,181,106, 21,199,197,197, 5,114,185, 28,133,133,133,200,207,207,135, 82, -169,132, 82,169, 68, 97, 97, 33,228,114, 57,248,124, 62,162,163,163, 75, 75,138,138,174,214,164,199, 43, 41, 57, 57,105,210,164, - 69, 81, 81, 81,142,108, 54, 27,165,165,165, 48,153, 76, 48,153, 76,208,235,245, 72, 76, 76, 68,108,108, 44,226,226,226, 80, 80, - 80, 0, 14,135, 3, 22,139,133, 71,143, 30, 21, 10, 75, 75,143,235,232, 49,253,214,112,128, 83,183,110,221,154, 58, 97,194, 4, - 56,185,184,116, 71,122,122,189, 12,204,233, 90, 12,140,226,237, 12,204,175, 6, 72,165,122,152,156,156,220,165, 71,143, 30,112, -116,113, 89,223, 34, 61,253,202,211, 6,140,211, 50, 26, 12, 55,111,221,186,213,123,226,196,137,216,189,123,247,122,187,228,228, -139,185,111,220,230,180, 3,236, 26,123,122,174,159, 60,121, 50, 46, 95,190, 12,163,193,112,179, 22,201,170, 25,223, 27, 77,158, - 49,215,245,141,129,239,187, 24, 12,198, 28, 0, 27,105,143,162, 80, 40,255,228,136, 86,131,110, 29, 10,140,198,165, 11, 23, 46, - 44,101, 50,153, 24, 49, 98,132,197,207,103,206, 4, 61,122,252,216, 35, 39, 39, 71, 98, 52, 26,235,212,178,211,106,183, 45, 92, -184, 80,174,211,233,224,227,227,131,130,130, 2, 24,141, 70,176,217,108,176,217,108, 48, 24, 12, 48,153, 76,136, 68, 34, 68, 69, - 69, 97,239,222,189, 74, 59,173,118, 91,157, 63, 18, 70,227,147,131, 7, 15,130,197, 98, 17, 62,159, 15, 6,131, 1, 54,155,141, - 45, 91,182,228,236, 0, 78, 1, 0,139,201,212, 1, 0,147,201,168,239,232,221, 58,239, 91,114,185, 92,152,202, 38, 1,212,185, -172,149, 86,187,117,195,134, 13,170,103,207,158, 65,163,209, 84, 70,223,212,106,117,229,224,122,185, 92, 14, 6,131, 1,141, 70, -131, 51,103,206,168,172,180,218,173, 53,233,229, 3, 89,233, 9, 9, 67,218,183,111,159,159,156,156, 12,133, 66,129, 39, 79,158, - 32, 60, 60, 28,199,142, 29,195,229,203,151,145,152,152, 8,131,193, 0,103,103,103, 16, 66,112,250,244,105,133, 65,165, 26,152, - 15,100,209, 99,162,102, 26, 73,165,189, 29,236,237, 83,237,108,109,211, 27, 73,165,189,223,124, 95, 12,196,199,199,199,195, 96, - 48,192,195,195,195,186,182,113, 90,196, 96,184,117,235,214, 45, 76,156, 56, 17,174, 77,154,172,115, 7,236,222, 92,198, 29,176, -115,247,244, 92, 87, 97, 96,136,193,112,171,161,109,182, 0,182,127,246,217,103,197,102,102,102, 56,122,244,168, 71,169,151, 87, - 28, 27, 24, 43, 2,154,245, 0,204,234,250,188, 35,176,115,229,202,149, 89, 12, 6, 3,135, 14, 29,178, 21,123,122,198,176,129, - 73, 98,160,145, 24,104,196, 6, 38,137, 61, 61, 99,142, 30, 61,106,107, 48, 24, 48,127,254,252, 44, 71, 96,103, 45,146,115, 9, - 33,131, 9, 33, 1,132, 16,215,189,187,182,225,252,207, 39, 42, 76,214, 52,148, 13,122,159, 0, 32,134,246, 56, 10,133,242, 79, -166,218, 48, 20,187,253,234,108,128,216,119,239,232,135,135,143,159, 43,108,173, 44, 47, 85,188, 87, 16,123,162,105, 47, 95, 75, -191,111,190,249, 6, 28, 14, 7,105,105,105,120,250,244, 41, 44, 45, 45, 49,110,220, 56,109,177, 74, 53,164, 74,173,195, 62, 0, -194,203, 53,203,234,169, 41, 18, 68,158,236,232, 38, 23,207,135,177,196, 98, 49,212,106, 53,152, 76, 38,248,124, 62,204,205,205, - 33, 16, 8, 16, 25, 25,137, 65,131,135, 26,115,205, 3,126, 77, 88,250,107, 61,181, 74,205,138, 92, 67, 29, 0,243, 40,224, 63, -246, 78, 78, 11, 87,172, 88, 33,232,223,191, 63,204,204,204,224,210,200, 59,203, 99,192,198,237, 76, 38,195,144,158,175, 92,238, -217,200, 73,252, 52, 33, 5, 0, 35,167,244,193, 10,167, 42,181, 14,127,215, 78, 55,221, 13,143,159,126,216,100,217,166, 77,217, -120,116,185, 92,142,236,236,108,228,228,228, 64, 46,151, 67,163,209, 0, 0,194,194,194,112, 62, 34, 78, 89,236, 18,148, 84, 83, - 59,127, 93,247,231, 22, 78,250,251,141, 15, 31,252,129,101,103,103,135,236,236,108,228,230,230, 66, 46,151,163,184,184, 24, 70, -163, 17, 5, 5, 5,216,179,239, 7, 99,190, 40,224,101,101, 66,200,218, 52, 53,105, 2,107,245,109,103,255, 22,238,100,234,212, -169, 22,150,150,150, 48,153, 76, 40, 44, 44, 68,106,106, 42,146,147,147, 17, 17, 17,161,201,145,235,160,177,237,155, 94,153,176, -180, 26,205, 63,144,191,157,102,213,188, 85, 78,142,142, 25,175, 94,189,178, 55, 26,141,112,118,118, 54,200, 11, 10,214,113,129, -203, 22, 64, 38, 0,146, 7,172,216,186,125,251,148,161, 67,135,226,189,247,222, 75,203,202,206,110, 92, 93, 95, 34, 0,203, 7, - 16, 23,185,184,196, 62,120,240, 64,154,154,154,138,137, 19, 39,230,189,122,241, 98, 73,197,120, 45, 5,208,205,221,211,115,221, -209,163, 71,109,155, 52,105, 2, 95, 95,223, 44,126,106,106,203,231,128,162,134,254, 89,227,177, 41,143, 63,215,120,214,240, 86, -239,125,252,241,199, 48, 24, 12,136,136,136,192,253,251,247,241,234,213, 43,220,190,125, 91,110, 41, 20,142,174, 82,235,176,218, -254, 57,208, 91,227,113,232,208, 65,134,153,153, 25,246,237,219,135,168,168, 40, 0,128,191,191, 63, 38, 79,158, 12,131,193,128, -241,227, 39,144,115,207, 5, 73,181,245, 79, 0,173, 0,124,133, 50,147,247, 30, 33,132,207, 96, 48, 50, 0,184,162, 97, 99,178, -104,255,164,154, 84,243,223,163,249,143,164,206, 90,135,171,191,133,248,183,101, 62,166,103,156,216, 21,202,238,218, 45,160, 89, -104, 72, 48,179,125,251,246,112,117,117,133,191,191, 63, 82, 83, 83,121, 18,137,164,174,122,106,234,128, 1, 99,147,253,252,252, - 36, 75,150, 44, 17,247,235,215,143,227,234,234, 10, 66, 8,162,162,162,112,234,212, 41,253,238,221,187,149, 69, 14,131,229,178, -107, 63,170,235, 83, 79,237, 62, 80, 4,224,115,151,140,140,239,103,207,154, 21,220,166,109,219,169, 33, 33, 33, 76,145,185,128, -179,118,249, 52, 62, 0,172,254,250,152,120,104,208, 56,108,245, 2,186,143,173,190,142, 92,213,118,166,166, 79,127,245,254,240, -222, 94,255,153, 51,197, 56,106,212, 40,161,165,165, 37, 92, 93, 93, 97,101,101,133,164,164, 36,164,167,167,147,179,103,207,170, -239, 62,138,231,156,190,252,240, 21, 95,236, 88,159,186,132,170,128,254, 31,188,124,255,253,247,173, 38, 77,154,100,209,174, 93, - 59, 14,143,199, 3,143,199, 67,118,118, 54, 18, 19, 19,245,103,207,158, 85, 23,217, 15, 44,148, 93, 59,170,170,103,173,195,226, -128, 49,161,137, 55,175,132,204,143,125,242,100,130, 9,104,173,215,235,157,141, 70, 35,131,201,100,102,154, 76,166, 39,122,149, -106,175,214, 63,100, 11,173,117, 88, 63,140, 70,163,153,209,104,132, 92, 46,199,149, 43, 87,216, 47, 94,188, 88,241,248,241,227, - 21, 25, 25, 25, 40, 45, 45,197,200,145, 35,225,239,239,143,107,215,174, 33, 55, 59,251,108,109, 90,207, 1, 5, 47, 61,125,242, -244,233,211, 47, 28, 60,120,144,249,248,241, 99,219,125,251,246,237,169,206,192, 76,152, 48,193,148,157,154, 58, 89, 11, 40,106, -233,159,181, 29,155,121, 23,143,238,120, 60,108, 68, 80,139,144, 85, 43, 56,157, 59,119,134,173,173, 45,186,117,235, 6,189, 94, - 47,105,222,188,121, 93,199,166, 42, 96,192,232,164,214,173, 91, 11,183,108,217, 34,157, 50,101, 10,230,204,153, 3, 0, 40, 46, - 46,198,229,203,151, 49,127,254,252,172, 84,118, 7, 77, 93,253,179, 60, 82, 85, 97,192,110, 0, 8, 0,144, 4, 58,240,157, 66, -161,252, 51,169, 40, 42,237,136,178,194,210,231, 80,118,113, 94,119,173,195,155,247, 99, 80,181,204, 71, 25,142, 79, 13,110,147, - 94,204, 92,184,206,151, 85,170,180,226, 48, 74, 44, 19,226,227, 25,117,213, 60,172,172,167, 38,246, 86,219, 36, 31,105,191,118, -245,234,121, 91,183,110,237, 93,145,194,193,220,220,252, 73,177, 70,243,139,157, 86,187,173, 72,236,253, 75, 67,107,243,165, 3, -217, 0,102, 89,201,100,219, 3,135,142,220,192,183,246,224, 44, 91,179,187,132,197,100,234, 18, 51,114,177,213, 11, 16,214, 99, -130,100,145, 14,136,149, 59, 26,178,109,130,158,175,252,236,179,255,172,254,252,243,246, 34,145,168,187,222, 96,240, 54,153, 76, -128,201,148, 80,164,209,220, 32,122,253, 3,173,255,170, 77,124,177, 35,169,119, 93, 66, 73,115,149,245,203, 19,237,247,239,221, - 59,247,248,241,227,191, 91,119, 27,173,118,123,145,164,121,120,125,214,189,234, 50, 37,192, 29,228,228,220,169, 45,116, 73,107, - 29,214,243,234,195,100,154, 97,101,101,117,160,119,239,222,252, 62,125,250, 96,208,160, 65,232,220,185, 51, 76, 38, 19, 8, 33, - 80,169, 84, 56,118,236, 24, 54,108,216,144,208, 24,248,188, 46, 61, 45,240, 11,239,252,249,129,173, 91,183,222, 87,155,129, 41, - 55, 89,117,142, 73,172,253,216,228, 37, 24,196, 67, 82,198,204, 94,235,165, 83,102, 74,108,204, 13,210,216,152, 39,204,250, 31, -155, 62, 42, 99,212,177, 14, 35,135, 15,159,205, 98,179,187,149,207,128, 36,207,158, 62,149, 85, 20,149,134,255,228, 43, 13,236, - 75, 21,185,235,232,192,119, 10,133,242, 79, 55, 90,131, 80, 54, 94,171,178, 36, 79,141,181, 14, 43,162, 62,108, 54, 59, 39,233, -244,204,113,181,169,115,128,222,229,145, 44,212, 89,235,176,252,255, 20, 64, 5,173,246,139,223, 36, 35,173, 50,187,144,243,198, -242, 13, 73,139, 88, 8, 60,135, 65, 27,136,156,167,192,153, 89,101,122,237, 87, 47,174,186, 78, 53,254,200,254,230,123,205, 10, - 74,128,155, 80,171,111, 66,173,174,118,208, 46,135,109, 86, 80, 87, 59,223, 92,247, 84, 64,249,174,235,254,166,102,157,230,225, - 29,182,231,191,141,215,121,121,167, 1,136, 92,194,194, 28, 46,134,133,141,250,207,130, 5, 35, 29,157,156, 60,109,109,109,173, - 44, 44, 44,152,247,238,221, 75, 54,148,148,108,111, 3,236, 47,143,166,214,137, 22,248,197, 39, 53,181,229, 7,195,135,207,102, -176,217, 93,171, 26, 24, 98, 48,220,246, 0,118,214, 22,201,122,219, 99,211,149,231,216,187, 60,146, 5, 22, 48,189, 62,125, 35, -189,172, 29,107, 96, 48,172, 65,116,116, 53,125,190,193,125,105, 53,131,193, 80,129, 14,124,167, 80, 40,255, 92, 42,234, 29,158, -251, 95,127,113, 31,170, 73, 53,255, 65,154, 44,148,205,162,163,219,147,106, 82, 77,170, 73, 53, 41,245,130, 77, 55, 1,133, 82, -111,140,248,245, 54, 24,133, 66,161, 80, 40, 21, 84,140,205,170,202,247, 64,217,208,157,154, 92,105, 67,102, 19,188,141,179, 13, -167,154, 84,147,106, 82, 77,170, 73, 53,169,230,191, 78,179, 46,237,191,227,108,198,138, 49, 89,149, 99,179,254, 87,208,176, 42, -213,164,154, 84,147,106, 82, 77,170, 73, 53,255,233, 56,150,155,172,170, 15, 0, 13, 76, 88, 74,161, 80, 40,255, 84, 66, 66,192, - 36, 4, 12, 66, 66,152,132, 28,103, 17, 18,196, 34, 4,239, 84, 10, 36, 40,168,250,100,182,159,140,179,178,160, 91,156, 66,249, - 71,145,137, 26,138, 74,211, 49, 90,255,191,184, 73,165,210, 93, 0, 24, 89, 89, 89, 51, 0,164,210, 77,242,215,195,218,218,186, -183,193, 96,128, 82,169,252,229,159,184,126, 45, 60, 49,156, 48,209,188,242, 5,130,212,103,137, 56, 80,221,178,205,189, 48, 17, -140, 95,115,113, 49, 76,120,246,244, 5,126,106,192,215, 49, 7,246,113,221, 9, 0, 23,194,211,102,227,207,201,171,213,212,206, -206,238, 18,155,205,102, 27,141,198, 89, 57, 57, 57, 97, 53, 27,161, 32, 22, 0,112,200,181,165,242, 44,251, 37,159,126,196,224, - 20,105,247,202,181,197, 26, 5,139,195,122,201,227, 72,111,205,156,194,188, 80,168,238,244,180,186,207,159, 56,113,162,198, 42, -222, 45,189, 48,144,105,108, 49,216,191, 85,114,210, 87,219,218,111,237,238, 97,203, 73, 78,123, 36, 90,255,157, 98, 23, 87,226, - 62,120,226, 40, 70, 24,219,156, 49, 97,239,222,124, 53, 61,202,234,207, 90,192, 90, 15,248,114,120, 60, 87,163,193,224,192, 0, - 8,139,205,206, 46,213,106,211,204,128,232,165,128,252,159,174,105,198,227,185, 24, 13, 6, 7, 0,248, 43,182,147,242, 91,106, - 52, 90, 34,145, 40,146,201,100,186, 84, 45,134, 91, 81, 79,176,226,181,170,239, 49, 24, 12, 24,141,198,244,194,194,194,118, 13, -248,126, 75, 0,163, 0, 84, 76, 81, 63, 12,224, 24,222,126,192,177,165,153,153,217, 66,161, 80,216,171,184,184,184, 37, 0, 8, - 4,130, 88,141, 70,115, 85,175,215,127,245,150,186,108, 0, 31,136, 68,162,158, 76, 38,179, 39, 33,132, 65, 8,185,166, 86,171, -175, 2, 56, 14,224,109, 50, 37, 8,236,237,237,215, 88, 91, 91,143, 93,186,116,105,190,141,141,141,207,252,249,243, 31, 22, 20, - 20,252,152,151,151,183, 28, 13,168, 81,247, 39,227, 41,149, 74, 15,115, 56, 28, 86, 90, 90, 90, 79, 0,112,117,117,189,166,211, -233,140, 57, 57, 57,227, 0,188,104,160,158, 16, 64, 71,145, 72,212, 78, 36, 18, 5, 24,141,198,230,229,245, 25,159,169,213,234, - 8,189, 94, 31, 9,224, 30, 0,205, 95,232, 24,177, 96,179,217, 7,203,251,186, 55, 0,213, 63,237, 36, 64,152,104,254, 52, 54, -206,167,210,120,181,108, 86,243,194, 12,184, 85,179,108,189,141, 86,175,238,142,131,135, 12,233,203, 4, 0, 93,233,133,193, 87, -111,100,254,252, 7,175, 78,211, 17, 35, 70,220, 57,120,240,160,149, 86,171,197,140, 25, 51, 14,135,135,135,239, 84, 42,149, 75, -107, 61,113,136,172,230,111,220,114,217,156,193, 96, 2,128,189,201,100,180,127,253,250,133,247,211,152, 59, 3, 98, 99,239,174, - 45,142,187,122,207,196,224,204,212,163, 91, 92,125, 26,209,220, 3,129,131, 71, 14, 31,244,249,231, 33, 24, 59,122,108,163,216, -216, 18,129,179,101, 18,183,160, 88,232,101, 99,103, 63,228,243,213, 39, 24,183,110,158, 30,114,112, 95,232,213, 41, 83,108,122, - 81,179, 85, 47, 24,171,217,236,142, 98, 47,175,128,209,167, 79, 67,228,234,202,102,243,120, 76, 0, 48,104,181,174,234,180, 52, -199,163, 67,134,116, 8,137,143,191, 30, 2,220,167,154,255, 47,154,148,134, 24, 45, 38,147,233,242,250,245,107,123,161, 80, 88, -118, 50, 38, 4, 70,163, 17, 70,163,177,178,120, 49, 33,164,242,175,193, 96, 64,179,102,205,234,117, 69, 11,160, 23,128, 15,123, -244,232, 17,244,213, 87, 95,113,124,125,125, 43, 74,134,116, 91,182,108,217,215, 81, 81, 81, 39, 1,236, 71, 89,242,198,250, 94, -241,246, 23, 10,133,135, 54,110,220,104,217,183,111, 95,182,147,147, 19, 24, 12, 6,178,178,178, 58,134,135,135,183,155, 63,127, -254, 44,141, 70, 51, 30,192,165, 6,108,159, 86, 22, 22, 22, 39,134, 15, 31,238,210,189,123,119,126,139, 22, 45, 96, 52, 26,241, -232,209,163, 41,145,145,145, 99, 78,158, 60, 25,172, 82,169,130, 80,255,122,109, 12,145, 72, 52,201,210,210,114,205,170, 85,171, -172,199,143, 31,207,141,137,137, 41,244,240,240, 96,220,186,117,203,238,216,177, 99,179,214,173, 91,247,129, 82,169, 92,174, 86, -171,127, 64, 61,106, 40, 90, 88, 88, 68, 50,153, 76,151,250, 24, 97, 0, 13, 49,195,109, 26, 55,110,124,236,230,205,155,141, 83, - 82, 82,140,195,134, 13, 59, 0, 0, 87,175, 94,245, 45, 45, 45,101,244,235,215,239, 66,122,122,250, 40, 0,143,234,185,238,126, -214,214,214, 63,143, 29, 59,214,218,211,211,211,188,113,227,198, 12,161, 80, 8, 22,139, 5,133, 66,225, 20, 19, 19,211,231,254, -253,251,197,225,225,225, 5, 90,173,118, 8,128,232, 6,236,167,206,246,246,246, 19, 56, 28, 78, 43,131,193,224, 12, 0,108, 54, -251,117,105,105,105, 76, 78, 78,206, 65, 0,119,222,246, 0,113,112,112,216,177,102,205, 26,219,156,156, 28,178,110,221,186, 29, - 42,149,106,210, 63,245,100,112,248,199,227,136,124,120, 31, 40, 43,155,195,168,166,255, 49, 0,152,125,250,233, 2,180,123,175, - 3,198,141,253,160, 78,205,247,123,187,108,228,112,205,108, 74, 74, 74,238, 40,138,180,199,133,230,252, 81, 99,199, 4, 38, 0, -192,133,139,215, 71,181,111,111,117, 77,108,206,251,128,207,231,119, 46,213,233,243,207,255,146,254, 89, 67, 76,149,179,179,243, - 37, 43, 43, 43,243,130,130,130,172,220,220,220,111, 7, 15, 30,188,122,255,254,253, 86,201,201,201, 72, 75, 75,195,188,121,243, - 68,233,233,233,179,163,163,163,239,234,116,186, 26, 35, 91, 42, 85,193,182,101, 75,134,174, 18,139,109, 89, 66,115, 75, 88,136, -173,225,225,217, 26, 29, 59, 15,198,192, 65, 83,145,152, 16,213,113,255,190,207,163, 94,191, 14,255, 82,100,221,100,181, 92,222, -184,198,243, 82,139,166,232, 62,100,120,153,201, 90,181, 42, 4,241,113,113,170,148,151,204, 79,206,157,102,155, 15,236,221,140, -103,208,101,165,220,186,121,186,113,215,110,195, 0,160,221,193,125,161, 87, 63, 25,103,213,123,199,225, 66, 21,253, 73,170,249, -220,249, 57,135, 51,169,255,150, 45,246,254,179,102,153,169, 95,190,212, 39,125,247, 93, 81,118, 68,132,145,205,227, 17,215, 1, - 3, 24,118, 61,123,242,103, 61,123,102,118,123,221,186, 0, 78,104,168,199,114,189,254, 16,213,252,159,106,254,219,169, 24, 4, - 95,117,246,225,247,181, 26, 45, 6,131, 1,161, 80,136,163, 71,143,130,195,225,128,205,102,131,195,225,212,248,191,155,155, 91, -125, 26, 50, 66, 42,149,126,189,115,231, 78,135,254,253,251,131,207,231, 87,190,193, 98,177,208,183,111, 95,244,233,211,135,147, -145,145, 49,230,232,209,163, 99,214,174, 93,155, 45,151,203,231,160,188, 48,116, 45,244,244,241,241, 57,117,249,242,101, 65, 73, - 73, 9, 34, 34, 34, 80, 88, 88, 8, 46,151, 11, 23, 23, 23,244,235,215,143, 29, 23, 23,103,221,183,111,223, 83,241,241,241,129, - 0,174,213,163,173,237,236,237,237,111, 28, 63,126,156,223,186,117,107, 70, 98, 98, 34,252,253,253, 1, 0, 10,133, 2,195,134, - 13,227,143, 31, 63,222,115,204,152, 49,247,114,114,114,186, 3,136,172, 67,175,173, 84, 42,253, 97,248,240,225, 78,107,215,174, -181,180,176,176, 64, 74, 74, 74,166, 84, 42,245,174,216,222, 99,198,140,225, 14, 30, 60,216,113,195,134, 13,219, 78,156, 56,241, - 89, 78, 78,206, 36, 0,178, 90, 93,107,185, 33, 54, 55, 55, 71,118,118, 54, 14, 31, 62,140,217,179,103,131,197, 98, 33, 39, 39, - 7,199,142, 29,195, 39,159,124, 82, 97,104,234,101,134,205,205,205,251,120,121,121,237,185,122,245,170,139, 68, 34,129,147,147, - 19,115,229,202,149,173, 60, 60, 60, 4,141, 26, 53, 98,101,102,102,226,212,169, 83, 30, 19, 38, 76,248, 57, 53, 53,117,138, 86, -171,173,243,150,154,131,131,195,222,115,231,206,185,197,198,198,226,187,239,190, 67, 65, 65, 1,184, 92, 46, 36, 18, 9,164, 82, - 41,188,189,189, 25, 75,150, 44, 49, 31, 60,120,176,249,156, 57,115,246,234,116,186, 54,245,216, 71,173,237,237,237,119,245,236, -217,211, 35, 52, 52, 84, 34,149, 74, 81,113, 97,160, 80, 40, 92, 82, 82, 82, 58,174, 90,181, 42, 40, 50, 50, 50, 57, 39, 39,103, - 38,128,199, 13, 60,112,218,180,104,209, 34,112,216,176, 97,172,204,204, 76, 28, 60,120, 48, 80,165, 82,181,105,128,185,252, 91, - 17,249,240, 62,102,124, 60, 79,237,228,234,106,118,249,210,158, 17, 39,126,106,250, 80, 34, 40, 43, 72, 45, 47,134, 62,104,120, -252,123,253,250, 79, 53,123,127,208, 48,245,247,223,108, 19,213,199,104,113,184,102, 54,135, 15,109, 78,189,121, 43,178,213,149, -240,251, 3, 70, 12, 25, 66,204,204, 36, 30, 0,240,217,252, 79, 57,167,206,156,217,215,183, 79,135,140,110, 93,219,165,142, 27, -191,192,173, 1,205,109,218,180,105,211,235, 81, 81, 81, 14, 60, 30, 15, 5, 5, 5, 54,223,127,255,253,230,174, 93,187, 50,147, -146,146, 16, 23, 23,135,151, 47, 95, 66,161, 80,160,111,223,190, 34,153, 76,246, 45,128, 26,141,150,158,217,107,141, 83,163,210, -237, 54, 2, 97, 99,189, 81,105, 79, 74, 51, 91, 92, 57,119,197,239,200,193, 98,127, 7,199,102,222, 31, 78, 14,198,231,171, 79, -114,126, 60,188,126,213,255,177,119,221, 97, 81, 92,237,247,204,246, 70,135,165, 10, 22,164, 23, 27,106,108,177, 87, 48, 26, 91, -138, 70, 19, 53,150,152, 88, 99, 52, 26, 53,166,104,140,198, 22,141, 45,137, 5, 19, 99, 55, 88, 81, 17,236, 5, 81,233, 40,210, -100, 23,118,105,187,203,246, 50,243,251,154, 58,214, 45, 0, 0, 32, 0, 73, 68, 65, 84, 67,150, 15, 9,176,139,229,251, 37,249, -246, 60,207, 62, 59, 59, 59,115,246,222,185,119,239,156,121,239,123,223,247,194,249,223, 1, 90,235,198, 51, 2, 80,232,254,249, -146,197,144, 43,180, 24,255,206, 84, 76,120,103,170, 43, 5,157, 23,101,210, 8,116,234, 74, 39,123, 86, 70,220,150, 93, 63,188, - 9,160, 69, 29,177,117,193, 38,182, 26,199, 74, 6,163,107,204,143, 63, 10, 35,166, 76,225,220,251,242, 75,101, 89, 82,146, 58, - 96,216,176,202,142,211,167,107, 1, 64,145,151,199,202, 94,190,156, 47,124,253,117, 94,183, 5, 11,156, 77, 58,157,231,202,149, - 43,187, 44,123,154,188,188, 89,156,126,227,198,153,150,253,250,107,231,164,121,243,250, 16, 6, 3,125, 72,183,110, 41,171,247, -237, 43,126, 17,206,151, 89, 78, 81, 98,162,182,194,223, 31, 29, 71,142, 44,247,115,119,215,190,204,186,191, 72, 57,109,168,133, -217, 87,235,195,186, 79,168,136,139,139,235, 13,224, 18,128, 47, 99, 98, 98, 86, 0,128,163,163, 99,105, 85, 85,149,251,145, 35, - 71, 44,138, 44, 38,147, 9, 47, 47, 47, 4, 6, 6, 74, 36, 18,137, 71, 19, 5, 40, 34, 73,178, 5, 69, 81,181,214,151,198,160, -213,106,145,147,147,131,118,237,218, 61,193,211, 68,180,141, 26,117,248,124,126,110,102,102,166, 91,122,122, 58,238,220,185, 3, -127,127,127, 56, 59, 59,131,201,100,194, 96, 48, 64, 46,151, 35, 56, 56, 24, 28, 14, 7,157, 58,117, 42, 83, 42,149,254, 22,166, -128, 56, 2,129, 32, 39, 49, 49,209,183, 99,199,142,184,117,235, 22,124,125,125,225,233,233, 9, 0,200,203,203,195,149, 43, 87, - 48,108,216, 48,220,189,123, 23,163, 71,143, 46, 82, 42,149,129, 0,180,141, 17,186,184,184,136, 47, 94,188,248, 36, 50, 50, 82, -163, 84, 42,105,165,165,165,204,164,164, 36,163, 66,161,176,147,201,100,204,170,170, 42,166, 92, 46,103, 40,149, 74, 38,141, 70, - 99,169,213,106,230,133, 11, 23,232,122,189,190,201, 0,153,230,118, 58,113,226, 4, 34, 35, 35,113,228,200, 17,204,159, 63, 31, - 87,175, 94,133,175,175, 47, 14, 30, 60,136, 5, 11, 22, 32, 43, 43, 11,110,110,110, 8, 11, 11,179,212, 70,104,219,182,237,195, - 7, 15, 30,180,101,177, 88,230,188,142,230,124,121,144, 74,165,120,244,232, 17,138,139,139, 17, 16, 16,128,119,222,121,231, 81, -113,113,113,128,165,158,231,227,227, 35, 77, 75, 75,115,107,215,174, 29, 74, 75, 75,225,228,228, 4, 71, 71, 71, 56, 57, 57,213, -110,251,251,251, 99,222,188,121,240,244,244,148,104, 52, 26, 15, 75, 34, 40, 50, 50,242,236,133, 11, 23,220, 28, 28, 28, 80, 82, - 82, 2,185, 92, 14, 6,131, 1, 62,159, 15, 55, 55,183, 90, 33,159,147,147,131,232,232,232,178,220,220,220,193,205, 16, 73, 52, - 15, 15,143,204,251,247,239, 7, 82, 20,133,194,194, 66,100,101,101, 97,230,204,153, 57, 26,141, 38, 4,255,162,156,125,117,252, -174, 88, 19,223,255,144,245,230,136,238,186,140,180, 56,130, 67,102,161, 67,132,131, 12, 0, 82, 82,229,142, 90, 90, 48, 66,195, - 99,168,163,199,175,177,247,236,222,193, 4, 9, 15, 16,200,202,200,193, 87,141,113, 15,234,235, 53,101,206,156, 15, 34,250,244, -236, 77, 83, 40,149,238, 63,253,180,190, 83,110,110,134, 59, 0,248,251,135, 74,102,204,152,155,108, 47, 16, 72, 46, 93, 73, 36, - 55,108,248, 37,245, 92,130,120,151, 21, 69,246, 15, 12, 12,188,126,226,196, 9, 55,119,119,119, 56, 58, 58, 66,169, 84, 66,175, -215, 35, 61, 61, 93,115,224,192, 1,131,131,131,131,125, 73, 73, 9,170,170,170, 64, 16, 4, 78,156, 56, 81, 8,160,101,125, 34, -179,143, 22, 0,204, 28, 26,202, 12,235, 23,232,204,226, 24,121, 60,102,182, 23, 8, 19,135,160,236, 60, 78,159, 77,105,119, 58, -254,214,187,111,142,154, 47,236,213,251, 77, 44, 91, 58,198, 32, 18, 21,118,212,163, 87,102, 67, 62, 90, 33, 1,232, 55,114,244, -155, 99, 87,174, 92,129, 21,203,190, 68,220,137, 99, 50, 59, 1, 77,235,224,196,116,124,253,181, 30,154,121, 31,141, 40,170,174, - 22,249,174, 92,115,224,157,232, 17,243, 90,244,236, 53, 18, 87, 46, 31,195,190, 95,191,188, 67,240, 40,219, 52, 98, 61,172, 0, -156,157,252,253,167,125,146,147,195,186,183, 98, 69,181, 81, 36,170,140,154, 59,183,172,161, 99,159,196,199, 11,216,222,222, 14, -206,111,188,225,178,177,101, 75,202, 32,145,108,111,200,199,168, 33,206,243,118,118, 78,191,159, 62,221,159, 98, 50,123, 47,252, -236, 51, 94, 76, 76, 12,228,114, 57, 14, 31, 62,140,237,219,182,105,189,188,188, 30,120,167,166,222,141,144,203,151, 90,203, 25, - 53,119,110,153,201,100, 34,198, 46, 88, 48, 48, 45, 47,175, 95,137, 68,210, 10, 0,188, 92, 92,138,162,252,253,239,252, 18, 23, -151,181,185,117,107,210,218,114,238, 60,115,198,227, 80,126,254, 20, 23, 23, 23, 94,169, 68,194,224,176,217,229,175,133,133, 29, -220,186,100,201, 37,227,253,251, 44,110,139, 22, 14,142, 49, 49,205,174,123,212,220,185,101, 21, 10, 5,227,147,175,191,238, 81, - 80, 90,218,170, 90,171, 13,168, 82, 40, 60, 77, 6, 3,205,129,207, 47,111, 19, 28, 44, 81, 39, 37,137,219,168, 84,179,119, 1, -146, 87,213,214, 13,105,145,127, 16,234,199,209,250, 75,174,195, 75, 49, 49, 49,127, 89, 93, 67, 81,148, 85,214, 44, 38,147,249, -204, 52, 85, 19, 96, 17, 4,129,228,228,100,184,186,186,194,211,211, 19, 28,206,179,201, 7,165, 82, 41,174, 94,189,138,140,140, - 12,180,111,223,222, 60,141,209,184, 34,226,112,230,172, 89,179,198, 73,167,211,225,206,157, 59,136,138,138, 2,135,195, 1,139, -197,122, 70, 4, 74, 36, 18,132,135,135, 99,225,194,133,142,223,126,251,237, 28,173, 86,219,232, 19, 41,131,193,152, 53,117,234, - 84,119,179, 5,171,168,168, 8,157, 58,117,170,253, 94, 40, 20, 34, 37, 37, 5, 81, 81, 81,104,209,162, 5,198,140, 25,227,190, -111,223,190, 89, 70,163,113,109, 99,156,108, 54,155, 22, 25, 25,217, 25, 0, 4, 2, 1,104, 52, 90,182,131,131,131,208,195,195, - 67,224,224,224,240,151, 58,254,250,235,175, 85, 52, 26,205, 96, 81, 13,208,104, 40, 41, 41, 65, 68, 68, 4,100,178,167, 25, 92, -148, 74, 37, 2, 2, 2, 32,151,203,107, 69,171,183,183, 55,212,234,166, 93,191,218,181,107,183, 34, 36, 36,100,144, 64, 32,224, - 48,153, 76,220,187,119, 15, 29, 59,118,196,129, 3, 7,224,231,231, 7, 62,159,143,156,156, 28, 68, 70, 70, 34, 49, 49, 17, 66, -161, 16,225,225,225, 28,119,119,247,203, 21, 21, 21, 9, 5, 5, 5, 43,154, 40, 39,205,206,206, 14,137,137,137,248,229,151, 95, -144,151,151, 7,145, 72, 4,123,123,123,116,232,208, 1, 97, 97, 97,232,222,189, 59,114,114,114, 64, 88,238, 76,158,129,129,129, -113,183,110,221,114,163, 40, 10,251,246,237, 67,117,117, 53,116, 58, 29,104, 52, 26,184, 92, 46,156,157,157,209,175, 95, 63, 8, -133, 66, 4, 6, 6,226,143, 63,254,112, 27, 58,116,232, 41,137, 68,210, 1, 64,137,165,235,234,236,236, 60,123,249,242,229,190, -238,238,238,200,207,207,135, 76, 38,131,135,135, 7,250,244,233,227,115,254,252,249,217, 6,131, 97,253,191,229, 70, 86,199,241, -157, 56,119,246,231, 81,129,109, 42, 35,219, 7,243,125,143,196,121,248, 30,136,147,132, 3, 64, 68,168, 71,218,168, 24,126,209, -189,180,184,162,115,103,143,221,201,200,198, 17, 88, 49,181, 45, 83,105, 15,198,159,191, 57,164, 99,251, 78,228,154,239, 22, 68, -127, 52,115, 10,199,221, 99, 50, 74, 11,143,225,252,197,100,191, 5,243,167, 10,215,174,219,121, 58,254,252, 77,154, 76,165, 93, -106,157, 41,203,111,243,238,173,221,221, 20,101,135,240, 48,147, 13,158,125, 4,252,253,131, 32,151,203,193,229,114,185,239,188, -243,142,105,241,226,197, 42, 7, 7, 7, 62, 65, 16, 72, 72, 72,144, 0, 24,108,137, 87,227,238, 76,153,244, 6, 35,197,166,147, - 20, 97,175, 38, 76, 21,236,212,244,199, 24, 52,160,111,105,207,174, 17,223, 46, 94,185,238,243,192,160,142,194, 15,166,124,201, -252,122,197,187,219, 64,160, 87, 67, 60,153, 15,113,145, 56,120,148, 7, 32,122,229, 87, 43,144,155,155,227,252,225,164,170, 47, - 25, 28,158,119, 72,203, 30,246,219,126, 73, 24, 18, 16,208,186,213,188, 89, 99, 78,254,240,227, 15,209,117, 45, 91,187,127, 93, -126, 28, 64,127,107,174,237,255, 16,218, 77,136,139, 67,117, 97,161,161,226,242,101, 77,255, 31,127, 44,243, 29, 60,120,189, 78, -175,119, 51, 15, 21, 52,130, 0, 97,118,157, 32, 73,130,177,112, 33,141, 98, 48, 96,112,118,158,132,202,202, 32, 75,156,243,197, -226, 81,239, 78,153, 18,125,252,204, 25,180,110,221,186,246,126,230,228,228,132, 5, 11, 22, 96,238,220,185,156,148,148,148, 46, -135, 14, 29,234,178,246,251,239, 61, 0,140,178,166,156,231,110,220,112,158,190,114,229,146,246, 81, 81,126,123,247,239,231,180, -109,219, 22, 0,240,232,209,163,192,239, 86,175,110, 25, 17, 25, 89,250,237,156, 57,187,211, 22, 47, 14, 7,112,185, 41,206,146, -164, 36,221,161,252,252, 41, 23, 19, 18,156, 34, 34, 34, 0, 0, 89, 89, 89,238, 27, 55,110,156, 26, 62,102,204,248,149, 51,102, - 44,141,209,104,170, 28,164, 82, 78,204,230,205,140,223,199,142,181,200,105, 46, 39, 0,244,249,224,131, 57,189,250,246, 13, 27, - 53,101,138,139,159,159, 31, 97,103,103, 7,189, 94, 15,145, 72,228,156,150,150,214, 54, 78,161,144, 31,189,113, 99, 31, 76,166, -129,175,176,173, 27,212, 34,255, 48, 75,214, 95, 53, 69,205,123,159,184,184, 56, 10, 64,159,152,152,152, 68,243, 13,220,100, 50, - 89, 37,178, 24, 12, 6, 8,130,176, 86,108,129,162, 40,148,149,149,161,172,172,172,118,234, 72, 34,145,224,226,197,139,200,201, -201, 1,147,201, 4,139,197,130, 94,111, 57, 7,173, 64, 32, 24, 48, 96,192, 0,198,141, 27, 55,224,239,239, 15, 30,143, 87, 91, - 46,243,139,197, 98,193,203,203, 11,114,185, 28,253,251,247,103,110,218,180,105, 64, 83, 66,203,209,209,113,216,184,113,227,216, -230,207,213,213,213,160,211,233,181,162,165,186,186, 26, 21, 21, 21,168,170,170,130, 70,163, 65,183,110,221,216,113,113,113,195, -202,203,203,215, 90, 83,127,149, 74, 85, 45,145, 72,156,122,245,234,229,188,123,247,238,172,110,221,186, 5, 63,211,211, 46, 93, -210,104, 52, 26, 38,141, 70,179, 42,143, 94,108,108,108,237,181, 47, 46, 46,198,182,109,219,106,191,203,201,201,193,166, 77,155, - 64, 81, 20, 40,138,106,178,141, 66, 66, 66,134,238,219,183, 47,106,239,222,189,149,116, 58, 29, 89, 89, 89,216,191,127, 63, 40, -138,130, 80, 40,132, 74,165, 66,105,105, 41, 18, 18, 18, 96, 52, 26, 97,103,103, 7, 31, 31, 31,238,172, 89,179,122,126,249,229, -151,204,166,132,150,201,100, 50,209,233,116,180,108,217, 18,203,150, 45,131, 70,163, 1,139,245, 84, 95,202,229,114, 84, 85, 85, -225,238,221,187,200,207,207, 7, 69, 81, 77,222,100,184, 92,238,152,189,123,247,186,179,217,108,168,213,106, 40, 20, 10, 20, 21, - 21,161,160,160, 64, 35,145, 72,140,246,246,246,180,150, 45, 91,210, 56, 28, 14,103,228,200,145,132, 89,112,198,196,196,184,238, -219,183,239, 45,157, 78,103, 73, 36, 9, 61, 61, 61, 63,159, 58,117, 42,183,110,159, 45, 41, 41,193,168, 81,163,248,215,174, 93, - 91, 44,151,203,247, 3,144,254,203,110,104,212,161,163, 65,183,239,156,207,138, 60, 18,231,225, 91,240,196,212, 99,193,167,235, - 24, 0,176, 99,251,170, 30, 71,226,138,175,134,180, 46, 45, 58,116, 52,232,182,179,115,134, 37, 33, 64,235,215,219,107,184,128, -207, 29, 55,234,141, 55,168,159,126, 90,223,233,163,153, 83, 56, 45,131, 22, 60,181,112, 50,221,209,223,248, 21,161, 82, 63,226, -254,244,211,250, 78,163,222, 24,125, 55, 47, 47,127,123,191,222,156, 63, 46, 38,138,255,108,202, 98,232,238,202,245,225,115,148, -240,241, 15, 67,112,168, 0, 41,247,178,112,248,224,117,132,134,191, 6,173, 86, 11,163,209, 40, 24, 62,124,184,234,192,129, 3, -154,236,236,108,133, 90,173,238, 13, 32,219, 82,229,159, 60, 73, 39,131, 61, 95,211,179,120, 28,163, 66,198, 82, 45, 90,122,104, -108,167,174,131,162,156,189,124,152, 66, 1,249,231,208,129, 93,246,255,178,107,217,220,165,203,247,163,115,151, 65,221, 50,178, - 46,135, 1,120,208,160,120,205, 69, 28,237,240, 81, 99,238,195,135,209, 5,249,249, 79,130, 60, 60,117,143,170, 40,195,236, 69, - 59, 7,246,234, 61,166, 93,219,208,215,217, 25,233,137,196,178,133,111,253,182,114,205, 15,239,152,197,214,133,248,223,122, 79, -154,116,157,189,123,119,227,214,241,255, 53,176, 56,156, 22,118, 45, 91, 50,242,118,239, 86,251, 15, 31, 94, 9, 0, 58,189,222, - 45, 47, 63,223,145,207,231,131,162, 40, 24, 12,134,103,124,136,205,126,195, 17,193,193, 30,214,112,230,125,241, 69,187,133, 11, - 23,162,164,164, 4, 70,163, 17, 76, 38,179,254,152, 13,165, 82,137, 73,147, 38, 97,243,247,223,191,102, 13,167,201,100, 34,166, -175, 92,185,228,179, 37, 75,218, 78,155, 54,141, 86,119,236,117,113,113,193,161,195,135,217, 91,182,108,105,241,249,230,205,147, -222,229,112,114,161,213, 54,201, 89, 22, 16, 0,151,210, 82,158, 89,100, 1, 64,112,112, 48,182,109,219,198,153, 60,121, 50,123, -248,240,225,235, 82,218,183,223,184,190,103,207,135,174, 65, 65, 14,108, 14,167,133, 37, 78,243,245, 4, 0,133, 70, 19,177,126, -227, 70,231,155, 55,111,162,180,180, 20, 37, 37, 79,159, 71, 9,130, 64,231,206,157,137, 9, 19, 38, 56,182,241,245,237, 2,147, -233, 85, 54,247, 95,180,200, 63, 8, 31, 54,176,239, 63, 62, 90, 53, 21, 34,106, 42, 72,212,185, 57, 62, 35, 88, 44, 9,173,231, - 65, 85, 85, 21,170,170,170,176,107,215, 46,176, 88,172,218,155, 47, 0,232,116, 58,107, 68, 75,164,183,183, 55,100, 50, 25,130, -130,130,158,177,100,177, 88, 44, 48, 24, 12,176, 88, 44,112, 56, 28,104,181, 90,248,249,249, 65,165, 82, 69, 54,197,169, 86,171, - 59,184,184,184,212,222, 96,181, 53,157, 85,171,213,214,150, 87,167,211,161,178,178, 18,213,213,213, 80, 40, 20, 80, 42,149, 29, -173,169, 47, 73,146, 72, 77, 77,125, 20, 28, 28,220,129, 78,167,195,206,206, 78,160, 84, 42,107,125,139, 42, 42, 42,176,103,207, - 30,229,123,239,189,231,118,226,196, 9,139, 66,139, 32, 8,124,252,241,199,224,112, 56, 80,169, 84,248,233,167,159,240,201, 39, -159,128,197, 98, 65,161, 80, 96,219,182,109,152, 55,111, 30, 24, 12, 6,116, 58, 29, 54,110,220,216, 40, 87,122,122,122,222,141, - 27, 55, 58,118,234,212,201,249,232,209,163,210,129, 3, 7, 10, 7, 15, 30, 12, 30,143, 7,181, 90, 13,131,193,128,215, 94,123, - 13, 33, 33, 33,144, 72, 36, 56,125,250,116, 89, 96, 96,160,219,205,155, 55,201,146,146,146, 2, 11,226,154,170, 99, 49,132,201, -100, 66,105,105, 41,170,170,170, 32,149, 74, 33, 18,137,240,228,201, 19, 48, 24, 12, 88,208, 89,112,117,117, 29, 29, 17, 17, 65, - 7, 0, 30,143,135, 14, 29, 58, 96,201,146, 37, 70,181, 90, 61, 14,192,233,154,195,134,238,220,185,243,232,149, 43, 87, 24,222, -222,222,200,204,204,132, 80, 40,100,112,185, 92,139, 66,203,211,211,243,215, 63,255,252,211,197, 44,174,205,215, 89,165,122,218, - 28,163, 70,141,114,217,187,119,239,175, 70,163,113,216,191,237,166,230,196, 3,171, 67,132,131,236, 64,156, 36,124,193,167,235, - 24, 33, 17, 79, 31, 94, 63,156, 6,198,218,239,231,135,143, 31,225,112,210,137, 39,103, 89,226, 25, 58,192,119,203, 27,111, 12, -164,189,243,118, 76, 14,139,229,228,191,125,199,151,238,238, 30,147,235,200, 48, 7,184,186, 57,192,191, 37,155, 56,116, 50,195, -125,209,226,175,180,177,123,127,200,253,237,247,184, 33,108,102,252,160,211,231,139,102, 52,198,157,253,168,234,132, 74,203, 13, -149,151,223, 39, 92, 60,122,160, 67,251, 96,184, 11, 43,177,243,215, 3,104,221,166, 51,180, 90, 45, 28, 28, 28,248, 38,147, 73, - 79,167,211, 99,173, 17, 89, 0,112,225, 66, 21, 25, 30, 94,165,163, 43, 72,227, 71,159,172,125,115,224,208, 55,194,250,245, 27, - 64,158,139, 63,167,239,209, 81, 47, 30, 58,184, 67,233,153,248, 45, 57, 98,209,227,192,240,200,158, 72, 79, 75, 24, 66, 81, 72, - 37,136,134,173, 79,105, 15,113, 70, 67,166, 39, 28, 56,240, 33,169, 38,239,242,190,254,230,193,208,232,232,137, 17,175,247,122, -157,140, 63,127, 81,199, 70, 89,134, 67,207,238,197, 31, 77, 25,122,244,231,216,141,131,206,156,254, 53, 64, 38, 47,136,179,137, -172,122, 15,105, 70,163, 7,131,195,161, 73, 19, 18,140,145,147, 39,107,205,255, 71, 62,159,143,227,199,143,131,205,102,215,190, - 88, 44, 86,237,182,135,135, 7,136,154,101,164,214,112, 2,128, 88, 44, 70, 73, 73, 9, 28, 29, 29, 33, 20, 10, 81, 82, 82,130, -107,215,174, 33, 59, 59, 27, 76, 38, 19, 67,134, 12, 1,173, 17,223,230,250,156, 99, 23, 44, 24, 24, 26, 25,233, 87, 95,100, 1, -128, 94,175, 71, 69, 69, 5, 70,140, 24, 65, 59,125,250,180,231,153,194,194, 55, 0,196, 54,197,217, 49, 58,186,188,244,208,161, - 6,127,187, 83,167, 78,196,213,171, 87, 57, 67, 6, 15,158, 59,255,155,111,182,108,222,187,183,200,100, 52,122, 54,167,238, 52, - 26,141, 70, 16, 4,124,125,125, 81, 81, 81,129,234,234,167, 51,216,118,118,118,112,118,118,134,193, 96, 0, 73, 81,204, 87,217, -214,141,105,145,127, 8,118,212, 17, 92, 59,254, 98,209,170,169, 20, 0,244,169,123, 99, 33, 73,210, 42,145,197,100, 50, 45,250, - 92, 89, 99,229,170, 15,107,132,150,185,172, 92, 46,183,246,143, 86, 87, 96,153,203, 73,163,209, 64,167,211, 45,222,196,107,196, - 16, 93,161, 80,224,240,225,195,232,221,187,119,237,180,148, 76, 38, 67, 85, 85, 21,100, 50, 25, 52, 26, 13,242,242,242,112,225, -194, 5, 4, 4, 4, 0, 86, 6,127,205,205,205,189,211,186,117,235, 40,243, 77,188,111,223,190, 45,118,239,222, 45, 26, 54,108, -152, 55, 69, 81, 88,186,116,105,217,107,175,189,230, 86,247, 38,111, 9,116, 58, 29,215,174, 93, 67, 64, 64, 0, 40,138, 2,139, -197, 66, 86, 86, 22,220,221,221, 65,146, 36, 24, 12, 6,164, 82, 41,236,237,155,142,145,152,154,154,250,254, 7, 31,124, 32,114, -116,116,108, 87, 94, 94, 46,230,112, 56,189,146,146,146,124,245,122, 61, 28, 28, 28,224,224,224,128, 83,167, 78,193,201,201, 9, -115,230,204, 41, 84,171,213,215, 4, 2,129,135, 90,173,190, 95, 82, 82,178,180, 57,237,109, 52, 26,161, 84, 42, 81, 89, 89,137, -138,138, 10,200,229,114,104, 52, 26,139,101,108, 8,189,122,245, 66, 92, 92, 28,125,213,170, 85, 63,231,230,230, 2, 0,252,253, -253, 49,103,206, 28,186,143,143, 15,242,242,242,112,231,206, 29,232,245,122, 80, 20,213,228,159,151,193, 96,244,125,239,189,247, -122,250,249,249, 17,122,189, 30, 36, 73, 66,171,213,194,188, 93, 88, 88,136,208,208, 80, 90,203,150, 45,187,229,230,230,246,133, -117, 11, 43,108, 0, 80, 90,120, 12, 62, 76,119,128,230, 0, 74,125, 12,229,101,207, 23,197, 69, 34,145,124,179,240,139,171,147, - 55,175,209,123, 60, 17, 3,193, 17, 35, 17, 24,214, 31,239, 79, 48, 98,213,247,135,225,215, 50, 24, 5, 5, 5,232,219,183, 47, - 75, 36, 18,125, 80, 93, 93,189,192, 90,238,248,248, 27,166,115,167, 78,143, 25,251,214,196,168, 1, 3,134, 25,207,158, 61,133, -212,251,103,211, 62,120,107,180,132, 34,171, 9, 23, 39,222,221,172,204,219,129,237, 58,244,129,206,104,234, 5,172, 88, 3,172, -160, 26,255,191, 67,119,242,164, 23,237,228,177, 95, 39,188, 51,126, 82,251,254,253, 7, 25,206,198,255,137, 59,215,227,239,173, - 91, 51, 53,113,213,198, 63,250, 14, 28, 50, 58, 92,232,113,237, 84, 68,144,118,138,175,171,227,163,157,187, 43,108,157,165,161, -255, 38,151, 75,162,102, 92,164, 17, 4, 40,138,122, 70,100,213, 23, 90, 52, 26,205,162, 1,160, 46,103,221,123,145,249,129,122, -251,246,237,224,112, 56, 96,179,217, 96, 50,153, 22,221, 47,234,114,166,229,229,245,219, 19, 27,203,105, 72,100,149,151,151,163, -188,188, 28,213,213,213,120,251,237,183, 89, 95,222,190,221, 9, 53,174, 31,141,113,250,121,121,105, 5, 60, 94,105,122,122,186, -119, 88, 88,216, 51,229,149,203,229,224,241,120,136,221,191,159, 21, 19, 29, 61,179,255,169, 83,235, 96, 33,254, 85, 67,117, 39, - 8, 2,238,238,238,112,118,118, 6, 65, 16, 48, 26,141, 40, 41, 41, 65, 90, 90, 26,110,223,190, 13, 58, 65, 24, 95,101, 27, 55, -164, 69,254,129, 86,173, 29, 13, 78, 29, 54, 54, 39,218, 28,161, 69,167,211,159,219,170,213, 24,172,153, 58,228,243,249, 15, 68, - 34, 81, 15, 31, 31, 31, 24,141,198, 90,161, 85,127,234,208,108,253, 72, 73, 73, 1,159,207,127,160,209,104,154,228,164, 40,170, - 91,151, 46, 93,112,228,200, 17, 36, 36, 36,224,241,227,199, 80,169, 84,208,106,181, 80,171,213, 72, 75, 75, 3, 73,146,136,136, -136,128, 64, 32, 0,159,207,127,160,213, 54,253, 32,170, 84, 42,197, 76, 38, 51,152,199,227,213,238,243,242,242, 66,121,121, 57, -105, 48, 24,176,103,207, 30,185,167,167,167,128,199,227, 89, 45, 92, 9,130,128, 68, 34, 65,139, 22, 45,106,125,180, 20, 10, 5, -220,221,221,205,194, 2, 90,173, 22,246,246,246, 22,167, 14, 1,104, 30, 62,124, 56,191,206,231,206, 99,199,142,253,237,192,129, - 3,109,206,159, 63,143,155, 55,111, 66, 40, 20,226,219,111,191,125,156,159,159,255, 14,128,219, 18,201,203,245,139,180,166, 15, -149,151,151, 31,126,240,224, 65,183, 46, 93,186,212,142, 18,125,251,246, 37,250,246,237,235, 86,215,212, 47,149, 74,113,235,214, - 45,156, 63,127, 30, 4, 65, 32, 39, 39,199,164, 86,171,127,107,106,150,194,199,199,103,247,146, 37, 75,236,140, 70, 99,109,223, -230,241,120,224,114,185, 96,177, 88,160,211,233,200,207,207,199,136, 17, 35, 28,127,252,241,199, 95,181, 90,109, 91, 0,122,252, - 75, 80,165,134, 62, 37, 85,238, 24, 17,234,145,182, 99,251,170, 30, 31, 78,131,121,234,208, 24, 17,234,158,150,146, 90,234, 24, -229,110,185,190,167,207, 23,125,164, 51,156, 30,126,250,204,165,113,159,206,157,195,244,247, 15,149,156,191,152,236,215,223,248, - 21,225,234,230,128,242, 50, 57,242, 11, 75,145, 91,160,163,252,253, 67, 37,119,110, 61,224,124,191,126, 67,160, 82,165, 49, 79, - 29, 54,217, 79, 47, 95,123, 60,114,221, 38, 78,226,196, 15, 58,179,121, 60,111, 84,148, 61,128,159,159, 16, 35, 98,218,225,151, -189,215,224,232,232, 2, 15, 15, 15,208,104, 52,129,181,117, 47, 43, 43, 35, 14,255,126,121,242,123,147,166,190, 54,120, 80,180, -241,204,217,147,140,132,115, 39,174,253,186,227,243,163, 20, 93,201, 39, 40, 5,175, 85,107,207,251,143, 30,166,188,211,111,192, -219,224,177,236, 3,128,144, 6, 59,108,237, 2, 3, 10,133, 71, 14,172,224,190, 55,233,195,238,131, 7,191, 97, 60,123,246, 24, -206,158,218,123, 99,249,242, 86,167, 30, 23,239,103, 93,191,253,132, 59,114,204,140,202,184,211, 25,186,209,195, 91,103,123, 11, - 58,168,129,199, 54, 85, 85,247, 65,146,193, 40, 53,106,181,190, 45, 6, 15,166,171, 10, 10,152,118, 30, 30, 70, 0, 48, 24, 12, - 22,133, 22, 26,153,130,174,207,105,109, 89, 84, 42, 21,200, 70, 98, 39,214,231, 44,145, 72, 90,213, 60,132,215,194, 96, 48,212, -138,172,242,242,114, 84, 85, 85, 65, 32, 16, 64,170,213,122, 88,195, 57,168,107,215, 61, 95,174, 88,177,224,208,225,195,172,186, - 34,203,252, 98, 50,153,248,110,205, 26,214, 39,159,126, 58, 99, 38,131, 49, 27, 70,163,213,215,211,252,208, 78,167,211,193, 96, - 48, 80, 80, 80,128,194,194, 66, 20, 20, 20,160,160,160, 0, 60, 30, 15,212, 43, 94, 4,244, 15,246,207, 50,139,172,186,239,181, - 86,174, 38,195, 59, 52,199, 25,222, 90, 97, 96,106,198,252,174, 53, 66, 75,169, 84,158,191,112,225, 66,215,145, 35, 71, 50,110, -220,184, 1, 79, 79,207, 90,161,101,126, 55, 79, 71,241,249,124, 28, 61,122, 84,175, 84, 42,207, 91,248, 51, 93, 56,117,234, 84, -212,178,101,203,152,239,191,255, 62,210,211,211, 49,109,218, 52, 84, 85, 85, 65, 46,151,163,188,188, 28, 42,149, 10, 93,187,118, - 5,151,203,197,253,251,247, 13, 42,149,234,130, 5,139, 29, 37,145, 72,170,133, 66,161, 87,253,239,198,140, 25,227,177,117,235, - 86, 85,102,102,166,161, 71,143, 30, 14,214, 10, 14, 51,126,255,253,247, 90, 75, 93,118,118, 54,182,110,221, 90,235,147,149,156, -156,140,181,107,215,214,198, 62,107, 38,110,151,149,149, 25, 13, 6, 3, 2, 2, 2,224,227,227, 3,141, 70,131, 13, 27, 54, 24, - 1,220,254,255,234,205, 26,141,230,208,196,137, 19, 63,187,123,247,174, 23,131,193,120,106,210,174,169,159, 94,175,199,195,135, - 15,145,150,150,134,204,204, 76, 84, 84, 84,212, 62, 8,164,164,164, 84, 26, 12,134, 63, 26,227, 21, 10,133, 75,127,249,229, 23, - 79, 62,159,255, 76,127, 54, 91, 67,205, 86, 82,169, 84, 10, 39, 39, 39,244,239,223,223,253,194,133, 11, 75,181, 90,237,178,127, -201, 61,141, 24,243,102,118,231, 79, 62, 26,137, 81, 49,252,162, 35,113,197, 87,215,126, 63,191,198, 25,222, 61,109, 84,140, 79, -209,189, 44, 39,140,121,243, 88,103, 0, 79,208,180,195, 54,121, 49, 81,124,188, 75, 23,231,132, 35, 39, 78,252,186,120,225,220, -228, 5,243,167, 10, 85,234, 71, 92,255,150,108, 2, 0,114, 11,116,212,253,116, 82,179,118,221,220,228, 85,107,126,164,149,150, - 87, 77,187,117,171,241,240, 6,117,197, 11,141, 6,174,127, 72,111, 81, 96, 80,207,214, 55,174,197,194,142,175, 70,112, 72,103, - 12, 30,212, 13, 9,151, 82, 80, 34,213, 64, 44, 22, 67,171,213, 54, 25, 46, 33,243,254,209, 9, 20, 65,249, 17, 20, 81, 72,208, - 40,238,132,137, 83,122, 69, 71,191, 65,197,197,157, 48, 30, 59, 26,123,229,143,125,155, 14,209, 88, 76,134, 90,231,168, 35, 8, -141, 12,180,212,244,106,229,211, 7, 26, 38,135,213,184,249,181, 38,176,107, 88,120,136,231,132,137,211, 28,135, 13, 29, 65,157, - 58,117,140,252,227,192,158,132, 63,118, 69,198,146, 52, 57, 75, 92,164,226,200,228, 6, 25, 69,176,157,170,229,164,170, 52,183, -173,198, 59,122,140, 30, 56,100, 83, 87,117,239, 3, 90,237,147,234,162, 34, 47,151,222,189, 57, 15, 87,172,224,123,116,237,170, - 33,106,124,136,155, 18, 90,116, 58, 29,160,209, 72,107, 56,173, 45,139, 90,173, 6, 9, 24,158,135,211,104, 52, 62, 35,178,204, - 66,203,252,127,177,134,115,199,242,229, 55,252, 6, 15,174,184,116,233,146, 71,159, 62,125, 8,133, 66, 1,133, 66,241,140,216, -242,246,246, 38,194, 34, 34,248,191, 39, 36,248, 91,123, 61,173,169, 59,141, 70,123,229, 66,235, 31,142, 70, 19, 73, 55,153,130, -199,108,209,178, 70,104, 89,105,209, 50, 24, 12, 6,184,187,187,163,172,172,172,209, 27, 63,141, 70, 3,143,199, 51,207, 17, 55, -185,242, 78,171,213,110, 88,176, 96,193,172,161, 67,135,186, 5, 7, 7, 67, 42,149,194,195,195, 3, 92, 46,183,214,119,204,204, -151,156,156,140, 95,126,249, 69,174,213,106, 55, 88,224, 92,191,102,205,154,143, 70,141, 26,229,226,233,233, 9,103,103,103,220, -191,127, 31,206,206,206,144,203,229,200,202,202,130,189,189,125,173,223,206,137, 19, 39, 20, 90,173,118,189, 5,241, 70, 37, 37, - 37,233,237,237,237,239, 75,165, 82,122, 69, 69, 5,163,178,178,146, 33,151,203,153, 50,153,140,121,230,204, 25, 55, 71, 71, 71, -213,197,139, 23,165,126,126,126,244,199,143, 31,211, 13, 6,131, 69,245, 74, 16, 4,102,207,158, 13, 22,139, 5,173, 86,139, 13, - 27, 54, 96,193,130, 5,181, 62, 89,107,214,172,193,146, 37, 75,106,133,243,206,157, 59,155,213,115, 40,138,130, 94,175,135,193, - 96,128,193, 96,176, 74,252,190, 8,172, 20,236, 37, 57, 57, 57, 49, 93,186,116, 57,119,240,224, 65,215,154,152,100, 40, 45, 45, - 69,105,105, 41,164, 82, 41,170,171,171, 97, 52, 26,225,227,227,131,210,210, 82, 28, 59,118, 76,166, 80, 40, 6,163,137, 21,135, -116, 58,125, 98,175, 94,189, 24,245,203, 96,126,202, 51,139,119, 14,135, 3,145, 72,132,190,125,251,178, 47, 93,186, 52, 17,192, - 63, 90,104,213, 13,239, 48,104,240,100, 86,104,120,119,221,189,180,184,162,144,214,165, 69,227, 71, 56,156, 4,128,148,212, 82, -199,123, 89, 78, 8, 13,143,161, 6, 13,118,142, 42, 45,217, 17, 9, 64,223, 84,186, 30, 0,112,228,115,198, 14, 28,208, 85,100, - 47, 16,208,214,174,219,121,250,167,159,214,119, 58,116,242, 63,225, 29,214,174,123, 26,222, 97,224,128,174,100,102, 70,230, 88, - 0,187,172, 21, 47, 49, 49,195,239,254,178,251, 23,100,166, 93,244,254,108,118, 59,118, 69,169, 1, 60, 59, 95, 68,117,240,192, -142,221, 15,112,239,222,189, 18,157, 78,215,183,201,254, 77, 80,126,105,233,169, 65,145,225, 97,158, 19, 38,126,232, 16, 19, 51, - 2,113,113,199,177,111,207,174,164,209,111,143,250,185,184, 82, 78,119,103,242, 89,124,138,100,211, 89,142, 12, 22,135, 39,209, -233,158,174,129, 96, 50,185, 14,192,216, 38,111, 60,211, 63, 28,239,216,111,192, 8,156, 60,117, 28,251,246,236, 72,252, 34,124, -204,174,214, 29, 67,137,174,157,190,159,209,186, 77,235,150,202,234, 82, 57,141, 96,235, 53, 26,210,254,251, 61,249, 63,228, 46, -153,152, 11, 96, 29,108,171, 14,235,226,254,190, 97,195,186,124,242,232, 17, 75,216,179, 39, 79,148,144,192,175,201, 68,210,164, -208, 98, 48, 24,160, 26,159,234,122,134,147,216,187,151, 6,160,201, 69, 88, 44, 22, 11, 42,149, 10,134,198, 45,216,207,112,122, -157, 61, 91,244,232,209,163, 64, 23, 23,151,103, 68, 86, 69, 69, 69,237,182, 70,163,129, 74,165, 2,143,199, 75, 83, 55, 60, 35, -242, 12,103,105, 82,146,102,245,236,217,203,222,121,251,237, 77,231, 47, 92,224,186,186,186, 66, 38,147, 61, 35,180,116, 58, 29, -250,245,239,207, 90,115,247,238, 4,200,229,203,173,185,158, 30,125,251, 90,244, 7,166,211,233, 32, 95,241,212,225,191, 0, 31, - 54, 36,188,104,150,166,112,172, 93,117,216,200, 13,178,126,118,239, 37, 81, 81, 81,154,236,236,108,248,249,249,213,138,149,186, -191,233,224,224, 0, 39, 39, 39, 36, 39, 39,227,155,111,190, 81, 3, 88, 98,129, 83,161, 82,169,222, 26, 56,112,160,154,193, 96, - 32, 36, 36,164, 54,126, 22, 73,146, 96,179,217, 16, 8, 4,184,123,247, 46,134, 15, 31,174, 82,169, 84,111,225,175, 49,180,234, -115,202, 84, 42,213,187,131, 6, 13, 82,165,167,167,163, 87,175, 94,184,119,239, 30,170,171,171, 81, 93, 93,141,188,188, 60,132, -133,133, 65,165, 82, 97,235,214,173,106,149, 74,245, 46, 0, 89, 83,156, 10,133, 98,248,130, 5, 11,232,191,253,246, 91,107, 31, - 31,159,240,206,157, 59, 7,247,239,223,191,237,155,111,190,217,114,216,176, 97, 94,129,129,129,154,193,131, 7, 11,135, 14, 29, - 42, 84,169, 84,204,171, 87,175,138, 13, 6,195, 80, 11,229,172, 21, 39,217,217,217,181, 83,133, 12, 6, 3,101,101,101,181,145, -251,205,131, 82, 35, 66,120,128, 37,177,109, 22, 88,102,193,101,133,159, 91, 67,156, 22, 79, 98,179,217,102,139, 39,101, 5,103, - 74, 70, 70,198,192,222,189,123,167, 76,158, 60, 89, 81, 82, 82, 2,123,123,123,248,251,251, 35, 40, 40, 8,110,110,110,208,235, -245, 56,122,244,168,242,216,177, 99, 15,100, 50, 89, 95,252, 53,134,214,128,122,215, 49,175,161, 65,214,108,205, 50, 11, 45, 46, -151, 11, 31, 31, 31,243,181,205,107,206,245,124, 78,188, 90,206, 26, 1,211,191,223,224, 54,195,162, 71, 58, 30, 61,126,141,189, -105,203,177, 7, 81, 3,176,211,181,149,252,132,107, 43,249,137,168, 1,216,185,105,203,177, 7, 71,143, 95, 99, 15,139, 30,233, -216,191,223,224, 54,233,105,153,193,117,243, 30, 54, 84, 78, 46,151,219,189, 87,207,168,202, 75, 87, 18,201, 85,107,126,164,245, -235, 59,250,238,174,159,143, 30,221,245,243,209,163,253,250,142,190,187,106,205,143,180, 75, 87, 18,201, 94, 61,163, 42,185, 92, -110,119,107,234, 62,253,195,241,142,209,195, 70, 32, 46,238,168,241,208,239, 91,215, 28, 56,156,211,123,202,172,164,210,236,236, -123,148,228,201, 89, 48,105, 5,200,200,200,144,213,136,172,108,107, 56,167, 77, 29, 95, 87,100, 93,118,245,236,181, 51, 35, 3, -166,248,248, 63, 13, 23, 46,220, 85, 95, 78,145,200,238,164,151, 85,136,164, 21,143,229,242,114, 29, 73,154, 96, 50,153,232, 95, -126, 89,235,176,219, 96, 27,245,232,209, 7, 23,207,239,199,158,221,219,101, 36, 9,205,216, 67,135, 76, 99,199,174,160, 90,182, -106,213, 50,246,247,253, 68,204, 27, 35, 29, 41,128, 28, 62,106,132,211,111, 7,126, 35,218, 4,180,105,229,239, 95, 27,210,230, -159,215,151, 94, 1,231, 10,160, 82, 94, 80,144,152,252,227,143, 90,143,183,222,114, 97,123,120, 56,192,100, 34,204,227,123, 99, - 47, 6,131, 81,223, 2,211, 40,167,143,155, 91,241,137, 19, 39, 16, 20, 20, 4, 31, 31, 31,212,245,145, 53, 7,228,118,117,117, -197,225,195,135, 65, 61, 27,156,186, 81,206,142,173, 91, 39,127,183,122,181,142, 36, 73, 84, 86, 86,254,197,154, 85, 89, 89, 9, -146, 36,113,234,228, 73,157,252,105, 38, 16,171,234,222,151, 78,175,126,231,245,215, 87, 69, 71, 71,235, 31, 61,122, 4,146, 36, - 81,215,178, 37,145, 72, 96,103,103, 7,141, 86,235, 11,128,111, 13,167,228,204, 25, 1, 44,140,235, 13, 88,180, 94, 69,187,255, -211, 69, 86,221,132,210, 31, 90,101,209, 50, 26,141,240,245,245,125, 38,165, 11,141, 70,123,230,213,204, 21,135,123,211,211,211, -207, 14, 30, 60,120,217,107,175,189, 54,125,217,178,101,244,224,224, 96,200,100, 50, 56, 59, 59,195,221,221, 29, 89, 89, 89, 56, -113,226,132,169,172,172,108, 27,128,149,176,110, 9,125, 66, 78, 78, 78, 76,187,118,237, 14, 44, 90,180,200,113,208,160, 65, 76, - 95, 95, 95, 80, 20,133,187,119,239,226,200,145, 35,250, 93,187,118,201,107, 68,150,181,206,203,231, 68, 34,209,232,161, 67,135, -198, 78,156, 56,209,222,100, 50, 49,243,242,242,160,213,106, 97, 48, 24, 80, 88, 88,168,143,139,139,171, 86,169, 84,227, 1,156, -179,130, 47,185,170,170, 42, 44, 62, 62,126,226,213,171, 87,191,153, 60,121,178,107,255,254,253, 89, 70,163, 17, 87,174, 92,145, -118,236,216,209, 93, 34,145,232, 15, 31, 62, 92,174,209,104,150,152, 76, 38,171, 82,240, 16, 4, 1,185, 92, 14, 55, 55, 55,104, -181, 90,144, 36, 9,157, 78, 7, 59, 59,187,218,180, 73, 20, 69,161, 57,206,245,245,250, 0, 93,175,215,227,237,183,223, 6, 73, -146,216,176, 97, 3,140, 70, 99,179,201, 28, 29, 29,239,164,164,164,196,116,232,208,161, 86,188,152,251, 16,135,195,129,155,155, - 27, 92, 93, 93, 17, 23, 23, 7, 38,147,121,199,146,191, 91, 13,238,149,149,149,117,140,143,143,239,254,224,193,131,247, 0,116, -208,235,245, 62, 38,147,137,160,209,104, 98,138,162,238,203,229,242,159, 97,101, 10, 30,137, 68,242,205,164, 73,147, 58,238,223, -191,223,142,193,248,207, 95,131,193, 96,128,195,225,192, 28, 28,147,162, 40,232,116, 58, 44, 93,186, 84,174, 84, 42,191,249,183, -140, 18, 81,157,187, 98,199,214,141,118, 23, 46,158,149,102,228,224, 72, 3, 33, 28,158,148,150,236,136, 20, 21, 21,217, 69,117, -238,106, 21,167, 65,167, 47,127,119,252, 60,191,154, 20, 60, 75,243,242,242,183,199,238,253, 33, 23, 0,190, 95,191, 33,176,180, -188,106, 90,102, 70,230,216,237,219,127,239,110,208,233,203,173,225,252,143,120,137,149,129,130, 6,192,205,187, 15, 74, 91, 15, -127,235,204,146,128, 54, 14,111, 72,202,213,197,213,213,170,143, 1,228, 90, 91,247,158, 61,122,227,226,185,223,176,111, 79,172, -156, 34,233, 26, 55, 55, 55, 10, 0, 50, 50,220,168,140,140, 42,234, 63,126,197, 78, 74, 38,117,111,229,188,143,251,207,147,201, - 43,214,111,216,218,244, 84, 74,187,246,175,161, 93,251,215, 48,235,227,207, 29,195,194, 67,252, 0,224,208, 33,152,194, 3,210, -255, 92,246,197,138, 55, 86,174, 92, 1,185, 66, 11,115,186,158,172,212,244,147,185,185,208,217,238, 89,207, 98,153,209,120, 19, -243,230, 5,170, 42, 42,132, 61, 63,251,204,141,241,233,167,180,166,156,225,235,254,127,173,225,188,125,255,254,201,105, 83,166, - 20, 47, 95,182,108,240,182,237,219,121,145,145,145, 40, 41, 41, 65, 72, 72, 8,124,124,169, 74,126, 90, 0, 0, 32, 0, 73, 68, - 65, 84,124, 16, 31, 31,143,195,127,252,161,172, 82, 40,150, 0,248,201, 26,206,189,167, 78,101, 5,135,135,151,109,223,190,221, - 59, 58, 58,154, 80, 42,149,144,201,100,144,201,100,208,106,181,168, 9, 8, 77,101,231,228,100, 24, 12,134,109,214,214,221, 36, -149,114, 87,118,237,250,132, 69,146,223,141, 30, 53,106,193,202,175,190,226,180,105,211,134,208,106,181,181, 86, 45,189, 94, 15, - 59, 59, 59,189, 78,167,115, 5,160,178,134,147,179,107,151, 81, 42,149, 66, 40, 20,214,134,107,170, 27,151, 80,161, 80,128,162, - 40, 91, 48,221,231, 64,163, 10,201,217,217,249, 14,131,193,104, 81,215,186,213, 80,238,188,186,251, 12, 6,195,147,178,178,178, -168,122,138,183, 49,127, 40,127, 0,223,246,235,215,111,244,252,249,243,137, 75,151, 46,225,216,177, 99, 84,110,110,238,161, 26, - 43, 86,110, 19, 79, 58,141,113,218,115, 56,156, 57, 2,129, 96,128, 57,132, 3,159,207,127,160, 84, 42,207,215, 76, 23, 42,158, -131,211,129,195,225,204, 22, 8, 4, 3,107,210,175,192,222,222, 62, 69,169, 84,198,107,181,218,141,104, 60, 81,117, 83,156, 60, - 71, 71,199,111,220,220,220,222,253,244,211, 79, 93,147,146,146,196, 23, 47, 94,100, 85, 85, 85,237,215,233,116, 77, 37,149,254, - 11,167,139,139,203, 29, 58,157,222,226, 21,181, 17,218,181,107, 23, 55,124,248,240,232,241,227,199,195, 96, 48,224,167,159,126, - 66,124,124,252,201,135, 15, 31,198, 88,120, 26,173,207,233,214,162, 69,139, 75,211,167, 79,111,249,246,219,111,243,157,157,157, -193, 96, 48,160, 84, 42,241,240,225, 67,220,189,123,151, 58,126,252,120,117,114,114,242, 19,149, 74,213, 7, 64, 89, 51,174,231, -139, 60, 53, 63,195,201, 96, 48,122,251,250,250,254,190,124,249,114,251,129, 3, 7,242, 92, 93, 93, 65,167,211, 97, 48, 24, 32, - 22,139,145,154,154,138,179,103,207, 42, 15, 29, 58,164, 44, 47, 47,127, 27, 64,226,255, 71, 57, 95, 38,103,104, 32,190,168,151, - 40,186,209,104,239, 22,142,181, 88,206,126,189,189, 70,140, 29, 61,116, 8, 0, 28, 60,124,250,140, 21, 73,165, 27, 45,167,165, -178, 90,195, 25, 18, 64, 91,158,150,158,250, 76, 64,203,240,176,136,236,208,200, 81, 95, 91, 67, 84, 39, 50,252, 51,117,175, 51, - 29, 91,215,166,251,204, 52,107,168, 63, 98, 70,140,125, 51,250,243, 37,139,241,237, 55,171,112,252,224,209,147, 25,185,207,164, - 9,250,199,245,165, 87,204, 73,124,205, 96,188,198,247,242,122,125, 3, 73, 46,190,151,154,106, 87,247,129,205,108,121,174,251, - 80,233,237,237, 45, 17,139,197, 30,214,112,198,108,222,172, 87, 9, 4,156,197,223,125,215,187, 90,163,233,189,114,229, 74,198, -237,219,183,177,245,199, 31,141,154, 39, 79, 98,165,192,236, 70,102, 67, 26,229,108, 57,123, 54,119,225,214,173,239,251, 7, 4, -184,191,247,222,123, 76, 38,147, 9,165, 82,137,162,162, 34,156, 59,123, 86,151,158,145,145, 46,151,203,223, 0, 32,178,150, 51, -102,243,102,189,147,191, 63,248, 66, 33,117, 33, 33,193,113,218,156, 57,211, 91,181,110,237, 56,120,200, 16,166,131,131, 3, 42, - 43, 43,145,151,151,135,163, 71,143, 74,170,171,171,189, 1,152,172,225,140,189,122,181,221,169,196,196, 49, 95,127,253, 53, 59, - 34, 34, 2,142,142,142, 80, 40, 20, 72, 77, 77, 69, 98, 98,162,118,219,182,109, 50,153, 76, 54,221,100, 50,157,120,133,237,254, -111,176,106,153,177,195,162,208,250, 47,254, 1,163, 0,124, 81,179,253, 21, 44,231, 12,252, 55, 13, 62,126, 46, 46, 46, 59, 52, - 26, 13,165, 86,171,167, 1, 40,252, 27,150,147, 17, 21, 21,181, 85, 34,145,116,167, 40, 10,142,142,142,215,210,210,210,102,162, -145,149, 55, 22, 56,233, 0,186,219,217,217,117,181,183,183,239,173,213,106, 67,107,166,223, 50,148, 74,101,162, 94,175,191, 89, - 99,125, 50,253, 63,215,157, 14, 96,160,183,183,247, 20,146, 36, 3, 8,130,112, 50,153, 76, 48, 24, 12, 85, 36, 73, 62,148,201, -100,187, 0,196,255, 13,202,249, 82, 56,195,218,226, 77,138,134,208,198, 4,193, 51, 66,171,158,128, 32, 72,100,164, 63,194,209, -102,148,147, 54,116,128,239, 22,224,233,202, 68, 88,118,174,253,143,208,178, 66,188, 52, 91,100,182,165, 79,162, 8,234, 25, 78, -130, 34, 10, 67,218,189,185,239, 69,132,150,181, 8, 11, 66,111, 80,232, 78, 82,184,153,249, 16, 23,255,197, 99,221, 75,227,252, - 22,112,249,209,217,249, 26,141,193,240, 4, 64,171,177,190,144, 36, 65,152, 40,130, 48,214,157,222,170,247, 96,217, 36,167, 30, -136,100,114, 56,190, 38,163,209,163, 4,176, 59,101, 50,117,210, 80, 84,117, 11,224,139, 20, 32,235,121,202,169, 7, 34,233, 28, -142,223, 41,138, 26, 33, 21, 8,218, 73,212,106, 33, 0,202, 78, 32,200,144, 43,149,123, 52, 26,205, 22,252,117,230,194, 34, 39, -139,195,105, 97, 50, 26, 61, 0,128,198, 96, 72, 14,104,181,190, 79, 28, 28,222,211,104,181, 45,237,236,236, 12, 58,157, 78,174, -209,104,198, 27,141,198, 11,205,169,251, 67,163, 49,236, 42,141,214, 75, 47, 16,184,234, 9, 66,160, 51, 26,245, 58,189,190, 72, -163,209, 60, 0,240, 3,128, 71,175,184,221,109,120,206, 63,139,141,211,198,105,227,180,113,218, 56,109,156, 54,206, 87,207,201, - 7,224, 87,243,176,248, 79,172,251,191, 9,214,249,104,217, 96,131, 13, 54,216, 96,131, 13,255, 24,168,208,128, 79,150, 13,255, -191, 32,154, 80,165,205, 49, 9, 62,143,178, 61,111,227,180,113,218, 56,109,156, 54, 78, 27,167,141,243,127,142,211, 18,247, 63, -113, 74,178,209, 92,135,175, 26, 54,243,175,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 89,208,108,151,160, 81,120, -212,188, 94,246,177, 54,252,187,251,194,127, 3, 62, 53,175,230, 28,239,101,107, 70, 27,108,176,193,134,255, 13,161,101,237, 77, -235, 69,110,110, 47,122, 99, 92, 69, 16, 16, 17, 4, 68, 0, 86,189,196, 99, 45,193,219,205,205,237,147,176,176,176, 88, 15, 15, -143, 89, 0,220,155,121,126, 32,159,207,223, 40, 16, 8, 46, 9, 4,130, 75,124, 62,127, 35,128,192,151,212,110, 4,128,105, 28, - 14, 39,193,203,203,171,152,205,102, 39, 0,152,142,231, 95,185, 26,140,167,113,210,190, 2,208,174, 57, 39,186,135,143,248, 67, - 24, 62,226,190, 48,124, 68,170,107,196,240, 64, 97,248,136, 84, 97,248,136,251,238,225, 35,254,120, 5,253,245,101,182,239,203, - 42, 79, 33, 65,160,208,202,242,252, 64, 0, 69, 4,129, 39,127,147,242,219, 96,131, 13, 54,216,208,168, 10,240,246, 30,237,229, -229,117,222,203,203, 43,222,219,219,123,180, 21,167, 12,104,224, 38, 97, 34, 8,152, 44, 12,250, 77, 29,103,201, 92, 89,247,220, -181, 86, 86,173, 46,167, 7, 65,192, 68,213,128, 32, 64,186,187,187,111,242,242,242, 90, 85,255,229,238,238,190,137, 32, 64,214, - 57,214, 84, 71,224, 53,215,172,234, 49, 97,194,132,131,149,149,149,113, 58,157, 46, 46, 39, 39, 39,174, 79,159, 62, 7,234, 89, - 34, 26,229,228,114,185,239,116,233,218, 61, 57,241,202,205,156,236,135,249,162,244,172,199,249,127,158,185,112, 59, 34,178,221, - 45, 46,151,251, 78, 51,218,136, 0, 48,141,193, 96, 36,216,217,217, 61, 97, 48, 24, 9, 0,102,208,233,244, 19,171, 87,175,206, - 79, 75, 75, 43,189,122,245,106, 85, 98, 98, 98,241,228,201,147, 31, 18, 4,241,103, 3,130,125,128, 21, 22,152,101, 5, 5, 5, -103,196, 98,241, 89, 30,143,247,141, 21,199,215,114, 10,195, 71,220,151,200,244,148, 68,166,167,132,225, 35,168, 58,219,247,155, -121,205, 45,181,209, 95,250, 2,135,195,241,179, 32,232, 95,165,137,254, 47,229, 1,224, 89,243, 93, 20,128,205, 53, 47,243,114, -118, 79, 46,135,243,178,250,231,203,184,158, 54, 78, 27,167,141,211,198,249,111, 69,199,154,119, 47, 60,245,215,170,189,119, 55, -119,213,225, 71, 57, 57, 57,118, 0, 16, 20, 20, 52, 19,192,225,230, 8, 9,130,192, 66,146,164,104, 0, 64,163, 17,159,245,237, -219,175, 35,143,199,123, 38, 10,178, 90,173,102, 39, 36, 92,236, 79,146, 20, 81,115,220, 66,138,194, 70, 0,165,214,254,134, 78, -167,165, 49,153,108,208,104,196,188,136,136,200, 86,101,101,101, 73, 52, 26, 45,182,184,184,184,178,217,102, 28,130,192,206,157, - 59,131,188,188,188,254, 18,173, 89, 44, 22,179, 71,140,120,163, 89,124,147, 0,142,150,195,233,202, 34, 8, 47,147,209,232, 4, - 0, 12, 6,163,242, 54,155, 29,245,237,215, 95,243, 9,130, 32,203,203,203,161, 86,171, 49,119,238, 92, 94,122,122,250,200,178, -178,178, 45, 22,104,131,218,181,239, 56,247,236,217, 51,161,242,138, 74,205,206,245,219,147,213, 12,150,170,117, 88, 8,107,235, -142, 61,206, 31,190, 63,254,227,204,204,180, 20, 52,156,142,164, 46,104, 0,142,206,153, 51, 39, 60, 38, 38,134,173, 80, 40,184, -106,181,186, 85,108,108,236,210,168,168, 40,187, 14, 29, 58,176,127,255,253,119, 66, 38,147,129,162, 40,126, 72, 72, 8, 53,110, -220, 56,205,129, 3, 7,102, 1,216,212,132,240, 93,248,244, 90,210, 54, 4, 7, 7, 47, 7,128,156,156, 28, 86,157,107,204, 12, - 13, 13, 21, 0, 64, 86, 86,214,151, 20, 69,206, 1, 0,138,194, 26, 0,139, 27, 48,173,229,132,247, 28, 11, 16, 8, 72,187,114, -144, 27,222,107,172, 6, 20, 30, 18, 64, 78,205, 3,193, 74,160, 78, 92,168,103,145, 33, 18,137,158, 43, 55, 97,116,116, 12, 65, - 16,196,161,228,228,228,195, 18,137,164, 53, 73,154,166, 54, 85,206,198,218, 74, 40, 20,158, 53,153, 76,218,138,138,138,218, 64, -153,194,118,111,118,119,181, 23,244,151, 86, 42,146,202,211,143, 39, 90,217, 55, 9, 87, 87,215, 73,101,101,101,171, 0, 76,201, -200,200,232, 8, 0,161,161,161, 44, 0,119, 28, 28, 28,122,232,117, 58,194, 54,254,217, 96,131, 13, 54,252, 87,132,214, 93, 0, -209,248, 79, 10,158, 29,207, 35,180,216, 0,144,148,148, 4, 0,156,231, 40, 8, 81, 87,192,204,158, 61, 27, 94, 94, 94,245,197, - 11, 46, 93, 74,120,145,202, 62,243, 27, 95,125,245,149, 93, 85, 85,213,128,159,127,254,249,117,138,162,214,138, 68,162, 27, 22, -206, 47,165, 40,172,161,209,136,207, 8,130, 0,135,195,205,158, 62,125,250,221,154,239, 90,253,249,231,159,252,225,195,135,171, - 0,228, 3, 0,135,195,245,161,211,105, 65, 20, 69,153,111,184,141, 10,194, 49,128,191,145,205,238, 55,109,243,102, 99,167,225, -195, 25, 2,161,144, 0,128,252,204, 76,215, 53,223,127,223,163, 50, 55,151,173,118,117, 45, 47, 87, 42,213,217,217,217,224,112, - 56, 4,157, 78,239,100,169,194, 2,129,224,147,175,191,253, 78, 32,175,168, 82,107,228, 10, 29,221,104,208,218,243,248,166,210, - 18, 73,185, 29, 79,160,250,236,139, 21,236,143,166, 78,252, 68,169, 84,206,180, 64, 53,107,222,188,121,161, 93,186,116,241,249, -227,143, 63, 8,153, 76, 6, 6,131, 97,215,161, 67, 7, 68, 69, 69,153, 46, 94,188, 72,180,110,221, 26, 17, 17, 17,184,114,229, - 10,174, 93,187, 70,116,236,216,145,127,228,200,145, 9, 6,131, 97,147, 37,113, 77,167,211,230,134,132,132,116, 16, 8, 4,186, -160,160, 32, 76,157, 58, 21, 20, 69, 97,192,128, 1, 17,118,118,118,135,149, 74, 37, 59, 43, 43,243,117, 75, 34, 91,146,118,124, -156,217,178, 5, 32, 18, 20, 30, 74,211,142,215,157,126, 12,205,202,202,122,173,178,178, 18, 79,219,133,170, 77, 96,254,250,235, -175, 55,167, 47,149, 82, 20,214, 12, 31, 30,243, 25, 64, 16, 3, 6, 12,168,154, 53,107, 22, 45, 51, 51,243,221, 55,223, 28, 25, -145,147,243, 16,205,124, 24, 8, 26, 52,104,208,149, 83,167, 78,185, 6, 5, 5, 73, 43, 42, 42,106,191,240,116,117, 26,156,120, -100,195, 39,223,108,140, 13,217, 75, 17, 85,210,140, 99, 15, 44,244, 77, 98,210,164,247, 75,237,236,236, 70, 29, 58,116, 40, 75, - 44, 22, 51, 88,172, 90,237, 74,119,119,119, 23, 6, 5, 5,205,112,113,113,145,208,105, 52,119, 10, 20,101,169,127,218, 96,131, - 13, 54,216,240,220, 56, 89, 35,174, 78,214,255,130, 1, 0,113,113,113,181,145,105, 99, 98, 98, 26,125, 2,166, 40,170,244,222, -189,123,190, 42,149, 10, 20, 69, 89, 51, 96,215, 93,162, 89, 74, 16,180,173, 52, 26, 49,147, 32, 8, 68, 68, 68, 62,222,176, 97, - 67, 67, 57,189,116, 17, 17,145,143,233,116, 90, 27,138,162, 64, 16,180,159, 40,138, 44,109,132,179,193, 27, 17,155,205, 89, 8, - 0,158,158, 94,185,167, 79,159,214,141, 25, 51, 6,223,127,255, 61,107,209,162, 69, 11, 24, 12,198,172,194,194,194,146, 38,202, - 9, 0,139,133, 66,119,254,206,157, 59,131,166, 79,159,126, 87, 44, 22, 47, 6, 0, 47, 47,175, 85, 0,194, 0,228,215,217,135, -109,219, 14, 20, 79,157, 58, 53, 91, 34,145, 44,110,140,115, 20,208,214, 55, 36,164,223,202,164, 36,138,166,213, 18,101,151, 47, -203,165,165,165,134, 71, 82, 41,127,247,157, 59, 49, 75, 87,173, 98,250,250,249,225,210,137, 19,110,101, 42,149, 84,166,213,106, - 74, 75, 75, 41,163,209,120,205,138,186,135,187, 11,221,249,219,127,248,233,182, 61,147, 78,186,183,240, 33,152, 46, 46, 12, 26, -223,129, 77,103,208,180,109, 90, 5,178, 1,132, 91,106, 35, 22,139, 53, 97,208,160, 65,252, 3, 7, 14, 16, 17, 17, 17,112,114, -114,194,229,203,151,145,146,146,130,202,202, 74,154,193, 96, 64,231,206,157,241,221,119,223,193,207,207, 15, 85, 85, 85, 40, 44, - 44,116, 99,179,217, 66,131,193,208,216,245,124,166, 63, 45, 92,184, 16, 94, 94, 94, 48, 26,141,168,168,168,128,209,104,132,157, -157, 29, 0,224,201,147, 39, 56,113,226,184, 53,125,201, 34, 40,138, 66,183,110,221, 20, 4, 65,100,212,183,104, 53,135,211,199, -199,231,119,169,180,108,104,191,126,253, 80, 89, 89,105, 88,177, 98, 5,218,181,107,135,160,160, 32,139,229,244,246,246,158,102, - 52, 26,151, 1,128, 94,175,223,205,229,114, 63,216,183,111,159,107,221, 20, 33,102, 75, 86,169,164,188,242,218,237,180,172,121, -211,198,244, 73,186,145, 90,164,103,142, 40,148,221, 63, 46,107,160,156,139, 89, 44,246,207, 45, 91,182,252, 97,246,236,217, 94, - 46, 46, 46,208,106,181, 75, 75, 74, 74, 48, 99,198, 12, 0,192,176, 97,195,218, 49,153,204,211,147, 39, 79, 70,235,214,173,139, - 43, 42, 42, 10,147,147,147,167,170, 84,170,212,231,189,158, 86,194,198,105,227,180,113,218, 56,159, 27,214,106,145,191, 41,196, -120, 54,156,195,142,103,132, 86, 76, 76, 12, 17, 23, 23, 71, 89, 81,177,242, 22, 45, 90,248,242,120, 60, 0, 40,111,110, 41, 72, -146,156,229,234,234, 42, 89,188,120,113,207,160,160, 32,221,172, 89,179, 82,243,243,243,151,212, 61,166, 85,171, 86,223,252,248, -227,143,200,206,206,206, 95,181,106,213,149,242,242,242,230,230, 49, 91, 68, 81,216, 80, 99, 29, 43, 59,113,226, 68,187,164,164, -164,153,235,215,175, 23,126,244,209, 71,172, 79, 62,249,100, 60,128,239, 45,145,208,233,116, 85, 67,211,133, 13,193,203,203, 75, - 71,167,211, 27, 13, 18, 23, 3,240,184,108,118,223,149, 73, 73,148, 46, 63, 95,245,203,186,117,246,219,111,221, 90,110,160, 40, - 15,119,119,119,244,234,209,163,154, 75,167,151, 73, 74, 74, 72,247,182,109,233,121,167, 79,187,169,217,108,209,129, 3, 7,100, -229,229,229,199, 44,154,240, 8, 66, 78, 82,148,206,174,133,159, 97,204,200,129, 17,183,111,166,100,218,187,187,209, 58,118,136, -104,151,153,157,159, 12,146,212, 19, 4, 33,183,196,227,232,232, 24, 84, 94, 94, 14,185, 92, 14,161, 80,136, 13, 27, 54,192,211, -211, 19, 42,149, 10,105,105,105, 84,139, 22, 45,136,164,164, 36,180,104,209, 2, 82,169, 20, 58,157, 14, 10,133, 66,162,213,106, - 27,203,205, 88, 74,163,209,127,165,209,136,247, 9,130, 64,155, 54,254, 5, 91,182,108,209,145, 36,137,208,208, 80,188,249,230, -155, 56,114,228, 8,210,210,210,204,150, 39, 93,203,150,173, 10,104, 52,162,101,141, 86,122,110, 11,140, 57,181,143, 72, 36, 26, -245,156,127, 26,154,183,183,247,248,128,128,128,153,239,188,243,142,129,205,102, 67,169, 84,154,175,133, 97,232,208, 97, 85,195, -135,199, 56,158, 60,121,178,209,114,234,245,250,101,197,197,197, 94,106,181, 26, 67,134, 12,249,100,237,218,181, 2, 54,155, 13, - 0, 48,153, 76,207, 88,178,190, 94,191,247,236,156,101, 91, 18,206,254,254,157,247,215,139, 62,232, 51,126,214, 55, 9, 0,206, - 52, 84, 48,157, 78,151, 43,147,201,166,204,155, 55, 47,118,219,182,109,206, 75,150, 44, 1, 73,146,160, 40, 10, 70,163,177, 54, -145, 56, 73,146, 56,122,244, 40, 30, 61,122,244, 77, 61,145,101,131, 13, 54,216,240,183, 67, 51,180,200,223, 17, 94,120, 58,109, -136,250, 98,235,191, 30, 25,158, 78,167,111, 63,119,238, 92,135,215, 95,127,157,209,191,127,255,136, 51,103,206, 68, 20, 23, 23, -167,214, 88, 15, 34,250,247,239, 31,225,238,238,142,141, 27, 55,170,232,116,250,246,231,252,153,218,155, 94, 73, 73,201, 93, 0, -107,143, 28, 57,178,102,218,180,105,240,244,244, 12, 19,139,197,255,213, 58, 59,112, 56, 29, 39,111,216, 96,100, 26, 12,180,205, -107,215, 58,172, 75, 72, 88,243,199,193,131,140,110,221,186, 17, 20, 69,225,193,253,251,188,239, 54,109,226,191, 61,114,100,126, - 86,110,174,241,248,217,179,134,210,226,226,138, 98,169,116, 25,128, 10, 75,252, 6,131,225,122, 78, 78,142,119,175,222,221,124, - 18,111,165,166,140, 25, 57,172, 31,147, 65, 35, 30,230, 63,185,227,229,233,230,120, 41,225,188,218, 96, 48, 92,183,196,163, 84, - 42,243,140, 70,163, 11, 69, 81,194, 75,151, 46, 65, 40, 20,162,178,178, 18, 6,131, 1, 58,157, 78,167, 82,169,184,229,229,229, -208,104, 52,208,106,181,112,112,112,192,131, 7, 15, 74,141, 70,227,197,198, 56, 77, 38,211,100, 14,135,243, 21,147,201,100,179, - 88, 44,209,157, 59,119, 32,151,203, 91, 57, 57, 57,125,111, 52, 26, 33, 18,137,144,148,148,244,169,131,131, 67, 62, 0,112,185, - 92,176,217, 28, 87,173, 86,107, 4, 80,252,188,215,156,162,168,231,110, 47, 79, 79, 79, 63, 30,143,183,242,179,207, 22,134,182, -111,223, 1, 82,169, 20, 36, 73, 66, 32, 16, 64,165, 82,193,193,193, 1,221,187,119,207, 91,185,114,165,152,162,240, 97, 19, 98, -144, 94,211, 62,152, 54,109,154,192,193,193, 1, 69, 69, 69, 8, 9, 9,169, 21, 90, 98,105,249,131,171,183, 83, 51,231, 77, 31, -219,123,255,137,132,140,179,151,238,100,140, 28,210,163, 61, 65, 80,173,154, 42,163, 68, 34,145, 50, 24,140, 89,211,166, 77,251, - 42, 40, 40,168, 13, 69, 81, 8, 12, 12,196,160, 65,131,112,250,244,105,100,103,103, 67,169, 84,154,110,220,184,241,155, 88, 44, -254,211, 54,132,219, 96,131, 13, 54,188, 82,252,197, 55,235, 25,139,214,127, 19, 18,137, 68,154,153,153,121, 38, 57, 57, 57,102, -220,184,113,184,116,233,210, 36, 0,243, 0,128,195,225, 76, 26, 55,110, 28,146,147,147,145,153,153,121, 70, 34,145, 72, 95,198, -111,178,217,108,141, 78,247,212, 56,197,229,114,185,205, 60,189, 85,205,148, 33, 0,180,106, 98, 95,227,166, 17, 6,195, 43,114, -200, 16, 70,101, 74,138,124,231,205,155, 95,197,198,198, 50,122,246,236, 73, 24,244,122,152, 72, 18,254,254,254, 68,255, 1, 3, - 4,191,198,198,186,152,148,202,164,175, 63,251,236,242,142,201,147,171,115,106,252,192, 44, 65,171,213,110,154, 57, 99,202,128, -132, 75,151,125,194, 66,218,186,156, 57,151,112,215,213,213,145, 31, 20, 16, 32, 40,175,172, 48, 45, 89,244, 41, 67,171,213,110, -182,196,163, 86,171,143,158, 63,127,126,164,175,175,175, 48, 53, 53, 21, 58,157, 14, 38,147, 9,253,251,247, 7, 69, 81, 28, 0, - 36,131,193, 64,102,102, 38,244,122,189, 36, 39, 39, 71,244,240,225, 67, 14,128,213, 22,202, 87,160,213,106,145,145,241,116,214, -174, 69,139, 22, 3,163,163,163, 97, 52, 26, 49,100,200, 16, 28, 63,126,124, 96, 70, 70,198,186,186,154,239, 69,219,188,198, 66, - 22,234,237,237,125,164,102,151, 85, 78,240, 62, 62, 62, 17,254,254,254,219, 86,175, 94,205,106,209,162, 5, 40,138,130,179,179, - 19, 84, 42, 21,202,202,202, 17, 22, 22, 6, 95, 95, 95,172, 94,189, 26, 0,126,107,202,226, 70,146, 36,196, 98, 49,242,242,242, -144,155,155, 11, 95, 95, 95, 16, 4, 1,133, 66, 1,163,241,105, 78,110,190, 66,126,242,199, 95,255,236,123,112,219,178,240,174, -145,129,126, 55,239,166, 75, 38,140, 26,200, 15,108,237, 23, 36, 77, 93, 65, 3, 86, 52,154,116, 89, 36, 18, 61, 20,137, 68,227, - 36, 18, 9,171,170,170, 42,106,224,192,129, 27, 7, 12, 24,128,187,119,239,226,242,229,203,111,115, 56, 28,137, 94,175, 55,122, -122,122,126, 72, 16,132,131, 94,175,223, 95, 94, 94, 46,182,141,135, 54,216, 96,131, 13, 47, 29,102, 31, 45,212,121,111,158, 69, - 43, 52, 52, 84,144,159,159,255, 94,171, 86,173,216, 0,192,227,241,194,252,253,253, 23,228,230,230, 42,154, 91, 26,149, 74,245, - 71,108,108,236,160, 31,126,248,129, 53,108,216,176,182, 71,142, 28,233, 2, 0,195,134, 13,107,107,111,111,143,216,216, 88,189, - 74,165,122,105, 49,145, 12, 6,195,235,157, 59,119, 70, 69, 69, 5,242,243,243,155, 53,133,242,231,159,127,242,241,212, 47,171, -201,125, 77,193,168,211, 57, 59,249,248,208,138, 19, 18,244, 21,114,185,215,235,189,123, 19, 6,189, 30, 52, 26, 13,229,229,229, - 40, 44, 44,132,163,147, 19,145,153,147, 99,183,107,225,194, 63, 91,181,111,207, 54,233,116,174,205, 40,166,178, 76, 82,250,254, -199,179, 62, 58,186,127,255,111,194, 42,185,252, 17,143,199,215,114, 56, 44,207,217, 31,127,108,170,168,168,152, 8,160,218, 10, -158,213,251,247,239, 31, 50,100,200,144,251,126,126,126,238, 82,169,212,179,170,170,202, 84, 81, 81, 65,199, 83, 95, 43, 2, 0, - 18, 18, 18, 32,151,203,141, 38,147, 41, 9, 79, 99, 97,233,172, 45,104,203,150, 45, 29,163,162,162,250, 8,133, 66,200,100, 50, -184,186,186,162, 67,135, 14,125,232,116,250,207, 5, 5, 5,178,151,217,235,227,227,227,237, 41,138,122,141,162, 40, 12, 25, 50, -196,170,115, 76, 38,211, 7,209,209,209, 44,130, 32,160, 86,171,192,229,242, 32, 16,216,193,222,222, 1, 65, 65,193, 16,137, 68, - 24, 60,120,176,238,209,163, 71, 91,197, 98,241, 31, 22,184, 32, 18,137, 32,149, 74, 81, 88, 88,136,178,178, 50, 0, 64, 89, 89, - 89,173,115,254,203,128, 76, 38, 27,209,189,123,247,249, 51,102,204,128,209,104,196,136, 17, 35, 80, 84, 84,180, 46, 47, 47,239, -128,183,183,247,248, 15, 62,248, 64,232,234,234,138,249,243,231,243, 0,124,105, 27, 15,109,176,193, 6, 27, 94, 58,234,251,104, -253,213,162,213,212,156,168,167,167,103, 47,130, 32,150,170,213,106,182,121, 74,134, 32, 8,182, 80, 40, 60,174, 86,171, 87,137, -197,226,102, 57,197, 85, 85, 85,201, 31, 63,126,124,252,250,245,235, 99, 71,141, 26,133,248,248,248,137, 0, 48,106,212, 40, 92, -191,126, 29,143, 31, 63, 62, 94, 85, 85, 37,127, 25, 53,247,241,241, 25,218,187,119,239, 81,157, 59,119, 70, 92, 92, 28, 76, 38, -211,181,230,156, 95,119,133, 33, 26, 88,117,104,222,103, 21, 25,157, 14,130, 32,106,173, 25,101, 82, 41,178,179,178, 80, 81, 89, - 9,173, 70, 3,165, 74,101, 10,106,221, 90, 45,211,233,152, 4,208,220,185,175,130,228,219, 55, 10, 85, 74,165,187,171,179,139, -154,207,231,160, 74, 46, 99,221,185,125,163, 26,192, 35, 43, 57,116, 20, 69,245, 62,125,250,244, 50, 58,157, 62,206,206,206, 14, - 51,103,206,164,247,233,211, 7, 44, 22, 11, 90,173, 22, 85, 85, 85,136,141,141,149,154, 76,166, 54, 53,231,216,241,249,252, 61, -116, 58,253,137, 66,161, 88,106,241, 7,116,186, 97, 49, 49, 49, 12,157, 78,135,175,191,254, 26,203,151, 47,199,144, 33, 67, 24, -183,111,223, 30, 6, 96,255,203,234,241, 36, 73, 98,224,192,129,117,157,225, 51,172, 57,143,201,100, 70, 4, 4, 4, 64, 42,149, - 66, 42,149, 66, 40, 20,194,219,219, 27,158,158,158, 88,183,110, 29,181,113,227,198, 51,122,189,126,107, 89, 89, 89,169, 53,101, -200,205,205,173,181, 12,106, 52, 26, 40,149, 74, 20, 21, 21,213, 78, 29,170, 5, 14, 67,102,189, 63,188,189, 82,173, 86,221,124, -144, 83,184,244,147,241,221,148,106,181, 42, 39,175, 48, 27,216, 68, 90,209,191, 63,156, 56,113,226,135, 99,199,142, 69,117,117, - 53,174, 95,191,142, 30, 61,122, 96,205,154, 53, 94, 73, 73, 73,243, 58,119,238, 12, 38,147,137, 75,151, 46,193,104, 52, 22,217, -198, 66, 27,108,176,225,239,140,127,168,127, 86,147,104,210,162,229,235,235,235,100, 50,153, 62,141,142,142, 30, 56,114,228, 72, - 12, 30, 60,248,153,239,247,239,223,111,127,248,240,225, 85,155, 54,109, 26,162,215,235, 87, 55,103,170,143, 36,201,163,251,247, -239, 31,214,173, 91, 55,126,223,190,125,253, 1,128,195,225,232,246,239,223,175, 34, 73,242,232,115,212,197, 28,136,177, 20, 0, -188,189,189,219, 49, 24,140, 81, 67,135, 14,109,247,254,251,239, 35, 45, 45, 13,177,177,177, 15,131,130,130,174,148,150, 54,203, -191, 58,223,194,170,195, 85,150,172, 91,116, 54,187,188,170,164,196,201,206,207,143,233,108,111, 47,142,139,139,243, 29, 48, 96, - 0, 81, 84, 84,132,202,202, 74,104, 52, 26,220,190,125,155,100, 0, 5, 12,103,103,162,224,250,117,130,206,102,151,227,217,149, -124, 22,225,235,229, 28,248,197,162,233,173, 52, 90, 77,184, 76, 38, 51, 50,152, 76,102, 11, 79,167,162,172, 71,205,154,137,211, -242,249,252, 40, 0, 12,146, 36, 85, 46, 46, 46,252,115,231,206,129,205,102,131, 32, 8, 68, 70, 70,130,203,229,178, 40,138, 42, - 4, 0,123,123,123,246,246,237,219, 29,199,143, 31,127,217, 18,113,199,142, 29,153, 28, 14,231,141,160,160, 32, 92,191,126, 29, -169,169,169, 5,215,175, 95,111,217,177, 99, 71,248,249,249,189,225,229,229,117,240,238,221,187,134,151,209,177,159,174, 88,109, -190, 51,188,201,100, 34, 9,130, 0,141, 70, 3, 73,146,144, 74,165,104,211,166, 13,182,108,217,130, 13, 27, 54,124, 45, 22,139, - 79, 52,131,203, 36,151,203, 33, 16, 8,144,154,154,170,141,142,142,230,208,104, 52, 60,124,248,176, 86,104,185,187,185,132,245, -232, 28, 17,242,245,250,189,103, 5, 28, 14,103,112,159,168,208,244,156,130, 39, 20, 69, 88,156, 54, 14, 13, 13,101,181,105,211, -102,226,216,177, 99,145,155,155,139, 85,171, 86,149,137,197,226,132,179,103,207,142,158, 49, 99, 6,189, 71,143, 30, 40, 47, 47, -199,175,191,254,106,188,115,231,206, 47, 37, 37, 37,123,109,195,184, 13, 54,216, 96,195,223, 68,104,249,250,250,142,101,177, 88, -243,223,122,235, 45,122,112,112, 48, 74, 75, 75,225,224,224, 96, 32, 8,130, 9, 0, 78, 78, 78, 6, 30,143,135,233,211,167,163, -125,251,246,189, 22, 46, 92,216,131,193, 96,108, 17,137, 68,123,172,249, 97,137, 68,162,162,209,104,135,102,206,156,185, 58, 37, -229,110, 27, 0,184,117,235,214, 99,145, 72,180, 72, 34,145,168,154, 89, 15,115, 80, 76,130,195,225,222, 12, 12, 12,204,139,138, -138,114, 24, 57,114, 36,132, 66, 33,146,147,147,241,221,119,223,229,232,116,186,101,137,137,137,198,255,246, 69, 54,106,181, 37, -119,142, 29,179,239,243,238,187, 14,179,163,163,215,126, 52,115,230, 15, 95,124,241, 5, 35, 56, 56,152, 80,169, 84,184,121,243, - 38,117,248,240, 97,195,175, 95,125,181, 1, 2, 1,243,250,225,195,108,157, 78, 87,208, 76,203, 93,239,158,175,247, 10, 94,251, -195, 38,104,212,213,184,121,237, 36, 42, 43,165,216,190,227, 72,176,143, 15,213,187,184,184, 56,209, 90, 46,130, 32,130,226,227, -227,221, 41,138, 2,155,205,198,202,149, 43,225,237,237, 13, 7, 7, 7, 40, 20, 10,204,155, 55,207,113,206,156, 57,142, 0,144, -150,150, 86, 27,158,193, 18, 68, 34, 81,247,233,211,167,219, 27,141, 70,156, 57,115, 70, 71, 16,196,210,243,231,207,255, 28, 25, - 25,201,238,213,171,151,253,222,189,123,123, 0,184,244,178,132,214,115,158,247,240,220,185,115,157,199,141, 27, 71, 49,153, 76, -162,170,170, 10, 78, 78, 78,216,178,101,139, 82, 44, 22,159,108, 38,215,202, 69,139, 22, 45,171,217,222,189,116,233,210, 41,171, - 87,175, 22,150,148,148,212, 90, 53, 37,101, 21, 23,187, 71,127,108, 42,175,146,233,126, 89,191,112, 12,143,203, 97, 47, 93,253, -203, 37, 3, 29, 55, 44,246, 43,163,145,205,231,243,217, 20, 69,225,208,161, 67, 40, 40, 40,248,160,188,188,188,196,100, 50, 29, -249,244,211, 79, 23, 4, 7, 7,183,206,202,202, 42, 80, 40, 20,107, 36, 18, 73,158,109,184,179,193, 6, 27,108,120,101, 48, 59, -193,155, 87, 31,158,196,211,233,196,198,133,150,201,100,154,126,246,236, 89, 58, 73,146,216,177, 99, 7,238,220,185, 67,241,249, -252,165,124, 62,255, 71, 30,143,103, 82,171,213,211,166, 78,157, 58,126,249,242,229,180, 94,189,122,225,250,245,235,180, 54,109, -218, 76, 4, 80, 87,104, 13, 64, 19,177, 54,100, 50,217,237,210,210,146, 54,117, 2, 84,182,225,112,184,183, 45, 84,166, 62,103, -253,160,152, 93, 87,174, 92,169,244,242,242,210,165,166,166, 98,219,182,109,228,157, 59,119, 18,216,108,246,118,177, 88,172,181, -146,243,101,160,150,147,109, 52, 38,239, 91,176, 32,180,211,136, 17,228,148,249,243,171, 89, 60,222, 39,107, 55,109, 90, 88,165, - 80,120,131, 32, 40, 87, 71,199,130, 29, 43, 87,174, 26,242,198, 27,213,105,137,137,220,148,248,120,166,208, 96,184,215,156,114, - 22, 23, 23, 39, 94,186,116, 25,187,119,254, 0,189, 94, 11,113,241, 83,157, 86, 86, 46,131, 5,145,245, 23, 78,163,209, 40, 27, - 61,122, 52, 11, 0,111,194,132, 9,108,137, 68,130,182,109,219, 2, 0,228,114, 57, 78,158, 60,137,144,144, 16, 0,192,131, 7, - 15,106,183, 45,149, 83, 32, 16,188,209,163, 71, 15, 20, 20, 20, 32, 45, 45,237,130, 88, 44, 46, 7,112,161,168,168,104, 88,231, -206,157,113,244,232,209,225, 77, 8,173,102,181,145,149, 66,235, 47,156, 60, 30,111,209,145, 35, 71, 62,184,118,237,218,184, 5, - 11, 22, 48,251,247,239, 15, 0, 80, 40, 20, 42, 0,166,230,112,170,213,234,237, 0,106, 87,206,230,231,231,239,155, 63,127,126, -210,220,185,115,133,230,242, 73,211, 79, 92,151, 2,215,195,251,124,240, 69,247,206,225,193,223,108,140, 61, 91, 88, 84, 26, 43, -203, 56, 46,179,166,238, 20, 69,193, 96, 48,128, 36, 73,184,184,184, 40,203,203,203, 33,145, 72,242, 36, 18,201,204, 71,143, 30, - 53,171,238, 47,179,207,219, 56,109,156, 54, 78, 27,231,255, 40,172,143, 12, 79, 81,148,145, 36, 73, 92,186,116, 9, 71,142, 28, - 49,233,245,250, 15,197, 98,113,221,104,213,155,146,147,147,227, 71,143, 30,189, 39, 43, 43,139,158,158,158, 14,138,162, 76,205, - 41,141, 70,163, 49, 16,196, 95,247,189,104, 45,119,239,222,141,146,146, 18,125, 81, 81,209,121,163,209,120,244, 5, 87, 47,190, -240,170,195,221,128,246, 29,157,238,252,242,158, 61, 7, 46,139,143,231, 76,249,252,115,237,164,247,223,255,212,164,211, 25,232, - 44, 22,201, 22, 8,104, 38, 14,135,153,150,152,200,221, 56, 99,134,139, 90,171, 61, 19,219, 12, 7,115,179, 69,171, 79,159, 94, -152, 52,101, 46,212,117, 44, 90,215,111,103, 67,171, 71,179, 44, 90, 90,173, 54, 92, 44, 22,131,203,229, 22, 2,240,124,239,189, -247, 64,146, 36,212,106, 53, 20, 10, 5, 68, 34,145,236,253,247,223, 55,213,136, 39,198,168, 81,163, 28,172,225,245,247,247,247, -102, 50,153, 56,115,230, 12,152, 76,230, 73, 0, 96, 50,153, 39,227,227,227,135,189,253,246,219,240,241,241,241,207,205,205, 37, - 96,193, 63,205, 61,124,196, 31, 20, 16, 8, 2, 1, 79, 77,112, 8, 16,134,143,184, 79, 0, 57, 53, 81,227, 51, 58,118,236, 8, - 88,233,151, 85, 23, 53,139, 59, 54, 24, 12,134,131, 11, 23, 46,156,217,181,107,215, 65,203,151, 47, 39, 80, 19,170,225, 5,145, - 93, 92, 92,252,250,226,197,139,207, 82, 20,245,140,232,151,148, 85, 92,236, 22, 51,139,170,170,146,165, 72, 51, 78, 60,104,150, -197,212,104,124,161,112, 22, 54,216, 96,131, 13, 54,188, 52,171,214, 95,208,168,208, 34, 8, 98, 71,239,222,189, 63, 4, 64, 39, - 8, 98,155, 72, 36,250,203,224, 47, 22,139,179,189,189,189,191,111,221,186,245, 52, 0, 20, 65, 16, 59,154, 89,168, 82,138,194, -119, 52, 26,177,240,169,184,123,174, 0,149,230,180, 36, 11, 1, 16, 52, 26,125,207,221,187,119, 63, 47, 44, 44,148, 90,105,129, -104, 18, 47, 99,213, 33, 0,252, 6,228,189, 85, 80,112,118,126, 68,196,128, 33, 51,102,160,221,144, 33, 14,222, 45, 91,154,212, -122, 61,249,224,202, 21,226,218,161, 67,172,148,248,120,166, 90,171, 61,115, 20, 40,108,110, 57,139,139,139, 19, 47, 38, 36,158, - 27, 51,106,216, 32,255,214,222, 79, 69, 67,158, 8,101, 21,178,115,205, 17, 89,245, 68,239,136, 45, 91,182,156, 96,177, 88,140, -186,169,108,244,122,125,133, 86,171, 13, 7,128,202,202, 74,239, 29, 59,118,252, 78,163,209, 10, 44,241,165,167,167, 31, 95,182, -108,217,168,252,252,252,115, 69, 69, 69,249, 0, 80, 88, 88,152,111, 48, 24,246,136,197,226, 81, 5, 5, 5,135, 97,197, 34, 0, - 10, 8, 76,187,114, 48, 18, 0,194,123,142, 69,218,149,131, 92, 0,145,225, 61,199, 2, 0,158, 55,151, 97, 93,212,132, 65, 88, -122,253,250,245,253,131, 6, 13,154,138, 23,136,233, 85, 95,108,233,245,250,150,245,119,154, 45, 91,205, 33,210,233,116, 6,181, - 90,109, 52,153, 76, 12,189, 94, 79,233,116, 58,131,109,156,179,193, 6, 27,254,173,160, 40,170, 51, 0,161,121,216,172,121, 23, -214,219,214,161, 38, 93,160,121,168,172,249, 44, 37, 8,226,118, 29,142,218,253, 86,156, 11, 0,101, 0,238, 19, 4,209,152, 17, -100, 71, 99,159, 27, 21, 90, 34,145,232, 48,172, 72, 26,109,237,113, 77, 96,113, 77,158, 56,224,249,243,176,213,114,152, 76,166, -210,194,194,194, 23,110, 80, 26,141,150, 55,124,248,240,102, 29,111,233,152, 3, 64,193,199, 90,237,222,184,205,155, 59,156,217, -182,205,199,100, 52,186, 18, 0, 69,103,179,203,117, 58, 93,190,208, 96,184,215, 92, 75,214, 51,214,152,199,197,131,115, 31, 23, - 35, 32, 32,128,122,248,240,225, 83, 91,207,139,225,158, 82,169,244,181,212, 5, 84, 42, 85, 47, 43,197,224,111,197,197,197,191, - 53, 32,216,127, 23,139,197,191, 91, 91,168,218,164,210, 0,141, 36,200, 49,225, 61,199, 30, 2, 64,154,147, 74,191, 76,148,148, -148,100,161, 38,206,219,223, 13, 5, 5, 5, 90,130, 32,246,125,247,221,119, 19, 82, 82, 82, 14,136, 68, 34,173,109, 40,182,193, - 6, 27,254,205, 34,139, 32,136,184,154,207, 49, 53, 70,161,184,250,219,230, 99,204,199,213, 61,198,204, 81,127,127, 83,231, 2, -192,162, 69,139, 62, 95,181,106, 21, 31,128,181,201,152,159, 59,169,244,171, 66,233,223,132,163,174, 40,216,249, 42, 42,186, 25, -208,193,104,188, 1, 99, 29,159,124,195,203, 53, 68, 60,124,248,144,248, 55,255,225,204, 73,165,235, 32,226,127,117,240,201,207, -207,223,226,231,231,183, 93, 36, 18, 25, 97,131, 13, 54,216,240,239,133,176, 33, 97,212,136, 40,139,105,234,251,103, 30,220, 27, - 56,174,161,207, 4, 65,196,173, 90,181, 42,166, 25,229,173,181,104,209,108,109,103,131, 13,255,108,252,127,172,164,181,193, 6, - 27,108,248, 55,160,190, 21,203, 44,190,234,127, 94,180,104,209,231,104,122,198,201, 11, 79,173, 88, 94, 53,159,107,253,181, 8, - 60, 93, 57,208, 16,154,179,154, 96,192,115,212,239,188,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 57, 78, 75,220, -231, 27, 16, 68,209,141, 77,245, 53, 53,141, 88,127,219,210,185,150,142, 37, 8,162,177, 48, 63,230,169,194,250,239,175, 28, 3, -108,156, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56, 95, 4, 20, 69,117,166, 40, 42, 26, 79, 23, 76, 81, 20, 69, 69, 83, - 20, 53,100,209,162, 69,139,205,251, 22, 45, 90,180,152,162,168,254,230,227,106,142,169, 61,199,188,175,254,123,253,125, 77, 29, -219, 68, 17, 63,172,183, 93,251,249,239,226,163,101,131, 13, 54,216, 96,131, 13, 54,216,208, 32,204, 43, 6,235, 88,155,164, 0, - 30,172, 90,181,170,178,142,239,148, 20,192, 61, 0,237,107,142,147,214,136,180,186,190, 85,186,154,207,186, 6,142,209, 89,115, -108, 35,216,209,200,182, 77,104, 53,134,246,158,180,175,252, 90,184, 71,213, 52, 0,168,154, 36,192,100, 77,188, 34,202, 28,184, -136, 36, 81, 60,222,237, 0, 0, 32, 0, 73, 68, 65, 84, 65, 81, 20, 68,146,170,228, 7, 18,124,241,188,191, 23,228, 13, 23,119, - 46,119, 3, 73, 81, 61,107,118, 37,202,202,181,115,211,228,168,178,150, 35,196, 3,161, 92, 26, 62, 37, 41,180, 3, 0, 26,129, -251, 26, 18,223,103,150, 54, 63,158, 84, 67,253, 60, 92,136, 15,217, 60,254, 91,142, 78,206, 1,149,149,101, 57,122,141,246, 96, -186, 20,219,209,252,188,140,240,119,198,107, 36,133,207, 1,208,152, 52,172,203,169,176,122, 37,135, 13, 54,216, 96,195,139, 90, - 71, 94, 40, 46, 30, 65, 16,166, 6, 56,137, 23,228,180, 5,195,179, 66,108, 53,176,251, 86, 3,251,110,255,157,202,221, 44,161, - 21, 38,196, 12, 16, 88, 1,128, 2,133, 47,211,165,248,169, 89,231,123, 97, 0,151, 78,223, 5,128,174,209,155,230, 83, 36,146, - 26,188,152, 52,188,206,101,209,215, 1, 32, 53, 38,211,228,116,177,245,254, 98,225, 62, 24,194, 32,105,251, 72,138, 98,154, 72, -106, 15, 40,196,217,177,112,245, 70, 49, 52,205, 41,171, 95, 11,247,168, 99,183,196,131, 18,126,154,141,174,237,218,130, 50, 25, - 1,210, 0,126,175, 79,113, 97,253,123,232, 26,234, 7,138, 52, 0,164, 17,118, 67,215, 98,104,132, 35,245, 64,242,124,121,176, -131,188,225,210,210,205, 61,117,231,206, 93,158,222,254, 97, 4,105,212, 35,235,214,185,241,115, 22, 46,235, 23, 14, 89,132, 53, - 98,171,157, 23,166,248,181, 10,254,116,238,138, 31,232, 94,222,190, 2,210,160, 53,150,228,101,116,220,180,102,217, 97, 22,173, - 96,221,125, 49,118, 89,219,151,195,132,152,198,224,176,199,242,184,130, 0,149, 74,241,208,164, 55, 28,164, 49, 25, 67,190, 95, -187,161, 67,159,129,195,236, 76,138, 18,154,129, 68,216, 31, 7,126,111,185,121,203,214, 97,169, 98,211, 27, 0,200,230,212,153, -164,176, 48,123,239,135,195,152, 12, 58, 17,250,193, 78, 58, 96,124, 46,161, 21,234,142,119, 8, 10, 22,195, 75, 80, 4, 46,103, - 72,240,219,243,252, 70,136, 59,126, 38, 40, 4,129,192, 33,130,194,239,233, 82, 72,108, 67,158, 13, 54,252,187, 64,163,209, 18, - 72,146,236,251,146,133,193,107, 20, 69,221,176, 93,221,255,109, 52,207,162, 69,224,235,180, 71, 69,206, 48,233, 17, 30,228,255, - 21,208, 60,161,197,165,211,247,220,206, 41,245,132, 81,143,157,223,204, 60,160, 51, 0, 70,131, 30, 38,163, 1, 38,163, 1, 70, -163, 30, 38,131, 1,148, 65,139,101,191, 36, 0, 58, 5,162, 34, 2,247, 0, 38, 47,107,127,131, 73,209,246, 37, 95, 57,231, 66, -232,100,248,237,167, 85, 31, 23, 73,171, 63, 62,127, 95, 84, 22,230,174, 94,156, 46,193,175,205, 17, 4, 9,219,102, 35,246,232, -201, 39, 27,127, 86,102,146, 20, 5, 23, 7, 94,240,248,152, 52,223,189,199, 19,138, 54,236,209,100, 2,128,163,128, 29, 60,241, -126,142,223,139, 52,130, 59,151,187, 97,251,214,205,158, 94,174, 60,194,120,109, 53,140, 38, 19,124, 91, 70,211, 23,207, 26,239, -245,245,250, 93,235, 33,215, 78,106,234,252, 96,119,132,181,106, 29, 58,127,207,201,107,126, 74,185, 68,119,110,255,231,143,160, -133,193,211, 39,148,249,213,170, 31,232, 75, 62,155, 61, 79,103,122,114, 51, 75,130,116, 75, 99, 77,168, 59,142,175, 90,189,182, - 93,191,161, 49,118,100,181,148,174, 81, 86, 7,237,252,101,215,138,144,118, 93,248,189, 34, 90,176, 36, 7,167, 19,106, 69, 5, -244, 52, 46,167, 95,248, 0, 7,245,132,183, 13, 59,119,199,206, 74,151, 96, 83,115,234,108,162,254,211,247, 72,242,249,163,174, - 19, 20,122,165,220, 72,152,102, 18,221, 6,101, 50, 0, 38,125,237, 59, 76, 6, 80,228,211,247,174,211,127, 1,240,124, 66,139, - 70, 97,208,249, 43,183,189, 74, 75,196,157,215,175,253,118, 49,117,251,246,105,152,176, 47,163, 2,137,205, 21,152, 0,130,218, -184,210,207, 26, 76,208, 22, 85,153,130,204, 59,251, 5,113,186,123,217, 17,253, 11,101, 68,210,229, 71,234, 68,219,208,100,131, - 13,255, 47, 22, 19, 35, 69, 81,140,151,204, 57,140,162,168, 83, 47, 72,243, 41,128, 41, 53,219,187, 0,124,255, 18,138,214, 2, -128,103,205,118, 9,128, 39,182, 30,240, 66,168,239,252,254,220,113,180,184,160, 72,224,208, 72, 0,224, 53,183, 20, 20,192, 5, - 65, 7, 12, 74,140, 24, 58, 16,110,238,158,128, 65, 5,232, 85,248, 63,246,206, 59, 60,138,170,109,227,247,204,108, 75, 54,189, -108,122, 33,180,132, 64, 32, 32, 16, 58, 65, 65, 4,194, 71, 17,164, 9, 8, 47, 69, 68, 17, 65, 84, 80, 64, 68,138,138,128,210, - 65,165, 73, 71, 74, 64, 74,148, 94,162,212,132, 36, 4,146,144,222,123,178,217, 54,229,124,127,164,152, 64,202,110, 64,125,225, -157,223,117,205, 53, 91,239,157,153, 51, 59,115,207,115,158,231, 12, 88, 13,192,170, 1, 86,131,220,140, 36,192,160, 6,226,127, - 5, 71,136,194,228,213,213, 21, 1,177, 7,240, 74, 7, 47,168,108,204, 48,107, 72,107,199, 45,167, 98,183,109, 59,115,191,111, - 84, 54, 70, 25,181,172,132, 32,168,109, 11,172,221,166,142, 57,126, 43,167, 63, 0, 12, 12,116, 56, 21,212,218,219,115,205, 14, -109,204,201,136,130,215, 0,224,181, 54,214,191,118,246,115,245, 18,208,248,168,175, 64, 72, 79,183, 38, 45, 40,254,246,102, 8, -197,169, 40, 46,214, 32,245,209, 78,216,185,191, 68,243, 2,122, 55,244,125,115, 6, 31,191,183, 96,165,180,172, 56, 75, 47, 24, -114,120, 21, 83,192, 72,228, 2,133,180, 11,186, 82,161,144,159, 61,117, 60, 55,231,179, 47, 63, 6, 48,174, 62,157,214, 78,152, -185,106,213,154,182,221, 59,182,114,202, 60, 52,139, 42, 45,200, 2,199, 40, 21, 67,186,118,135,109,203,214, 66,214,249, 85,148, -188, 89, 95,216, 58, 52, 67,218,213,159,145,120,253, 48,213,163,195,112,197, 79,123,100,111, 2,134, 90,141, 86, 11, 71,244,232, -223,171,243,190,102, 94,110,174,132, 8, 16, 4, 2, 34,240, 40,213,178,248,100,127, 60,120,158,199,235,253,123,188, 98, 33,167, -136, 32, 8, 32, 68, 64, 74,102, 94,217,239,225, 49,175,196, 23, 32,220,152, 72, 85, 96,151, 62, 61,238,222,188,222,138,141, 61, -142,142,227,150,199, 80,192,229,106,251, 92,143, 91,167,127,106, 5,252,216,120, 47, 71,129, 79, 60,181, 2, 94,189,166, 50,155, -247,156, 82, 21,229,164, 77, 56,180,115,195,136,141,155, 55,239,142,201,198,116, 83, 76,214,251,189,228,151, 87,255, 94,236,208, -181,153, 69, 78, 74,181, 56,101, 83, 59,186,255,166,147, 81,239, 93, 91, 18,212,106,193, 9, 82,120, 49, 78, 27, 33, 30,183, 68, - 68,254, 89, 8, 33,207,220,108, 37, 37, 37,165, 63,141,217,114,119,119,239,149,150,150,246, 85,101,182, 10, 69, 81, 95, 53,105, -210,100,225, 95, 23,170, 53,174,245,138,120,158, 31,151,150,150,118,177, 62,205, 65,131, 6,185,157, 56,113,194,167,154,166, 15, - 0,159,218, 62,107,107,107,203,119,235,214, 45,241,196,137, 19,233,226, 30,210, 40,195,101,178,209,138, 73, 62, 48,171,131, 46, -163, 20, 0, 98,140,248,124,141, 46, 63, 45,203,175,216,190,120,252,138, 54, 77,236, 81,162,214,227,204,141, 68,240, 60, 11,158, -227, 42, 34, 91, 28,120,142, 69,255, 64, 71,116,211, 78,199,119,161,247,193,241,194,242,250, 52, 31,199, 64,132, 49,237,251,190, -177, 95, 16,136, 92, 33,165,139,124, 61, 29,156,230,188, 30, 72,207, 26,210, 6, 26, 3,247,198,207,231,227,126,143,206,198, 86, -163, 52,133, 39,135, 39, 34,181,189,198,115, 13,174,123, 61,209,168,160,190,193, 61,173,137,174, 8,108,110, 60, 74,202, 88,196, -231,177,200,212, 22, 66, 65,101, 24,165, 41, 16,180,243,112,119, 85, 94,217,247,209, 35, 7,166, 88,226,196,112, 50, 57,205,129, - 23, 8, 67, 10,163,116,246,173,250, 73, 43,243,182,234, 91, 78,115,165,213,248, 94,175, 14,178, 73,254,121, 42,101,238,219, 31, - 78, 29, 60,241,232,226,118,100,223, 8, 69, 94,122, 34,101,173, 45,132,179, 67,115, 12, 24, 55, 10, 95,143,234,132,146,226, 18, - 48, 25,113, 54,114,169,194, 22, 48,212,170, 73,120,140, 91,181,242, 75, 87, 9, 67,151,111,207,202,137,103,161,209,233, 0,158, -131,153, 68, 0, 69, 42,223, 99,193,179, 6,101,187,225, 31,205, 0,248,240,134,214, 61, 58, 27,123, 90,171,208, 19, 2,219,138, -176, 26, 80,192,229,168,156,191,204,143,191, 19,198,188,212,255,173,158,132,194,165,198,180, 81,128, 3, 66, 58,250, 88, 90, 88, - 20,199, 32,245,224,187,136,131, 25,113,238,254, 31,140,153, 52, 83,185,101,203,150,193, 0,121, 27, 53,115,212,170, 52, 91, 57, - 51,211, 88, 30, 11, 1, 64,195,146,237, 86,114,106,210,170,189,215, 28,192,252,117,135,135,202, 72, 86, 92,158, 80, 96, 56,247, -233,253, 46,115, 66,131,219,222, 14, 78,161, 40, 69,242,133,135,186, 34, 83,246, 37, 19, 17, 53, 69,205,191, 93,211,218,218,186, -105,147, 38, 77, 22,178, 44,219, 75, 38,147, 57, 27, 12, 6, 8,130,144, 41,151,203, 47, 37, 38, 38, 46, 41, 46, 46, 78,248,111, - 91,247,187,119,239,154, 98,182, 26,212,148, 74,165,184,127,255,254, 67, 19,204, 86,216, 99,223,223,117,249,242,101,236,223,191, - 31, 0, 16, 27, 27,139,150, 45, 91, 90,212,246,197, 71,143, 30, 89, 4, 7, 7,239, 2,224, 89,159,102, 68, 68, 68,211,227,199, -143,227,224,193,131, 0,128,251,247,239,195,215,215,183,214,133,185,124,249, 50, 51,118,236,216,166, 0,210,255,129, 54,122, 17, - 76, 86,245,249, 95, 70, 43, 52, 52,148,132,132,132, 80,143, 63,174,133,120, 47, 59,121, 7,104,121, 0,136, 55,117, 9,162,179, -176,114,237,206,211,175,253,118,112,125, 47, 51, 25,141, 69, 91,231,164,228,228,151,116,145, 80,229,221, 47, 28, 1,109,103, 41, -191,182,124, 66,160, 87, 65,169, 22,199,254, 72,187, 24,149,109, 90,136, 52, 42, 3,103, 1,193,182,252, 25, 15,173, 38,219,119, -194,215,103,247,238,253,248,181,118,179,135,180,195,209,171,137,179, 1,174,193, 81,223,137, 32,128, 8, 92, 85,242,123,197,165, - 3, 32,212,188,129,175, 0, 82,254,154, 96, 90, 68,171, 55, 32, 41,112,194, 0, 43,165,124,221,180,105, 83,172,217,156, 7,200, -215,203,144, 82,160, 69,166, 70,138, 82,137, 19,210, 98, 34,120,154,194,217, 6, 67, 46, 20,138, 9,167,181,181,147, 91,210, 1, -253,102,184, 23,159,154, 95, 32,167, 56,198,122,216, 82,219,220,223,190, 77,228,212, 57,106,138, 66,131,195,207,219,216,216,182, -212,230, 37, 50, 69, 5,185,176,117,105,131,215,222, 8,193,231,131, 90,163,164, 88,141,156,252,107,164,133,171, 53,149,116,105, - 55, 22, 12,240, 71, 94, 86, 6,116, 44, 64,169,117,249, 90,189,182,180,206,237, 72, 99,243,251,115,231,141,241,118, 85, 89, 84, - 22, 21, 16,129, 71,160,127, 51,244,235, 21,132,179,151,175,224,207,136, 88, 8, 21, 69, 5, 68, 16,144,154, 93,144,165, 53,240, -219, 77,218,160, 60, 7,194,106,107, 53, 98,104, 68,151, 97,128, 19,148, 60,240, 89,167,166, 86,147, 63, 14,241,182,178, 80, 80, -208,178, 60,180,122, 22, 37, 87,214,193,161, 73, 91, 40,205,204,168, 14,208, 72,110,161,246,109,171,101,177, 48, 33,163,208, 21, -165,153, 24,219,175,205,123, 59,150,191, 99, 65,153,149,239,154, 44, 95, 51,146,117,101,113,167,211, 99,191, 56,114,110,255,129, -209,110, 95,127, 56, 62,184,255, 7,219,207, 1, 56, 37, 30,183, 68,158, 71, 70,140, 24, 97,150,149,149,117,222,211,211,179,117, -191,126,253,148, 61,123,246,132, 90,173,198,153, 51,103,160, 86,171,189, 61, 61, 61,189,207,156, 57, 51, 60, 57, 57, 57,202,195, -195, 35,248,224,193,131, 70,231,208, 86, 24, 32,166,234, 16, 12,112, 20, 69,161,226, 53,170,226,181, 70,223,231, 86, 46,151, 35, - 41, 41,233,153, 71,182,210,210,210, 30, 54, 38,178, 85, 90, 90, 42,115,119,119,135, 74,165, 2,207,243, 80,171,213, 56,114,228, - 8,138,138,138, 32, 8, 2,204,205,205,177,116,213, 86,196,220, 58,143,240,240,112, 20, 21, 21,201, 26,210, 76, 77, 77,165, 2, - 3, 3,161,211,233,192,113, 28,180, 90, 45,194,194,194,170,158, 75, 36, 18,204,251, 98, 53, 98,111,156,199,237,219,183,145,154, -154,250,143,220,109,196, 4, 47,242,223, 72,157, 99,102,253,227, 85,135, 60,207,125,178,101,199,222,107,159, 76, 31,133,153,163, -251,122, 46, 89,127,184,111,116, 46,118, 0,128,191, 35, 38,188,217,167,133,151,173, 82,138,207,127,190, 1, 16,242,201,211,254, -222,189,124,196,182,118, 22,102,255, 18,158,116,126,254,168, 14,104,230,106,221,178, 64,158, 47,143,143, 55,226,158,130, 2, 7, - 59, 75,133,223,192, 64,135, 83, 16, 4,216, 90, 41, 90,129,231, 96,107,169,240,123,173,141,245,175, 0, 96,173,148,182,170, 45, -242, 85, 23, 29, 61,165, 83,149, 10,201, 84, 11, 43, 91,175,137,131,251,153, 15, 28, 60,220,220, 82,202, 33, 47,252, 12,138,165, - 30, 96,237,189,161, 99,243,145,154, 16,199,255,118, 61, 58, 45,183, 68, 55,167,193,197, 36,184,152,150,112, 95,213,180, 93, 63, -187,220,208, 5,217, 77,223,250,217,135,134, 64,151,236, 30,150,101,225,212,217,252,143,248,132, 82,129,212, 26,209,169, 65,113, - 81, 81, 34,203,195, 85,195, 75,172,226,206,253,132,143, 7,180, 69, 65,126, 54,180, 6, 14, 69, 26,206,224, 98,107,166,208, 37, - 68, 66,103,224,160,103, 5, 72,109,221,113,230, 90, 68,174,192,178,191,214,165, 25,159,135,219,241, 71,110, 91, 86,127,173,153, - 35, 2, 63,178, 54,191, 13, 86,131,164,212,116,236, 56,113,173, 67,124, 30,110, 63, 77, 59, 19,129, 43,239,126,174, 22,201,162, - 8,122, 54, 38, 9,190,149, 19, 58,203,204,100,223,127, 53,123,108,235,174,190,246, 10, 33,245, 26, 40,193, 0, 11, 94, 2,141, -156,135,141,103, 51, 8,250, 18, 82,166,213, 22,222, 3,234,107,124, 6, 0,136, 65,141,175,199,183,177,160,236,154,129,143, 63, - 5, 73,251,169, 96, 43,162,253,113,121, 66,132,225,220,167, 49,221,230, 30,239,253,197,217, 62,209,233, 39, 22, 69,187,143, 88, - 23, 8,108,111, 34,158,174, 69,158, 71,252,252,252, 92,210,210,210,238,205,157, 59,215,126,216,176, 97,248,229,151, 95, 80, 92, - 92,140,237,219,183, 99,205,154, 53, 88,188,120, 49, 88,150,197,150, 45, 91,148,135, 14, 29,234,188, 97,195,134, 84, 47, 47,175, - 54,201,201,201,153, 13, 24, 44, 10,128, 2,128,180,226,220, 69, 1, 16, 78,158, 60,137,129, 3, 7,226,228,201,147, 66,197,107, - 60,202, 47,126, 26,117,239, 79,185, 92, 14,185, 92,142,162,162,162,103, 98,182,164, 82, 41, 44, 45, 45, 33,151,203, 81, 82, 82, - 98,178,217,226, 56,142, 73, 77, 77, 69, 81, 81, 17,250, 13, 30,140,213,203,151,163, 79,159, 62,232,215,175, 31, 8, 33, 8, 11, - 11, 67,223,238, 1, 24,245,127,193,136,142,142, 6,199,113, 70, 45,111,102,102, 38,178,178,178,240,218,224,193,216,186, 97, 3, -130,130,130,224,231,231, 7,142,227,112,254,252,121,140,232,223, 29,102, 67,251, 34, 54, 54, 86,220,169,141,143,102, 61,147, 28, -173,167,230, 94, 14,174, 11, 71, 47,132,142,238,223, 57,100,112,143,214,216,186,239,183, 47,161, 42,222, 11, 0, 14, 58,197,210, -241,125,154, 33, 42,185, 0,191,221, 78, 15,141,206,197, 51,169,214, 16,120, 56, 58, 88, 43, 1, 70, 14,141, 65,224,172,227, 27, - 78, 96, 22, 8,129,178,215, 71,120,115,112,148,103, 80,107, 79,207,202,170, 67,203,129,223, 98, 66,196, 67,175, 78,126, 46, 94, -224, 89,128,103, 97, 61,234,103,224, 11,139, 6,151,163,187,143,252,236,251,179,102,117, 27, 48,244, 13,115,185,210, 6,124,113, - 10,216,204, 8,228, 61,184, 8,181,178, 37, 50,147,226,177,255,116,120,209,131,212,188, 98,154,198,153,172, 34,221,135,241, 5, - 40,109, 72, 87,203, 98,249,194, 5,115, 6,237,223,187,207, 74,209,172, 7, 21,183,110, 96,145, 92,194, 41, 84, 62, 47,209,101, -102,142,100,217,246,125,214,106, 61, 86, 52,164, 83,166, 46, 62, 28,118,230,212,168, 22, 77,123, 88, 61,250,243, 4, 52, 90, 29, -116, 44,208,166,115, 48,120,158,200, 41,154, 18,172, 25,134,202,206, 43, 0,197,242, 89,151,238, 60,202,184,124, 39,158,209, 89, - 97, 69,189,163,139, 60,238,238, 41,230,189,193,193,237, 1, 86,131,255,235,213, 22,171,119,255,246, 46,192,191,245,116,141, 92, - 30,209, 34, 64,143,214, 42,108, 34, 4, 61,110, 28, 89,211,170,227,208,247, 97, 74, 68,171,141, 35, 6,248, 55,117,251,105,245, -210,143,236, 29, 60, 90, 50,148,192,130,184,180, 3,138, 83, 9,149,122, 13, 54,238, 65,224,221,186, 99,203,119,223,148, 10, 2, -217,139,122,134,182,224, 5, 64, 72,190, 0, 62,230, 23,196,199,199,195,209,251, 6, 64,209, 32, 77, 30,193,192,149,127, 77,103, - 32, 39,214,110, 63,222,231,195,151,151,183, 25,220, 74,226,117,237, 78, 92,246, 27,147,220,148, 93,188, 24,223,168, 12, 11, 58, - 87,173, 22,196,227,151,200,243,132, 86,171, 61,188,114,229, 74,251,144,144,144,202,136, 12,174, 93,187,134,109,219,182,193,194, -162,230,113,114,224,192,129, 32,132,216, 47, 90,180,232, 48,128,174,117,105,118,235,214,109,240,237,219,183,211,219,183,111, 31, - 95, 97,182,100, 0,232,200,200, 72, 58, 37, 37,133,178,179,179, 35,110,110,110,108,122,122,186, 0,128,159, 52,105, 18,115,224, -192,129, 22,106,181,250, 66, 99,141,150, 92, 46,127, 38, 57, 91, 82,169, 20, 20, 69, 65, 46,151, 67, 38,147,129, 16, 98,146,217, -226,121, 94,114,242,228, 73,220,184,113, 3,139,219,183,199,108,119,119,216,219,219,227,252,249,243, 32,132,192,194,194, 2,249, -249,249,216,187,119, 47, 94,126,249,101,112, 28, 39, 51, 70,247,224,193,131,184,121,243, 38,190,232,216, 17,179,109,108, 96,105, -105,137,176,176,242,222, 64,133, 66,129,164,164, 36,132,133,133, 33, 56, 56, 88,220,169,159, 18,163,119,158,222,128, 36,159,130, -139, 65,175, 1,225, 8, 64,193,205,223, 31,178,232,232,154,201, 57,198, 64,211, 88,240,221,142,208, 65,223,190, 63,152,154, 58, -164,131,219,146,159,206,189, 13, 0,147, 95,247,117, 87, 42, 36, 88,123, 52,138,208, 52, 22, 60,139, 21,244,247,135,140,202,195, -219,253,130,252,144, 94,168, 71, 92,122,225,239,209,128, 81,119,113,254,237,219, 55,177,243,216,249,148, 53, 59,181, 49,132, 16, -216, 90, 42,252, 38,220,141,243,250,233,228,205,228, 85,251,181, 49, 68, 32,176, 85, 74, 91,189, 21,221,189,193,170,195,142,158, -210,169, 31,204,153,211,125,200, 91,115,205,184,152, 3,208,199,157,134, 96,208,160,216, 32, 67, 33,227,130,212,228,100, 44,219, - 18,154, 82,172,214,143,186,151, 99,154,193,124,144,135, 82, 9, 85, 60,108,217,231,243,207, 46, 95,186,200, 82, 19,127,190,148, -161, 56, 13,211,164,183,100,233,226,111,169, 18,157,254,141,248, 2,148, 52,164,163,179,194,138,149,171,190, 27, 52,101,220,240, - 24,223,150,189, 29,248,244, 4, 7,109,113,113,246,207,167,110,186, 84, 92, 41, 82, 0, 16,151,154,135,156, 34, 53,199,115,236, - 5, 43, 41,150, 68, 25, 19, 29,172,160,169, 19, 84, 33, 61,218,140, 85, 89,201,160, 41, 45,132,147,149, 20,253,131,154,143,101, -255,136,253, 40, 33,219, 20,187,246,184,209, 98, 65, 88, 13,174,175,120,185, 21,225,217, 86,224, 89, 24,238,238, 50, 61, 50, 70, - 97,246,204, 94,150,214,118,250, 71, 52,212, 22,128,185, 35, 40,107,111,192,198,135,146,250,191,129,244,248,123,220,187, 99,199, -229, 37, 36,166,254,224,104, 94,127,183, 54, 43, 16, 8,137,231, 81,154, 21,135,200,116, 3,218,100,151,247,182, 91,103,221, 2, - 47,142,152, 35,242,130,146,148,148, 52,254,147, 79, 62,185, 28, 20, 20,228,236,232,232,136,182,109,219,226,216,177, 99,152, 59, -119,110,213,103,218,183,111, 15, 66, 8,242,243,243,177,114,229,202,204,244,244,244,241,245, 94,160,223,187, 23,179,115,231,206, - 94,173, 91,183, 54,200,100,178, 66, 0,138,194,194, 66,179,252,252,124, 74,171,213, 66, 16, 4,193,198,198,134, 79, 79, 79,103, - 71,141, 26,165,187,122,245,106,115,181, 90,157,244, 52, 17, 45, 79, 79,207,200,188,188,188, 34,138,162,158,122,232,135, 74,147, -229,232,232,168, 42, 45, 45, 21, 0, 20, 52,102,232, 7,142,227,208,177, 99, 71,156,190,120, 11, 39,127,187,138,226,244,251,120, -123,202,120,180,109,219, 22,167, 79,159,110,116,155, 5, 6, 6,226, 84,216,101, 92,190,113, 7, 73,177,119,241,238,219, 83,208, -166, 77, 27,156, 58, 37,102, 47,152,192, 9,212,204,205, 58,241,184,209, 10, 14, 13, 13,173, 60,244, 63, 97, 95, 91, 57, 34, 80, -106, 43,223,181,104, 64,115,127,105,191, 69,160,164,230, 56,208,242, 84,247, 5,203,214,197, 48, 78, 73,227, 34,179, 27,174, 14, -171,241,167,201,198, 61, 18, 30,179,231, 78,116,171,177,255, 23,228,137,173,199,148,159, 1,192, 27, 61,155,226,143, 7, 57, 8, -143,205,222, 19,149,131,123, 79,187,214, 1, 78, 80,242,185,216,179,242,189, 33,193,222, 30, 46,216,246,203,101, 80, 20, 14, 27, -117,194, 37,132, 4,181,246,198,154,157,143, 87, 24,186,120,173,218,175,141, 57,115,175,100, 0, 0,244,107,165,252,181, 83,115, - 59, 47, 82, 61,113,171, 22,204,229,146,105, 3,134,191,105,198,197, 30, 3, 18,195, 64,113, 58,104, 12, 2, 50,114, 75, 80,102, -227,137,243,215,238,104,138,180,250,247,163,114, 26, 23,197,139,206, 69,188,236,207, 59,201,165,106,141,171, 82,213, 92,203,208, -130, 80,170, 35,248, 35, 42,177, 56, 42, 19,247,141,209,136,143,135,190,139, 59,215,115,211,142,253, 11,165, 50,249, 27, 12, 5, -202,201,214, 66,181,233,219, 47, 96,101,101, 9, 65, 95, 10,168,115, 48,236,157,101, 57,145,233,108, 83, 0,104,233, 0,203,158, - 77,165, 59, 36, 52,149,122, 46,206,240,105, 67,191, 65,177,152, 62,174,127,123,169,160, 87,227,189,149,251,176,249,163, 33,120, -243, 21,127,233,137, 43,177,211, 1, 44,105,108, 91, 19,158, 3, 97, 53,232, 58,255, 98, 12, 5, 92, 38, 64,143, 27,251,151,182, - 2,110, 25,173,209, 1,144,242, 18,202,191,157,151,133, 76, 72,189, 2, 33,245, 10, 97, 60,187,131,242,234, 69, 81, 46, 29,201, -247, 95, 45, 86,111,221,186,237,140, 64,227,115, 35,134,202, 0, 47, 0,185,177,151,161,215,235,193,242,128, 86,171,133, 90,173, -134, 69,220,169,170, 28, 45,153,148,122,109,214,196,193,129,164, 52,189,236,120, 12,151,188,109, 74,171,174,164, 52,189,236,122, - 50, 31,155,171,214,137,209, 44,145,231,145,248,244,244,244,215, 6, 14, 28,248,219,233,211,167,237, 3, 2, 2, 0, 0, 55,110, -220, 40,191,232,236,216, 17,190,190,190,200,202,202,194,232,209,163,115, 51, 50, 50, 94, 67, 3, 57,191, 37, 37, 37, 9, 7, 15, - 30,116, 86,171,213,237, 63,253,244,211,108,111,111,239, 98,173, 86, 75, 21, 22, 22, 10, 28,199,193,206,206, 78,222,190,125,123, -116,235,214,173,244,218,181,107, 77, 82, 82, 82, 74, 0, 36, 54,102,225,135, 12, 25,130,139, 23,203,139,246,158,197,184, 90, 50, -153, 12, 1, 1, 1,238,241,241,241,105, 21,231, 22,147,143,241,213, 79, 47,119,238,220,193,133, 91,169,144,232, 53,144,231,164, -227,250, 47, 7, 49,120,218, 12,112, 92,227,239, 45,127,231,206, 29, 28, 9,187, 14, 11,133, 4,247,239,223,195,193,131, 7,241, -246,219,111, 63,149,102, 35,169,215,139,252,151,147,129, 58,242,180, 36, 0, 16, 18, 18,114,161, 50, 90, 81,157,102,205, 32, 87, -148, 98, 81,191, 14,238,243,222,232,209,156, 97,139,211, 33,240, 2, 24, 41,224,228,104,141, 93,187,246, 52,221,179,111,223,181, - 13,235, 55,124, 39,112,220,130,200,108,148,153,176, 80,139,190,221,119,249,141, 93,115,130, 37,111, 15,104,101, 15, 0, 50, 9, -141,181,199,238,113, 0, 22, 61,205,218,118,113,135, 89, 41,139,169, 78, 14, 54,159,125,242,159, 65,246,193, 29,125,113, 33, 60, - 18,223, 29,188,118, 81,158,141,157, 70,239,220, 2,139,199,253, 83,109, 85,135, 16, 26,206,187,228,121,226, 34,179,176,131, 33, -241, 28, 96,208, 66,171, 51, 32, 37,143, 71, 74,190, 22, 18,165, 12, 55, 98, 83, 53, 14,153, 8,125,138,213,166, 44,148,102,110, - 11,191, 92,229,161,213,148,114,197, 5,185,156, 76,126, 93,170, 52, 87,100,152,146,170,112, 61, 13,218, 94, 62,210,151, 0,129, -145,155,145,178,249, 31, 76,180, 72,139, 58,141, 22,116, 58, 40, 66, 96,238, 63, 8, 86,230,140,172, 71, 19,105, 50, 0, 88, 88, - 40,229, 43, 63,159,107,243,254, 71,159, 55,152, 3,230, 15,200,124,155,185,188, 31,224,109,135,139, 55, 99,112, 49, 34,233,222, -197, 27,247,219,244,105,235, 6, 95, 15,219, 89,242,130,194, 21,209, 48, 61, 66, 90,222, 48, 28,192,106,171,170, 14,253,157, 48, -166,211, 27,159,214, 85,109, 88, 43, 62,128, 16,203, 19, 80, 12, 3, 80,116,121, 5,100,202, 21, 72,108,155,145, 61,251,143,148, -109,219,182,243,139,232, 92,227,139, 51, 88, 30,124,113,113, 49, 44, 44, 44,112, 42,150,211,189,217, 95,166,160,105, 26, 41,177, -183,254, 74,134,183,167, 91,203,250, 44,109,117,101,113,167,211, 86,114, 74,225, 54,232,115,127, 46, 98,103,106, 99, 79, 18, 34, - 34,255, 13, 20, 21, 21,221,141,142,142,238,223,174, 93,187,237,239,189,247,158,213,184,113,227,220,166, 76,153, 66, 3, 64, 86, - 86,150,176,102,205,154,244,239,191,255,190, 40, 55, 55,247, 45,150,101,141, 25,202,132,100,100,100, 92,253,225,135, 31,114, 46, - 93,186,212,166,115,231,206,138,151, 94,122, 73,176,179,179,147, 40, 20, 10, 94,175,215,107, 99, 99, 99,249,248,248,120,215,194, -194,194,135, 0,226,208,136, 59, 86, 84, 68,175,150, 48, 12,179,144, 16, 18,240, 44,114,180,148, 74,165, 27,128,135, 20, 69,181, - 48,181,219,240,137, 19,182, 68,130,130,130, 2,148,101,222,131, 89,234, 3,180,179,160,209,218,206, 18,214,214,214, 79,101,138, -138,138,138, 0,117, 26, 46, 95,190, 3,112, 28,108,108,108, 96, 99, 99,243,143, 27,173,186,188,200,115,194,212, 90, 94,171, 63, - 71,171,181, 10,111,155,235,177,102,218,160,230, 50, 31, 47, 15,232, 82,111,224, 78, 74, 41, 22,116,233, 28,197, 40,172,180,211, -198, 15,233, 56,124, 68, 19, 4,119,235, 68,249,184,218,204, 90,241,237,198,119, 90, 35,119,110, 84, 54,214, 26,179, 68, 81, 57, - 72, 16,144,189,237,220,221,212,233, 30, 74, 13, 4,129,224, 92, 68, 6, 34, 18, 11,182,197,228, 32,193,148,181,107,237,138,190, - 18,208,251, 8, 33,102, 54, 22, 22, 37,173,125, 61, 28,251,118, 13,164, 95,235,221, 17, 50, 6,184,252,199, 29,204,254,246,240, -117, 65, 32,131,110, 25,217,109, 88, 94, 97, 88,211, 64,149, 87, 24,178, 53, 42, 12, 9, 33,164,188,234,176,254,224, 3,195, 80, -153,101, 73,127,186, 72, 29, 90, 66, 19,119, 14,137, 5, 2,146,178, 75, 80, 44,113,129, 46, 45, 13, 32, 66,242,133,250, 19,171, -235,197,209,209,209,169,105,107,223,230,235,118, 28,132,161,172, 8, 9,231,183,163,180, 32, 3, 75, 55, 29,107,238,238,238,208, - 59, 45, 45,237,130, 9, 7, 27,223,223, 66,247, 56,129, 0,140, 84,129, 19, 27,246, 35,215,193, 28,142, 74, 25, 4, 77, 14,166, -189, 63,206,102, 64,191,113, 54, 0,144,116,255, 54,188,149, 26,163,116, 13, 14, 24,254, 70, 31, 63, 91,176, 26,236, 56,117, 91, - 75, 3,175,237, 60,115, 47,174, 79, 43, 91,179, 55,122,120,219, 45, 73, 47,124, 29,121,141, 27, 84,180, 50,162, 85, 21,225,107, - 68,181,225, 65,128,111, 37, 32,110,223,213,108,139, 17,253, 94, 82,202, 36, 20, 69, 74,211, 64,204, 29,177,113,199,129, 82, 57, -107,218,157,216, 5, 96, 73,208,242,132,133,229,251, 9,182, 15, 88,126,227, 63,103, 63,235,162,202,204,204,132,161,162,239, 48, - 33, 95,248,125,124,191,214,124,106,145,160, 63,179, 98,216, 8,202, 92, 37,255,240,235,157,231, 9, 32,142, 38, 45,242, 92,163, -209,104,110,106, 52,154,182, 31,126,248,225,152,249,243,231,247,178,176,176,104, 10, 0,106,181, 58,129,101,217,139, 21,255, 79, - 83,170, 3, 9,128,135,113,113,113, 9,113,113,113,206,187,119,239,182, 5, 96, 86,241,158, 22, 64, 33,128, 44, 60, 69,197, 97, -165,169,162, 40,106,225,179,218, 14,149,166,138,162,168, 22,141,249, 62, 77,211, 60, 69, 81,160, 40, 10, 10,133, 2,151, 46, 93, -194,200, 65,253, 16,125,162, 16, 1,182,150,232,252,214, 52,236, 59,123, 22, 12,195,128,162, 40, 48, 12, 99,210,121, 68, 34,145, -224,242,229,203,120,115,244, 8, 40, 36,128,141,141, 13, 62,252,240, 67, 28, 61,122, 20, 18,137,120,151, 62, 19,216, 82,205,112, - 25, 57,142, 22,133, 37,103,183, 47,147,129,103,113,124,251, 55, 8,141, 44,213,223,207,193, 2,191, 28,172, 57,136, 18, 33,231, -219,157,211,207, 94,142,252,122,210,168, 16,229,203,125,250,225,229,224, 62,146, 54,157,122,127, 6,212, 48, 90,125, 81,207, 88, - 27,188,128, 47,182,156,138,153,182,239,124, 44, 5, 67, 9, 70,189,218,137,240, 2,190,104, 96,101,158,208,180, 49,183,220,119, -249,218, 53, 59, 24, 74,145,120,251,119,179, 38, 77,155, 3,188, 1, 15, 31, 62,192,247, 59,126, 17,206,255,113,127,151,158,195, -123,241, 5, 80, 27,171, 89,126,166,228, 96, 99, 33,247,123,173,141,245,175, 2, 8,108,149,178, 86, 68,224, 97,171,148,182,234, -215, 74,249, 43, 33,132, 88,153, 75, 91, 17,158,109, 80, 83,163,231, 54,239,248,113,219,170,201,147, 39, 91,228,166,102, 34,189, - 56, 18,165,114,119,176, 74, 79,196,221,190,168, 41,211,113,198,156,196,235,220,158,185,185,185,217, 55,195,243,177,111,211,114, -176,122, 29,178, 83,203,189,106,122,110, 49,172, 29,221,175,165,165,165, 25,173,105,224,132,162,225,227,166,202,204,173, 96,254, -230,240, 16,121, 92,158, 14, 29,220,172,202, 15, 26,165, 57,136, 14,187,140,224,138, 28,211,248, 20, 26,222,129,110, 70, 45,167, -149,153,236,189, 1, 47,185, 35, 33, 57, 3,151,238,165,237, 72,200, 71, 58, 31,147,177, 35, 46,189,112,250,144, 46, 94, 88,125, - 52,234, 93,128,221, 99,202,186,251, 59, 97, 12, 33,232, 81,158, 12,175, 1, 1,122,248, 59, 97,140,145,149,134, 79,104, 74,100, - 24,187,234,215,164, 79, 15,252,153, 59,100,222,216,158,214,221,186, 13,148,131,211,163, 68,163, 99,163, 11, 81,108,138,102,177, - 70,216, 12, 96,115,229, 27, 55, 83,133, 93, 61, 23, 93,187,184,103,138,167,170,210,171, 95,140,211, 93, 3,112,109, 82,144,249, -103,178, 62, 75,253,174, 45, 9, 58, 29,145, 33,236,190, 24, 87, 53,134, 86,131,255,163, 70, 34,106,138,154,255,132, 38, 15, 96, - 23,203,178,187, 10, 11, 11,159,165,102, 58,158, 28,215,233,169,214,189,122, 55, 33, 33, 68, 82, 17,205,106, 40, 25,190, 94,205, -234,221,132,132,144,147, 21,209,172,134,162, 90, 53, 52, 5, 65, 72,239,216,177,163,253,224,193,131,193,243, 60, 30, 60,120,128, -164,148, 20,244,157,254, 46,108,109,109,113,241,238, 93,220,191,127, 31, 11, 23, 46, 4,203,178, 56,114,228, 72,106, 67,154, 18, -137,196,208,188,121,115,217,208,161, 67,193,113, 28,226,227,227,145,150,150,134,217,179,103,195,198,198, 6, 55,111,222,172,210, -204,205,205,133, 68, 34, 49,212, 18,221,250, 59,246,165,231,157, 39, 76, 86,253, 70, 11,224,193,179, 40, 58,187, 8,107, 47,193, - 96, 96,209, 42, 42, 7,143,162,254,138, 72,109,100,194,239, 30,191, 27, 25,147,112,243,202,203,114,100, 71,192,212, 43,137, 7, -121,200,176, 50, 43, 41,129,161,196, 26,241,191,226, 81, 86, 73,233,131, 60,100,152,124,197, 32,240, 20, 12,101, 64,198, 13, 92, -189,120, 1,231,175,223,193,159, 17, 49,252,213,155,177,251,104, 1, 95, 68,231,225, 65, 35,174, 66, 96, 57,104, 53, 38, 70, 60, -244,234,228,235,236, 5,158, 3, 17, 88,216,140,218,131,183,162,186,121,117,106,102,235, 85, 30,201, 98, 97,247,159,223,129, 85, -102,245,234,221, 72, 97,183,200,143,158,126,189,164, 48,175,203, 43,189,187, 90,216,248, 15, 64,238,195, 88, 60,184,115, 89,115, - 51, 50,238,234,141, 20,118,203,211,180,174,187,187,123,175, 87,122,251, 97,212,180, 79, 96, 40, 43, 66,252,249, 31, 81,154,159, -137, 75,215, 44, 17, 83, 92,220, 21,128,209, 17,173,107,201, 92, 27, 36, 23,160,123, 19,105,178, 21,116, 46,227, 67, 6, 67, 65, -105, 33,232,138, 65,149,229, 34, 46, 77, 95,244,250,166, 20, 30, 0,148, 10, 74, 98, 65,138,172,141,138, 60,122, 59,180, 84, 50, - 44,118,158,189, 7, 65, 40,191,125,147, 32, 96,227,206,223,227,166,127,241,102, 7,180,246,178, 11,188,157,150, 77,193,132,144, - 63, 69,208,243,207,125,159,183,210,254,246, 25, 32, 24,112,121,150,125,171,158,107,243,123,162,145,183,219,137, 76, 71, 26,128, -233,144,148,109,158,181,246,212,103, 29,207, 70,245,152,243,159, 33,214, 32,207,164, 66, 55, 54, 42,147,239, 21,180, 34,233,180, - 64,106,246,231,150, 71,182,252, 73,122, 49,185,125, 49, 78, 39,142, 10, 47, 34, 34, 2, 0, 40, 45, 45,157,246,214, 91,111,109, -150, 74,165, 42, 0,148, 32, 8, 16, 4, 65,242,245,215, 95, 75,121,158,167,105,154,230, 25,134,225, 78,158, 60,201,242, 60,159, -163,213,106,167, 53,164,201,113, 92,220,140, 25, 51,154, 55, 84,161,184,119,239,222, 74,147, 21, 39,182,132, 81, 38,171,250,188, - 42,202, 37,169, 39, 72,251,121,247, 55, 23, 45, 2, 64,129, 96,113, 84, 14, 30, 61,254,145,136,124,164,183,102, 12,179,219,116, -234,189,168,242, 59,166, 46,153,150,231, 71,116,106,235,187, 23, 0,116,132,127,179, 49,107, 87,172,211,188,209,190, 83,215,125, - 2, 33, 18,142,144,109,180,128, 67, 90, 14,209,198, 84,218,213, 69,122,118,225,205, 1, 1, 54, 4, 40,239, 50,172,234, 46,172, - 24,198,129, 16, 66,170,186, 11,191, 49, 67,110,145,174,193,113,160,174, 60,210,247,211,115,127, 78, 61,115,229,246, 52,158, 39, - 46, 12, 67,101,106,244,220,230,167, 53, 89, 0,144,150,150,118, 33,236,108,218,153,187,129,206,175, 58, 42, 43,162, 92,101, 64, -110, 25,206,164,229,148, 94,104,140,102,129,154, 29, 50,127,205,209, 99,114, 41, 35, 1, 33,229, 3,138, 18, 2,173,129,207,191, -150,204,181, 1,128,182,246,112,251,240, 8,183,151, 97,168,164,134,244,194,239,103,172, 30,181, 34,108,238,189,196,130,109,137, -133,136, 4,128,196, 66, 68,238,191,252,232,179,184,204,146,185,145, 73, 5,223,192,196,188, 10, 66,225, 82,167, 81,139,158,120, -237,105,183,103, 76, 6,238, 0, 24, 6,164,246, 27, 53,231,251, 57, 20,133,103,117,251,137, 88,141,129,120, 63,254, 98,101,100, - 75, 60, 86,137,136,252,119, 80, 25,213,162,105,122,201, 51,212, 60, 73, 81,212, 64, 0, 15, 77,248, 90,120,105,105,105,219,103, -188,122,121, 28,199,229, 25,243,193,127, 33, 33,254,121,101,203,191,245,195,125, 69,205,127, 94,179, 69,139, 22,196, 4,195, 34, -110, 79, 81, 83,212, 20, 53,255,167, 52, 9, 33,204,211, 76,117,104, 82, 79, 51,137,109,244,220, 51,181,174,231, 98,166,219, 11, -200,195,135, 15, 41,113, 43,136,136,136,136,212, 14, 69, 81,252,223,160, 41,142,142, 39, 82,105,176,106, 68,183,104,113,155,136, -136,136,136,136,136,136,136, 60, 19,147, 85,125, 94,110,194, 81,119,248,207,148,106,130,198,132, 16,195, 68, 77, 81, 83,212, 20, - 53, 69, 77, 81, 83,212,252,159,211,108, 72, 91,172,102,252,155, 13,152,168, 41,106,138,154,162,166,168, 41,106,138,154,255,123, -154,207, 51,117,230,104,137, 93,135, 34, 34, 34, 34, 34, 34, 34, 34,127, 19, 98, 50,188,136,136,136,136,136,136,136,200,211,209, -224, 77,165, 69, 68, 68, 68, 68, 68, 68, 68, 68, 26, 71,253, 55,149, 22, 17, 17, 17, 17, 17, 17, 17, 17,105, 52,166,223, 84, 90, - 68, 68, 68, 68, 68, 68, 68, 68,196, 40,182,136,155, 64, 68, 68, 68, 68, 68, 68, 68,228,159,161,102,213, 97,104,104, 40,169, 62, - 23, 17, 17, 17, 17, 17, 17, 17,249, 39,121, 81,189,136,216,117, 40, 34, 34, 34, 34, 34, 34, 34,242,116, 76, 21,141,150,136,136, -136,136,136,136,136,200,223, 67,157, 57, 90,149, 3,150, 6, 87,132,234,130,197,109, 37, 34, 34, 34, 34, 34, 34,242, 47,240, 98, -123, 17, 49, 63, 75, 68, 68, 68, 68, 68, 68, 68,244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,255, 77,136,247, 58, 20, 17, 17, 17, - 17, 17, 17, 17,249,135, 13,215,223,110,180,196, 59,155,139,154,162,166,168, 41,106,138,154,162,166,168,249,191,100,178,106,152, - 45,177,234, 80, 68, 68, 68, 68, 68, 68, 68,228,233,104,176,234, 80, 68, 68, 68, 68, 68, 68, 68, 68,164,113, 76, 5, 16, 82,241, - 56, 4,213,162, 90, 98, 68, 75, 68, 68, 68, 68, 68, 68,135,111, 75, 20, 0, 0, 32, 0, 73, 68, 65, 84, 68,228,233,216, 2,192, -181,194, 96,157, 0,144, 33, 26, 45, 17, 17, 17, 17, 17, 17, 17,145,103, 67,245,188,172, 65,213,204,151,104,180, 68, 68, 68, 68, - 68, 68, 68, 68,158,146, 58,115,180, 40,212, 93, 57, 16,102,194, 15, 52,166,250, 32, 76,212, 20, 53, 69, 77, 81, 83,212, 20, 53, - 69,205,255, 57,205,134,180,195,240,252, 49,213, 20,243,245, 44, 17, 75, 95, 69, 77, 81, 83,212, 20, 53, 69, 77, 81, 83,212,252, -159,229,153, 87, 29,118, 0,204,197,205,250, 66,226, 92, 49,137,136,136,136,136,136,136,212,207,223, 83,117,232, 15,252,103, 92, -128,106, 19, 27,153, 99, 29, 9,148,213,247, 89,149, 74,181, 89,169, 84,142, 43, 43, 43, 83, 83, 20, 37, 84,190, 78, 8, 1,128, -234,247, 58,138,207,201,201,233,217,208,111,203,229,242, 53,206,206,206,255, 41, 45, 45, 45,163, 40,138, 80, 20, 5,138,162, 0, -224,137, 57,207,243,169,121,121,121, 29,159,235, 38, 36,132,113,116,118,254, 67,202, 48,238,166,126,149, 23,132, 71,217, 89, 89, - 93, 77,248,202,114,138,194,188,242,159,197, 87, 0, 62,121,209,254, 17, 4, 96,140,249, 92, 0, 96, 21, 11,140,226,105,250, 93, - 41,176, 94, 39, 8,155, 0,128, 2,248,198,254,182, 46, 28,205, 41,130, 64,138,130, 13, 33, 40, 34, 20,238, 40,130, 16,247, 47, -109,138,225, 82,169,116,136,181,181,181,101, 94, 94,222, 5, 0,123, 1,140,118,112,112,232, 93, 92, 92, 92,202,178,236, 81, 0, -135, 27, 35,220, 51, 16, 31,201,101,210, 73, 90, 3,187,242,202, 29,252,216,187, 3, 28, 56, 1, 43,204,100,146,158, 58, 61,247, -213,229,187,216,102,162, 36, 85, 49, 85, 30, 51, 76,190, 71,218, 1, 35,219, 29, 0,142,216,217,249, 42, 84,214,191, 73,229,204, -163,194,172,210,113, 35,178,179, 83, 70, 62, 69,187,255, 55,226,232,232, 56,145,166,233, 47, 9, 33,224,121,126, 65,126,126,254, -246,103, 36,189, 0,128,109,197,227, 66, 0, 95, 62,165, 94, 18, 0,175,138,199,201, 0,188,197,243,122,163,217,248,203, 47,191, - 76,239,211,167, 15, 86,175, 94,141,141, 27, 55, 38,230,228,228,172, 0,176, 3,128,254, 95,208, 17,169,139,214,192,192,175,251, - 7,241,236, 79, 95, 8,213, 94,238, 91,199,159,249,135,241,227,199, 27, 8, 33,228,254,253,251, 68,175,215, 19,150,101, 9,199, -113,132,227, 56,194,178,108,213,228,238,238,158,246,216,215,159,208,164,105,122,237,235,175,191, 94, 66, 8, 33, 55,110,220, 32, - 26,141,134,232,116, 58,162,215,235,137, 86,171, 37, 26,141,166,198,228,236,236,156, 85,159,166,181,181,245, 13, 59, 59,187, 44, - 59, 59,187, 44,123,123,251, 44,123,123,251, 44, 7, 7,135,170,201,209,209,177,106, 82,169, 84, 89, 42,149, 42,203,222,222,254, - 70, 67,203, 89, 65,127, 0, 23,140,152,250,215,242,221,190,213,141,150,171,171,107, 22,105, 4, 30, 30, 30, 41, 70, 44,103, 37, -206, 20, 5,190,242,187, 20, 5, 65,161, 80,120, 85,127, 31, 79, 70,186, 26, 12, 41,187,185,185,189,238,234,234, 26,230,234,234, -122,214,205,205,237,117, 35,118,177, 26,154, 86, 86, 86, 55, 28, 29, 29,179, 92, 92, 92,178, 43, 39, 87, 87,215, 26,147,155,155, - 91,213,228,236,236,156,101,103,103, 87,103, 27, 17,128,169,107, 58, 15, 72, 20,192,203, 18,134, 9,117,118,118, 46,142,136,136, -224, 9, 33,132,166,233,180,202,207,152,178,238,143,155,172,178,203, 88,144,123, 78, 17, 94,250,104, 69, 81,238, 57, 69,120,217, -101, 44,208,133,163,121, 99, 53,141,164, 54,205, 9, 19, 38, 76,184,147,149,149,149, 86, 88, 88,152,177,105,211,166, 88, 51, 51, -179,203,155, 54,109,138, 45, 44, 44,204,200,202,202, 74,155, 48, 97,194, 29, 0, 51, 76,208, 4, 0,116, 13, 68,151,201,195, 93, -203,238, 28,121,179,236,229, 78,146,219,221, 3, 16,210,175,171, 44,109,221,199,254,101, 23,183,246, 40,235,243, 18, 29,105,162, - 38, 37,145, 72,186,121,121,121, 77, 82,169, 84,227, 43,166, 55, 43, 39, 23, 23,151, 55, 93, 92, 92,222,180,179,179, 27, 89,159, -230, 1,128, 49,102,242, 52, 51,235, 54,178,169, 87, 89,210,146,197, 36,226,253,119,201,164,102,158,197, 35,156,156,154,252, 11, -109,244,183,106, 58, 57, 57,165,179, 44, 75, 12, 6, 3,113,112,112, 72,127,134,203,249, 13, 33,228, 27, 66,200, 55, 0,190,121, - 6,154, 85,199, 51, 19, 12,118,125,154,102, 18,154,158,163,148,203,207, 42, 36,146,108,133, 68,146,173,148,203,207, 74,104,122, - 46, 0,179,255,166, 54,250, 27, 52, 45, 85, 42, 85,194,154, 53,107, 72, 89, 89, 25, 41, 43, 43, 35,107,214,172, 33, 42,149, 42, - 1,128,165, 9,154,141,213,121,145, 34, 88,143, 79,207, 46,162,229, 15,116,124, 57,176,197,161, 89, 19, 71, 65, 56,184,134,106, -224,138,233,135,174, 29, 59, 78,218,177, 99, 7, 0, 96,220,144, 33,120,181,115,103, 88, 89, 90, 64, 46, 47, 95, 28,138, 80,144, - 73,101, 24, 58,251, 3, 99,126,254,171,161, 67,135,142, 61,120,240,160, 37, 0,108,220,184, 17,195,135, 15,135,189,189, 61,148, - 74, 37,100, 50, 25,164, 82,105,141,121, 67, 48, 12,227,145,150,150,230,100,102,102, 86, 21,101, 19, 4,161,198, 68, 8,169,140, -190,129,227, 56,180,108,217,210,216,205,245,113, 81, 81, 81, 47,181, 90, 93,165, 81,219,212,180,105, 83, 0, 56,109,140,224,151, - 75,191,128,192,169, 33,145, 0, 28, 7,232, 12, 52, 4, 82,171,185,193,140, 25, 51,170,150,187, 49, 12, 26, 20, 66, 81, 20,117, -240,230,205,155,135,178,179,179,125, 4,129,159,210,200, 72,215, 59, 15, 30, 60,176, 4, 0, 95, 95,223, 25, 0, 14,153,178, 28, - 18,137,196,227,238,221,187, 78, 10,133,162,206,200,101,181, 8, 38, 12, 6, 3, 58,116,232,192,153,242, 27,206,128, 87, 62, 77, - 79,105,255,210, 75, 83, 23, 13, 29,106,246,199, 31,127,152,209, 52, 13,142,227,240,245,215, 95,115,132, 16,219,214,128,117, 20, - 80, 92,143,204,124, 0, 19, 43, 78, 6,219, 0,124, 93,195, 45, 16, 4,106, 88, 69, 72,124,233,208,206, 65, 77, 62, 66,212,189, -136,206,205, 44,143,192, 74,162,139, 3,254,217,168,150,181,181,245,144,213,171, 87,171,182,109,219, 86,124,255,254,125,195,166, - 77,155, 84,211,166, 77,179, 50, 24, 12,152, 62,125,122,142,159,159,159,108,245,234,213,170,195,135, 15,191,172, 86,171, 55,152, -212, 94, 20,190, 24, 61,228, 85,104, 89, 26, 44,203,169, 92, 85, 86,187,102, 77, 8,150, 18,162,199,206,163, 55,193,114,194,143, - 38, 70,178,186,142, 24, 49,162,217,158, 61,123, 36, 49, 49, 49,146, 86,173, 90, 65, 16, 4,240, 60, 15,150,101, 1, 0,130, 32, -160, 69,139, 22, 79,189, 93, 38, 1,190,142,206,246,103,187, 14, 28, 96,238,106,166,128,125, 65, 14, 38,203, 36, 86,219,149,186, -221, 0,186,189, 80,145, 93, 66, 32,145, 72,144,146,146, 2, 39, 39, 39,115, 65, 16, 50, 0, 44, 46, 40, 40,216,130, 23,151,206, -114,137,228,208,206, 31,215,186, 4,117,235,198, 56,187, 58, 33,246, 65, 50, 36, 20,223,247,238,159, 55,131, 39,189, 61,103,150, -158,227, 94, 7,240,199,139,182,226, 46,221,102, 12,163,104,102, 35, 69, 4,124,190,238, 88,201,242,175,214, 40,167, 79,153,192, -204,158, 61, 27,158,158,158, 62,195,134, 13,251, 10,192,219, 13,234, 4,205, 24, 6,134,222, 8, 66,176,232,251, 99, 37,203,190, - 90,163,124,187, 17, 58,207, 57,117,254, 71,158,218,104,249, 3,205,218,120, 58,157, 89, 62,239,109, 41,249,245, 39,186, 44, 47, -187,206,207,170, 84,170,205,175,189,246,218,184,237,219,255,138, 70,119, 13, 8,192,176,151,123,192,201,193, 6, 74, 11,121,249, -233, 72,160,112,231,254, 35,163, 12,129,167,167,231,244, 67,135, 14, 89, 86, 55, 19, 50,153,172,106,170,110,178, 42,167,202, 19, -112,125,152,153,153, 33, 44, 44, 12, 18,137, 4, 12,195, 64, 34,145, 84, 77,213,159, 51, 12, 3,103,103,147, 82,151, 86,216,216, -216,180, 43, 41, 41,177, 46, 44, 44,132,151,151, 87, 49,128,187,213,222,111,151,147,147, 99,109,138,160,192,169, 49,123,178, 63, -164,250,235,208, 75, 59, 67, 35,233,142,171,127, 70, 35,244,244, 5,164,165,103,162, 71,151,246, 24, 63,102, 4,206,158, 61, 11, -158, 55,185,167, 35,139, 16,124, 53,120,112,200, 71, 0, 69,245,237,219,183,112,230,204,153,116, 76, 76,204,216, 97,195,134, 6, - 60,120,240,176, 34,170, 72,205, 35, 4,107, 1,100, 25,169, 43, 7,128,139, 23, 47, 2,128,162, 49,251,158, 66,161,192,181,107, -215, 80,217, 77, 76,211, 52,104,154, 6,195, 48, 56,254,208, 17,106, 61,141,178,172, 72,188, 27,226,133,166, 77,155,130,166, 27, - 78, 73, 12, 6,204,174, 2,195, 40,169,116,182,171,155,155, 79,239,102,205,148, 97, 97, 97, 12, 0,120,123,123,147,140,140,140, -194,163, 71,143,150, 72,128,141,222,132,236,168,207,100,121,122,122,118, 79, 75, 75,251,178,114,155, 83, 20,245, 85,147, 38, 77, - 22, 86,181,155, 32, 96,241,143,106,233,172, 89,239,203,130,130, 63, 5, 0, 4, 13,222,131,226,248,229,254, 84,254,124,155,127, -250, 40, 81, 92, 92,188,175, 69,139, 22, 76, 94, 94,222, 85, 0, 73, 44,203,126,188,107,215, 46,167,201,147, 39,103,239,222,189, -123, 5, 0,183,149, 43, 87, 6,171,213,234,253,166,232,246,104,135,129, 47,181, 11,232,226,229,233,137, 11, 87,255,128, 76, 46, -181,157, 49, 49, 4,150,150, 18,124,179,237,132,144,148,154, 63,243,242, 93,236, 48,193,100,117, 30, 49, 98,132,207,158, 61,123, -228, 0,112,247,238, 93,100,102,102, 66,165, 82,193,220,220, 28, 82,169, 20, 12,195, 64, 42,149, 62, 19,147,101,227,233, 16,126, -228,200, 81,115,123,123, 91,172,251, 96, 22,198,103,103,193,214,202, 18,108,169,218,231, 5, 59, 81,248,246,236,217,211,140,231, -121,168,213,106,156, 63,127,222,198,220,220,220,198,195,195, 99, 17, 76,168,158, 50, 51, 51,203,210,106,181, 78, 21,143,179,181, - 90,173, 51,128, 98,133, 66, 81,121,156, 46,173,152, 27,219,157,152,132, 39,187, 9,147, 41,138,170,254, 90, 99,233,212,185, 83, -187,176,195, 7,127,182, 44, 42,201,132,173, 93, 54,104, 20, 97,203,150,245, 48, 55,183,198,162, 69,243, 37,143,250,190,236,222, -127,224,235, 97,247,162, 99,251,190,112,102,139, 80, 91,250, 14, 30,103,111,174,180,170, 56,151,176,216,190,117, 22,104,154,198, -194,133, 11,209,166, 77,155,169,247,238,221,251, 20, 64,126,253, 50,216,210,182,215, 27,246,114,179,242, 38, 22,120, 22,155,246, -206, 45,215,249,100, 26, 70, 15,110, 58,245,195, 17, 9,167,218, 52, 67, 73,197,133,185, 70, 74, 35,153, 10, 66,149, 97, 8, 13, - 13,237, 29, 18, 18,114,161,174,231,207, 1,174,248,107,252,172, 26,230, 75, 18, 26, 26, 74, 66, 66, 66,168,106, 43, 87,227,121, -125, 4, 2,142,118, 54,202,176,141,139,103, 89, 74,174,159, 96, 52,201, 15,145,174,173,113, 34,175, 81,162,169, 84, 42,199,109, -223,190,189, 70, 72,201,203,217, 9, 50,153, 20, 82, 25, 5,219,158,229,163,215, 23, 94, 10, 5, 69,213,105,178,106,104,170,213, -106,237,237,219,183, 45,183,109,219, 6, 39, 39, 39,248,248,248, 64,169, 84,194,204,204,172,134,185,170,110,184,106, 49, 90, 53, - 52, 43,223,151, 72, 36,160,105, 26,103,207,158, 5,199,113, 24, 49, 98,196, 19, 38, 75, 34,145,212,101,220,234, 42, 79, 61, 13, -224, 46, 33,164, 87,197, 9,248, 46,128,222,213,222,239,175, 82,169, 62, 6,176,194, 88, 77,134, 33, 96,180, 87, 33,120,172,129, - 36,101, 22,244,210, 64,156,187,124, 19,219, 55,175, 6, 0,248,180,234,132,145,195, 66,170,162,113, 70, 46,103, 21,238,238,238, -123,115,114,114, 7,188,252,242,203, 40, 40, 40, 96, 23, 47, 94,140,118,237,218,193,215,215,215,168, 54,170,227,202, 57,235,238, -221,187,158, 26,141, 6,132, 16, 99,204,217, 19,154, 20, 69, 97,215,174, 93,208,106,181, 79,124,216,174,247, 50,204, 29,238,141, -183,222,221,129,175,238,239,199,134, 13, 27,234, 93,119, 37,208, 78,107,211, 98,173,156,225,218,173,152,255,142, 98,252,248,241, -204, 91,111,189,133,228,228,100, 76,158, 60, 89,123,246,236, 89,125,102, 70,198, 81,185, 32,172, 51,212, 52,198,117,106, 42, 20, -138,157,167, 79,159,198,254,253,229,190, 36, 54, 54, 22, 45, 91,182,180,168, 97,146,243, 15,160, 36,105, 29,194,143,199, 32,104, -240, 30,132, 31, 31, 3,190,240,132,180, 99, 75, 20,153,178, 61, 27, 65,109,154,251,243,242,242,170, 76,212,238,221,187,205,119, -239,222, 61, 20,192, 49, 0,251, 1, 32, 63, 63,255, 91, 19, 53, 1, 10,111,189, 49,124, 40, 36, 50, 43,196, 60, 76, 69,239,174, - 29,224,236,228,132,187,209,113, 72, 74,203,207,162, 40, 76,236,223, 77,190, 66,163,209,127,122,233, 14,126,104, 64,147,242,240, -240,240, 61,112,224,128,172, 90, 4,186,234, 63,206, 48, 76,213,243, 74,227,221,152,253,179,210,100, 89,121, 88,134,127,177,190, -187, 69,120,196,110,180,244, 30, 8,187,129, 33,248,225,204, 25, 60,184, 23,165,213,151,113,175,252, 11,109,244,119,105,250, 14, - 31, 62,252,234,207, 63,255,108,155,146,146,130,139, 23, 47,194,199,199, 7,101,101,101,198, 92,240,214,208,212,106,181, 78,149, -223,161, 40,202,169, 50,240,174,215,235, 43, 27,163,242,143,104, 91,237,115,182,245,104,122, 85,251, 92,165,185,242,126, 6,235, - 46, 55,147,201, 14, 28, 57,188,215, 50, 42,230, 34,218, 7,118,129,165, 77,107, 8,124, 38,242,242, 75, 81,240, 48, 29, 75,151, -126,133, 69,139, 23,224,216, 47, 7, 45,253,252, 3, 15,233, 57,174, 5, 0,237, 11,211,238, 20,153, 26,118,124,247, 70,138, 8, -208,100,197, 40,164,234, 4,229,184, 49,175, 51,163, 70,141,194,177, 99,199,112,239,222,189,141,245,152,172,176,106,145,249,169, -145, 23,247,111, 4, 33,208,100,199, 40,100,154, 4,229,132,177, 35,153,241,163, 95,197,245,223,215,226,213,246, 9,145,110, 78, - 24, 86, 80, 97,177, 37, 12,242, 20,102,184, 66,194,113,189,154,217, 58, 15,128,170,102,176,206,227,175, 28,204,231,129, 65, 21, -198,106,234,227, 23, 38,146,198, 24, 44, 0,104, 9, 88, 82,114, 89,248,246, 69,239,184, 41,147,239, 73,116,145,215,144,174, 19, -200,166, 68, 78,232, 0,152,223, 2, 52,143,127,167,172,172, 76, 29, 23, 23,103, 62,113,216, 48,116, 11, 8,128,171,131, 3, 90, -120,120,192, 92, 33,135, 92, 38,173,113,201,106,116, 31, 2, 69, 17, 63, 63, 63, 12, 30, 60, 24, 82,169, 20, 74,165, 18,150,150, -150,144,203,229,181, 70,179,140,189,202, 37,132,128, 97, 24, 68, 70, 70, 34, 41, 41, 9,182,182,182,184,114,229, 10, 94,121,229, -149, 39,162, 90,213,205,153, 41, 33,250, 90, 78,252,149, 70,236,180, 41, 90, 60, 79,161,148, 4,194, 44,113, 38,202,168, 14,208, -233, 56,232,116, 58,252,112,217,128, 63,226,212, 48, 24,244,208,233,116,245,253,102, 93,208,110,110,110,227, 90,180,104, 49, 99, -204,152, 49,172, 92, 46,135, 90,173, 70, 89, 89, 25,238,221,187,199, 14, 24, 48,176,112,240,224, 16,155, 19, 39, 78,144,138,174, -195, 44, 19,180,243,220,221,221, 61, 43,186,103,243, 26,179, 87, 83, 20, 85,101, 98, 30,103,226,183, 81,144, 48,229,109,178,113, -227, 70,240, 60, 15, 66, 72,157,141,164,165,168,223, 22, 47, 91,101,179,114,205,143,176,177,119,198,133, 11, 23,248, 83,167, 78, -149, 80, 64,236,131,123,247,190,253, 63,224,228, 1,192, 96,202,242, 21, 20, 20,152,251,248,248,192,195,195, 3,130, 32,128,101, -217,170,232, 75, 94, 94, 30, 52, 26, 13,236, 45, 10,209,220,193, 3, 92,201,121,100, 68,126, 14, 87,203, 24,236, 56,173,103, 95, -242,197,157,255,130, 3,199, 79, 21,211, 83, 94, 53,195,221,201,197, 19, 52, 97,145,158,157,135,161,131, 94, 5, 35,179,196,163, -148, 92, 4,182,110,230, 58,246,255,186,187, 50, 20,135,121, 43,246,204, 0,132, 31, 26,146, 43, 45, 45,229, 99, 98, 98,112,247, -110,185,223,181,182,182,134,133,133, 69,141,255, 56, 77,211, 79, 21,209,170, 52, 89,203, 54,190, 98, 65, 75,213, 40,230,195,176, -109,215, 77, 4,250,133, 96, 83,248,159, 90, 62, 43,191,239, 55, 90,109,236,222,231, 56,152,225,226,226, 50, 77, 16,132, 69,132, -144,194, 30, 61,122, 56,239,217,179,199, 46, 45, 45, 13, 55,111,222,196,194,133, 11,115,120,158,231, 8, 33, 20, 33,228,243,103, -240,115, 66, 53,131,245, 44,145, 42,205,240,174,163, 53, 53, 68, 66, 91,251,112,197,165,143,114,245,228,104, 25, 39,124, 15,128, -173,247,224, 70,211,255, 57,184,111,163,155,163, 74, 64,176,234,101,100,100, 25,176,236,131, 9,200,203, 43,193, 15, 91,151, 3, -144,195,192, 49,232, 21,252, 58,156,156,220, 49,117,202, 84,151,141,155, 55,189,195, 9,194, 55,120, 65,200,188,186,225, 23, 0, - 97, 42,149,234,222, 59, 83,167,170,124,124,222,132,153,153, 25,246,238,221,139, 61,235,214,241,107,128,145, 10,224,220,116,224, -151,122,117,194,255,210,153, 53,125,186,202,223,127, 58, 20, 10, 5,126, 63,245, 19,180,153,187, 74, 6,117,131,161, 76,139, 65, - 77, 6, 19,251,196,227, 84,190, 84,138,135, 0, 32, 53, 67, 6,128,199,187,193,158, 55,131, 85,201, 9,252,149,151, 53,181, 70, - 68,171,209,199, 78,169, 60, 98,235,251,163,189,157,161,163,244,151,143, 35, 77, 39,240, 43, 31, 24,152, 91, 69,100,110,116, 45, - 38,171, 98,199, 22,188,188,188,240,114,199,142, 24,214,179, 39, 36, 18, 9,204,228, 50, 88,153,153,131,240,229,145,172,202,174, -195,122,206,137,168, 45,250,228,224,224, 0,153, 76, 86,101,176, 76,136,102,213,170, 41, 8, 2, 36, 18, 9,238,222,189,139, 30, - 61,122,192,211,211, 19,251,247,239, 71,255,254,253,159,232, 74, 52,213,100, 85, 26,173,199,186,241,250, 3,168,140,100,153,100, -180,180,122, 10,185,250, 64, 80, 84, 0, 56, 14,224, 9,160,211,106, 65, 8, 64, 8,192, 26,244,208,106,181, 85,191,105, 76,151, -172,139,139,139,151,185,185,249,146,143, 62,154,231, 31, 24,216, 30, 57, 57, 57, 16, 4, 1, 22, 22, 22, 40, 43, 43,131,181,181, - 53,186,117,235,246,104,201,146, 37, 25,132, 96,170,137, 38,235,169,169,220,230,103,206,156,169,209,109, 88, 57,169, 51, 82,241, -214,123,187, 33,151,148,119, 45, 85,230,240,212,119,220,237,211,171, 59,174,222,138,229,254, 51,111,173, 78,154,119,115,133,139, - 32,108, 79,125,138,245, 34,132, 32, 55, 55, 23, 89, 89, 89, 24, 50,116, 40,246,252,252, 51, 18, 19, 19,209,186,117,107,244,233, -211, 7, 78, 78, 78, 72, 76, 76,196, 31,151,116,208, 21,228, 35, 95,127, 19, 74,171, 32, 28,185, 16,167, 91,184,209, 16,247, 47, - 30, 48,134, 0,152, 96,109,109,221,180,172,172, 44,131,227,184, 3, 0, 14, 0, 24, 41,145, 72, 70, 42,149, 74,215,226,226,226, - 4,148, 87, 19, 29,109, 72,204,220,204,204, 65, 97,102, 13,129,211, 65, 34,145,192,211,211, 7,132,215,163,160, 88,131,137,163, - 6,227,214,221,104,156, 58,119,157, 99, 89,225, 59, 99, 54, 43,195, 48,196,215,215, 23,217,217,217,144, 74,165, 48, 55, 55,135, -165,165, 37, 62,249,228, 19,172, 91,183,174,202,100, 53,214,104, 77, 2,124,173,189, 44,175,127,185,190,220,100,101,166,103, 32, - 43, 85, 10,149,131, 51,190, 91,183, 70, 93,144,152, 25,244, 35, 16,251,188,159,100, 5, 65,248, 60, 45, 45,205, 73, 34,145,184, -112, 28,135,148,148, 20,220,184,113, 3, 51,103,206,204,202,203,203, 11, 70, 35,215,209,204,204, 44,187, 50,146, 85,209,117, 88, - 87,119, 98, 97,181, 72, 86, 97, 61,146,117,117, 19, 54,243,241,176, 58,187,117,245,108,175, 78, 65,221,104,165,196,186,160,244, - 97,102,143,203, 23, 47,116,155,185,250,135,119,146, 10, 74, 95, 5, 16, 95,151,168, 66, 42, 29,208,165,123,119, 9, 72, 22, 36, -242, 30,248,106,229, 40,228,228, 22,163, 32,191, 4, 50,153, 5,244, 44, 3, 94,160,208,173, 71, 79,252,180, 99, 31,218, 76,153, -204,200,165,210,126,156, 94,255,194, 24,173, 10,150,127,255,253,247, 94,126,126,126,216,190,125, 59,206,237,220,137,241, 69, 69, -184, 64,211, 12, 43,149, 58,158,100,217, 45,104,192,104, 85,215,105,211,166, 13,126,252,241, 71,236,218,181, 43,121,220, 43,217, -135,102,143,131,147,193,128,215,110,222,135,125,147,193,192,205,251,176,127,201, 15, 45, 56, 9, 30, 82, 84,205,225,160, 66, 67, - 67,123, 87,159, 63,103,100,160,142, 46,118, 9,128,224,208,208, 80, 82,125,222,224,129, 83,213,114,250,242, 87,155,122, 7, 52, -247,162,216,253,107,145,162,230,244,159,222, 55,200, 31,148,146,217,209,192,154,122,174, 32, 8,195, 48,176, 50, 55,135,202,214, -182, 60,204, 79,211,128, 0, 8, 44, 64,241,229, 6,128, 8, 20, 8,111,210, 1, 3,114,185,188,214,196,119, 83,115,179,170,107, -150,148,148,224,209,163, 71,152, 58,117, 42,148, 74,101,185,115,207,204,132,183,183, 55, 36, 18, 9,210,210,210,240,251,239,191, -163,105,211,166, 80, 40, 20, 38,185,173,106,209,165,118, 40,175, 50,108,151,145,145, 97,237,234,234, 10,147, 35, 90, 2, 65,153, -142,130, 94,207,227,193,131, 7, 72, 79, 79,199,163,132,135,232,164, 46, 6, 1, 3, 66,136, 73, 17, 45,119,119,247,128,102,205, -154,109, 90,177, 98,133,204,195,195, 3,132, 16,216,217,217,162,172,172, 12,185,185,121,104,221,186, 53, 60, 61, 61,177, 98,197, - 10, 0,216,243, 79,155,172,199,246,169, 42,163, 85,221,112,189,247,127, 94,200,207,183, 4,195,208, 85,198,185,129, 28, 45, 25, - 0, 4,191, 58, 92,114,246,212, 73, 11, 14, 88,146,201, 48, 75, 36, 13,183, 35,203, 11,130,178,174,247, 83, 82, 82, 32,149, 74, -113,240,192, 1,228,103,101, 33, 48, 48, 16,157, 59,119,198,195,135, 15,113,235,214, 45, 56, 56, 56, 64,229,209, 21, 23, 18, 12, -136, 74,215,192,198,198, 6,113,169,244,191, 57,100,192,148,190,125,251, 46,252,246,219,111,157, 92, 92, 92,164, 57, 57, 57,126, -235,215,175, 15, 92,191,126,253,172,119,222,121,199,249,157,119,222,177, 83,169, 84,146,204,204, 76,223, 15, 62,248,224,165,176, -176,176,166, 0, 86,213, 39,104, 97, 97,101,207,200, 44, 64, 81, 18,216,218,216, 65, 34,183,128,192, 73,192, 11,128,181,141, 10, - 87,111, 29,196,149,136,146,105,217,121, 56, 96, 84,124,172,162,221, 29, 28, 28,158,136, 84,207,156, 57, 19, 91,183,110,173,234, - 70,108,172,201, 90,182,254, 21, 75,170,194,100,101,166, 72, 64,233,154,226,248, 47,215, 10, 11, 18, 51,123,188, 8, 38,171,242, - 24, 71, 8, 65, 66, 66, 2,202,202,202,112,233,210, 37,124,254,249,231, 57,143,155, 44, 39, 39,167, 41,214,214,214,139, 75, 75, - 75,191,202,204,204, 92,219,224,133, 95,185,137,170,124, 92, 57,175,181, 59,209,200, 69,245,174, 45,146,229,233,106,118,250,214, -165,221,222, 54,228, 14,133,164,169,192,131,226,123, 86,225, 78,189, 6,118, 26, 68,119,216,240, 69,147,206,211, 62, 57,157, 82, -172,245,171, 43,178, 37,240,124, 7, 11, 75, 43, 0,217,184,121,227,124,149,201,202,203, 47,130,206,192, 64,167,167,160, 53,208, -120,185,239,107, 88,183,105, 23,210,178,243,193,243,124,219, 23,204,100,217, 7, 4, 4, 76, 31, 57,114, 36,150, 44, 89,130,176, -111,191,213,191, 77, 81,197, 18,128,156,224,121, 8,132, 80,180,113, 73,236, 53,116,190,249,230,155, 95, 0,140, 94, 49, 19, 93, - 11, 74, 49,209,109, 48,177,111, 50,184,252,131, 35, 62, 34, 0, 96,159, 19, 86,243,148, 25, 18, 18, 66, 85,246,172,153,218,195, -246,223,142, 36, 36, 36,228, 66,104,104, 40,170,207,235,251,130,149,179,223,192, 15,231,204, 88,217,169,127, 79, 42, 99, 78, 63, -228, 23,107,185,249, 81, 6,121,170,166,126,147, 85,157, 15,215,175,199,173,216,242,255,177,135,147, 19,230,141, 29, 11,194, 1, - 87,238, 69, 97, 95, 88, 24, 70,245,237, 11, 11, 51, 51,163, 35, 27,130, 32,212, 26,197,170, 30,205, 50, 53,234, 84, 88, 88,136, - 3, 7, 14,160,115,231,206, 80, 42,149,144, 72, 36,104,215,174, 29,162,163,163,209,172, 89, 51, 80, 20,133, 35, 71,142, 96,216, -176, 97,136,143,143, 71,215,174, 93, 45,147,146,146, 76, 54, 90, 81, 81, 81,214,132,144, 94,149,209,143,198,162,211,233, 16, 19, - 19,131,193,131, 7,195,206,206, 14,238,238,123, 16,118,122, 55,148, 1,227, 65, 81, 48,201,104,241, 60, 63,105,208,160, 65, 50, -138,162,160,209,148,193,204,204, 28, 22, 22,150,176,178,178,134,175,175, 31,210,211,211,209,191,127,127,125, 92, 92,220,134,140, -140,140,253,166, 46,171,191,191,191, 69, 98, 98,226,248, 38, 77,154,200, 1,192,220,220,188,117,179,102,205,230,198,199,199,151, -152, 26,213,170, 52, 88, 20, 69,129, 97,152, 42,163, 37,161,105,184,186, 56, 85, 61,175,200, 79,163,234,209, 42, 78,203,211, 41, - 0,192,203,203, 11,235, 54, 31,163, 7, 13, 26,132, 89,179,102,129,101, 89,108,216, 80, 94,100, 55,102,204, 24, 24, 12, 6, 28, - 58, 84, 94, 36, 41,145, 72,234, 13,155,220,184,113, 3, 55,111,222, 4,203,178, 40, 42, 42,194,175,191,254,138, 11, 23, 47, 98, -239,145,223,144,152,240, 16,237,252,188, 49,121,242, 36, 72,165, 82,236,216,177, 3, 61,122,244,248, 87, 15, 8, 82,169,116,220, -214,173, 91, 93,183,111,223, 94,120,228,200, 17,117,151, 46, 93, 20,107,214,172,113, 90,183,110,157, 74,175,215,227,253,247,223, -207,190,126,253,186,110,232,208,161, 22, 91,182,108,113,109,222,188,121, 63,142,227,106, 51, 90, 22, 0, 70, 1,120,179,160, 68, - 47, 41, 44,209, 64,224,244, 72, 72,124,132,162, 82, 61, 4,222,128,228,212,116,148,106,121,228,229,151,160, 93,135, 87,191, 63, -127,254,252, 2,131,193, 48, 31, 64,104, 67,203,121,239,222, 61, 92,191,126, 29,137,137,137, 72, 72, 72,168,233, 20,167, 76,193, -174, 93,187, 76,142,104,213,110,178, 24, 80,186,102, 8, 61, 18, 94,152,253, 48,227,133, 49, 89, 21,199,160, 69,174,174,174,139, - 92, 93, 93,205,206,156, 57, 99,211,164, 73, 19,112, 28,167,127, 60,146, 21, 28, 28,252,233,214,173, 91, 93,155, 53,107, 54, 19, -192,218,255,134,101,167,105, 76,249,106,227,116, 71, 43,121,114, 58, 30,172,170, 24, 75,144, 1,202,138,129,243, 63, 67,210,253, -179, 71, 51,135,126,100,247,241,246, 37, 83, 4, 8,117, 86,200,198,197,167, 96,227,198,117,152,253,254, 68,252,244,195, 87, 16, - 4, 9,116, 44, 3, 47,159, 46,208, 25, 4, 80,180, 4,129, 29, 58,226,220,249, 75,144,210,192,129,237, 27, 95, 48,159,133,252, -200,200,200, 13, 71,142, 28,121,119,214,172, 89, 16, 4, 65,190,120,227, 70, 77, 78, 78,206,114,152, 54,254,213,227, 58,195, 54, -110,220, 24,251,241,186,156, 95,102,143, 3,147,120,156,202,191,121, 31,246, 35, 62, 34, 56,184,146,194, 75,126,200, 87,214,126, -138,191,248,216,252,197, 48, 90,149, 78,178,250,188, 54, 58,180,108,250,133,141,189,221, 36,218,202,221,113,222,172,183, 37,241, -153, 90, 28,106, 50,182,244,247,157,223, 89,100,114,138,239,227,160, 93, 99,202, 15,239,251,253,247,170,199, 95,239,217, 83,235, -123, 25, 35, 70, 24,125,101, 86, 87, 20,203,212, 72, 22, 0, 40,149, 74,219,126,253,250,225,149, 87, 94,193,235,175,191, 94,149, -147,213,190,125,123,236,221,187, 23,195,135, 15,199,237,219,183,225,234,234,138, 86,173, 90,161, 85,171, 86, 56,121,242,164,169, - 7, 57,240, 60,143,128,128,128,202,170,195,118,169,169,169,214,141,109, 72,157, 78,135,188,188, 60,216,219,219, 67, 46,151, 35, - 40,168, 51,222,125, 47, 8,142,174, 63, 34,192,223, 15,106,181,186,170,252,221,136,147,109, 64,139, 22, 45,144,147,147,131,156, -156, 28,168, 84, 42,184,185,185,193,197,197, 5,171, 86,173, 34,107,215,174, 61,101, 48, 24, 54,228,230,230,154, 28,201,114,113, -113,233, 73, 81,212,167, 26,141, 70, 94,237, 10, 87,174, 82,169,142,106, 52,154,229, 25, 25, 25, 70, 39,130, 82, 20, 5,131,193, - 0,138,162,112, 34,193, 13,106, 61,133,226,212,155,152,245,127,222, 53,140,151, 84, 42,109,176,187,148, 16,162, 30, 61,122,180, -147,167,167, 7, 82,226,238,225,224, 65,130,111,191,253,182,178, 42, 18,177, 21, 23, 6,149,207,251,244,233, 3, 31, 31, 31, 16, - 19,198,202, 16, 4, 1,119,239,222,197,158,163, 23,224,234,237,143,228, 7, 49,184,117,242, 56,154,168,236,209,166, 67, 71,176, - 44,251, 84, 67,111, 60, 11, 88,150,221,214,178,101, 75,162,215,235, 47, 0, 88, 23, 17, 17, 49, 49, 35, 35,227,253, 99,199,142, -185,141, 28, 57, 50,253,248,241,227,107, 0,108,143,136,136,152,190,116,233,210, 87, 56,142,171,181, 90,144, 97,152,159, 62,248, -224,131,224,145, 35, 71, 82, 50,154,213,159, 57,189, 67,194,113, 44,245,225,252,109,252,249,203, 23,104,142, 99,169,215, 71,127, - 32,156,252, 61,130,158,246,222,215,124,251, 46,131, 16, 25, 25,233, 18, 18, 18,178,148,101,217,122,141, 86,101,164,170,174, 8, - 37,195, 48,152, 56,113, 34,246,238, 53, 62,131,106, 50,208,204,218,219,242,250,178,245,125, 45, 41, 73,105, 53,147,213, 28,161, - 71,194, 11,179, 30,164,191, 80, 38, 11, 0,242,242,242, 54, 3,216, 44, 8, 66,150,133,133, 5, 74, 74, 74,106,219,255,204, 34, - 34, 34,204,228,114, 57, 94,125,245, 85,251,176,176,176, 88,154,166,215,166,167,167,215,233, 56,106,235, 38,172,173, 59, 17, 79, - 81,117,104,167, 66, 72, 80,207, 14, 86,247,109,150, 88,153, 73,180,183,155,196,154, 89, 83, 0,138,116,206, 9, 87,147, 70, 21, - 83,217,138,246, 29,251,188, 4,107,137, 69, 72, 33, 87, 82,171,209,162, 25,230, 86, 81, 65,225,128,226, 18, 61, 46, 95,137,196, -232, 81, 45,160, 51, 80, 16, 4, 26,165,106, 29,192, 72, 65, 3, 24, 51,118, 2, 8, 37, 65,126, 86, 58, 24,134,137, 0,199,225, - 5,227,147,233,211,167, 15,152, 63,127,126,211,121,243,230, 97,222,188,121,222, 91,183,110,221,188,108,217,178,121, 57, 57, 57, -109,209,192,224,227,245,232, 52, 57,190,247,179, 57, 71, 47,109, 42, 26,212, 77,243,224, 37,191,242,200,215, 75,126,200,151, 74, -241, 80,194, 32,143,144,154,105, 70, 33, 33, 33,189,171,207,159, 51, 30, 79,130,175,122,110, 84,142, 86,139,166,238,175,117,104, - 31,240,222,130,249, 11,172,162,175,158,199,199, 95,172, 35, 45, 59,246, 43,217,124,233,150,190,212,194,103, 64,105,238,195, 43, -198,250, 11, 0,120,237,229,225,104,215,186,243, 19,111,246,232, 83, 62, 88,251,229,115, 55,144,149,147,102,244,201,182,194, 28, -212,154,147,101, 76, 73,255,227,104, 52,154,194,200,200, 72,167,212,212,212, 26,137,239, 62, 62, 62,160, 40, 10,225,225,225,184, -126,253, 58, 70,143, 30, 13,137, 68, 2,169, 84,138, 11, 23, 46,152, 20,141,169, 22, 93,170,172, 58,236,239,225,225, 81, 87,181, - 97,131, 90, 26,141, 6, 69, 69, 69, 56,125,250, 52, 90,180,104,129,101,203,150,193,205,213, 25, 11, 22,204,129, 32, 8, 40, 46, - 46, 6,207,243,198, 70,180,132,202,104,145, 32, 8,200,201,201, 65,211,166, 77,177,126,253,122,172, 89,179,102,105, 70, 70,198, - 49, 83,151,209,211,211,211,150,231,249, 15, 7, 13, 26,212,111,232,208,161,232,223,191,230,120,172, 63,255,252,179,213,161, 67, -135,150,127,247,221,119,175, 25, 12,134, 21,217,217,217, 57,198,232,254,248, 99,249,240, 75,202, 46,139,240,241,200, 38,120,115, -198, 14,172, 90,117, 24, 10,133,162,198,137,119,201,146, 37,245,154, 24,129,144,150,178,220,171,233,115, 62,250,198,105,249,242, - 48,132,133,101,131,166,105,184,186,186,130,166,105, 60,122,244, 8, 52, 77,195,219,219, 27, 52, 77, 35, 45, 45,173, 50, 39,176, - 0,181, 84, 61,214,126, 21, 78, 67,171,213, 34, 37, 57, 17,169,113,177,176, 44,206,132,202, 90,137,130,123,119,209,110,242,148, -170,241,159,254,101,118,233,245,250, 93,213,158,127,115,252,248,113, 61, 69, 81,175,163, 60, 79,163, 50,162,177,148,227,184,165, -117,137,116,233,210,165,253,252,249,243,165,149,195,109,184,121,125,201, 25, 12, 6, 1, 0,252,218,245,170,225,246, 31, 62,124, -136, 85,171, 86, 65,173, 86, 67, 38,147,201,140,217, 14,130, 32, 84, 85, 24,214,102,194, 76, 49, 89, 0,224,224,237,241,125,248, -205, 11,252,157,184, 77,154,136,251,191,154,103, 36,211,160,245, 47,174,201,122, 60,178,229,225,225,177, 72, 16, 4, 66, 8,249, -172,218, 91, 10, 47, 47,175, 75,103,206,156,113,224, 56, 14,223,125,247,157,109,102,102,166,109,175, 94,189, 62, 6, 80,167,209, -170,173,155,176,182,238, 68, 84,171, 58, 84, 40, 20,246,122,125,157,193,147, 39,170, 14,121, 30,190,214, 86,182, 40, 64, 42,116, -142,108,251, 66, 7, 46,255,108,198,148,219,110, 73, 29, 90, 91,240,108, 83,186, 88, 15,119,165, 45, 4, 66,234, 44,141,214,177, -236,175,183,111,222,122,213,203,179, 5,115, 44,244, 34,134, 12, 27, 9,157,142,134,150,165, 64, 49, 82, 80,140, 12,109,219,117, - 64,171, 54,237, 64, 0,220,248,227, 42,167,103,217,179, 47, 82,219,187,118,127,119, 52, 69, 97, 45,136, 64,106, 25, 71,171,233, -176, 97,195,150, 3,120,175, 33, 29,167, 46,239,142,166,233,114,157,234,227,104,125,240,238,116,220,251, 67,106,115,241,230, 74, - 89,255, 46, 56,145, 19, 70, 65,105,246, 87,213,161,148,126,170,161, 57,158, 23,195,213,176,209,242,244,244,180,181, 86,152,253, -248,206,228, 73, 86, 73,119,174, 33, 51, 42, 28, 87, 46,198, 22,236, 59,116, 56, 95,157,151, 61,217, 4,147, 85,213,205,231,224, -210, 4, 62,254, 79, 26, 45, 51, 75, 21, 0,192,199,191, 51, 24, 11,211,134, 17,170, 45,154,213, 24,147, 85,253,128, 93,219, 24, - 90,211,166, 77,195,214,173, 91,209,189,123,119,180,108,217,178,234, 96,111,106,212,172,150,232,146,201,213,134,213, 41, 41, 41, -129,183,183, 55,182,108,217,130,136,136, 8, 88, 89, 89, 97,244,232,209, 40, 41, 41,169, 50, 88,198, 38,195, 19, 66, 30,158, 57, -115,166,211, 27,111,188, 65,164, 82, 41, 85, 88, 88, 8, 91, 91, 91,172, 95,191, 94,157,145,145,113,162, 17, 38,107,164, 76, 38, -155, 51,106,212, 40,198,207,207, 15, 89, 89, 89,176,182,182,102, 41,138,146, 2,128,173,173, 45,107,110,110,142,233,211,167, 35, - 48, 48,176,231,188,121,243,186, 75, 36,146,245,233,233,233, 59,234,219,151, 40,138,170, 58,161, 78, 94, 27, 3,189,190,252, 4, -189, 97,195, 6, 84,228,186,253,213, 69, 16, 23, 7, 24, 81,201, 98,105,105,137,150, 45, 91,214,218,246, 61,123,246,196,141, 27, - 55,202,187, 38, 37, 18, 56, 57, 57,225,202,149, 43, 70, 85, 82, 85, 14, 4, 25, 25, 25, 9,127, 31, 71, 68,132,157,129,163, 82, -138, 64, 55, 23,120,244,236,141,216,216,216,127, 51,154, 69,161, 60, 15,163,111,197, 62,184, 13,192,180,106,207,215, 3,248,222, - 20, 65,142,227, 8, 77,211, 84, 74, 74,138, 65,169, 84, 82,246,246,246, 18,133, 66, 1,157, 78, 87,101,184, 30, 62,124,136,208, -208, 80,164,166,166,194,222,222,158,182,177,177,129,193, 96, 40, 48, 70,223,215,215, 23, 46, 46, 46, 53, 18,223, 39, 79,158,220, - 40,147, 53, 17, 8,216,250,229,138, 38, 10,154,177,241,119,124, 13, 9, 49,143,180,180, 30,102,255, 11, 38, 11, 0, 10, 11, 11, - 55, 3,216, 92,249,220,209,209,241, 45,134, 97, 22,232,116, 58,155, 11, 23, 46,216,170, 84, 42,106,199,142, 29,236,103,159,125, - 86,200, 48, 76, 1, 69, 81,171,255,125,115,136,168,220,162, 56,111,169,157,155,112, 71, 75,174,190,159,242,113,171, 2,105, 11, - 21,213, 38, 0,195,178,163, 47,191,197,197,117,203,202,200,164, 9,132,168,122,142,193,219, 62,158,191,228,195,216,152, 91, 94, -102,214,102,152, 54,125, 62, 78,156, 58, 7,138,150,226,210,213,112,232, 13, 60,114,243,139, 48,106,204, 56,120,184, 58, 34,234, -250,233, 28, 78, 16,214,191, 88, 38, 91, 88,247,234,144,183,236, 20,230,202,138,109,194, 99,215, 15,115, 64,211,107,177,112,225, - 66, 4, 4, 4,204,136,140,140,252, 28, 13,140,163, 69, 81,194,186,182,189,199,216,201, 20,229, 58, 68,224,177,229,192,199, 21, -227,104,205,198,250,205,135,218,182,241, 73, 88, 92,223, 56, 90, 47,144,201,170, 62,175,223,104,121,123,123, 43, 44,164,152, 42, -101, 36,243,222, 25, 59, 84,149, 29,119, 15,169,209,183,202,187, 23, 12, 26, 67,230,131,104, 99,134, 66,239,139,154,227,119,144, -250,186,174,180, 90,163,174,232,107,104, 86,158,112, 31,143,102,153,104,178,158,208,172,110,182,170,143,155,229,233,233,137,229, -203,151, 27, 51,142,214,227,235, 94, 73,127,148, 39,192, 87, 79,134,239,111,164,201,170, 85, 83,165, 82, 6,231,135, 96, 0, 0, - 32, 0, 73, 68, 65, 84, 33, 47,175,124,132,132,224,224, 96, 4, 7,255, 85,207, 96, 48, 24,170,162, 88, 86, 86, 86,181, 69,180, -158,208, 52, 55, 55,255,248,240,225,195,147,174, 94,189,250,198,220,185,115,165,175,188,242, 74,165,153, 43,131,113,247,118,171, -161,201,243,252,244,211,167, 79, 51,130, 32, 96,203,150, 45,184,113,227, 6, 81, 42,149,159, 42,149,202,117,230,230,230,188, 70, -163,153, 54,101,202,148,113,139, 23, 47,166,123,246,236,137,107,215,174,209, 77,155, 54,157, 0,212, 24,196,178,214,117, 15, 15, - 15, 7, 77,211,224,242,147, 49,227,227,125,176, 48,151, 32, 38, 38, 6,249,249,249, 79, 12, 98,106,204,246,172, 30, 41,169,156, -122,246,236, 89,213, 13, 25, 20, 20, 4,134, 97,112,251,246,237,186,186, 97,171,107, 18, 7, 7,135,170,253, 67, 38,147,225,220, -185,115,248,226,139, 47,224,101,111,139,130,232, 8,184, 4,191,140,126,147,166, 96,244,232,209, 96, 24, 6,246,246,246, 85,145, - 95, 35,246,165,167,161,186,230, 36,127,127,255, 9, 81, 81, 81, 30,109,219,182,117,141,140,140,236, 19, 16, 16,224, 29, 17, 17, - 81,249, 92, 1,227,114,115,170, 52,255,252,243,207,131,235,214,173,155, 62,113,226, 68,153, 32, 8,124, 82, 82, 18, 11,128,114, -113,113, 97,254,252,243, 79,225,216,177, 99,208,104, 52,240,240,240,160,221,221,221,169,179,103,207, 10,209,209,209,225,132,144, -249,198,172, 59,207,243, 53,134,113,168,124,252,243,207, 63,155,252,127,111,210,202,119,217, 43,189,252, 60,115,211,111, 35, 35, - 45, 14,124,145,202, 16,122,228,184,206, 68,147,245,119,183,209, 63,169,185,228,193,131, 7,238, 58,157, 14,114,185, 28, 27, 54, -108, 48, 44, 95,190, 60, 42, 55, 55,183, 7,106,175, 40,175,161,217,200,170,195,252,122, 52,159,168, 58, 44,202,195,137, 35, 71, -255,236,100, 57,108, 27,102,164,231, 84, 37, 54, 18,138,178, 63,236,220,186,135,178,115,219, 52,250,228, 34,186,132, 47, 59, 81, -207,186,235, 53,122,253,200, 97,195,199,252,182,119,239, 30,203,207, 22, 45,194,149,240, 8,228, 21,150, 66, 32, 12, 4,138,194, -130, 5,159,193,197,209, 30,197,233, 15,202,116, 6,195, 48,212, 28, 67,235,185,111,119,138,162,103,158, 61,182, 99, 45, 77, 65, - 80,103,221, 87, 48, 37,113,202, 55, 71, 15,147,140, 28, 57, 18,135, 15, 31, 70,100,100,228,166,122, 76, 86,149, 38, 33,244,204, -136, 11,251,214, 82,128,160,201,185,175,144,148, 38, 40, 39,140, 29, 38, 25, 61,122, 52,126, 9,189,138,189,199, 19, 54,238, 61, -142,227,120,177, 49,125,100,120, 43, 9, 34,123,180,110,230,222,179, 67, 27, 51, 9,175, 65,106,116, 28,242,213, 90,156,189,151, - 84, 72, 19,186,209, 99,235,148, 31, 32,101, 72, 78,126, 80,203,149,149, 89,197, 9, 93,107,146, 38, 77,211, 53,162, 89, 79, 19, -201,170,190,156,206,206,206, 53,110,231, 82,253,196, 93,153, 3,212,136,161, 29, 62, 78, 78, 78,182, 78, 78, 78, 6, 33, 4,225, -225,225,214, 65, 65, 65, 31, 63, 77, 52,107,206,156, 57, 85, 81,171,199,231,181,189,214, 16, 21, 73,233,107, 88,150, 61, 48,111, -222,188, 25, 65, 65, 65,175, 46, 90,180,136,130, 9, 55,224,125, 44,154,195, 9,130,128,243,231,207,227,240,225,195,188,193, 96, -152,154,145,145, 17, 81,237, 35,223,221,188,121,243,236,240,225,195,119,220,191,127,159,137,138,138, 2, 33, 13,215,157,106, 52, - 26,180,108,217, 18, 28,199, 97,229, 12, 79,148,148,180, 5,199,113,224,121, 30, 22, 22, 22, 85, 81,188,234,230,185,161,253,136, -231,249, 39,140, 86,120,120, 56, 24,134, 65,143, 30, 61,112,235,214,173,170,136, 86, 67, 17, 40,131,193,144,236,236,236,236,188, -100,201,146,170,229,202,201,201,193,153, 51,103,208,165,107, 55,180,158, 58, 13,233,233,233, 88,189,122, 53,220,220,220,176,108, -217, 50,228,231,231,131,227,184,127, 58,156, 62, 32, 42, 42,202, 99,236,216,177,217, 17, 17, 17, 30,161,161,161,182, 33, 33, 33, - 22, 99,198,140,201,142,136,136,240,160, 40,170, 27, 76, 76,130, 22, 4,225,147, 5, 11, 22,156, 90,182,108,217,199,239,189,247, - 94,208,196,137, 19,165, 82,169, 84, 72, 75, 75,227,246,236,217, 67,181,108,217,146,150,201,100,212,233,211,167,133, 63,254,248, -227, 58,199,113, 43, 1, 92, 50, 37,226, 92,221,100, 49, 12, 99,172,201,170,193,251, 78,138, 9, 86,116, 78,143,117, 27,150,211, -126, 62, 30,134,157,123,206,164, 92,186,246, 32,158,209,113,239,255, 88,207,208, 0, 47, 50, 12,195,236,247,247,247,127,107,230, -204,153,230,253,251,247, 87, 44, 94,188,184,168,164,164,164, 46,147, 85,203, 5,243, 63, 82,117,248,195, 39,115, 67,223,255,160, -237, 91,205,254,227,210, 4, 97,234,108, 20, 72, 24,218,218,150, 70, 7,111, 6, 37,185, 15, 85,199,127,219,254, 8, 64, 67,227, -178,253,121,243,110,100,223, 54,109,219, 31, 90,185,108,165,211,167, 31,205,147, 30, 10,253, 21,132, 51, 32,252,194, 5, 88,202, -120, 18,125, 51, 44, 75,103,208, 15,197, 11,120, 11,158,140, 43,223,239, 5,112,212,222,222,254,206,164,137, 19, 91,250,251,143, -129, 82,169,196,193,131, 7,177,235,187,239,248, 53,192, 27, 10,224,214,244, 6,198,211,203,190, 94,165,115,123,202,164, 73,190, - 29, 58,252, 7, 74,165, 18, 7, 14, 28,192,142, 53,107,140,214,121,206,169, 28, 25,254, 4,254, 26, 33,190,129, 28, 45,154, 42, -185,254, 32,169, 52,252, 65, 82, 41, 4, 66, 4, 66,116, 52,141, 20,181,193,176,236, 65, 66, 90,163, 76, 65,101,215,225,210, 47, -103, 62,187, 62,143,106,230,167,177, 37,221,181,152,172,212,234,247, 72,171,126,146,174,235, 49,203,178,169, 70,202,175,240,242, -242,122,226,181,198,135,126,137, 73, 38,203,216,113,180, 0, 32, 47, 47, 47, 3,192,167,215,174, 93,251,249,213, 87, 95,157, 2, - 32,173,145,109,180,165,119,239,222, 83, 1, 48, 20, 69,109, 74, 79, 79,143,120,226, 15,159,145, 17,235,230,230,246,181,143,143, -207,180,242, 11, 83,106, 75, 3, 39,242,132,182,109,219, 26,106,107,139,186,158, 11,130,208, 96, 27, 21, 22, 22,162,115,231,206, - 79,220,211,146, 16,130,164,164,164,202,136, 83,213,182,175,207,192,149,150,150, 78,123,247,221,119, 55, 75,165, 82, 47, 0, 84, -165,201,229,121,158,249,254,251,239,205,120,158,103, 0, 80, 52, 77,115, 82,169, 84,123,248,240, 97,142,227,184,100,157, 78, 55, -237, 31, 62, 64, 28,160,202,111,197,160,142,138,138,242,171,136,100,165, 70, 70, 70,222,222,187,119,175, 10,192,190, 70,234, 94, - 42, 43, 43,187,180,124,249,242,158, 27, 54,108,248,100,218,180,105,157, 71,143, 30, 45, 9, 14, 14,198,137, 19, 39,248,243,231, -207,135,107, 52,154, 21,166, 24,172,138,182, 44,242,244,244,172, 50, 92, 13,252,151,235, 77,228,117,240, 86,172, 27,247,182,155, -217,150, 21,103, 74,115,211,245, 87,217, 82,253,252,237, 64, 36,254,135,201,202,202,154, 11,224,179,213,171, 87,167, 7, 6, 6, - 42,100, 50,153,222, 88,147,245, 15,194, 9,133,165, 3,191,237, 55,226,104,239, 5,239,250,244,235,211, 67,233,217,196,201, 61, - 58, 46, 11, 15,175,157, 80,223, 57,254,101, 34,209, 21, 12, 1, 96, 76,230,250, 31, 58,131,161,197,156,121,115,102,200,165,210, - 87,121,158,111,247,202,217, 35,132, 97,152, 8, 61,203,158,173,232, 46,212,190,192, 77,190,244,235,175,191,110,233,239,239,143, -131, 7, 15,226,236,238,221, 24,149,155,139,115, 12,195,208, 50,153,195,113,131,225, 27, 24,103,144,150,174, 90,181,202, 55, 32, - 32, 0,251,247,239,199,233, 29, 59,240,255,236, 93,103, 88, 20,201,218, 61, 61, 57,146, 36, 11,136, 24,128, 69, 49, 98, 90,113, - 49, 99,118,205,113,205, 57,103, 92,117, 13,107, 14,107, 90,149, 85,215,128, 57,187, 98, 22,179,152, 5, 65, 17, 84, 50,195,144, -135, 48,121,166,167,251,251, 65,184,168,132, 1,221,187,247,126,119,206,243,244, 51, 51, 29,206, 84, 87, 85, 87,157,126,171,234, -125, 7, 87,143,167,188,190,174, 5, 0,219,162,159, 89, 0,162, 1, 52, 7, 32, 0,160, 65, 97,104, 39,155,210, 93, 88,209,177, -226,227,247, 9,130,248, 59, 39,194, 86,238, 25,254,115, 68,126, 72,104,254,173, 83,161, 82,169,114,220,221,221,171,180,230, 90, -175,215, 87, 56,134, 75,146,100, 74,221,186,117,141,182, 90, 24, 35,138,114,114,114,124,254,198,194,248,170,185, 88,159,116, 34, - 20,149,224,232,232, 72, 21,119,250,101,137,176,178,246,209, 64,124, 85,254, 39, 45, 45, 45, 26,192,220,234,166, 51, 53, 53,245, - 44,140, 8, 26,109,236,121, 0, 32,147,201,190,121, 48, 95,130,166, 37, 43, 86,172,168,146,192, 6, 77, 87, 36, 62, 35,228,114, -121, 43, 99,254, 91,167,211,225, 31,196,169,162,141, 17, 25, 25, 57,129, 32, 8,127, 20, 14, 9, 4,226,219,120,243,126,144,159, -159,255, 96,227,198,141,237,246,238,221, 59,155,166,105,228,231,231,111,171,170,192, 42,121,123,206,200,184,252,173,110, 60, 39, - 93,123,251,120, 96, 74, 71, 85,174,110,246, 62,185,246, 48, 76, 40, 49, 70,209, 52,125,112,228,200,145,173, 1, 28,250, 90,178, -114, 86, 29,126, 45,226, 41, 89, 94,147, 59,243,126, 29,123,199,210,172, 39, 12, 44, 79,104, 25,151,160,205,190, 12,224, 0,140, -155,230, 80,114,191, 36, 69,109, 33,181,218, 45,165, 58,151,255,133,114,174,225,237,237, 61,123,204,152, 49, 88,182,108, 25,174, -111,222,172,155, 66, 16,121,108,128,190, 86,248,162,201, 32,128, 69,198,242,140, 26, 53, 10,203,150, 45,195,149, 13, 27,170,203, - 83, 17,108, 9,130, 8, 6,128,128,128,128,159,215,173, 91,103,181,120,241,226,198,235,215,175, 95, 91,244,251, 77,241,241,162, -190,174,215,226,197,139, 27,150, 58, 94, 0,224,249,223,156,159,101,122,134,255,187,209,217,196,105,226, 52,113,154, 56, 77,156, - 38, 78, 19,167,137,243,107, 64,211,116,207,194,143,242, 63,203,251, 94,234,243, 31, 1, 11, 38,152, 96,130, 9, 38,152, 96,130, - 9,255,133, 40,109,197,170,206,241,111,136,226, 57, 90,165,177, 23, 40, 92,214, 93,158, 42,173,202,170,135,234, 40,219, 91, 38, - 78, 19,167,137,211,196,105,226, 52,113,154, 56,255,231, 56, 43,227,254,226,122,154,166,123, 18, 4, 17, 76,211,116,175,242, 62, -139,133,213,231,223, 75,125,126,179,105, 7,101,160,120,110,214, 23,115,180,254,110,152,204,170, 38, 78, 19,167,137,211,196,105, -226, 52,113,154, 56,191, 10,197, 67,128, 0,232,128,128,128,197,255,129, 67,135,142, 69, 34,171,244, 6,160,130,161, 67,154, 62, -205,148, 72, 96,206,229, 10, 57, 0,160,213, 42,117, 78, 78,200, 39,136, 65,255,100,192, 91, 19,254, 59, 81,188,220, 59,253, 27, -159,107,130, 9, 38,152, 96,194,255, 6, 50,139, 45, 85, 0, 50, 1, 16, 69,191,181, 69,159,153, 69,130,236,243,239,159, 28,255, - 27, 33, 69, 57,150, 44, 86,121, 34, 43, 43, 75,104,195, 98,201, 60, 12, 6,245,119, 0,192, 98, 49,222,101,101, 89,197,208,244, -233,172,234,136, 45, 27, 59,187,151,108, 38,211,201,152,115,245, 6,131, 36, 43, 61,253, 83,215,241, 4,241,255, 65,224, 25, 43, - 34,190, 70,108,252,237, 66,197,198,198,198,222,222,222,190,143,185,185,121,155,220,220,220,103,153,153,153,231, 43,136,123,184, -142, 32,176,176,176, 94, 97, 35,128,197, 21, 80, 87,229,220,207,225, 46, 20, 10,167, 18, 4,225, 93,244,128, 69, 42,149,202,221, - 0,222,255, 15, 54, 72, 2, 0, 63,178, 88,172, 81, 54, 54, 54, 45,211,210,210, 86, 0,168,174, 55,111, 22,128,121,150,150,150, - 67, 44, 45, 45,235,230,228,228,196,230,231,231,159, 2,176, 5, 64,165, 75,165, 87,204,116,108,211,222,191,253,210,187,215,239, -174, 94,177, 67,250,248,139,227,243, 28,173,187,118,105,187,236,238,165,208, 85, 63,239, 74,205,169, 98,218, 24, 69, 27, 80,184, - 58,146,198,151,206, 94,191, 22,108, 0,189, 1,180, 7,112, 23,192, 37, 99,238,187, 28,180, 6,240,115, 81,154,183, 0,184,243, - 31, 94,143, 68,246,246,246, 27, 0,244,102,177, 88,111, 37, 18,201, 68, 0, 41,255,112,154, 88, 0, 90, 0,240, 70,161, 27,142, -231, 48,206,133, 67,165,176,182,182,238,197, 98,177,166, 22,185,118,217,157,157,157, 29,252,159, 90, 48, 92, 46,119,155,131,131, -195,120,149, 74,165, 36, 8,130, 46,237,239,145, 36,201,148,172,172, 44,159,255,111,141, 26, 65, 16,207,255,195,147, 56,177,140, -125,229,251,209,146, 72, 96,206, 98,201, 60, 50,210, 34,134,164, 74, 95, 15, 6,128,154,142,141, 79,217, 57, 52, 58, 41,145,112, -117, 14,158,253,196,108, 33,107, 55,147,201,110,170,214,106,108,216, 44,118,150,142,212,135, 49,180,244,212,180,232,243,101, 58, - 91,100, 51,153, 78, 9, 49,119,236, 72, 93, 14,216,252,154, 96, 11,106,149,155,218,154, 53,107, 86,235, 46,173,172,234,154,233, -120,252,217,108, 54,179, 11, 69,147,222, 52, 5, 48, 8,118, 36,105,208,135,112, 52,154,223,100,178,216,130,234,230,160,167, 53, - 28,104, 96, 40, 8,116, 1,141,155, 4,112, 34, 58, 27,105, 85,160, 48, 86, 68,124,141,216, 40,125,237, 86, 0,243,191,117, 77, -114,114,114,178,234,213,171,215,182, 95,127,253, 85, 32, 22,139,137,164,164, 36,255, 69,139, 22,253,240,226,197,139,185, 18,137, - 36,245,115,209, 71, 16, 88, 72, 81, 52, 3, 0, 24, 12, 98,145,173,173,157,144,201,100,126,225,219,200, 96, 48, 8, 51, 51, 51, -166, 83, 20, 77, 20,157,187,144,166,177,221, 24,193,200,231,243,135,121, 55,106, 58,119,195,166, 45, 98,123, 59, 59, 17,105,160, -116,241,137, 9,194,165, 1,243, 91,125,252,240,126,187, 90,173, 62, 94,157,231,154,201,100, 14,225,241,120,189, 0,120, 21,237, -139,210,104, 52,193, 6,131,225,164,177, 29,186,189,189,253,125, 38,147, 89,187, 42,127,108, 48, 24,146,210,211,211,125,171, 89, - 68,131,106,213,170,117,192,207,207, 79,216,178,101, 75,112,185, 92, 44, 91,182,108,158, 84, 42,173, 76,104,177, 0,204, 19, 10, -133, 67, 68, 34, 81, 93,185, 92,254, 81,165, 82,157,229,114,185,157,183,111,223,238,210,182,109, 91,179,244,244,116,130,201,100, -218, 95,185,114,229,167,109,219,182,249,147, 36,217,169,178, 78, 46,239, 35,189,148,215,219,171, 93,222,199, 59, 75, 1,116,255, -252, 56,169,230,143,162,153, 46,189, 84,244,171,228, 34,241, 97,180,200, 98,179,217,219, 29, 28, 28,198,168, 11,125, 5,208,159, -119, 56, 0,160,213,106,101,185,185,185,158,213,121,228, 1,140,179,180,180, 28,179, 96,193, 2,171,238,221,187,227,232,209,163, -211,246,237,219, 39,203,207,207, 63,136, 66, 71,152,209, 85,228, 92,152,150,150,214,131,205,102, 19, 46, 46, 46, 76,149, 74, 85, - 21,161,229,129,194, 32,204,207, 1,236, 70,161,235,130, 14, 64,225,243, 14, 96, 99,177,112, 99, 48, 24,187, 61, 61, 61,251, 68, - 69, 69,237, 1,176,186,186,207,186,131,131,195, 31,187,118,237, 26,220,183,111, 95,102,102,102,166, 83,147, 38, 77,142,165,165, -165,181,251, 6,205,200, 88, 30,143, 55,167,113,227,198, 13,162,163,163, 99,242,243,243,183, 20,229,103, 69,207,148, 51,128,206, -150,150,150,157,150, 44, 89, 34,238,213,171, 23,246,238,221,219, 99,223,190,125,242,130,130,130, 16, 20,206,233,249, 42, 17,200, - 98,177,166,166,164,164,216,208, 52, 13, 71, 71,199,169, 0,254, 35,133, 22,131,193,216,222,191,127,255, 49,199,142, 29, 19, 38, - 36, 36, 8,157,156,156, 74,156,103, 19, 4, 81,237,254,211,132,175,198,222, 82,130,171,114, 63, 90, 92,174,144, 99, 48,168,191, - 75,149,190, 30,252,131,223, 78, 11, 0,184,127,111,198, 96, 59,135,134,145, 92,174, 48,134,103,206, 63,215,191,119,231,166, 3, -123,249, 17,206,142,118, 72,145,102,216,255,121,226,122,183,224,235,119,206,161,208,129, 88,153, 32,117, 57, 16,232,110, 33,250, -225, 14,216,180, 79,197,239, 87, 82,240, 56, 60, 30,202,188, 44,212,118, 16, 96,211,236,174,112,176, 18, 86,239,213,203,206,189, - 3,201,226,157, 28, 62,108,164, 69,159, 31,189,216,174, 14, 14,160,105, 30, 98, 62,202,191,191,122,227, 78,139,179,167,143, 79, - 21,177,221,135, 40, 50,222, 27,221,184, 53,115,132, 64,161,195,143, 44, 38,241, 83, 91,159, 6,157,134,245,104,199,104,224, 85, - 31,111,223, 68,117,189,120,251,233, 38, 70,232,155, 16,210, 64, 7,137, 56,184,240, 74, 90,161, 67,191, 47, 4, 71,167, 78,157, -219,241,120,188, 79,156, 39,105, 52, 26, 78, 72,200,173,214,213, 17, 27,197,255,161,213,106, 24,108, 54, 23, 12, 6, 49,215,219, -187,145, 87, 86, 86,214, 29,130, 32, 14,164,166, 86,205, 90, 48, 3,224,202, 88,172,230, 12, 30,207,209,160,213, 90, 3, 0,193, -229,202,226, 25,140, 70, 75,126,254, 89,204,100, 50,169,236,236,108, 40,149, 74, 98,194,132, 9,252,143, 31, 63,246,151, 72, 36, - 59, 42,121, 35,193,190,125,251, 60, 28, 29, 29,191,136, 30, 43,149, 74,185,125,251,246,169, 78,209,123, 52,110,210,108,206,245, -235,215,188,242,115,100,234,125, 91,255,120,169,231, 11, 53,117,188, 60,217,187,247, 30,182,152, 56,102,196,140,119,239,222,132, -161,106,241,234,106, 9, 4,130,115,155, 55,111,246,238,208,161, 3,219,206,206, 14,233,233,233,136,138,138,242,190,125,251,246, -143,135, 15, 31,158,167, 82,169,250, 3, 70, 5, 68,117, 15, 9, 58, 96, 39,170, 97, 13,131, 94,143,154,141,155,149,248, 55,251, -112,251, 6, 72,157, 14,148, 94, 15,175, 94, 63, 22, 89,147,105,120,121,121, 85,215,235,110,205,134, 13, 27, 30, 89,187,118, 45, - 71,163,209,224,233,211,167,184,115,231, 14, 37,149, 74, 43,115,136,203, 34, 8,226,198,242,229,203,157,125,125,125,205,178,178, -178, 96, 48, 24,108, 46, 92,184, 48,181,105,211,166,230, 46, 46, 46,220,160,160, 32,200,229,114,144, 36, 89,163,110,221,186, 53, -134, 13, 27,166, 13, 10, 10,154, 7, 96, 67,121,150,172,252,143,244, 82, 41, 81,183,155,103,243, 81, 72, 35,174,117,155,211, 13, - 87,205,235, 17, 37,150,173,110,117,235,154,229, 75,132,139,196,230,141,106,228, 75,110, 45,234, 86,183,238,190,107,177, 70,189, - 12, 49,138, 58,155,225, 39, 78,156, 16, 70, 69, 69, 9,189,188,188, 64, 81, 84,137, 7,254, 98,135,179,238,238,238,213,201,199, -245,147, 39, 79, 94, 52,120,240, 96, 52,110,220,184,196, 41,234, 47,191,252,130, 69,139, 22, 89,221,191,127,127,222,241,227,199, -231,157, 63,127,126, 3,128,128, 42, 90, 99,138, 81,213, 50, 94, 25, 23, 23, 55,232,220,185,115, 35, 22, 46, 92,232, 14, 96, 58, -128,101,217,217,217,126, 69,214, 24,110,145,208, 26, 59,111,222,188, 41, 1, 1, 1,232,209,163,199,178,167, 79,159,174,169,166, -149,143, 73,146,100,143,190,125,251, 50,245,122, 61, 68, 34, 17,244,122,125,189,175, 53, 74, 0,216, 53,105,210,164, 41,147, 39, - 79,134,149,149, 21,244,122,189,199,137, 19, 39,246, 45, 91,182,172, 13,128,113,229,164,117,212,148, 41, 83, 6,140, 28, 57, 18, - 62, 62, 62, 96,177, 10,179,113,243,230,205, 88,181,106,149,248,198,141, 27, 63, 6, 5, 5,253,120,241,226,197,179,248, 52,108, - 87,149, 64, 81, 20, 88, 44, 22,146,147,147, 97,103,103,199,163, 40,234, 58, 65, 16,123,115,114,114,206,255, 7,117,230, 27, 7, - 13, 26, 52,252,216,177, 99, 98, 0,216,180,105, 19,230,204,153, 3,123,123,123,136,197, 98,147,212,249,207,177,104, 77,172,212, -162, 85, 25,148, 74,101,179,197, 51,127, 2,131, 81,248,214, 88,191, 78, 45,172,251,121, 34,113, 49,248,122,179, 10,109,240,252, -154,136,126,184, 3, 60,151,217,208,232, 73, 60, 9,143,195,205, 77,254,133,189,101,247, 37,208,232, 58, 21,119, 54, 53,184, 2, -193, 70,173,193,240, 8, 14, 14, 79,145,152,152, 89,153,200,178,117,176, 15, 14, 12,220, 32,240,174,231, 9, 29,169,135, 36, 67, - 2,130,224,193,217,201, 12, 99, 71,117,103,251,249,213,180, 89,185,242,143,203,105, 20,250, 41,179,222, 87,234, 48,212,195, 6, -135,154,121,187, 15, 30,214,211,151,215,200,187, 33, 56, 60, 65,201,177,230, 62, 62,104,238,227,195, 8,144, 23,116,121,246,252, -101,151, 51, 55,158,104,148,250,196, 83, 49, 89, 24, 93, 73, 35, 83, 34, 56,102,205,154, 5,123,123,251, 79, 78, 72, 79, 79,199, -237,219, 33,101, 94, 83,133,134,172,228, 63,214,172, 89, 99, 38,147,201,186,239,223,191,191, 35, 69, 81,107,210,210,210, 30, 26, - 67, 50, 18,168,157,199,227,117, 26,179,101, 11,213,180, 79, 31,166,165,131, 3,131, 50, 24,136,212,216, 88,235,173, 59,118,180, -207,249,240, 65,160,168, 81, 35, 71,166, 82, 41, 99, 98, 98,192,231,243, 9, 22,139,213,162, 12,170,116,154,198, 70, 6,131, 88, - 68, 16, 4,120, 60,126,204,228,201,147, 95, 21, 29,171,125,233,210, 37, 97,239,222,189,149, 0, 18, 0,128,199,227, 59, 49,153, - 12,143, 66, 79,236,216,104,140,192, 20,137, 68, 51, 87,175,221, 32,202,207,201, 85,233, 20, 10,189,173,185,152, 32,196,102,204, -252,188,130, 2,137, 52, 83,179,100,197, 42,230,164,177, 35,103, 42, 20,138,169,198,138,172, 38, 77,154, 60, 59,119,238,156,157, -181,181, 53,114,115,115,145,157,157,141,103,207,158,129,162, 40,244,239,223,159,247,125,171,150,205,126, 94,178,244,113,178, 68, -210,198, 24,177, 37,170, 97,131, 77,190, 77, 11, 59,235,132,236,146,242,217, 59,168, 87,201, 57,171, 82,242,138,173,115, 95, 19, - 66,170, 77,167, 78,157, 56, 0, 48,110,220,184,252,130,130,130,117, 0,142,161,114,143,254,243,150, 46, 93,234, 84,167, 78, 29, -215, 99,199,142, 65, 46,151, 3,128, 93,157, 58,117,224,225,225, 97,184,123,247, 46, 60, 60, 60, 96,102,102,134,251,247,239,227, -241,227,199,240,241,241, 49,227,112, 56,131,117, 58, 93,153, 66,171,189,127,251,165,188,222, 94,237, 60,155,143,130,216,220, 17, -251,142,159, 68,244,203,195,237, 52,186,168,165, 28,195,189,145, 42,154, 55, 58, 51, 73, 28, 80,219,199,207,186,126,195, 62,112, -109,254,202, 70,109,120, 16,183,180, 75,157,245, 44,190,250,240,138, 45,210,236,242, 68, 22,128, 77,253,251,247, 31,116,226,196, - 9, 75, 0,136,136,136, 64,122,122, 58,108,109,109,193,231,243,193,102,179, 75,226,147, 86, 19,163,119,239,222, 93, 34,218, 72, -146, 44,137, 2, 32, 20, 10,241,195, 15, 63,160,105,211,166, 56,127,254,252,232,114,132,150,111,171, 86,173,142,186,186,186,186, -148,222,169, 80, 40, 48,116,232, 80, 0,128,159,159, 95, 39,129, 64, 64, 23, 11, 66,169, 84, 42,127,254,252,121, 23, 0, 79,203, - 81,150, 42,137, 68,130, 5, 11, 22, 32, 62, 62,126, 90, 96, 96, 96, 34, 0, 62,151,203, 45,121, 63, 6,224,209,176, 97,195,237, -115,230,204,193,199,143, 31,241,246,237,219,103,168,254, 80,170, 65, 36, 18,125,208,235,245, 62, 36, 73, 66,165, 82,161, 95,191, -126,252,179,103,207,166, 51,153,204,119, 89, 89, 89, 35, 80, 56, 39,197, 88,240, 1,108,153, 60,121,242,148,133, 11, 23, 34, 36, - 36, 4, 23, 47, 94,196,200,145, 35, 49,123,246,108,136,197,226, 49,179,103,207,126,140,194,128,230,159,163,211,238,221,187, 97, - 48, 24,190,120, 54,248,124, 62,124,125,125,209,160, 65, 3, 92,188,120,177,211, 87, 8, 45, 87, 95, 95, 95, 46, 69, 81, 80, 40, - 20,184,123,247,174, 88, 32, 16,136,157,157,157, 39, 0,248,143, 17, 90,174,174,174,147, 79,156, 56, 33, 46, 61,250,195,227,241, - 80,170, 30,152,240,207, 91,180, 42,124,195, 42,129, 86,171,212,177, 88,140,119, 53, 29, 27,159,186,127,111, 70,201,208, 33,192, -120,167,213, 42,117, 0, 96,160,104,228, 43, 73, 8,120, 12, 36,164, 21,224, 77,108, 86, 89, 84,159, 44,209,100, 11,106,129,215, - 50, 1, 52, 77, 67,171, 51, 64,147,151,134,117,151,149,136, 74, 81, 67,171,144, 65,171, 43,156,134,101, 99, 99,195,186,126,253, -234,156, 91,183,110, 79, 57,120,240, 32, 51,197,194,226,109, 1,208,172, 44, 78, 43,171,186,102, 20,151,123,106, 79,224, 50, 1, -205,140, 69, 76,146, 2,245,157, 91,194,198,210, 5,105, 89, 10, 60,122,123, 5,239,222, 7,163,142,163, 43,102,207,236,198, 95, -189,246,216, 73, 14,233, 86, 43, 55, 55, 62,191,188,116, 22,191, 69,253,113, 45, 6,100, 78, 44, 12,217, 31, 97, 40, 72,253,226, - 4,177,109, 45, 52,239,224, 4, 91,151,122,188,209,179, 87,141, 2, 62, 17, 90,165, 57,211, 9,130,177,135,193, 32,166, 16, 4, -129,198,141,155,164,108,217,178,165, 44, 87,224,186,198,141,155,164, 48,153, 12,231,194,134,157,177,155,166,169,244, 74,210,249, -137,168,225,114,121, 11, 11,205,254,142,201,151, 47, 95,214, 13, 26, 52, 8,155, 55,111,230, 46, 90,180,104, 9,147,201, 28, 87, -198,240,222, 39,156,253,128, 90,150,245,234,117, 93,243,232, 17,205,214,235,137,156,103,207,242,115,165, 82, 50,173,160,128,123, -250,221,187, 30,227,231,207,231,186,184,184,224, 97,112,176,117,166, 66, 65,231,106, 52,170,220,220, 92,154, 36,201,103,229,112, - 46,182,181,181, 19,238,219,183,207, 99,242,228,201,175,164, 82,233, 98, 0,112,116,116, 92, 7,160, 1,128,132, 82,251, 16, 24, -120, 82, 50, 97,194,132,152,140,140,140,197, 21,165,179, 20, 26,218,217,218, 9,143,255, 17,244,186,134,153,128, 97,235, 92,147, -193,182,180,100,145, 92, 1,135, 2, 84,117, 92,234,137, 0, 52, 44,231,218,207, 57, 9,129, 64,112,238,175,191,254,178, 99,179, -217, 48, 24, 12,176,181,181, 69,124,124, 60,114,115,115, 81, 80, 80,128,184,119, 81,112,115,113,193,202,128, 69,142,211, 23, 5, -156, 83, 42,149, 62,159,117,102, 95, 6, 64,214,235,190,176,236,149, 21,197,224,243, 97, 47, 35,203,189, 52,226,147,146,146, 32, - 22,139,225,237,237, 45,126,244,232,209,131, 10, 68, 86,233, 32,192,131,219,182,109,107,118,236,216, 49,248,248,248,192,194,194, - 2,119,239,222, 69, 68, 68, 4,116, 58, 29, 67, 46,151, 67, 44, 22, 99,253,250,245,168, 85,171, 22, 10, 10, 10,144,144,144, 96, -205,102,179,109, 62,243,104, 95,194,121,247,250,221,213,121, 31,239, 44, 77, 35,174,117,219,119,252, 36, 38, 12, 27, 2, 7, 58, -246,129, 69, 61, 98,117,215,222,109,127,161,153, 46,189, 68,102,141,173,220,189,123,131,195, 21, 99,250,194, 85,136,137,188,100, -165, 44,120, 61,141, 48, 36,187,172,216,114,122, 86, 25,247, 78, 0, 96,184,184,184,140, 63,125,250,180, 89,137,233,133,201, 44, -137,121, 88, 58, 8,124, 5, 1,223, 43,205, 79,130, 32, 16, 31, 31, 15, 59, 59, 59,136,197,226,146, 0,226, 81, 81, 81,120,242, -228, 9,138,163, 81,148,195, 57,226,214,173, 91, 46, 34,145,232,147, 19,104,154, 70, 86, 86, 22, 72,146,132, 80, 40,132,193, 96, -128, 78,167,131, 94,175,135, 90,173, 22, 55,104,208, 96,170, 94,175,127, 90, 22, 39, 69, 81,115, 7, 15, 30,220,246,233,211,167, -117,119,236,216, 1,173, 86,187, 41, 45, 45, 13, 3, 6, 12, 0, 69, 81,232,212,169, 83,107,154,166,163,151, 44, 89, 2, 0,152, - 51,103,142, 94,161, 80, 76,174,206,189, 23,161, 65,243,230,205,235,134,132,132,160, 93,187,118,208,104, 52,216,188,121,179,121, - 96, 96,160,121, 80, 80,144,237,194,133, 11, 15,100,102,102,250, 87,194, 73, 0,216,228,224,224, 48,165,125,251,246,130,162, 24, -166, 56,124,248, 48, 86,174, 92,121, 2,192,146,171, 87,175, 46,191,120,241,226,168,241,227,199, 99,229,202,149,179,115,115,115, -247,151,199, 25, 23, 23, 7, 91, 91, 91,152,155,155, 23, 54,150, 58, 29,194,194,194,112,243,230, 77,124,247,221,119,198,220, 83, -121,233,116,237,223,191,255,129,227,199,143,155, 37, 39, 39,227,254,253,251,112,115,115,131, 82,169, 52, 38, 54,236,173,191,161, -195, 46,151, 83,165, 82,169,147,146,146,196, 27, 54,108,128,163,163, 35, 92, 93, 93,193,231,243, 65, 16, 4,244,122,125, 69,225, -213, 42, 77,167,159, 31, 88, 89, 18,171,190, 22,150, 86,211,104,154,102,229,229,201,254,208, 33,247, 76,108, 44,180,255,198,123, -255,111, 70, 51, 0,175,240,105,204, 67,105,137,208, 10, 14, 14,166,123,245,234, 69, 20,127, 58, 57, 33, 63, 43,203, 42,198,206, -161,209, 73, 59,135,134, 69,113,191, 24,239,152, 76,171, 24,123,123,101, 62, 0,232, 72, 26,161,239,114,241,250, 67, 26, 34, 62, -164, 65,196, 51,206,248,162,209,145,133, 51, 86,105, 26,106,249,191, 94, 90,117, 74, 25, 52,186,194,233, 30, 90,141, 18,121,153, -111,137, 65,253,186,240,167, 76,153, 4, 71, 71, 39,219,242,248,116, 60,254,236,233,115,122, 88,214,176,100, 35,248,209, 53,180, -254,174, 31,248, 60, 54,178,243,212, 0, 1,188,143,189, 9, 80,102,136,140, 73, 66,171,134, 66,248,119,245, 18,159, 63, 19, 61, - 31,192, 50, 99,210, 75,166, 60, 3,199,189, 59,216, 6, 61,244, 89,209,160,114, 19, 1,145, 3, 84,132, 24,217,210, 68,188,123, -112,214,168,119, 70,138,162,166,217,216,216,228, 46, 89,178,164,125,253,250,245,117, 83,167, 78, 13, 79, 76, 76,156,251,217,219, -202,111,187,119,239,198,135, 15, 31, 36,107,214,172,185,155,149,149,181,180,138, 5, 29, 64,211,216, 86, 52, 20,151,117,225,194, -133,230,247,238,221,155,189,109,219, 54,251, 25, 51,102,112,103,204,152, 49, 22,192,175, 21, 13, 23,230,243,120,157,215,220,191, - 79,147, 41, 41,154, 35, 59,119,114,119,133,134, 46,209, 81, 84, 77, 27, 59, 59,226,251, 86,173, 20, 66, 6, 35, 43, 59, 61,157, -180,173, 91,151, 25,127,243,166, 53, 45, 16,164, 94,189,122, 53, 95, 46,151,151, 27, 58,135,201,100, 42,203, 26, 46, 44, 11,142, -142,142,218,178,230,112, 85,208, 33,230, 83, 52,173,179,172, 83,135,238,218,169, 77,253, 15,209,177,177,124, 75, 75,166,123,125, - 55,207, 55,239,226,159,209, 6,131,154, 32,136,124,163,198, 74,152,204, 33,219,182,109,107,100,110,110, 14,138,162, 96, 97, 97, -129,204,204, 76,104,181, 90,228,231,231, 67, 91,144, 7,109, 94, 30, 34, 18,227,209,182,125,123, 12,234,214,213, 43,232,194, 95, - 67, 12, 6,195,137, 10,199,243, 26, 55, 43,177,100,173,170,109,253,175,177,160,228,220, 18,209,181,161,153, 59, 56, 98, 49,186, -204, 13,248,154, 7,253,213,229,203,151,175,244,239,223,191,199,252,249,243, 25, 82,169,244, 90,124,124,124, 91, 0,111, 43,186, - 72, 44, 22,215,203,202,202,130, 92, 46,135,133,133, 5,182,109,219, 6,123,123,123, 40,149, 74, 60,127,254,156,118,118,118, 38, -238,222,189, 11,103,103,103,100,103,103, 67,167,211, 65,165, 82,165,105,181,218,114,135,203,139,134, 7,187,207,233,134,171,209, - 47, 15,183,115, 34,226,158, 15,158,231,247, 33, 58,226, 93,210,141,155,143,126, 37,213,252,228,220,148, 91,139,234,180,120,101, - 51,109,193, 74,252,190,105, 57,162,159,222,207,177,175,149,191, 75, 64,104, 14, 85,148, 94,133, 66,161,126,247,238,157, 89,120, -120, 56, 8,130,128,133,133, 5,132, 66, 97,153, 98,171, 26, 96,148,182, 64, 41, 20, 10,112, 56, 28, 88, 91, 91, 99,255,254,253, - 37, 29,175,155,155, 91, 69, 28,127,116,233,210,101, 72,173, 90,181,204, 74,239,108,209,162, 5, 38, 77,154,132, 61,123,246, 32, - 52, 52,244,147,120,154,105,105,105, 82,189, 94, 95,209,125,231,166,167,167,119,235,215,175,223,203, 7, 15, 30,152,239,223,191, - 31, 36, 73,150,185,237,219,183, 15, 79,158, 60, 89, 6,224, 93, 53,235,209,119, 3, 6, 12,184,127,244,232, 81,203,204,204, 76, - 20,215, 13,133, 66, 1,131,193, 0, 79, 79, 79,130, 36,201,202,230,189, 49,152, 76,230,133,157, 59,119,246,158, 48, 97, 2, 88, - 44, 22,180, 90, 45,118,238,220,137, 69,139, 22,165, 23,189,148,234, 0, 44, 57,116,232,208,168, 62,125,250,160, 73,147, 38, 94, -119,238,148, 63,179, 67, 46,151, 67, 46,151,131,205,102,195,193,193, 1,171, 87,175,134, 86, 91,216,172,120,120,120,148, 60,198, - 0,254,240,240,240,232, 29, 19, 19,179, 25,133,115,215,190,128,131,131, 67, 63,154,166, 39, 26, 12,134,130,118,237,218, 89, 31, - 63,126,220, 76, 34,145,224,229,203,151, 88,182,108,153,140,162, 40, 3, 69, 81,132, 74,165,138,179,179,179,123,201,227,241, 4, - 74,165, 50, 39, 59, 59,123, 45,128,107,255, 84, 79, 78, 16, 4,193,102,179, 49,110,220, 56,176, 88, 44, 8, 4, 2,168,213,106, -232,245,250, 18, 49,143, 42, 14, 75,215,175, 47,182,102,129, 51,193,202,172,193,236, 65,179,122,217, 58,214,116,130,165, 57, 15, - 81, 81,111,219,222, 14,185,185,147,203,138, 14,164,180,250,192,232,132,188,191, 61,216,253,231, 90,228,191, 84,104,125, 17,243, -144, 85,118, 97, 14, 50,208,244,233, 44,137,132,171,227,114,133, 49,197, 86, 46,123,123,101, 62, 65, 12, 50,216, 54,236, 11, 82, -167, 47,106, 40,232,162,205, 72,161,165, 55,224, 67,116, 36, 30,220,248, 11, 54, 74, 9,178,226,154, 2,156, 70,208,170,242,160, -214,234,138, 68,137, 1,225, 47, 67,144,159,151, 3,111,159, 94, 0,131,241,164, 60, 62, 11,107,162,215,247,205, 27, 51, 63, 36, - 69,162,133,199, 64,212,117,110,135, 68,105, 62,114,229, 26,200,242,213,104,234, 29,128, 76,153, 10,249, 74, 53,222,126, 8,130, - 83,205,186, 12,130, 21,219,201, 88,161,165,121,123, 14,154,119, 23,193,113,109, 11,174,103, 31, 48, 93,125,145,244,250, 14,194, -175,110, 69,202,155,135,160, 41, 3, 28, 61, 90, 26,251,144,236,188,118,237, 90,203,182,109,219,178, 58,119,238,220,228,202,149, - 43, 77,164, 82,105,120,145,192,104,210,185,115,231, 38,182,182,182,216,190,125,187,138, 32,136,157,213, 44,236, 18, 11, 88, 70, - 70,198, 51, 0,107,206,157, 59,183,115,210,164, 73,176,179,179,107,148,154,154, 90,238,133,153,108,118,147,209,107,215,210,108, - 38,147, 62,241,251,239,156,149,215,174,109, 57,120,232, 16,167, 99,135, 14, 4, 77,211, 8, 11, 11, 19,110,248,253,119,225,240, -190,125, 19, 18, 51, 50,200,123,161,161, 58,105, 74, 74, 65,134, 66,177, 82, 42,149,166,253, 19, 53, 91,175,215, 63,142,139,143, -115,242,105,213,212,246, 85, 84,220, 27,255,142,223,127,207, 96, 48, 24,209,177,137,161,182,182,230,194,155, 55,110,234,244,122, -253, 99, 99,184,120, 60, 94,175,142, 29, 59,178,100, 50, 25,106,214,172,137,204,204, 76, 72, 36,146, 66,139, 67,158, 12,186,188, - 60,232,243,115, 97, 80,200, 17,247,252, 25,154,214,173,195, 59,205,227,245, 82, 42,149, 21, 10,173,226,183,204,178, 2, 93, 23, -239,227,154,153,129, 43, 22,131,168,250,176, 97, 95, 75, 75,203, 69,185,185,185, 87, 0,172,214,233,116,211, 23, 45, 90,212, 98, -199,142, 29, 54,107,214,172, 49,159, 56,113,226,105,185, 92,222, 20,133, 65, 85,203,235,192, 62,146, 36,105, 13,192, 62, 36, 36, - 4,118,118,118,200,203,203, 43,182,180,104,149, 74, 37, 63, 59, 59, 27, 26,141, 6, 90,173, 22,230,230,230,120,241,226, 69, 14, - 73,146,151, 42, 75,156,121, 61, 98,181, 70, 23,181,212,218, 75,148,170, 35,173,252, 50,114, 40,217,138, 45,210, 85, 0,182,116, -171, 91,119,159,142,186, 31,247, 62,242,146, 85,252,243,187, 57,169,239, 21,117,247, 95,137,171,104,142, 22, 13,128, 34, 8,130, -246,240,240, 64,102,102, 38,152, 76, 38,132, 66, 33,196, 98, 49, 22, 47, 94,140,157, 59,119, 86, 71,104,241, 69, 34,209, 90, 6, -131, 49,132,193, 96,216, 26, 12, 6, 4, 4, 4,160,119,239,222,224,114,185,208,233,116, 37, 22,205, 98, 43, 85, 37,150,142,176, - 39, 79,158,152, 63,121,242, 73,179,213,193,198,198,230,182, 70,163, 65,108,108, 44, 46, 92,184,208, 30,192,189, 42,150,117,108, - 88, 88, 88, 55, 95, 95,223,195,205,155, 55,175, 71,211, 52, 26, 53,106,132,161, 67,135, 34, 40, 40, 8,225,225,225,200,203,203, -163,110,222,188,121, 16,192,230,170,246,225, 69,249,235, 57, 96,192,128,135,199,142, 29,179,202,206,206,134, 74,165,130, 66,161, -192,233,211,167,209,182,109, 91,216,216,216,224,232,209,163, 36, 77,211, 21,149, 61,131,193, 96,236, 15, 12, 12,236, 61,126,252, -120,236,218,181, 11, 39, 78,156, 64,159, 62,125, 48,100,200, 16,100,102,102,218,111,218,180,105, 84,209, 48,225,242,161, 67,135, - 66, 46,151,227,249,243,231, 81, 70, 62,243,200,205,205, 69,110,110, 46, 4, 2, 65,233,103,140, 0, 16,180,117,235,214, 97,179, -103,207, 70,221,186,117,151,199,197,197,109, 69, 25,171, 68, 41,138,154, 44,145, 72,172, 88, 44,150, 53, 73,146, 72, 78, 78,198, -139, 23, 47, 48,109,218,180,156,156,156,156, 73, 0, 18, 1, 44, 25, 55,110,220,234,185,115,231,150,212,165,185,115,231, 6, 95, -185,114,165,219,191,219, 24, 35, 46,110, 0, 0, 32, 0, 73, 68, 65, 84,154,227,225, 97,217,144,203,228,205,146, 21, 48,173,101, - 50, 89, 73,219,161,213,106,161,209,104, 62,177,100,113, 56,108,235, 22, 77,107, 93, 86, 41, 11,126,126,251, 62,183,220, 0,233, - 94,245, 44, 26, 11, 69, 22,179,219,182,235, 56,162,107,183, 31,153,164, 94,143,235,215, 47,225,207, 63,119,163,131,175, 7,234, -214,111,132, 25, 51,103, 89,104,180,100,192,205,155,215, 22, 89, 62,121,112,173, 32, 63,119,113, 69,156,255,227,184, 92, 36,174, - 46,151, 57,116, 88,150,130, 44,114,225, 32, 43,250,105, 99,101,101,245,187,193, 96,232, 96,110,110, 14, 42, 55, 6,111, 95, 60, - 69,142,140, 13,141,202, 0,138, 46, 20, 91, 70, 9, 23,141, 22,247,175, 95,196,182,173, 91,144,157,157, 13,223, 31,218, 67,206, -114, 65, 45,151, 90, 80,171,148, 69, 15, 13,160,211,234, 97,107,239,138, 87,175,194,245,249, 10, 69,185, 13, 18,135,175,243,170, -101,239, 1,141,174, 13,248, 92, 46,242, 10,180,144, 21,137,172,163,103, 6, 67,163, 84,129,212,234, 64,106,245,176,173, 53, 0, -223,217,119, 4,101,184,212,176, 74,217, 71, 25,160,139,191, 15, 93,252,125, 8,218,204,196, 95,235,134,125,214,145, 26, 23,119, - 55, 51, 51, 51,227,205,155, 55,151,194,194,194,250, 13, 30, 60, 24,119,238,220,153, 8, 96, 74,209,240,205,196,193,131, 7, 35, - 44, 44, 12,111,222,188,185,148,153,153,153,241, 45, 74,158,203,229,170, 52,154,194, 62, 86, 40, 20,242, 43, 57,215,169, 69,255, -254,140,188, 87,175,242,183, 62,122,180,124,223,254,253,156,206,157, 58, 17,122,146, 4,101, 48,160,190,187, 59,209,181,107, 87, - 81,208,169, 83,214, 76,189,254,201,130,233,211, 67,246,140, 28, 89,240, 76,161, 48,118,162,121,237,162, 33, 67, 0,168, 93,193, - 62,163,161,209,104,118, 76,158, 48,166,243,189,251, 15, 93,106,185, 56,153, 95,191,121, 47,156, 39,224, 50,234,186,213, 99,202, -242,114, 88,171,150,255, 44,208,104, 52,198,138, 86, 47, 27, 27, 27,164,165,165,225,195,135, 15,208,104, 52,208,235,245,160,148, - 10,104,101,185,208,230,229,128, 80,171,192, 51, 24,160,206, 74, 71,237,186,117,128,127,173, 72,172,116, 40,170, 44,161, 85,252, -201, 55, 55, 7, 71, 36, 6,131,205, 54, 58, 56, 58,128,230, 45, 91,182, 60,117,246,236, 89,206,216,177, 99, 91,221,186,117,235, -119, 0,137, 18,137,164,211,178,101,203,158,253,254,251,239,188, 73,147, 38,121,110,222,188,121, 20,128, 63,202, 35, 81,171,213, -167, 46, 95,190, 60,220,213,213,213, 62, 34, 34, 2,106,181, 26, 20, 69,161,123,247,238, 64,225,220, 26, 0, 64,116,116,180, 74, -173, 86,103, 68, 70, 70,230, 39, 38, 38,234, 96,196, 42,193, 21, 59,164,143,243,211,238,247,183,119,112,122,194, 23,212,118,163, -229,175,250,205, 25,232,180,105,235, 25,137,250, 90,108,108,193,210, 46,117,214, 43, 10, 94, 79,179,116,150,239,186, 22, 28,103, -204, 68,248,146,213,133,214,214,214, 96,177, 88, 96,179,217,224,112, 56, 32, 8, 2, 51,103,206,196,222,189,123, 43, 27, 58,252, - 68,100,153,153,153,189, 89,185,114,165,243,164, 73,147, 56,124, 62, 31, 50,153, 12, 71,143, 30,197,184,113,227,240,231,159,127, -150, 57,255,197,136, 33,165,207,173,165,179, 71,142, 28, 9,173, 86,139,161, 67,135, 98,223,190,125,179, 13, 6,195,189,106, 60, -210, 79,194,195,195,221,195,195,195,205, 1,244, 25, 50,100,200,161, 1, 3, 6,224,222,189,123,184,116,233, 82,123, 20, 46,250, - 80, 1, 88, 7,192,174,232,179,162,231, 83,100,111,111,191,155,162,168, 62,182,182,182,225, 30, 30, 30,222,199,142, 29,179,204, -200,200, 40, 94,252,128,248,248,120, 28, 56,112, 64,186,127,255,254,124,131,193, 96,205, 96, 48, 46,231,230,230, 46,174, 64,176, -237,223,186,117,235,152,162,225, 64,156, 61,123,150,222,178,101, 11,177,108,217, 50,200,100, 50,116,232,208, 1,129,129,129,179, -228,114,121,147, 45, 91,182, 76, 24, 52,104, 16, 86,173, 90, 5,133, 66,177,181,178,151,149, 10,196, 23, 1,224,251,173, 91,183, -186,206,158, 61, 27,103,207,158, 69,243,230,205, 5,113,113,113,123, 0,140, 47,171,252,104,154, 70, 92, 92, 28,148, 74, 37, 30, - 62,124,136,229,203,151,203, 74,137,172, 89, 83,166, 76, 89, 61,107,214, 44,172, 93,187,150,142,136,136,200, 24, 48, 96,128,253, -222,189,123,153,245,235,215,159,165, 84, 42,255,109, 66,203,179,126,141,245, 45,154,183, 91,228,232, 84, 31, 71,143, 29, 71, 78, - 78, 78, 73,158, 20,231, 11, 77,211, 40, 40, 40, 64, 90, 90, 26, 44,204,205,176,105,243,234, 30, 83, 39,142,113, 65,161, 27,140, - 47, 77,150,117,173, 54, 15, 24, 50,118,222,208,225, 99, 16, 17,254, 18, 65,135,254, 64,100, 68, 88, 9, 31,169,215, 33, 38,234, - 5, 98,162, 94,192,222,193, 21, 93, 59,183, 39,134, 13, 27,214,125,228,240, 33,182, 0,254, 54,215, 17,255,197,214, 44,224, 75, - 63, 90,123, 63, 17, 90,149,152,235,108,172,172,172,222,156, 60,121,210,218,215,215,151, 73,146, 36,174, 93,191,142,105, 83,126, -194,168,145, 1,208,193, 10,164,150, 3,138,195, 55, 42, 37, 42,149, 18, 52,104, 40, 20, 10,132,134,134,130,166, 72, 4,237,221, - 2,154,166, 74,132, 22, 64, 67,171,211,193,169,150, 39,118,239, 91, 67,130,205,126, 6,125,217,174,107,242,179,153, 6, 61, 73, - 67,146,145,132, 36,105, 36, 44,204,106,129,197,174,133,236, 92, 37, 88, 12, 7,232,213,209, 48, 20, 93,171, 84,164, 64,165,251, -186,242, 51,148, 97, 61,165,171,208,232,170, 84,170, 35, 71,142, 28,233,241,219,111,191,113,123,246,236,233,113,230,204,153,239, - 1,160,103,207,158, 30,230,230,230, 56,114,228,136, 86,165, 82, 29,249,134, 22,159,142, 45, 91,182,132, 76, 38, 67,124,124,124, -120,133,247,166,213, 90,139,237,236,152, 25,119,238,232, 51,101, 50,151,142, 29, 59, 18,122,146, 4,131, 32,144,147,151,135,196, -132, 4, 88, 90, 90, 18,111,162,163,197, 59,103,204, 56,239,225,237,205, 42, 94,145,104, 12, 46, 93,186, 36, 68,225,188,172, 10, -247, 85, 17,138,140,244,180, 49,211,167, 79, 63,127,228,200, 81,139,244,140,244, 24, 30,151, 75,138,197,252,154, 35, 71, 76,101, -229,230,230, 14, 7, 32, 55,150, 76, 38,147, 33, 46, 46, 14, 2,129, 0, 28, 54, 27,148, 74, 9,131, 66, 14,117, 78, 38,152, 58, - 45,184, 6, 3,106, 8,121,112,177,183, 71, 45, 91, 27,163, 56, 63,220,190, 81, 50,241,189,244,112,225,166,150, 94,224,138,196, -224,154,137, 49, 53,248,110,209,219, 40, 7, 88,246,171, 49,180, 54, 78, 78, 78,127, 29, 59,118,140,147,153,153,137,176,176,176, -112, 0,121, 0,204, 0, 80, 81, 81, 81,183, 34, 35, 35,123, 21,173,186,171,108,181,216,150,115,231,206,117,241,245,245, 37,221, -220,220, 68, 25, 25, 25, 46, 50,153,140,146, 74,165,159,152,132,110,220,184,193, 43, 40, 40, 80, 80, 20,117,190, 72,100, 85,234, -191,104,206, 64, 39,126,232, 43,204,244,243,175,221,200,220,166, 49,114,200, 87,141,158,132, 75,103,206, 25,232,180, 99,235, 25, -137, 90, 64,104, 14, 17,134,100, 23, 22, 95,109,236, 36,102, 26, 40,156, 43, 21, 26, 26,138,196,196, 68,196,197,197,125, 34,168, - 38, 78,156,136,160,160, 32,163, 44, 90, 34,145,104,237,138, 21, 43,156,103,207,158,205, 41, 37,138, 48,125,250,116,228,229,229, - 97,223,190,125,152, 62,125,122,149, 59,254,207, 80,167, 99,199,142, 61, 29, 29, 29,145,157,157, 13, 7, 7, 7,248,250,250,246, -190,119,239,158, 27,128,248,106,214,251,169,254,254,254,171, 87,174, 92, 9,189, 94,143,113,227,198,225,253,251,247,167,222,191, -127,191,173, 86,173, 90, 51, 23, 46, 92,104,111,111,111,143,193,131, 7,139, 72,146,236, 95, 30, 73,141, 26, 53,214,253,241,199, - 31,195,123,246,236,201,208,233,116, 63,220,190,125, 27, 9, 9, 9,208,106,181, 32, 73, 18, 31, 63,126,196,244,233,211,165, 69, -171, 27, 63, 26,145,174,177, 75,150, 44, 25, 51,115,230, 76,108,216,176, 1, 43, 86,172, 56,104, 97, 97,225,221,180,105,211,102, - 43, 86,172,192,130, 5, 11,224,234,234, 10,107,107,235,239,150, 45, 91,230, 53,119,238, 92,236,216,177, 3,203,151, 47, 63, 8, -224, 64,117, 50,130,162, 40, 98,253,250,245, 77,182,110,221,234, 88, 44,178, 24, 12, 6, 78,158, 60,137, 87,175, 94,245,142,141, -141, 45,235,154, 64, 7, 7,135,137,142,142,142,220,155, 55,111,138, 93, 93, 93, 65,146,164,190, 72,100,237,172, 85,171,214,180, -143, 31, 63,162,103,207,158,136,141,141, 61, 2, 96,148,133,133,133, 98,238,220,185, 66,129, 64, 96,161, 84, 42,255, 93,157, 55, -152, 12, 98,244,218, 85, 11,240,252, 85, 52,206,157,227,224,249,243,231,176,183,183, 7,143,199, 3, 77,211,208,104, 52,200,204, -204,132, 94,167, 65,163,134,117,112,120,255,122,100,100,100, 2, 12,162,220, 41, 55, 4,131, 24, 49,230,167,126,120,240,240, 58, -246,236,249, 3,114,185,162,156,151,111, 62,234,123,120,193,169,166, 29,146, 83,146, 65, 48, 96,243,119,222,235,127,249,208, 97, - 73, 19, 4, 99,220, 59,148,134,165,165,229,182, 19, 39, 78, 88,119,232,208,129,169, 80, 40, 64, 81, 20,218,249,250, 98,230,236, -217,184,116,236, 24,220, 91, 13, 5,161, 21,131, 20, 26,183,234, 65,173, 82,162, 65,179,239, 49,104,240, 16, 36, 37, 38,194,191, -215, 0,168,213,202,146, 55,140, 98,139,150, 86,171,131,141,157, 11,110,220,184,193,196,184,113,111,177,179,108,163,132, 65,199, -125, 29,243, 81,221, 54, 87,245, 10,161,207,131,160,211,232,208,168,209, 50,232, 40,107,216, 57, 79,132, 94,127, 1,249,153,183, - 11,135, 49,172, 59, 32, 37, 41, 9, 12, 38,231, 77,117,115,144, 82,100,126, 85,163,155,151,151,151, 23, 23, 23,119, 38, 52, 52, -116, 68,255,254,253,113,227,198,141, 9, 0,208,191,127,127,132,134,134, 34, 46, 46,238, 76, 94, 94, 94,222,183, 40,109, 71, 71, -199, 62,237,219,183, 31,218,162, 69, 11, 4, 7, 7,131,166,233, 7, 70, 61,216,108, 54,205, 96, 48, 64, 81, 20, 8, 0,217,185, -185,120,255,254, 61,178,179,178,160,215,235,161,144,203, 41, 47, 15, 15, 57, 77, 81,102, 85, 73, 79,233, 21,134, 40, 99,213, 97, -241,190,106,220,106,226,179, 39,143,146, 10,228,114, 91, 43, 75,171, 2, 46,151,107,144,229,230,230,189,125, 19,161, 53,178,115, - 40, 70, 84,100,100,164,119,106,106, 42,146,146,146, 64, 42, 10,192,212,104,193,208, 40,209,233,251, 54, 16,128, 6, 31, 20,216, -148, 30,108, 38, 27, 5,133,171,243, 42, 29,238, 48,148,122, 73, 40, 22, 89, 4, 65, 20, 14, 23,138, 68,224,138,205, 62,177,112, - 25, 83,159,120, 60,222,177,211,167, 79, 59, 58, 57, 57, 97,213,170, 85,112,118,118,254,174,102,205,154, 74, 11, 11, 11,129,189, -189, 61, 26, 52,104,128,239,191,255, 30, 87,175, 94,133, 17,121, 64,210, 52,221,245,193,131, 7,243, 30, 61,122, 52, 72, 36, 18, - 17, 51,102,204, 96,117,239,222, 29, 60, 30, 15, 74,165, 18, 50,153, 12,199,143, 31,207,162, 40,170,120, 81,138,181, 80, 40, 60, - 64, 16, 68,188, 66,161,152,253, 57,225,225,223, 26,213,204,200,161,198,209,114, 97, 63, 63,255,218,141, 58,250,119, 70, 29,247, -142,232,232,159, 4, 0,235,107,176, 18,134,110, 92, 98,121,222,210,140, 56,112,227,218,205,229,190,126, 29,151, 44,146,223, 89, -189, 97,111,110,165,243,233, 8,130, 0, 69, 81,159,248, 14,250,252,248,168, 81,163,112,242,228,201, 74,243,145,193, 96, 12,153, - 52,105, 18,231, 51,203, 51, 36, 18, 9,122,245,234,133,254,253,251,127, 34,180,108,108,108,224,224,224,128,132,132, 4, 0,200, - 54,178, 94,205, 28, 59,118, 44,161, 82,169, 48,126,252,120,236,219,183, 15, 67,135, 14, 37,238,221,187, 55, 19,192,236,170, 86, -118, 6,131,177,105,225,194,133,243,166, 79,159,142,156,156, 28, 92,185,114, 5,221,187,119,199,201,147, 39,109,175, 92,185,178, -182, 67,135, 14, 96, 50,153, 8, 14, 14, 6, 73,146, 21,250,250,226,112, 56,125,122,246,236,201, 72, 78, 78, 6,135,195,129,143, -143, 15, 82, 82, 82,160, 84, 42, 33,145, 72, 48,107,214,172,180,236,236,236,246,198, 62, 71, 28, 14,103,246,204,153, 51,113,226, -196, 9, 4, 4, 4, 28, 2, 48, 62, 47, 47,111,208,163, 71,143, 78,244,237,219, 23, 18,137, 4,231,207,159,199,242,229,203,137, - 81,163, 70, 97,215,174, 93,152, 53,107,214,193, 34,171, 83,121, 21,191, 32, 35, 35,195,162, 94,189,122, 72, 79, 79,135, 92, 46, -199,249,243,231,237,174, 94,189,234,230,228,228,100, 30, 23, 23,103,248,245,215, 95,185,179,103,207,198,182,109,219, 16, 22, 22, -134,160,160, 32,116,236,216,145,140,141,141, 45,211, 74, 86,228,178,225, 60, 77,211, 55, 69, 34, 17, 10, 10, 10,138,159,187,249, - 1, 1, 1,211,215,173, 43, 52,178,167,166,166, 98,244,232,209, 35, 67, 66, 66,168, 14, 29, 58, 8, 57, 28, 14,212,106,181,226, -223,217,107, 83, 6, 10, 0, 5, 55, 23, 49,174, 95,218,143,151,225,177,120, 25, 30, 9, 46,175,112, 18,188, 74,165, 68,179, 70, -245,209,202,167, 37, 82,165, 18, 28, 9,218,143, 26, 54, 78, 21,182, 35, 52, 77,131,195, 50,192,203,195, 1,199,130,254, 64,240, -149, 16, 4, 29, 57, 94, 50,231,141,197, 98,163,105,179, 86,240,241,241, 69,108,220, 71,236,223,191, 7,182,118, 46,166,193,193, -106,162,100,232,176,244,231,103,202,191,163,175,175, 47, 83, 46,151, 67,173, 86, 35, 45, 45, 13, 9, 9, 9,176,180,178, 68,108, -106, 60,218, 11,117, 72,163,242, 17, 21,254,198, 64, 48,217, 97,149,253, 97, 79,191,166,128, 95, 83, 76, 27, 59,180,130, 87, 86, - 26, 34,115,155,194,161, 27,146,252,128, 29, 59,200,242,132, 22,105,208,223,186,126,243,118,203,177,163,250,176,111,220,222, 7, -189,150,130, 74,111, 1,133, 90, 11,133,142, 13,134, 69,119, 32,235, 30,152, 44, 30, 90, 55,169,143,243,231,174,234,104, 82, 31, - 98,116, 6,217,123,131, 76,143, 44, 37,180, 50, 62, 27,119,168, 97,244,208, 97, 73,199,107, 48,156, 60,122,244,232,143,109,218, -180, 17,118,232,208,161, 94, 81,199,169, 59,122,244,168,178,200, 25,102, 85,241,137, 55,120, 7, 7,135,102, 28, 14,103,104,247, -238,221,155,141, 25, 51, 6,111,223,190,197,145, 35, 71, 98,234,215,175,127, 71, 42, 45,127, 69, 54,147,203,205,150,103,100, 88, -138,221,220, 88, 86,102,102,169, 87,175, 92,113,237,220,165, 11,145,148,148,132,236,236,108,168,213,106,132,133,135,211,108, 38, - 51,133, 48, 55,103, 68,191,122,197, 96,114,185,217,229, 89, 27,203, 64, 66, 37,171, 14,215, 85,215,186,229,226,104, 85,111,121, -192,228, 58,106,141,218, 59, 63, 63,159,100,177,217,108,103, 7,203,196,232,143,198,183,137, 26,141, 38,248,214,173, 91, 63,118, -238,220,153, 23,243, 58, 12,100, 94, 30,180,121, 50,112, 40, 3,106, 52,107, 2,166, 78, 3,104,245,112,242,162,161,206, 21,226, -222,211,104,189, 70,163,169,212,169, 97,177,208, 98,124, 38, 12,184, 98, 49,120,102,230,224,137,197,159, 11,134,202,222,228,132, - 93,187,118,237,212,186,117,107,208, 52,141,189,123,247, 66,167,211,113,117, 58, 29,180, 90, 45,116, 58, 29,242,243,243, 17, 20, - 20,132,221,187,119, 63, 2,112,208,136,219, 39, 5, 2, 65, 95,130, 32,236, 88, 44,150,210,214,214, 86,116,242,228,201, 18,119, - 19, 77,155, 54,133,153,153, 25, 7, 69, 78, 33,237,236,236,216,127,254,249,167,101,239,222,189,239,151, 57,220,209,232,187, 5, -117, 72, 43, 63,190,160,182,155,185, 77, 99,212,113,239, 8, 0,232,210,107, 44,234,212,175,133,252,172,215,110,106, 85, 66, 63, - 14, 75,102,245,102,135,228,173,160,167,247, 24, 69,198,221,247, 40,123,121,127,153, 29, 5,131,193, 40,119, 56,214, 24,145, 85, -168, 89, 24,182,197,243,124, 0, 32, 59, 59, 27, 82,169, 20, 81, 81, 81,240,244,244, 68, 78, 78, 14,156,156,156,160,213,106,209, -162, 69, 11,168, 84, 42,108,221,186, 21, 15, 31, 62,124, 4, 96,150, 17,255, 33,112,119,119, 31,221,172, 89, 51, 92,185,114, 5, -207,159, 63,151, 92,191,126,221,201,215,215, 23,110,110,110, 99,226,227,227,127, 46, 26,234, 51, 22, 34, 95, 95,223, 25,211,167, - 79, 71,100,100, 36, 38, 79,158,156,157,156,156,124,254,212,169, 83,227,151, 47, 95,206,240,247,247,135, 84, 42,197,166, 77,155, - 12, 15, 31, 62,220, 12, 96, 85, 37,249,248, 46, 57, 57,217, 89,173, 86, 35, 39, 39, 7, 36, 73, 66,169, 84,226,234,213,171, 8, - 10, 10, 74, 47, 18, 89, 31,140, 77, 92,147, 38, 77, 26, 48, 24, 12,156, 56,113, 2, 0,150,162,208, 99,255,249,126,253,250, 73, -126,253,245, 87,167,197,139, 23, 99,194,132, 9,208,233,116,216,176, 97, 3, 22, 47, 94,124,185, 72,100, 85,212,136,254,230,224, -224, 48,113,242,228,201,223,205,157, 59, 23,161,161,161,118, 47, 94,188,240, 9, 11, 11,131,139,139, 11,178,179,179, 89,214,214, -214,216,182,109, 27,230,204,153,115, 22, 64,214,227,199,143,135,196,197,197,173, 3,176,169, 18,209, 30,232,228,228, 52,145,166, -105, 90,169, 84, 38, 4, 4, 4,108, 90,179,102, 13,230,204,153,131, 55,111,222, 32, 47, 47, 15,102,102,102,196,194,133, 11, 71, - 47, 93,186, 20,227,198,141,163, 21, 10,197,238,127,119, 71, 77,211, 6, 40,101,145, 48,104,172,208,180,145, 39,154,122,215,198, -245,219, 47, 1, 0,157, 6,248, 66,169, 40,192,161, 67,123,241,225,195,123,176,216,108, 88,214,112, 48,198, 18, 8,109,254, 59, -228,234,164,232,220,193, 7,221,253,219,227,224,225,147, 32,245, 58,140, 31, 59, 28,178,220, 92, 28, 62,188, 31,177,113, 31,193, - 98,179, 97,109,243,247, 59, 66,173, 72,139,252,215, 11, 45, 35,134,159, 64, 81, 20, 36, 18, 9, 94,188,120,129,248,248,120, 8, -133, 66,168, 72, 3,181,231,214, 67,138, 32, 56, 41, 20, 77, 63,162,201, 18, 47,197, 95,114, 24, 12,146, 82, 30,107, 45,172,172, -172,184, 26,141, 10, 36,169, 47,213,171, 16, 0, 1,112, 88,128, 99,205, 58, 72, 78, 74,166,213,106,245,221, 10,223,160, 52,234, -109, 23,207,159,158,254,125, 91, 95,155,238,157, 86,226,252,133,101,144,229,231, 67,173, 99, 67,161,214, 65,169, 6, 44,107,120, -160, 69,163,198, 72, 77,205,198,235,231,247,228, 44,141,210,152,137,162,239,119, 46, 25,235, 62,118,218, 2, 8, 92,219, 66, 19, -117, 30,148, 60,189,196,162,197, 23, 91,161, 70, 45, 47,228, 42, 52, 56, 29,242, 18,168, 66,168,151,140,140, 12, 37,147,201, 60, - 58,125,250,244, 13, 47, 95,190,112, 6,128,151, 47, 95,166, 72,165,210, 69, 25, 25, 25, 85,181, 73, 23,123,131, 39,248,124,193, -203,250,245,235,167,250,248,248, 88,244,235,215, 15, 54, 54, 54, 8, 11, 11,195,186,117,235,222,233,116,186, 5,247,238,221,171, -112,168, 71,171,213, 74, 94, 94,184, 96,222,254,167,159, 44, 23,244,238,189,105,250,244,233,219, 86,173, 90,197,118,119,119, 39, -244, 58, 29, 34, 34, 34,232, 99, 71,143,234,119, 47, 94,188,149, 43, 18,177,158, 93,188,200, 38, 53, 26,201, 63, 93,137,157,156, -156,252,124,127,104,231,181,249,183, 29, 80,171,228,120, 26,122, 25, 50, 89, 38,254,216,123,206,203,201,137,246,147, 72, 36,247, -140, 21,192, 7, 14, 28,152,215,170, 89,179,102,117, 93, 92, 16,145, 24, 15, 46,101, 0,135, 36,193,212,105,192, 32,213,112,241, -166, 65, 48,204, 32, 77,203,199,154, 19,103, 34,141, 17,198,223,245,232,131, 85, 41,121, 32, 8, 2, 91,218,120,131,107, 38, 6, - 71, 36,198,212,191,110,151, 8,131,224, 85,139,193, 21,139, 81,175,149, 81, 14,225,149,119,238,220,121, 17, 17, 17,209,194,219, -219, 27,243,230,205, 67, 66, 66, 2, 40,138, 66,122,122,186, 90, 42,149, 74, 50, 51, 51, 19, 80,232,255,103, 95, 37,157, 88,105, -213,225,116,239,222,189,146,225,134,144,144, 16,212,172, 89, 19, 22, 22, 22,200,207,207,199,164, 73,147, 44,127,249,229, 23, 0, -192,139, 23, 47, 80, 90,160,124,142,136,151, 81,155,115, 11,104, 25, 45,127,213, 47,135,124,213,168,163,127, 50,186,244, 26,131, -155,193, 7,113,251,250, 45,212, 96, 37,196, 67, 84,112, 53, 43, 62, 43, 63, 69,225, 30,232,213,124, 60, 83,170,184, 30, 56,163, - 79, 12,211,209,145, 58,189,120, 79,126,110, 69,105,117,119,119,135,189,189,125,201, 28, 45, 22,139,133,113,227,198,129,166,105, - 99, 69, 86, 81, 95, 67,101,170,213,106,123, 62,159,143,180,180, 52,124,252,248, 17,177,177,177, 37,174, 3, 40,138,210,207,159, - 63,159, 61, 99,198, 12,236,217,179, 7,119,239,222,125, 4, 96, 37, 0, 99, 95,214,134, 15, 30, 60,216, 76,171,213,226,248,241, -227, 36,128, 94,167, 79,159,126,209,162, 69, 11, 86,183,110,221,204,118,237,218, 53,188,168,140,140, 22, 90,230,230,230, 28,157, - 78,135, 93,187,118, 33, 57, 57,217, 15, 64,212,179,103,207, 2, 7, 15, 30,188,219,219,219,187,126,100,100,228,123,185, 92, 62, - 21,192,235,202,200,210,211,211,199,250,248,248,156,166, 40,202,181,115,231,206,162,223,126,251,205, 60, 58, 58, 26,206,206,206, -160, 40, 42, 2, 85, 12, 97,245,254,253,251, 40,169, 84,234,213,190,125,123, 92,189,122,117,189,193, 96, 88, 11, 96,195,148, 41, - 83,156, 18, 19, 19,209,172, 89, 51,212,168, 81, 3,209,209,209, 5, 82,169,116, 55, 10, 67, 18, 85,102,194,141, 3,176, 40, 48, - 48,176,113, 96, 96,224,208, 26, 53,106,180, 14, 11, 11,195,131, 7, 15,176,121,243,102,252,242,203, 47,104,215,174, 29,230,205, -155,151, 5, 96, 40, 0, 50, 46, 46,206, 40,191,121,197,150, 45, 0,104,222,188,121,234,186,117,235, 48,126,252,120,250,207, 63, -255,220,126,244,232,209,217,195,135, 15, 47,233, 3, 71,143, 30, 77, 31, 57,114,100, 52, 10,195, 48,253, 59,161,215,233,180, 48, -175, 81, 7,242,220, 36,100, 38,135, 66,104,230, 0,255,142, 77,160, 84,105,113,233,226, 89,188,142, 8, 7,131,193,128,189,131, - 11, 44,173,108, 16, 19,243, 30,168,120,181,177, 94,167,211,193,204,170, 54,228,121,201,208,102,188,132, 64,108,135, 49, 63,245, -131, 82,165,195,185,243,103, 17, 25,249, 26, 76, 38, 19, 14,142, 46,176,176, 44,228, 36,232,138, 87, 48,155, 0,160, 12,127, 90, -149, 10, 45, 38,147,121,231,218,181,107, 3, 91,181,106,197,250,240,225, 3, 62,124, 40,124,185,145,201,100, 36, 1,195,153,140, -136,139,195, 42,184,188, 51,138, 86,103,148,142, 93, 40, 54, 51,147, 68,191,139,178,151,229,164, 35,252,213, 67,124,136,137, 64, -124,108, 20,116, 58, 53,152, 12, 6, 24, 76, 6,106,215,105,136,135,143, 66,181,106,146, 12, 45,143,179, 48, 29,177, 5, 34, 59, -247, 33,171, 87,253, 28, 60,103,193, 10,193,160,129,123,240, 58,250, 45,228,164, 3,104, 26,112,176, 22,161,105,221,133,144,164, -102,226,196,193, 93, 74, 74,167, 27,241,153, 15,173, 47, 56, 1,192, 62, 11, 13,118,239, 61, 56,110, 95,208,177, 21, 11,102, 76, -178,239,219,127, 4,184, 57,111,161, 79,125,137, 58, 45,186,131,224, 89,226,202,141,219,184,247,226,109, 58,101,160, 87,216,103, -227,207,152, 74, 56, 75, 35, 55, 55,247,113, 90,154,212,185,148, 23,120,103, 30,143, 95,217,234,184,207, 57, 63,241, 56,207,100, - 50,154,175, 94,189, 90,111,111,111,175,139,140,140,196,158, 61,123,168,151, 47, 95,222, 96, 48, 24, 59,165, 82,169,186, 50, 78, - 91,189, 62,252, 88, 64, 64,131,150,253,251,211,195,102,204, 80,130,199,155,185,105,203,150,128, 76,153,172, 38, 77, 81,176,173, - 81, 35,101,211,226,197,235, 6, 14, 30, 44,123,243,240,161, 32,244,194, 5, 1,151, 36, 95, 26,145,206,111,129,114, 57, 37, 18, -201,189,187,119, 31,224,208,190,223,160,211,105, 32,149, 36, 2, 0,178,178,243, 80,137,200,250,156,147, 86, 42,149,253,151,254, -242,203,147,165,115,102, 59,252,208,169, 51,146,194,195,160,203,201, 4,161, 39,193, 38, 88, 80,100, 8,145,145, 46,199,162, 35, -167, 50,228, 74,101,255, 50, 58,137, 50,211, 89,108,177,226,153,155,129, 35, 18,131, 43, 54,251,196,138,197, 55, 55, 7, 87, 36, - 6,139,203, 45,107, 2,247, 23,156,114,185,124,192,192,129, 3, 95, 63,123,246,204,106,252,248,241,248,254,251,239, 95,169, 84, -170, 14, 0, 10,170,155,159, 20, 69, 73,126,248,225, 7, 6, 65, 16,226, 17, 35, 70,240, 50, 51, 51, 75, 60,171,203,229,114, 92, -189,122, 21,158,158,133,171,250,223,188,121,131,134, 13, 27,150,203, 57, 97, 81,164, 4,192,170, 57, 3,157, 54, 61, 9,151,206, - 4,176,190, 78,125, 23,220,190,126, 11, 15,110,135, 6,180,246,166,118,244, 24,209,226, 87, 97,135,193, 11,188,154,143,103,138, -205, 29,113,248,220, 89,102,212,203,253,107,148,202,136,122,216,115,126,126,121,233, 36, 8, 2, 52, 77,127,225,202,129,201,100, -226,232,209,163, 85,189,247, 83,251,246,237,155, 50,121,242,100,142, 84, 42,197,187,119,239,160, 80, 40,192,231,243,113,253,250, -117, 18,192,174,163, 71,143, 94, 63,122,244,104, 55, 20,174, 38, 10,169, 74,253, 20,137, 68,211,253,253,253,241,238,221, 59, 60, -127,254,252, 44,128,215,175, 94,189, 58,251,225,195,135, 33,237,218,181,195,193,131, 7,167,171, 84,170,125, 85,225,164, 40,170, -180,207,164,226,136, 15,225,114,185,188,117,104,104,104, 85,203, 93,154,157,157,221,182, 72, 88, 39,219,219,219,155,135,135,135, -163, 86,173, 90,208,233,116,173,170, 90,151,242,242,242,126,219,185,115,231,159, 99,199,142,197,175,191,254, 58,226,212,169, 83, - 35,122,244,232,129,158, 61,123,226,192,129, 3,120,253,250,245,122, 24, 23, 86,172,172,123,127, 13,224,181,189,189,253, 52, 23, - 23, 23,108,222,188, 25, 17, 17, 17,235, 86,173, 90,181,248,245,235,215,240,244,244,228, 69, 69, 69,145,213,105, 67, 0,192,220, -220,220, 92,175,215,227,194,133, 11, 79, 1,204, 25, 49, 98,132,221,182,109,219,134,138,197, 98,228,228,228,168, 34, 35, 35,135, - 3,184,248,239,110,235,104,130, 88, 50,126,194,204,192, 9,227,135,243,125,154, 55,133, 50, 63, 5, 42,121, 58,148, 5,105,216, -185,239, 6, 8,130, 1, 91, 91, 71,216, 57, 56, 35, 49, 49, 9,143, 46, 95,209, 42,148,170,109, 92, 61,181,190, 98,206, 25,133, -156,205, 10, 57,149,138, 12,168,228, 25, 37,156,118,118, 53,139, 56, 19,241, 48,244,138, 90,165, 80,252,166,165,137,141,127,243, -189,255, 55,163,106,177, 14, 75, 67, 38,147,205,154, 52,105, 82,135, 69,139, 22, 89,147, 36,201,172, 81,163, 6, 18, 19, 19,201, - 51,103,206,228,200,229,242, 89,213, 73, 13,139,205,126,237,238,225,217,161,111,223,190,100,159, 62,189, 57, 35,199,118, 99,217, -218,217, 33, 47, 55, 27, 49,239,194, 16,253,246, 37,220, 61,155, 96,249,170,173,128,165,101,165,129, 36,139,194,234,244, 90,185, -116,254,201,182,126, 93,205, 61, 27, 54,225, 52,173,103, 1,157,158, 68, 74, 74, 10, 46, 94, 8,215, 69,190,120,144, 79,145,218, - 33,202, 44,227, 66,240,220, 3, 72,100,227, 15,111, 59,221,209,181,155,118,206,219,245,199,161, 5,139,102,142, 23,181,243,237, -130,136, 91, 7,113, 54,248,164, 66,173,209,110,226, 48,177, 37, 50, 27,202,152, 42,230,129, 90,173,214,125,222,159,170,213,106, -221,215,150,244,129, 3, 7,144,158,158,174, 77, 72, 72,184, 70,146,228,169, 10,130, 61,127,129,157,128,182,159, 70,115,107,169, -175,111,183,165,215,175,243, 71, 47, 92,168, 29, 49,114,228,124,104, 52, 58,112,185, 52, 75, 36, 98,128,199, 99,191,121,248, 80, -176,125,202,148, 26,132, 86,123,243, 80, 5,110, 3,202,192, 55, 95,117, 88,108,209,106,223,190, 29, 70,143,159, 3, 85, 41,139, -214,227,231, 49,208,232, 96,180, 69,171, 8, 73, 9,201,201,173,103, 46, 89,122,110,136,127, 39, 47,111,215,218, 60, 91,183,218, - 16, 59, 56, 32, 59, 51, 19, 15,159, 71,235, 87,157, 60, 23, 89, 36,178,140,242, 43, 67, 81, 84,225, 36,119, 0,157,102, 45, 2, -193,100, 2, 69,110, 28,138, 87, 14,185,181,248, 30, 4,139, 5, 3, 77, 65,163,209, 24, 51,233, 47,229,227,199,143, 3, 70,140, - 24, 17, 18, 28, 28,204,240,247,247,111,122,254,252,121,234,107,234,142, 74,165,106, 13, 0,124, 62, 63,222,210,210,210,105,236, -216,177,208,235,245, 80, 42,149,200,203,203, 67, 74, 74, 74,238,216,177, 99,117, 0, 32, 16, 8,184, 3, 7, 14, 52,175,140,115, -235, 25,137,122,206, 64,167, 29, 53, 88, 9, 67,243,179, 94,187,213, 96, 37,196,183,246,166,118,108, 61, 35, 81,155,215, 84,172, -206, 74,184, 23, 35, 85, 92, 15, 60,124,238, 44,115, 84,191, 1, 6,103,241,251, 0,190, 29,125,166, 50, 94,130, 32,190,112, 78, -106,164,200,250, 4, 5, 5, 5,139,151, 45, 91,214, 83, 38,147, 57,119,235,214,141,227,229,229,133, 39, 79,158, 32, 56, 56,152, -124,252,248,113,178, 66,161,248, 25,128, 26,192,141,234,228,169,135,135,135, 27,139,197, 42, 30, 74,251,189,104,247,239,231,207, -159, 31, 50,126,252,120,212,174, 93,187, 65, 84, 84, 20, 15, 85,120,142,104,154, 46, 25,101,248,150, 32, 8, 34,118,251,246,237, - 78, 14, 14, 14,196,213,171, 87, 73, 38,147, 89, 29,203,205,129,253,251,247,183,210,235,245, 19, 38, 78,156, 8, 63, 63, 63,144, - 36,137, 35, 71,142, 96,255,254,253,198,138,172, 10, 17, 19, 19,243, 50, 57, 57,249,135,249,243,231, 99,243,230,205,139,231,207, -159,143,228,228,100,196,196,196,132,125, 13,111,126,126,190, 42, 41, 41, 73,216,166, 77, 27,159,200,200,200,200, 14, 29, 58, 52, - 28, 63,126, 60,214,175, 95, 79,223,189,123,119, 32,128,171,255, 68,239, 29,253, 33, 39,136,109, 96, 93, 95,181,250,183, 95,234, -213,117,155, 60,110,204, 96,166,135,123, 67, 40,242, 82, 96,109, 99, 15,103,151, 58,200,204,200,194,181,107, 87, 13, 89, 89,185, - 7, 12, 12, 98,229,135, 15, 57,169, 95,195,233,228, 92, 7, 25, 25, 25,184,114,229,138, 33, 87,150,191, 23,122,198,170,168,196, -220,116,152, 96,140, 37,107, 34, 42,240, 18, 95, 17,108,172,172,172,142,155,155,155,167,155,155,155,167, 91, 89, 89, 29, 7,140, - 90,125,208,185, 84,235,192,252,100, 27, 56,144, 15, 62,191, 53, 88,172,185,150, 86, 86, 87, 45, 44, 44,178,219,183,111,175, 13, - 12, 12, 84, 71, 69,189,161, 36,146,100,218,194,194, 34,175,228,252,178, 56, 63,131,149, 85, 93, 51,145, 99,195, 95, 44,156,155, - 62, 20, 59, 54, 40, 16, 59, 54, 40,176,112,110,242, 72,228,216, 96,133,149, 85, 93, 51,163,210, 89, 14,234,216,193,214,221, 6, -187, 60,109, 9,149,187, 13,118,213,177,131,173,209,247, 94,241,176,159,129, 32, 96, 64,225, 50,108, 84,131,179,152,131, 98, 50, -153,135,156,157,157, 29, 81, 53,135,117, 95,112,142, 4,106,143,228,241, 38,156, 14, 8, 24, 29,127,247,238,136,252,184,184, 97, -121,177,177,131,195, 78,158, 28,242,251,144, 33, 35,135,241,120, 19, 7, 2,117,141,229,116,116,116, 92,247,242,229,203, 96, 99, -183, 82,194,203,232,252,172, 91,199,233,186,127,231, 86,244,244, 73,253,233,233,147,250,211,254,157, 91,209,117,235, 56, 93,255, -138, 50, 34,152, 76,230, 80,161, 80,120, 92, 36, 20, 70,136,132,194, 8,161, 80,120,156,201,100, 14, 69,197,115,168, 62,225,180, -182,182,126, 97,111,111,159, 94,149,205,198,198,230, 85, 21,210, 57,204,205,205, 45,153,193, 96,108,173,226, 51, 93, 17,167,187, - 64, 32,136, 21,137, 68, 41,165, 55,129, 64, 80,218, 49,148,181, 80, 40,188, 36, 18,137,182, 25,195,185,113, 73,195, 95, 30,221, -152,246,122,227,146,134,191,124,126,108,198,143, 86, 99,159,132,172,204,158,241,163,213, 88, 99,210,105,103,103,119,215,206,206, - 78,106,103,103, 39,181,183,183,175,112,179,177,177,121, 97, 4, 39,223,204,204,108,155,153,153, 89,186, 72, 36, 50,136,197,226, -116,145, 72,180, 21,165, 92, 91, 84, 55, 63, 25, 12,198,250, 6, 13, 26,168,153, 76,230,159,159, 29,218, 92,175, 94, 61, 53,139, -197,218, 84, 69, 78,243,118,237,218, 25,194,195,195,105, 63, 63, 63, 26,128,213, 55, 44,119, 7, 43, 43,171,171,230,230,230, 73, -102,102,102, 59, 1,136,170,201, 73, 0, 24,234,228,228, 20,214,177, 99, 71,165,147,147, 83, 40,128,190,223, 48,157, 61,127,252, -241, 71, 42, 41, 41,137,166,105,154, 78, 74, 74,162,127,252,241, 71, 10,133,142, 34,191,166, 77, 94, 50,101,202, 20,250,241,227, -199,244,227,199,143,233,208,208, 80,186,103,207,158, 20,128,159,190,178,157,199,183,186,119,175, 58, 54,117,191,171,111,117,106, -248, 0, 95,234,198,197,173,244,242,159, 39,211, 93,252, 26,210,158,245,172,206,185,187, 91,187,127, 11,206, 95,126,158, 68,119, -254,161, 1,229, 85,215,234,164, 87, 29,155,186,255,230,123,255,255,104,213,194,223, 61,225,236, 95,166,197, 79,197, 82,217,168, - 89,179, 38,178,179, 91,241, 89, 44, 95, 30,143,215,129,193,100,222,201,201,204,156, 93,244,186,101,248,119,153,106, 43,236,208, -235,130, 91, 65, 72,130,234,112,126, 50,145,189,154,156, 85,225, 48,138,179,188,160,210,148, 70,147,106, 77,146, 47,118,162,194, - 60,248,132,211,201,201,105, 2, 69, 81,110,198, 38,136,193, 96,196, 75, 36,146,125,213,201,207,250,245,235,211, 69,195,219,196, -183, 44,247,191,163, 46,253, 47,113, 30,254,173, 81, 77,207, 70,223, 45,136,120, 25,181,185,104, 88,177, 4, 43,102, 88,153,249, -118,108,191,236,225,237,187,191,174,216, 41, 43,248,135,239,157, 1, 35,231,180,125, 3,206, 98, 39,161, 85,226,100,179,217,129, - 45, 91,182,156,240,228,201,147, 63, 13, 6,195,196,255,209,250,217,147,201,100,206,247,240,240,104, 26, 19, 19, 19,102, 48, 24, - 54,163, 12, 71,145,213, 72,231,207,110,110,110, 83, 57, 28, 14, 79, 46,151,203, 82, 83, 83,151, 1, 56,245,159,150,159, 94,245, -107,248,208,116,137,211,237, 53,239, 62,230, 60,251,102,156, 52,101,160,104,230,234,152,184,236, 87,255, 64,185,255,127, 19, 89, -123,255, 29,127,220,217,196,105,226, 52,113,154, 56, 77,156,223,156, 83, 96,202, 79, 19,231,255, 67,206,255,151, 96,153,178,192, - 4, 19, 76, 48,225,191, 14, 42, 83, 22,152, 96,194,127, 28, 74, 91,181, 74,172, 89, 68, 5,170,180, 42, 38,193,234, 40,219, 91, - 38, 78, 19,167,137,211,196,105,226, 52,113,154, 56,255,231, 56,255,191,138,172,189, 21,252,254,219, 96, 50,171,154, 56, 77,156, - 38, 78, 19,167,137,211,196,105,226,252, 95, 16, 90,101,254, 54, 13, 29,154,240,183, 99, 71, 63, 56, 1,192,204,243,144,252, 29, -231,155, 96,130, 9, 38,152, 96,194, 63,140,189, 40,103,232,240, 63, 65,104,213, 4,208, 26,133,129,111,163, 1, 60, 0, 32,251, - 10, 62, 27, 0,131, 9,130, 24, 4, 0, 52, 77,159, 70,225,170,145, 44, 99, 46,230,243,249,233,106,181,218,174,232,123,134, 90, -173, 46, 29,203,128,192,151,171,217,232, 82, 91,153,112,115,115, 75,215,104, 52,118, 70,252,125, 30, 77,211,175, 25, 12, 70,132, - 88, 44,190, 29, 19, 19, 19, 92,149, 27,239,208,161,195,104, 38,147,185, 6, 0, 12, 6,195,146, 59,119,238, 28,250, 27,203,173, -149, 75, 77,135,131, 58,189,142, 76,207,204, 89,134, 47, 29,249, 1, 0,118,245,194, 58,130,196,130,162,239,155,166, 5, 87,236, - 71,167,170,231, 87, 0, 31, 54,155, 61,221,222,222,190,123, 74, 74,202, 11, 0, 11,129,202,189, 26,187,184,184,252,196, 98,177, - 70, 24, 12,134,186, 76, 38, 51,150, 36,201,163,201,201,201, 65,166, 54,196, 4, 19, 76, 48,193, 4, 35,196,214, 23,168,146,208, -242,180,134, 3, 13, 12, 5,129, 46,160,113,147, 0, 78, 68,103, 35,205,216,235,123,120, 66,175, 39, 11,255,147,195,128,225,234, - 71,198,222,238,221,187, 59,207,152, 49, 3,223,127,255, 61,158, 60,121,210,230,192,129, 3, 99, 79,157, 58,245,154,162,168, 59, - 0,158, 0, 70,185, 82, 16,161,208, 79,203,240,238,221,187,119, 94,179,102, 13,179, 97,195,134, 80,169, 84,184,123,247,174,239, -166, 77,155,182, 61,122,244,232, 22,128, 99, 69,130,160,220, 0,120,106,181,218,174, 56, 24, 39, 65, 16,118, 3, 7, 14,124, 86, - 90, 92, 21,197, 87, 35,104,154,126, 76, 16, 68,168,193, 96,120,114,230,204,153,100, 79,160,213, 36, 55,206,153,217,241, 58,231, -207, 57, 53, 26,141,221,133,141,107,193,226,241,160, 41,200, 71,155, 49,255, 18,189, 55,127, 89, 0,130, 34,193, 4, 45,235,176, -122,219,107, 0, 17,169,169,169,175,253,252,252,226,171, 90,194, 76, 38,115,205,181,107,215, 28,105,154,134,191,191,255, 26, 0, -127,151,208,226,181,246,105,114,231,210,217,227,124,121, 78, 58,186,245,123,156,100,255, 0, 0, 32, 0, 73, 68, 65, 84, 29,114, -244,125,114,198,104, 0,103, 63, 17, 77,221, 97, 79, 16, 88, 48,101,237, 49, 38, 0,236,254,121,248,194,173, 93,177, 99,206, 13, -164, 1,232, 80, 36,126, 0, 96, 35,128, 59,187,186,195, 30,192,162, 41,107,143, 17, 0,176,231,231,225, 11,118,117,199,246,105, - 87,171,236,182, 98,234,232,209,163,119,172, 89,179,134,233,232,232, 8,137, 68,210,173, 65,131, 6, 30,249,249,249, 13, 80,193, - 36,226,218,181,107,159,108,215,177,119,157,254,131,134, 10,109,109,172,144, 42,205, 50, 63,121,252,207, 73,204,199,119,187, 39, - 36, 36, 12, 49,181, 33, 38,152, 96,130, 9, 38,148,131,234,123,134,111,230, 8,129, 66,135, 31, 89, 76,226,167,182, 62, 13, 58, - 13,235,209,142,209,192,171, 62,222,190,137,234,122,241,246,211, 77,140,208, 55, 33,164,129, 14, 18,113,112,225,149,180,226,149, - 48,122, 18,172, 27, 23,142, 21,246,132, 99,135, 51,159, 61,123, 86,191,121,243,230, 37,161, 97, 58,117,234,132, 78,157, 58, 17, -187,119,239,110,114,227,198,141, 38,251,247,239,215,133,132,132, 28, 68,197,254, 81,166,215,171, 87,111,211,142, 29, 59,120,126, -126,126,224,241,120, 37, 7,196, 98, 49,122,247,238,141,222,189,123, 51, 83, 83, 83,253, 47, 93,186,228,191,113,227, 70,109, 98, - 98,226,124,252,203, 75,115,133, 88,182,108,153, 79, 25,187,175, 17, 4,241,145, 36,201,176, 38, 77,154, 36,123, 0,245, 39,245, -248,254,230,212,182,238,162,217,139, 15,148,201,195,226,114,113,120,116, 97, 95, 93, 90,104,197,223,190, 10,177,185, 89,182,208, -204,236, 53,128, 8, 0,175,105,154,142,136,141,141,141,250, 14,104,210,218,138,113,240, 79, 25,213,184, 10, 98, 11,201,201,201, -176,176,176, 16,248,249,249, 73, 9,130, 88,113,247,238,221,111, 61, 33,175,213,138, 5, 83, 57,178,132,215, 72,123,247, 24,115, - 7,249, 10,103,239,252,235, 87,181, 86,127,182,162,139, 8,130,193,216, 24, 74, 5,160, 48, 24,239,178,236,236,108, 63, 0,176, -182,182,230, 2,184,179,245, 41,122,204,105, 75,124,141,111, 55, 14,147,201,220,117,224,192,129,241, 63,253,244, 83, 97,232,136, -135, 15, 33, 22,139,177,106,213,170,218,243,230,205, 91, 71,146,228,172,242, 44, 89,237, 58,246,174,179,125,243,175, 13, 10,114, -242, 52,127,236, 58,245,188,166,183, 39, 99,202,244,121,102,219,117, 26, 7,131,193,240,147,201,178,101,130, 9, 38,152, 96, 66, - 85,172, 89,149, 10, 45, 15, 27, 28,106,230,237, 62,120, 88, 79, 95, 94, 35,239,134,224,240,254,229,186,165,185,143, 15,154,251, -248, 48, 2,228, 5, 93,158, 61,127,217,229,204,141, 39, 26,165, 62,241, 84, 76, 22, 70, 27,155,170,226,160,180,107,250,218,119, - 84,228,102,240, 1, 64,100,105,167,254,249, 66,218,237,182,109,219,194,217,217,153, 19, 18, 18, 50,174, 18,161,245,115,116,116, - 52,143,201,172,216, 31,106,205,154, 53, 49,112,224, 64,120,122,122,114,219,183,111,255,115,121, 66,139,207,231,103, 16, 4, 97, - 7, 0, 53,106,212, 48,172, 88,177, 34,140, 46, 4, 0,208, 52, 77, 63,102, 48, 24, 79, 40,138,122,250,215, 95,127,165, 52, 0, -236,186, 53,247,124, 48,117,228, 64, 33,125,102, 91,185, 34, 65,157,159, 95,230,126,161, 88,148, 41, 16,137, 94,243,132,252, 8, - 20,198,242,138,112,118,118,142,106, 0, 56,183,244,116,187,177,123,206,112,179, 63, 39,254, 90,105, 94, 54,107,214,204,163,113, -227,198,124,131,193, 0,133, 66,129, 61,123,246, 88, 8, 4, 2,139,238,221,187, 47, 47, 93, 1,188,128, 70, 3,106, 50, 39,174, - 76, 53, 76,171, 70, 69,178,108,215,198, 39, 97, 96,239,238,230, 62,173,219,225,253,157, 35,200,201, 41, 64, 94,174, 28, 20, 69, -125,225,215,103,218, 85,164,239,234,133, 77,187, 23, 15, 95, 68, 48, 24, 68,147,126, 11,209,199, 33,111,102, 96, 96,224, 27, 0, -108, 46,151, 91,186, 30,214, 20, 56,121,111,170,223,181, 29,246, 44, 25, 9,154,162,104, 0,155,170, 96,205,178, 51, 51, 51,187, -120,227,198,141, 86, 45, 90,180,192,147, 39, 79, 16, 23, 23,135,169, 83,167,106,167, 77,155,198, 25, 53,106, 20, 49,119,238,220, - 25, 27, 55,110, 60, 3,224,209, 23, 15, 2,139, 53,162,111,255, 33, 92,121,110,190, 90,171,209,105,107,216, 88, 82, 26,133, 90, -153, 37,203, 87, 15, 25, 62, 65,251,230,213,211, 17, 0,190, 16, 90, 95,153,159, 38,152, 96,130, 9, 38, 24, 1,154,166, 91, 0, -176, 5,144, 73, 16,196,243,210,191,139, 78, 41,142,214,242,249,239, 44, 20,142, 74, 89,151,162,203, 66,225,116, 31, 91, 0, 6, - 0,207, 8,130,144,125,101, 18, 43, 94,101, 24, 28, 28, 76,151,254, 44, 37,180,104,154,166,105,125,246, 71, 90, 19,115,149, 86, - 62,223,247,197,166,122,115,150,150, 62, 59, 69, 63, 61,246, 11,237, 97, 83,113, 20,246, 30,158,208, 15,111, 12,122, 74, 11,208, -179,218, 91,170,159, 61,123, 22, 66, 81, 84,112, 64, 59,208,244,219, 99, 52,253,246, 24, 61,167, 13,232, 51,103,206, 92, 91,183, -110, 93,112, 80, 80, 80, 48,128,202,230, 41,165, 23, 60, 15,165,159,218,129, 46, 15,209,209,209,116, 96, 96, 32,189,120,241, 98, -250,207, 63,255,164, 81,137, 7,117,127,127,255,187,145,145,145,244,168, 81,163,194, 80,129, 99, 64, 47, 64, 52,162,182,195, 59, -205,201,109, 58,237, 79,141,104,217, 15,252, 50,239,223,209,209,241,147,244,172,119,119,160,127,111,233, 78, 31,234,210, 60,141, -166,233,107, 52, 77,175,167,105,122, 8, 77,211,158, 0,208, 12, 48,239,235,104,253, 65,125,106,187, 74, 59,177,117,165,113,239, -154, 53,107,230, 49,127,254,252, 28,173, 86, 75,199,199,199,211,127,252,241, 7,125,243,230, 77,250,194,133, 11,180,175,175,111, -106,169,244,218,143,245,116, 77,215,238, 95,169,169, 78, 45, 98, 51,153,191, 63,191,121,134,254,240,224, 52,253,236,196, 58,250, -232,210, 97,244,140,190,173,116,230, 2,158, 26, 64,199,242,174,155,214, 22,245, 61,107,219,198, 36, 38, 38,210, 58,157,142, 30, - 51,102, 12,237,239,239, 79,119,237,218,149,238,220,185, 51,221,169, 83, 39,186, 99,199,142,244,237,219,183,233,212,212, 84,186, -115,187,230,138, 94, 94,240,169, 66,210,188, 93, 93, 93,211,226,227,227,105,157, 78, 71,135,132,132,208, 71,142, 28,161, 67, 66, - 66,232,128,128, 0, 26,192,161, 41, 83,166,168,100, 50, 25,237,239,239,159,130, 50,188,198,187,186,186, 70, 69,198, 36, 39,111, - 93,187,239,246,225,223,143,223, 62,119,230,230,237,139,215,159, 93,190,112,253,249,169,167,225,177, 23, 92, 93, 93,163,202, 40, -255,175,202, 79, 19, 76, 48,193, 4, 19, 42,215, 34, 69, 66,171,103,145,177,163, 39, 77,211,157, 63,251,221,179, 72, 56,125,241, - 59, 32, 32, 96,113,233,223,197,231, 4, 4, 4, 44, 6, 64,183,105,211,230, 56, 77,211,245,191, 65,242, 39,150,177, 85,110,209, - 42, 6,153,242, 12, 28,247,238, 96, 27,244,208,103, 69,131,202, 77, 4, 68, 14, 80, 17, 98,100, 75, 19,241,238,193,217,138, 3, - 73, 20,225, 74, 52,216, 0, 66,162,162,162,240,238,221, 59, 36, 39, 39, 67, 40, 20,126,113,222,195,135, 15, 33, 16, 8,224,232, -232,104,156,210,213,126,218,207,189,110,238, 10,113, 27, 63,100, 13,155,140,144,144, 16,100,100,100,128,195,225,128,203,229,130, - 36,201, 74,249, 24,140,194,136,191,197, 86,172,178,206,241, 3, 88,188, 26,226, 75,187,151,207,114, 99, 60, 14,102,171,146, 62, - 32, 85,109, 48,206,146, 39, 22, 65, 40, 18, 74, 5, 2, 97,201,112, 33,128, 8,130, 32,222, 55, 3,216, 34, 49,255,210,193,213, -115, 29,152,175, 66,248,170, 15,175,203,228,232,220,185,243, 36, 0,203,105,154,206,109,220,184,177,253,154, 53,107,172, 36, 18, - 9,222,190,125,139, 83,167, 78,101,146,133, 55, 74,208, 52,189, 18, 0, 90, 3,124, 75, 91,203,235,191,255, 50,203, 12,119, 78, -114,171, 83,139, 44,188,122, 95, 30, 48,106,202,180, 29,179,122, 67, 81,160,194,177,155,175,112,237,229,199, 62, 0, 30,162,130, -121,111,187, 30,225, 3,144,217,169,127,255,254, 97,247,239,223,183,217,191,127, 63, 72,146, 44,115,219,191,127, 63,110, 61,120, - 57, 19,192, 11, 35,147, 85,211,205,205,237,214,211,167, 79,109,133, 66, 33,110,222,188,137,220,220,220, 18, 75,214,232,209,163, -137,220,220,220,161,123,246,236, 25,144,144,144,176,249,193,131, 7,217, 40,140, 5,249, 73, 69, 96, 50,153, 31, 73, 82,247,157, -163, 87,125,214,160,222,237,218,201,179, 95, 67,108,221, 24,143,195, 63, 94,202,149,101,171,152, 76,230,199,210,231,127,139,252, - 52,193, 4, 19, 76, 48,161,106, 32, 8, 34,152,166,233, 94, 4, 65, 4,127,190,239,243,239,197,231,173, 91,183,174,228,119,241, - 53,235,215,175, 95, 91,234,183,242, 27, 37,175,194,201,240,237,139, 20,100,251,178, 78,210,188, 61, 7,205,187,139,224,184,182, - 5,215,179, 15,152,174,190, 72,122,125, 7,225, 87,183, 34,229,205, 67,208,148, 1,142, 30, 45,141, 77,136,250,187,239,190,131, - 90, 93, 56, 53, 75,163,209,128, 35,178, 82,207,157, 56,156, 15, 0, 20,139,175, 41,165, 96,141, 34, 52,107,219, 1, 45,211,105, - 60,179, 47, 52, 84,180, 76, 47,188,110,245,152, 49,224,112, 56,224,112, 56, 32,138,166,254, 24, 35,180,136,162,147,169,194,225, -171,178, 18, 65, 40,121,236, 99, 39,150, 79,111,201, 75,136,224,106, 34, 31, 35, 85, 67,209,151,210, 13,151,141, 73,175, 80, 36, -148, 8,132,194, 8,129, 88, 84, 34,180, 8,130,248, 8, 0, 52,155, 29,116,100,229,244,198,162,244, 88,145,250,121, 8,164,106, - 74, 87, 14,205,202,171, 87,175,218,177, 88, 44, 7,131,193,128,164,164, 36,188,121,243, 6,219,183,111, 79, 47, 40, 40,104,255, -234,213,171,152,210,218,209, 32,224,158, 10, 90, 53,171, 14,235,245, 61,190,230, 99,100,149,107,143,141,247,143,254,125,218, 55, -185, 60,105,228, 18,252,216,163, 43, 70,181,111, 64,199,167,230,168, 1,220, 44, 50,189, 86, 6,201,171, 87,175,186,252,240,195, - 15, 71,155, 54,109,234, 69,211, 52, 26, 53,106,132,161, 67,135, 34, 40, 40, 8,225,225,225,200,207,207,215,221,184,113, 99, 27, -128, 3, 70, 38, 75,104,101,101,117,237,246,237,219,182, 66,161, 16, 55,110,220,128, 74,165,130,163,163, 35,166, 77,155,198, 93, -191,126,253,225,252,252,252, 65,235,214,173,227,199,199,199,255,126,253,250,245,218, 40,140, 59,247, 69, 37,208,106,181,123,143, - 5, 29,218, 49,109,250, 12,167,219, 79,222,134,104,228, 5, 22,174,174,201,249,182, 86, 98,179,109, 27, 86,214,210,106,181,147, -202,206,207,187,213,202, 79, 19, 76, 48,193, 4, 19,190, 64,133, 90,164,180,120,250, 92,108, 85, 69,164, 1, 80, 5, 4, 4,252, - 76, 16, 68,112, 64, 64,192,207,235,214,173, 83, 1, 72,253, 59, 68, 86,137,208,234,213,171,215,189,224,224, 96,244,234,213,235, - 94,185, 20,148, 1,186,248,251,208,197,223,135,160,205, 76,252,181,110,216,103, 55, 79, 85, 59,117,189, 87,221,188,173,209,104, - 88,135, 14, 29, 42,153,183, 5, 0, 6,131,225,155,151, 98, 85,132, 86,145,208,251, 34, 17,110, 60,241,189,189,115, 6,181,182, - 54, 40,217,218,135,151, 32,209, 80,228,230, 15, 58,229,243, 92,122, 99,121,156, 23,102, 79, 66,242,131, 91, 16,138,197,201,227, -239, 71,148, 88,177,138, 68, 86, 28, 0,212,230,153,133, 4,206,250,209,215,129, 3,142,246,242,105,164,106, 40, 77, 96,130,254, - 64, 57,149, 13, 52, 77,255, 31,123,223, 29, 22,197,213,120,125,102,182, 47, 75,239,160,128,138,162, 52, 65, 81, 20, 27, 98,137, - 26, 49,177,247,146,152,232,107, 55,150,136, 26, 99, 73, 20, 18, 99, 47, 81,147, 24,203, 27, 11,177, 69, 68,141, 45,104,196,134, - 40, 93, 80, 68,154, 75,111, 11,108,159,153,239, 15, 96, 69,100,217, 5,205,247,203,155,236,121,158,125,102,103,103,230,236,157, -123,103,238, 61,247,220,134,231,207,159,163,186,186, 26,209,209,209, 56,117,234, 84, 97, 35, 34, 11,109,249,198,127,252,244,249, -148, 30,166,146, 60,174,226,193, 85,188,148,211,122, 53,117, 89,119, 30,217,155, 75, 18,191, 19, 36, 75, 56,176,103, 71, 44,254, -116, 20,182,253,244,155, 90, 97,219, 55,120,231,185,200,241,149,114,229, 42, 61, 69,150,198,108,140,141,141,245,140,141,141,229, - 3, 8,154, 56,113, 98,228,152, 49, 99, 16, 21, 21,133,243,231,207,187, 1, 16,215,158,183, 1, 53, 11,101,127, 11, 32, 93,155, -241,200,229,114,143, 95,189,122,213,203,209,209, 17, 87,175, 94,133, 84, 42,197,156, 57,115, 20,243,231,207,231,206,152, 49,131, - 40, 47, 47,215, 56, 89,209,209,209,197,218, 68, 22, 0,228,230,230, 94, 60,117,242,104,175,126,253,250,141,106,231,214,201, 52, - 93, 82, 81, 96,100, 36, 16,222,138,186,193,125,112,239,246,238,220,220,220,251,141,199,231, 53,189,227,211, 0, 3, 12, 48,192, - 0,237,208, 75,139, 52,112,166,154,131,122,215,113, 66, 67, 67, 19, 67, 67, 67, 95,115,188,222, 18, 13, 71, 29, 94,168, 43,211, - 90, 52,143, 22, 85,158,245,230, 13,208,116,115,110,246,141,223, 44, 44, 44,212, 66,161,240, 53,161, 69,235,201, 89,114,230, 24, -210,231, 78,214, 56, 89,117,206, 22,134,206,120, 43,161, 69,211,116, 52,128,215, 2, 97,100,219,113,210,246, 17, 30,189, 61,219, -181, 34, 85, 39,119, 32,167, 90, 45, 91,251, 68, 41, 75,145, 48, 31, 36, 55,210,201, 90,195,169, 86, 65, 32, 18,102, 10,141, 69, - 13, 69,214, 11, 0, 16,217,185,141,249,110, 88,167,254,190,157,218,147,234, 19, 91,145, 91,173,170, 12, 73, 86, 42,211,171,152, -211, 90,226,112,237,123,239,189,183,214,202,202, 74,176,115,231, 78, 51, 23, 23, 23,168,213,106, 69, 67,145,101,100,219,113,210, -142,145,222,189, 59,218, 91,144,170, 95,119, 33, 91, 74, 85,239, 72, 87, 29,214, 71,100, 89,155, 25, 95,222,183,105,174,208,136, -207,129, 76, 38, 67,216,222, 95,241,251,237,132,224,162,132,179,151, 1, 92,126,139, 7,242,147,224,224,224,109, 27, 54,108,128, - 74,165,194,204,153, 51,241,236,217,179,223,159, 60,121,178,195,217,217,121,217,231,159,127,238,104,111,111,143,241,227,199,115, - 85, 42,213, 12, 45, 28,223,252,242,203, 47,193,190,190,190,136,138,138, 66, 89, 89, 25, 28, 28, 28, 48,127,254,124, 94,104,104, -232,225,138,138,138,113,155, 54,109, 18, 60,127,254,188, 73, 39,235,181,231,154,162,190,222,191,109,238,178,238, 61,251,144, 79, -159,166,170,179,252, 3,201, 27, 87,207,223,180,178,178, 58,156,149,149,245, 42, 62, 71,117,110,118,124, 26, 96,128, 1, 6, 24, -240,110, 64, 16,196,133,218,126, 87,175,185, 92, 13, 69, 88,157, 99, 85,127,191,225,249,181,199,223, 69,101,249, 64, 35,194,235, -245,233, 29,130,131,131,245, 30, 86, 79, 87, 21,234, 37,158, 26,226,253, 78, 80,181, 50, 6,123, 85, 32, 9,174,200, 66, 54, 98, -195,149,235,218,206, 21,137, 68,122, 59, 90,180, 92,166, 43, 81,154, 37,180,106,251,104, 93, 98, 24,230, 53,161,101,102,215, 49, -112,197,231,139,182,247, 25, 51,148,204,255, 52, 0,101,149,114,249,231, 73,106, 58,167,186,105,145, 85, 83,138,171, 50,140, 68, -198,241, 2,145, 81,125,145,149, 5, 0, 2,219,246,254,203, 23,207,219, 59, 96,210, 8,162,112, 78, 31,148,150, 73,229,203, 18, -213, 68,174,148, 25,151, 12,220,104,140,238,250,245,235,251, 1,236, 15, 12, 12,204, 23,137, 68,168,172,172,124, 35, 13,234,194, -219,123,204, 80, 50,255,147, 30, 40,169, 82,202, 63, 79, 84,227,165,148, 62,174, 75,100,217,152,155, 92,222,183,113,174,209,203, -156, 23,224,114,185, 48, 54, 54,198,149, 63,227, 81,148,120,238,109, 4, 22, 72,146, 92, 23, 18, 18,178,118,222,188,121, 40, 46, - 46,198,249,243,231,241,254,251,239,227,216,177, 99, 46,145,145,145,219,130,130,130,192, 98,177, 16, 17, 17, 1,149, 74,149,166, -133,102,212,172, 89,179,150,141, 25, 51, 6,247,239,223,135, 88, 44,126,205,201, 42, 43, 43,155,184,119,239,222, 49, 25, 25, 25, - 58,157,172, 6,240,111,219,190, 43,119,229,154, 45,144, 87, 23,176, 11,115,239, 70, 93,187, 66,222, 41, 41, 41, 49, 2, 80,222, -210,248, 52,192, 0, 3, 12, 48, 64,111, 87, 75,155, 22, 41,172, 21, 81,133,141,237,215, 19, 88,141,237, 19, 13, 92, 48, 69,131, -227,143,255,202,123,210,203,209, 98,219,121, 67,157,159, 80, 79,104, 21,188,118, 92, 96, 98,169, 87,211,161, 74, 13,246,190,131, -154,121,180, 4,197,197,197, 2,107,107,107, 89,125,129, 96,100,100, 4, 71, 71, 71,148,150,150,226,192,129, 3,128,238, 78,209, -106,211, 49, 83,225, 63,105, 38, 30,180,230,129, 81, 41, 53,206,214,190,143, 62,122, 77,108,113,185,220,186,190, 97,186, 10,221, -123,181, 78,211, 29, 0, 76, 87,183,118, 95, 9, 68,162,143, 4,214, 78,214,139,231,126,194,201, 40,144,227,122,159,149,101,191, -126,179,194, 56,155, 49,158,151,133,242,219, 58,248,210, 63,252,254,104, 67, 39, 43,167,139, 91,187,213, 2, 35,193,167, 60,203, - 54,246, 33, 75,230,114, 50,242,229,196,117,255,207, 43, 78,125,251,185,209,115,152, 44,203, 65,217, 13, 61,146,103,237,251,239, -191,191,150, 97, 24,134,166,233, 53, 0, 80, 63,188, 75,230,127,202, 73,207,147,225, 90,159,213,165,167,190, 89, 97,146,141,166, -195,107,221,121,100,111, 59, 11,211,203,251, 54,205, 51, 18,231,102,130,207,231,195,196,196, 4,217,249,229,224,176, 89,210,183, -124,222,248,125,251,246, 93, 49,119,238, 92,196,199,199, 99,206,156, 57,226,172,172,172,211, 39, 78,156,152,243,229,151, 95,178, -135, 12, 25, 2,177, 88,140,205,155, 55,171,254,252,243,207, 77, 0, 54, 55,250, 60,178,217,159,124,245,213, 87,204,203,151, 47, -137,231,207,159,195,193,193, 1, 11, 22, 44,224,109,218,180, 73,211, 39,171, 57, 78, 86, 29,114,115,115,163,126,191,122, 7, 31, - 92,220, 14,181, 74, 30, 85, 86,156,117, 51, 37,189, 52,202,146,199, 91,218,170,107,231, 22,197,167, 1, 6, 24, 96,128, 1,239, -196,197,122,208,212,254,223, 0,141, 53, 29,234, 37,180,210,118,173,254,216,237,227,121,203, 33,116,233, 13,121,242, 25,208,149, -249, 26, 71, 75, 96,108, 1, 75,103, 15,148, 85,201, 17,126,237, 33, 0,164, 53, 39, 84, 18,137, 4,126,126,126,216, 51,163,227, - 0,153,164, 88, 32, 4, 32,231,155,202,206,242,250, 94,143,140,140,172,166,105,250, 56,128, 72, 29, 52,235,188,188,188,118,111, -217,178,133,231, 49,233, 99, 84,222,189,213,208, 65,129, 80, 40, 4,159,207, 71, 92, 92, 28,174, 95,191,174, 0,176, 78, 71,130, -222, 83,171,213,143, 79,156, 56,145,211,161, 93,171,161,126, 93,124, 22,174, 90, 25, 98,146,116,235,119,172,217,180,155,238,208, -109, 72,121,216,177,179,146,114, 99,231,129, 82,241,147, 71,122,220,234,227, 6, 34,235,165,123, 91,167, 1, 93,188,189,150,175, - 89,179,218, 52,241,214, 21,124,249,237, 62,198,205,119, 80,249,183,167,206, 85, 20, 25,181,121, 79, 86,144,114, 95,159, 56,140, -138,138,218, 15, 96,127,221,126,195,240,134,108,216, 65,119,236, 62,180, 52,236,216,169,170, 10, 19,231, 65, 77,133,215,198, 99, - 84,175,214, 54, 22,151,119,125,253, 31,163,188,220, 44,240,249,124, 24, 27, 27, 35, 75, 92,134,181,219, 79, 86, 41,105,122,232, -219, 10, 45, 19, 19, 19,190, 82,169,196,158, 61,123,144,149,149, 21, 0, 32, 43, 38, 38,102,223,132, 9, 19,118,118,238,220,217, - 61, 49, 49, 49,173,178,178,114, 30,128, 20,109, 36,230,230,230, 1, 54, 54, 54,196,157, 59,119,240,159,255,252, 71,177, 96,193, - 2,238,244,233,211,137,210,210,210,150, 58, 89, 0,128, 86,173, 90, 5, 14, 30,216, 19,189, 7,207,137, 82,200,202,110,102,164, - 28,142, 34,153,219,130,150,198,167, 1, 6, 24, 96,128, 1,255, 26,180,108, 98,240, 64,128,221,209, 10,179,189, 90,113,243,142, -124,179,128,145,164, 71, 51,210,251,251,153,138, 51,159, 50, 23, 54, 79,103, 34,119, 45,102,230, 12,247, 98,220,109,137,188,142, - 86,152, 29,248,166,112,123,109,117,239,247, 59, 65, 53,184, 61,152,193,237,193, 12,239, 8, 21,128, 85, 93,187,118, 61, 59,223, -255,213, 60, 90,243,253,193, 0,248, 15, 0, 99, 45,193,106,108,197,112, 7, 0, 7,252,252,252,212, 55,110,220, 96,158,140, 27, -196,196,186, 91, 51,243,230,205, 99,190,252,242, 75,102,242,228,201,140,141,141,141,186, 54, 34, 28,116,113,126,240,193, 7,173, - 1,192,201,201,201,188,155, 71,135,188,184,107,231,153,155, 71,118, 50, 63,205, 31,205,244,232,236, 81,100,239,222,239,177,208, -161, 83, 23, 29,209,167,225,180,183,183, 95,201, 48,204, 80,134, 97, 28, 0,192,205,205,202,184,171,123,135,151,143,175,158,103, -110, 29,221,205,252, 52,127, 52,211,211,199,179,184,181, 71, 80,138,192,214,221, 95, 31,206,198,208,104,120,189,221,139,236, 58, -244,122,212, 68,120, 53,156,237,252,199,159,203,121,153,207,220,187,119,143,137,140,140,100,110,221,186,197, 28, 57,113,142,113, -238, 62,174,210,186,243,200,222,205,120,116,180,133,211,108,248,240,225, 76, 90, 90, 26, 51,108,216, 48, 6,128, 89, 11, 57,207, -102,100,100, 48, 9, 9, 9,204,170, 85,171, 24, 0,135,230,206,157, 43, 45, 47, 47,103, 6, 13, 26,148, 85, 43,176,216, 45, 9, -167,107,219, 86, 97,163, 70,244, 93, 55,255, 63, 99, 2,223, 54, 62,223, 33, 12,156, 6, 78, 3,167,129,243,223,192,249,191, 12, -135, 90, 87,171,110,219, 85, 47, 71, 43, 10, 80,163, 24,251,189,109,149,255,221,180,121,215,210, 61,251, 15, 45, 95,177,240, 19, - 81,223, 62,131, 17,127,245,103,156,138, 56, 81, 37,147, 43, 54,115, 89,216,146, 80,140,234, 84, 29,161,168,157, 71,235, 53,196, -198,198, 26, 89,182,127, 53, 7,211,211,154,185, 89,247, 53,243, 6,197, 0,102, 61,124,248,112, 75, 80, 80,208,198, 79,123,251, -143,158,223,107, 0, 84, 42, 21,142, 28, 57,130,204,204,204,211, 0, 86,235,235,184,197,199,199, 23,121,182,119, 89,196, 97,177, -151,207,155, 60,202,166,240, 89, 18,114,146, 99, 1, 0,114,185, 84,149,151,118,211,183, 57,129, 19, 10,133,247,108,108,108,158, -216,216,216,148,118,108,231, 52,139, 15,206,154, 57, 19, 63,180, 45,206, 72, 65,118, 98, 77,203,168, 92, 86,173,204, 73,187,225, -222,146,212,117,113,113,225,139, 56,152,221,104,120, 21, 50, 85,254,211,148, 46,250,240, 84,203, 21,155,214,111, 59,242,222,215, -203, 63,226,155,154,154,226, 97,194, 83,172,217,122,172, 74,170, 80, 13, 45,138, 63,251, 78,154,199, 24,134,129, 74,165,210,123, -160,131, 22,172,240,245,245,237,180,113,227, 70,183, 25, 51,102,224,109,157,172,250, 72,207,200, 13,105,229,228,234,249,244,201, -195, 32, 75, 33,247,191,111, 19,159, 6, 24, 96,128, 1, 6,252,107, 48,188,214,204,153, 85,111, 27,171, 83,104,213, 33,161, 0, -213, 0, 54,180, 99, 85,238, 91,185,113,219, 90,146,216,254, 17,205, 48, 63,171, 73,172,127, 94,140,194,183, 12, 92, 53,135, 13, -245,123, 35, 39,179, 1,128,195,110, 89, 1, 89,139, 52, 0, 99,126,184,125,191,251, 15,183,239,127, 81,251,219,215, 0,154,213, -150,107,194, 70, 66, 31, 79,215, 86,125,187,122, 9, 88,148, 20, 57,201,207, 80, 82, 37,195,149,196,204, 50,146, 33,127,110,110, -160,158, 63,127,254, 7, 0,216,153, 25, 37,247,245,108,239,220,207,207,203,136, 67, 40,144,147,244, 16,229, 82, 5,126, 79,204, - 44, 7, 65,180,184, 67,245,187, 10,111,126,252,185, 7,191,129, 24, 68, 16,196,213, 85,243, 39,241,215,110, 61,254, 78, 69, 22, -128,234,220,220,220,226,234,234,106,171,151, 47, 95, 42,208,242, 73,226,158, 86, 84, 84,116, 94,188,120,241,134,101,203,150, 45, -255,230,155,111,184, 45,233,147,165, 13,165,185,153,103,250,121,189,187,244, 55,192, 0, 3, 12, 48,224, 95,129, 89, 13,182,208, - 91,104,105, 4, 67, 1, 10, 1,204,115,117,101,150,164,167, 67,241,174, 66,214,152,211,245,150,120, 0, 96, 68,139,175, 38, 9, -201,221,180,204,202,123,105,153,149,160, 25,134,102, 24, 57, 73, 34,187, 74,169,220,148,246, 60,183,229,163,238, 8,130,122,240, - 52, 75, 26,243, 44, 91,198,208, 52, 67, 51,140,130, 32,144,167, 82,209,155, 18,159,103,158,251, 59,132,183, 40,254,236,237, 8, - 53,209,247,246,189,132, 37, 85, 85,202,221, 69,201,103,163,223, 97,186,168,226,227,227,167, 4, 4, 4,124, 76, 81,212, 62, 0, -170,183,224, 82,168,213,234, 21, 97, 97, 97,167,227,227,227, 79, 70, 71, 71,139,223,133,200,250, 75,211,223, 0, 3, 12, 48,192, -128,127, 42, 90,182,168,180, 54,188, 75,145,245,119, 68,194,211, 23,126,127, 5,111,226,211, 23,222,255, 11,225,205, 79, 62, 19, -147, 15, 76,252,139,162,247,119,138,162,126,127,151,162,250,210,165, 75,109,209,200,178, 58,127,183,244, 55,192, 0, 3, 12, 48, -224, 31,139, 89,218,196, 23,219, 16, 55, 6,252, 3,192,188, 43,145,101,128, 1, 6, 24, 96,128, 1, 45,128, 86, 71,139,128,246, -145, 3, 87,155,241, 7, 45, 25,125,112,213,192,105,224, 52,112, 26, 56, 13,156, 6, 78, 3,231,191,142,243,159, 8, 7,212,116, -136,191, 80,187,109, 82,124,189, 75, 24,134,190, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,167,163,209,142,240, 64, - 77,231, 97, 3, 12, 48,192, 0, 3, 12,248,171,192,175,253,180,244,184, 1, 6,252, 47,138, 45,141,224,106, 73, 31,173, 14,181, -219,167,127, 97, 96,231, 59, 56, 56,204,242,241,241,241,224,114,185,164, 68, 34, 89,127,227,198,141,117, 13, 79,234,235,201,142, - 97,145,104,253,234, 23, 2, 32, 88, 0, 73,130, 98,144,115, 43, 78,218,205,144,238,127,107,184, 8, 77,109,126, 35, 72, 22,143, - 82, 43, 65,169,148,168,233,110, 85, 3,154, 86,103, 82, 74,249, 16,109, 23,219,251,142,114, 86, 83,244, 55, 0,179, 7, 32,231, - 2,244, 94, 2,236, 57, 12,212,223, 19, 96,253, 7, 44,230, 91, 80,196,231,108, 14,107,165, 56,246,215,236,127, 66,132,133,135, -135,179,222,230,250,113,227,198, 53,186,128,168,163,163, 99,132,145,145, 81,123,109,215, 85, 85, 85,137,197, 98,113,208, 63,252, -121,236, 7, 96, 23, 0,175, 6,191,167, 0, 88, 4,224,218,219,254, 65, 32,192,182, 3,102,115,129,207, 1, 64, 9,124,155, 15, -236,143,250, 27,245, 49,180,177,177,185,201,102,179,221,170,170,170,170, 36, 18,137,171,137,137, 73,186, 72, 36, 18,169,213,234, -180,194,194,194,126,205,164,155,139, 87, 75,105, 45, 7,176,183,153,199, 13, 48,224,127, 5,111, 53,234,176, 99, 77,254,128, 64, - 0,253,186,119,239,110, 87, 85, 85,133,148,148,148,124, 0, 55, 1, 68,213,126, 82,223, 69, 72, 73,146,252,110,219,182,109, 75, - 23, 44, 88,160, 89, 12, 58, 46, 46, 14,190,190,111,206, 17,202, 34,209,250,198,249,171,182, 15,226, 83,209,125,208,216, 90,161, - 69, 2, 85, 98, 4, 13,246,111,105, 16, 76, 44, 44, 44,214, 19, 4, 49,142, 36, 73,157,133, 26, 77,211, 20,195, 48,225,165,165, -165,107, 1, 72,154,243, 71, 34, 35,190, 74, 77, 81,141,254, 7,155,197,162,170,170,229, 90,167,189,176,180,180,140, 38, 73,178, - 93,253, 5,179,129,215, 23,208,214,118, 76,173, 86,231, 20, 21, 21,233, 35, 66, 5, 36,155,187,136, 32,184,131, 65,210, 29, 1, - 2, 4,200, 84,154, 82, 92,161,213,202, 29, 0,100,111, 35,178, 28,156, 92,111,125,182, 58,172,117, 66,114, 10, 86,205,159,140, -111,118, 29,194,202, 69, 31, 99,199,129, 99, 88, 52,107, 18, 60, 61,189,208,212,178,226, 52,184,155, 86, 47, 28, 55, 40,116,207, -201, 62, 43,231,141,227,135,238, 9,239,187,106,254, 4,222,166,221, 39,251,174,154, 63,158, 31,186,251,100,159,149, 11,199, 9, - 55,237,253,149, 6, 48,181, 37,129,156,228,230, 88, 69,168,213,141,214,182, 25, 54, 91,126, 44,237,165,232,255,226,141,158, 49, - 99,134,143, 84, 42,125, 56,121,112,215,176, 46, 29, 91,229, 54,118, 78,113, 94,110,171,244, 39,177, 33, 28,174,208,239,195,144, - 67,113, 77, 90, 14,124,126,187,148,148, 20, 55,154,166, 65, 81, 20,212,106,181,102,171, 80, 40,208,175, 95,191,119, 53,112,102, - 4,128,245, 53, 47, 43, 66, 1,156,124, 11, 46, 99, 54,155,253, 25,143,199, 11, 84,171,213, 30, 0,192,225,112,146,229,114,121, -148, 90,173,222, 6,160,178,153,124,219,115,115,115, 61,141,141,141,161, 84, 42, 53, 11,208,179, 88, 44,119,103,103,231, 61, 50, -153,204,237,109,111,222, 14,152,221,171, 79,159, 29,211,151, 46,101, 73,111,222,196,142,131, 7,183,163,162, 2, 0,246,232,186, -150,199,227, 93, 38, 73,210,165, 57,255, 71,211,116,166, 66,161, 24,210,156,107,216,108,182,219,203,151, 47,109, 29, 29, 29, 33, -145, 72, 32, 18,137, 68,117,251, 45,112,178, 54, 51, 12, 35,172,205,219,119,244,236,217, 51,128, 32, 8, 53, 0,134,166,105,242, -222,189,123,147,104,154,102,215,230, 79,155, 1, 28, 4, 32, 55,148,217, 6,252,143,186, 89, 7,154, 43,180, 34, 1, 4,118,239, -222, 93, 56,113,226, 68, 4, 6, 6,194,205,205, 13, 2,129,160, 38, 19, 47, 46,182,123,244,232,209,248,155, 55,111,142, 63,127, -254, 60,146,146,146,164, 0,254, 4,208,232, 75, 61, 48,184,207, 2,129, 49,127, 39, 0, 20,230, 20,139,115,158, 23,236, 20,139, -197,155, 1,212,159, 34,220,117,234,212,169, 75, 22, 46, 92,136,136,136, 8, 28, 59,118, 12,114,185, 28, 18, 73, 19,250,165,186, - 0,165,215,195, 0, 81, 6,144, 21, 5, 24,217, 2, 34,187, 22,199,148,133,133,197,250, 69,139, 22, 45,246,244,244,212,204, 98, -174, 82,169,160, 86,171,161, 82,169, 80, 90, 90,138, 37, 75,150,212, 20,180, 12, 3,154,166,113,241,226,197, 5,179,102,205, 66, -105,105,233,103,141,113,246,244,115,138, 33, 9,178,117,157, 87,195, 80, 84,206,221, 71, 57,221,212, 20,197,146,201,148,141,174, - 84, 46, 16,112,155, 20,121, 28, 14,167,117,210,111,191,217,146, 60, 30, 24,138, 2,104, 26, 12, 77,215, 70,103,237,135,169,249, -141,161,104, 48, 42, 10,180,154,134, 90, 42,135,255,220,185,250, 68, 69, 47, 14, 79,120,108,202,167, 75,237,123,244,236,201,105, -227,228, 8, 53, 69,227, 89, 70,142,253,195,152,187,189,195, 15,239,153,163,144, 74, 38, 1,104,209, 60, 91, 60, 35,211,223,119, -127,255, 67,235, 7,143, 18,112,237,198, 77, 92,189, 30, 5, 0,184,124, 35,186, 78,112,235, 76, 42,168, 43, 59, 47,154, 57,146, - 31,182,251, 56,103,209,204, 81,172,111,118,159,224, 44,252,248, 67, 86,216,206, 99,220,133, 31,127,200, 10,219,117,140,187,112, -230, 72, 86,232,142,159,124, 0, 88, 0, 40,213, 70,166, 45,141, 8,181,154,255,223,244,124, 22, 0, 20,238,219, 7, 85, 65, 1, - 28,215,174, 5, 0, 76,113,181,211,187,185,195,218,218, 58,134,195,225,180,214,117,158, 74,165,210, 41,130,103,204,152,225, 43, -149, 74, 99,212,106, 53,195,102,179, 67, 38,143,122,239,236,208,190,190,197,245,207,137,139,123,108,181,105,211,111, 35, 79, 62, -148, 48,227,253, 76, 30, 70,124, 55,163, 91,240,178, 67,143,155, 40,144, 73,185, 92,142,180,180, 52,212, 95,228,189, 30,168,150, -214,157, 0,236,176,178,178,234, 81, 92, 92, 60, 5,192,170,138,138, 10, 31, 22,139, 5, 75, 75,203, 85, 10,133,226,153,153,153, -217,143,229,229,229,209,181,174,145,190, 75, 6,244, 51, 53, 53, 61,114,230,204, 25,139,174, 93,187,146, 69, 69, 69,104,219,182, - 45, 74, 74, 74,252,111,222,188,233, 55,115,230,204,153, 18,137,100, 90,109,101, 80, 95,116, 50, 50, 50, 98,166, 79,159, 78, 80, -212,171,219,253,233,167,159, 48,196, 91,221,222,198,220,168, 90,166, 96,202,175,165,153,253,135,203,229,254,153,153,153, 89,222, -220,200,224, 2,159, 79, 95,186,148,101,252,226, 5,140, 31, 63,198,148,138, 10,246, 55, 53,238,150, 78,161, 69,146,164,203,145, - 99, 63,187,241,120, 60,168,213,106,141, 24,172,203,163, 84, 42, 21,148, 74, 37, 84, 42, 21, 40,138,130, 74,169, 66,232,215,223, -182, 56, 47, 52, 50, 50, 50,114,112,112,200, 55, 50, 50, 50,122, 23,165, 16,159,207,103, 31, 62,124,120, 18,143,199, 3, 0, 40, - 20, 10,120,123,123, 19,134,242,217,128,127,152,216,122,195,229,106, 74,104, 13,171,168,168, 0, 69, 81, 48, 49, 49, 1,139,245, -122,185,111,101,101,133,193,131, 7,163, 95,191,126,152, 56,113, 34,146,146,146,132, 19, 39, 78, 28,172,141,108,242,210, 96, 56, -185,217,213, 22, 38,180,195,237, 11,143,194,126,250,234, 87,155,188,188,188,165,245, 78,155, 57,123,246,108,162,184,184, 24,227, -198,141,187, 41,151,203, 63, 0, 80,161,141,147,162,145, 19, 52,113, 10,104,134, 16,110,187,247, 3,161,144, 73, 25,146, 36,165, -117, 77,135, 45,137, 37,130, 32,198, 57, 58, 58,226,248,241,227, 80, 40,222,156, 46,204,212,212, 20,137,137,137,175, 92, 53, 22, - 11, 61,123,246,100, 17, 4, 49, 14,192,103,141,115,146,173,111, 63,120, 97, 91,183, 31, 60,216,139,219,211,143,204,127,153, 95, -197, 0, 32, 86,175, 94,173, 17,110, 0,176,126,253,122,125,194, 9,146,195, 65, 97, 84,212,171,140,152, 77,130,228, 18, 32, 56, - 0,201,174,105, 69, 5, 3, 48, 20, 64,171, 1, 90, 5, 8, 28,156,244,137, 6,255, 86,206,110, 17,155,182,238, 53,151,171, 24, - 28, 63,119, 13, 25, 25,207,193, 34, 73,184,182,119,195,123,253,251,114,252,186, 7, 56,125,187,110,233,249,151, 89, 79,135, 1, -184,223,236,136,166, 25, 65,123,103,107,252,248,211, 67,216, 88, 24, 99,220,200,247, 33, 20,240,241,205,174,159,241,245,202,249, -112,115,117,193,254,237, 27,181, 94,110,102,102,182,193,195,173,189,203,222,195, 23,224,225,238,206,218,123,228, 2, 60, 60,107, -183, 94, 30,172,189, 71, 46,192,211,203,147,181,247,200, 5,248,120,117,106, 19, 35,190,183,161,164,164,100,190,246,248,108,144, - 70,239,213,164, 17,167,146,214, 20, 4, 47,230,204, 1, 0,141,208,106, 14, 56, 28, 78,235,151, 47, 95,218,234, 58, 79,151,107, - 80,235,100,197,168,213,106, 20, 20, 20, 16,101,101,101,140,185,185,249,200, 75,251, 87,157, 25,210,199,183, 4, 0, 30, 63,126, -108, 25, 26,186,105,228,137,152, 10, 72,239,238, 38,254,251, 91, 20, 61,229,131,192,152,115, 97, 51,252, 80,187, 36, 68, 67,200, -229,242,140, 46, 93,186, 48,181,223, 91,241,249,124,110,131,231,205,177, 67,135, 14,111,184,214,122, 52, 41,238,184,115,231,206, -124, 79, 79, 79,184,187,187, 71,247,232,209,195, 84, 36, 18,225,210,165, 75,240,240,240,240, 50, 53, 53,189, 23, 30, 30,206, 89, -177, 98,133,239,193,131, 7, 1, 96,129, 30,209, 57, 40, 40, 40,232,120, 68, 68,132,128,203,229, 66, 42,149, 34, 49, 49, 17,102, -102,102,224,241,120,248,240,195, 15, 89,189,123,247,182,234,223,191,255,169,212,212,212, 73,104,198, 8, 40,153, 76,198,172, 90, -181, 10, 70, 70, 70, 48, 50, 50,130, 72, 36,130, 72, 36,130,177, 0,196,190, 69,206,194,133, 7,202,132,159,173,221, 23,118,100, -239,186, 27, 78, 78,244,151,217,217,217,101,205,125, 22,164, 55,111,194,248,241, 99,160,222,187,171, 47,204, 68,150, 8, 9, 9, -209,229, 72,129,203,229,162, 87,175, 94, 58,249, 44, 45, 45, 79,179,217,236,215,106,166,106,181, 90, 16, 18, 18, 66,165,166,166, -138, 72,146, 20,209, 52,141,144,144, 16, 74,173, 86, 11,108,109,109,163,105,154,206, 47, 42, 42, 26,173, 71,112,229, 0,150,147, - 36,185,131,207,231,179,219,180,105,147,185,102,205,154, 59,181,110, 38, 24,134, 33,219,180,105,227, 47, 20, 10, 93,228,114,185, - 26, 53, 77,135, 6, 55,203,128, 70,193, 48,140, 95,141, 41,172,129, 2, 0,175,246,123,113, 77,105, 7,235, 6,191, 3, 64, 81, -109, 69,209, 78,203,126, 49,128, 36, 0,157, 0,216,214, 30,123, 64, 16, 68, 73, 11,130,169,221,209,138,136,136,208, 84, 97,131, -131,131, 53, 5,139,137,137, 9, 30, 60,120, 0,130, 32, 96, 98, 98, 2, 83, 83, 83,152,153,153,161,162,162, 2, 73, 73, 73, 72, - 73, 73,193,139, 23, 47, 64, 16, 4, 92, 93, 93, 81,247, 2,213,131, 38,131,251,101, 75, 4, 4,198,124, 16, 4,208,117,128, 15, -124,250,121,163,251,253,244, 69, 49, 87,137, 3, 98,177, 56, 13, 0,219,219,219,123,102,207,158, 61,177,117,235, 86,200,229,242, -173, 90, 68,150,134,243, 86,146,186, 27, 0, 56, 56, 56, 44, 59,122,233,153,209,212,161,237,171,197, 98,241,119, 45,136,156,215, - 50,226,162,162, 34,189,215,226,163,105, 26,165,165,165, 77,114, 54,116, 8,182,237,216,109, 46, 41,207,199, 87,223, 28, 63, 96, -234, 77, 0, 0, 32, 0, 73, 68, 65, 84,133, 74,165,194,210,165, 75, 65,211,180,230, 83, 86, 86,166, 87, 56, 25,138,122,211, 59, - 32,107, 90, 79, 9, 54,224, 60,161, 70, 87,100, 29,223, 13,130, 1, 8, 10,192,155,247,213,176, 16, 18,176,184,194, 19,235,190, -217,105, 30,155,146,131,115,215, 98,161,172,200,133,248,241,153, 26,203,177,215, 36,156,148,179,208,195,167, 61, 22,175,254,214, -226,139,197,211, 78, 40,164, 18,119,188,222,140,120, 85,247, 75, 67,225,171, 13, 27,112, 96,231, 86,124,187,117, 39, 42,202,203, -192,225, 88,215,102,244, 20, 40,138,106,250,222, 25,102,104,200,162,143,136,111,190, 63, 13,127, 79, 7,156,186,116, 31,125,186, -184,224,204,239, 49,232,231,215, 22,231,174,198, 98, 64,143,246,136,140, 74,192,226,217,147,136, 73,151, 15, 14,109, 78, 26,109, -223,190,219, 92, 82,145,143,136,141,135, 81,176,103, 15, 50,231,207,135,127,237, 57,247, 9, 2,220,214,173, 1,174,238, 52,106, -136,228,228,100,200,229,242,198,106,251,240,240,240,208,153,238, 82,169,244,161, 90,173,102,242,243,243,137,252,252,124,136, 68, - 34, 34, 49, 49,129,242,242,242, 30,197,164,252,250, 3, 0,132,134,110, 26,117,242, 97, 5,170,163,119, 66,122,103, 23,184,109, -227,200, 3,235,103, 43,103,173,221,255,176,222, 59,250, 90, 56,243,242,242,134,229,229,229, 1, 0,218,181,107,151,146,154,154, -218,169,174,169,185,182, 9,145,171, 86,171,221,234,154, 19,213,106, 53,228,114, 57, 6, 13, 26,196,106,234,222, 45, 44, 44,122, -122,120,120, 32, 54, 54, 22, 59,119,238,180, 12, 10, 10,194,211,167, 79, 65, 16, 4, 54,109,218, 68,120,122,122,114,138,138,138, - 48,100,200, 16,156, 62,125,186, 87, 69, 69,133,174,248, 52, 17,137, 68, 7,207,159, 63, 47, 32, 73, 18, 18,137, 4, 52, 77,163, -119,239,222, 32, 73, 18, 9, 9, 9, 88,189,122, 53, 78,159, 62,141,179,103,207, 10,253,252,252, 14, 86, 87, 87,123,224,245,102, -125,109,105,196,200,100, 50,134,207,231,131,207,231, 67, 32, 16, 64, 32, 16,128,199,227,161, 82, 6,204,218,150, 41,103, 9,172, -105,175, 46,125,218,127,180,112, 19,249,221,154,143,175, 3, 56,167,239, 51, 15,212,244,201,218,241,243,207, 59,167,148,151,147, - 0,240, 35, 65,208, 74,134,249, 86,159,247, 29, 0, 42,101,229,112,113,109,141, 83, 39,206, 98,204,132,145,141,138, 44, 14,135, - 11, 46,135, 3, 83, 75,145, 78, 78, 46,151,107,151,146,146, 98,197,225,112,192, 48, 12, 40,138,130, 82,169,204,255,226,139, 47, -108,134, 15, 31,110,114,241,226, 69,114,248,240,225,180,133,133, 69,213,253,251,247, 11,212,106,181, 85,223,190,125,155,243,204, -239,245,241,241,233,122,230,204,153,143, 67, 66, 66, 98,150, 45, 91,246, 85,253,131,155, 55,111,222, 16, 25, 25,233, 50,106,212, -168, 35,143, 31, 63,222,219,156, 60,228,109,243,121, 3,231,223,143, 83,155, 22,169,133, 29, 65, 16, 17,245,242,236,224,186,253, -144,144,144, 85,161,161,161,137, 4, 65, 68,212,255,189,238,188,218,202, 98, 68, 99,251,181,215, 90,174, 92,185,210, 59, 44, 44, -108, 83, 64, 64,192,241,232,232,232,231, 0,154, 43,180,154,238,163, 85,119, 67,245,111,178, 65,161,134,138,138, 10, 84, 84, 84, - 32, 59, 59, 27,251,246,237,171,125,161, 57, 96,179,217, 96,179,217,154,254, 12,218,112, 45,226,207, 93, 0,118,117,237,218,149, - 19,127, 39,252,226,231, 7, 22, 14,236, 54,168, 43,235,225,181,248,177,168, 89,143,112,216,244,233,211,173, 1,224,240,225,195, - 69, 0, 46,254, 31,169,230,240,180,180,180,197, 14, 14, 14,154, 62, 42,245,155, 15,213,106, 53, 4, 2, 1,234,250,178,200,100, - 50,236,219,183, 79,205, 48, 76,120, 19,156, 72, 77,188,142,180,196, 27, 53,215,209, 52,104,234,213,245,235,214,173, 3,195, 48, -154,194,126, 78,173,115,162, 83,228, 53, 22,231, 76,131,109,131,223, 25,138,210,209, 60,193, 93, 56,118,218,124, 7,154, 96,227, -183,235,143,192,225,112, 64,215,115, 51, 57,172,154,218,114,226,211,151,112,180,243,194, 7,147,102,219,159, 57,178,123,161, 90, - 41,251,166,185,113,237,238, 19,128, 69,139, 23,227,135, 3, 7,176,122,237, 6,141, 2, 80, 83, 20,212, 58,195, 73,146,131,122, -123, 67, 93,249, 18, 44, 22, 11, 3,252,219,131,197, 98, 97,112, 64, 71,176, 88, 44, 12,233,237, 14, 54,155,141,161,125, 60,209, -161, 67, 7,176,217,108, 82, 71,186, 35, 53,241, 26,210, 18,255,168, 39,122, 25, 48, 0,148, 98,241, 27,231,171,196, 98, 48,206, - 86,205,125,182, 48,115,230,204,178,236,236,108,101,195, 99, 78, 78, 78,220,155, 55,111,154,107,105,182,211, 64, 40, 20,250,177, -217,236,135, 37, 37, 37,180,145,145, 17, 73,211, 20,237,229,229,205,186,180,127,213,153,186,115, 86,174, 92,117,102,188,159,233, -168,163,225, 17, 12,183, 77, 31,130,224,240,213,159,174,221,207,229,112,133,126,128, 84,159,202, 3, 41,151,203,241,228,201, 19, -232, 10, 15,195, 48, 77, 54,253,148,150,150, 78,247,240,240,184,185,107,215, 46, 75,130, 32,112,235,214, 45,176, 88, 44,205, 39, - 61, 61, 29, 36, 73,226,243,207, 63, 87, 86, 84, 84,124,162, 43,108,108, 54,123,241,169, 83,167,204,120, 60, 30, 36, 18,137,230, -189, 97,177, 88, 72, 73, 73,193,119,223,125,135,233,211,167, 35, 43, 43, 11,142,142,142, 88,186,116,169,113, 88, 88,216, 98,165, - 82,185, 65,143, 36,138, 83, 40, 20,221,140,140,140, 32, 16, 8, 80, 39,184, 0,224,247, 68, 78,130, 84, 42,237,108,101, 85,109, -111, 19, 21,241, 91,175,160, 15,124,173,108, 28, 2,196, 98,113,179,150,206,122, 6, 28,200,160,168, 47,134,157, 57, 99,123,251, -204, 25,250,238,249,243, 57,124,137,100,191,222,207,144,138, 68,102,122, 14,252,252,252,240,240,225, 67,248,249,249,213, 23, 77, -224,241,120,224,114,185,224,114,185,176,182,208,171, 11, 5, 67,146, 36,110,223,190, 13,138,162,160, 80, 40,160, 80, 40,224,233, -233, 89,114,227,198, 13, 99, 0, 72, 79, 79,103,166, 78,157, 90,118,239,222, 61,116,233,210,244,122,234,118,118,118, 55, 89, 44, - 86,155,250,191, 21, 23, 23, 91,140, 30, 61, 26,165,165,165,239,143, 30, 61,186, 79,237,251,155,251,235,175,191, 78, 5, 0, 30, -143, 7,146, 36, 41, 24,240,175,135, 46, 45, 82, 95, 40, 53, 20, 92,161,161,161,193, 13,127,171, 47,170, 26,251, 94,255,218,176, -176,176, 77,245,184,165, 45, 8,190,238, 62, 90, 17, 17, 17, 76, 35, 10, 82,111,232, 18, 90,117,136,141,141, 85, 57, 58, 58,254, -144,246,232,197,192,246, 62,174, 16,138,248,239, 1,216,197,231,243,151, 76,155, 54, 13,119,239,222, 69, 66, 66,194, 79,120,203, - 81, 56,222,222,222,151,249,124,190,139,150,102,146,204,132,132,132, 33, 90, 10,134,181,231,207,159, 71, 83,157,225,175, 95,191, - 94,191, 80,170,223, 25,190,241, 7,131,102,160, 82,170, 80, 85, 45,125, 85,136,215, 10,173,170,170, 42, 76,152, 48,225, 53, 71, -171,160,160, 64,231,253, 17, 4,129,239,206,157,195,149,240,112,188,239,235,139,211,247,239, 35,108,218,100,184,187,180, 2, 67, - 17, 96, 8, 32,235,216,110, 20, 87, 84,226,151,107,183, 81, 34,169,198,148,190,125,225,102,106,221, 52, 47,135, 59,216,191,103, - 0,247,106,116, 18, 56, 28, 54, 72,208, 96, 84,213,112,244,232, 15, 22, 73,194,204,174, 45,184, 28, 14, 56, 28, 54,210,179,139, -224,225,221,157, 23,193, 19, 12,110,137,208,114,114,105, 11,138,162, 48,125,250,116, 28, 63,126, 28, 86,246, 46, 48,115,242,198, -215, 91, 15,224,253, 65,125,117,222,127, 93, 13,158,205,102,131,197, 98,189,177,173,251,174,143, 59,201,208, 12,148, 13,211,136, -102, 0,134, 65,235,141, 27,209,122,227, 70,220,175,253, 79,207,170, 42, 72,165, 82,160,135, 87,179, 68,150, 66,161, 64,118,118, -182, 50, 47, 47,207,174,145,227,249, 10,133, 66,167,176, 57,116,232, 80,220,140, 25, 51,186, 89, 90, 90,198,196, 61,126,172,242, -241,245,229, 92,220,183,234,108, 93,179, 33, 0,248,250,250,150,172, 90,181,234,236,212,113,193, 35,247,134, 76,164,230,110, 56, -194,230, 11,133,221,130,151, 29,138, 59, 54,110,156,238,246, 30,185, 60,195,199,199,135,209,231,190,170,171,171,243,154, 56, 60, - 2,192,250,174, 93,187,154, 6, 5, 5,225,230,205,155, 24, 51,102,140, 92,169, 84,166, 1,192,240,225,195, 59,254,242,203, 47, -188,164,164, 36,216,216,216,112, 50, 51, 51, 15, 66, 71, 7,121, 30,143,215,191,123,247,238,164, 92, 46,127, 67,100,133,133,133, - 97,210,164, 73,232,216,177, 35,104,154, 70,101,101, 37,130,130,130, 56, 59,119,238,236,175,167,208, 90,228,238,238,254, 29,106, - 70, 29,214,207, 11,147, 81,211,172,133,226,226,226,188, 71,247,174, 37,246, 29, 52,186, 91,155, 14,222, 14, 9,113, 15,155, 36, -180,181,181, 93, 73,146,228,120,154,166, 89, 21, 21, 21,217,143, 20,138, 14,158, 46, 46,118,189, 71,142, 68, 57,135,195,218,113, -237, 26,153, 47,145, 24, 3,208,171, 9, 82,166,170,130,139,107, 77, 87,191, 49, 19, 70,226,225,195,135, 24, 59,113, 20,184, 92, - 46,216,108, 78,205,187,201,173,113,180,204,173, 77,245,122, 54, 85, 42,149, 38, 15,175,235,231,165, 84, 42, 81,215, 53,203,200, -200, 72,115, 76, 46,151,131, 32,136,166,158, 13,183,147, 27,214,216, 10, 77,205, 64,169, 84,240, 26, 57, 86,243, 76,223,251,113, -175, 16, 52, 45, 44,203,204,192,130,240,243, 28, 24, 96,128, 22, 87,171, 41, 45, 82, 95, 40,189, 45, 8,130,136, 8, 9, 9, 89, - 5,128, 9, 9, 9, 89, 85,183, 31, 26, 26, 42, 5,144,219, 66,177,245,134,203,197,126, 23, 34,171,174,121,161, 41, 4, 5, 5, - 45, 48, 49, 49,217, 89,183,159,125, 55, 23,217,119,115,225,209,201,171,119, 87,223,110,229,147, 38, 77,130,149,149, 21,150, 45, - 91,198, 0,248,169,185,255,159,158,154,104, 12,128,113,112,112, 88, 86,155, 33,251,222,191,127,223,230,193,131, 7,232,222,189, -251, 43,235, 94,169, 68,159, 62,125,154,162,146,212,118,106,255,236,221,185,100, 52,148, 74, 37,170,171,165, 80, 40,148, 80,171, -104,168,213,106,248,121,153,224,200,129,144,154,223,212,117,238, 89,141,107,214,218,222, 4, 38,198, 28, 21, 73, 18,210,152,184, -188, 70,115, 76,133, 66,129,184,204, 76, 60,126,241, 2, 0,240, 65,104,211, 29, 95,143, 92,187, 9, 79, 79, 79, 93,161,109,223, -218,209, 30, 47,175,196,213,100,222,210,108, 60,248,243, 36, 76, 76,140, 1, 0, 94,129, 83,192,229,214, 8,173, 42,169, 18,214, -157,156, 64, 48,140,214,105, 1,140, 44,236, 47,179,185, 2, 23,134,162,193, 48, 52, 24,154, 2,195,208, 96,113,184, 70, 11,230, -124, 12,154,166,224,239,239, 15,130,197, 2,165,146, 99,220,136,193, 40, 45,151,192,202, 92,191, 66,130,203,229, 34, 48, 48, 80, -168,237,248,211,167, 79,165,245,133, 89,211,105,164, 66, 85,149, 20,114,185, 28, 74,133, 26, 74,149, 26, 84, 59, 46,190,250, 98, - 50,212, 74, 53,170, 39, 6, 64,169, 82,131, 94, 60, 10, 74,133, 10, 89, 70, 36,233,227, 97,173, 34, 65, 72, 31, 37, 23,154,234, - 18, 90,117,226, 64, 27, 26,235, 19,168, 69,108, 61,158, 49, 99,134,159,143,175,239,195,241,131,124,183,196, 39, 36,190,140, 79, - 72,124,227, 60,151,142,190, 25,115,195,142, 47,229,112,133,126,193,203,154, 30,117, 88, 31,245,155, 17,223, 18,171, 36, 18,137, -143,177,177, 49, 82, 83, 83,193, 98,177, 64, 16,196, 83, 0, 62, 0,224,224,224,240,140,205,102,187,178, 88, 44,236,217,179,135, - 96,179,217,157, 3, 2, 2, 86,201,100,178,147, 77, 84,232, 60, 76, 76, 76, 94,115,179,184, 92, 46, 66, 66, 66, 48,117,234, 84, -141,200,226,114,185, 56,116,232, 16,186,117,235, 6,133, 66,225,161,103,120, 31, 0,232,171,135,227, 71,212,138,115,157, 98, 84, -173, 86,207, 40, 30, 63,190, 3,162,162,208,219,213,213,211,207,207, 15, 74,229, 43, 67,211,213,213,213, 73, 34,145,228, 73,165, -210,255,162,102,106,131, 71, 77,138, 34, 25,141,204,244,154,238,167, 15, 31, 62,132,191,191,191,198,193,170,239,102,113,185, 92, - 8,121,198,205, 18, 90, 52, 93,147, 47, 73, 36, 18, 50, 42, 42,202,218,221,221,157, 0, 0,119,119,119,226,209,163, 71,150, 70, - 70, 70, 69,237,219,183,215, 89, 1, 22,154,154,225,208,140, 9, 0,128, 47, 7, 13,213, 84,140, 46,173, 95, 5, 14,135,131,129, -203, 86,189,241,220,211, 52,205,130, 1, 6,145,165,135, 22,121, 87, 34,171,161,163, 21, 26, 26,154, 24, 26, 26,250,134, 59,214, - 76,232,118,180,234, 91,119,205, 69,221,203,170, 13, 91,183,110, 69,231,206,157,155, 44,136,118,238,220,137,163, 71,143,110, 5, -144,222,108,203,113, 96, 87, 47,108, 59,147,232,218,209,139, 0,128, 13,139, 71,144, 85, 85, 85,184,125,251, 54,204,204,204,240, -244,169,222,211,126,153,152,153,153,173, 39, 73,114, 28,171,225, 8,128,198, 5, 38, 69,211,116,120,121,121,185,214,233, 29, 24, - 6, 80,170,212,168,170,150, 65,161, 80, 96,241,231,187,117, 6, 34, 20, 32,148, 10, 9, 59,176, 95,128, 80,155,163,227,223,185, - 63,230, 77, 51,126,163,240,102,145, 0, 73, 2, 93,252,107, 28,151, 71,247, 19, 65,211, 0, 69, 3,214,182, 22,248,233,216,150, - 38, 69,190,154,162,107,107,199, 20, 42,229, 20, 60,122, 6, 35, 39, 57, 74,227, 32,241,184, 53, 77,198, 92, 14, 7, 52, 67,212, -204,250,160, 77, 8,241,132, 46,165,226,116,183, 3, 17,241,152, 21,220, 25,191, 94,141,195,216, 65, 62,184,113, 47, 9, 65, 61, - 60,145,152,246, 2, 94,110,109,176,231, 96, 56, 24, 6,146,239,183,125,157,247,170, 64, 83,103,234,227,104,221,189,123, 87,218, -208,197,170,191,101,116,151,135, 96,152, 87,142,150, 84, 38,199,178,149,122, 77,231, 83,147, 70,125,123, 10,245, 57,185, 41,199, - 74, 31, 33,214,208,217,130,142,233, 89,218, 1,232, 6,172,248,191,204, 56, 41,138,194,133, 11, 23, 52,233,209, 88, 58,214, 79, - 59, 61, 68, 14, 50, 51, 51,145,152,152,136,158, 61,123,162,188,188, 28, 28,146,196,210,248,120,120, 78,155, 6, 5,151, 11,154, -166,193,227,241, 48,123,246,108,189,227,179,153,185,115,109,103,110, 74, 23,249,150,128,128,128, 14,169, 85, 85, 72, 76, 73,193, -160,117,235, 0, 0,145,145,145,175, 61, 19, 75,150, 44,225, 37, 37, 37,205,140,137,137,153,249,242,229,203,173, 0,150,106,205, -103, 25,185,166,143,214,248,201, 99,208,193,189, 29,142,254,124, 76,115,124,201,242, 69,224,112,184,224,112, 57, 48, 55, 51,215, -235,110, 84, 42,149, 70,180, 86, 87, 87,147,145,145,145,173, 7, 15, 30,204, 93,180,104, 17, 1, 0, 71,143, 30, 37,119,237,218, - 37,186,114,229, 10,183, 85,171, 86, 98,157,226, 82,169,124, 35,141, 9,130, 0,135,195, 1,151,199, 5,104, 26, 4, 65,136, 54, -111,222,188, 33, 49, 49,177,187,187,187, 59,228,114,249, 52,212, 12,212, 48,204,163,101, 16, 91, 77,106,145,198,250, 90,213,186, - 82,218, 80, 88,191,223,150, 54,161, 86,191,207, 22, 90, 54, 40, 67,191, 62, 90,141,129,197, 98,233,116,171, 72,146,212,217,116, -184,100,201, 18,152,152,152,104, 43,128,152,248,248,248, 36,177, 88,124, 0,192,238, 22, 37,206,181,216,196,245,159,141,146,160, -182,109,213,220,220,188,104,192,128, 1,149, 0,148, 39, 79,190, 94, 65,150,203,229, 90, 11,112, 51, 51,179,245, 63,254,248,227, -194,145, 35, 71,146, 13,167, 24,168,223,188, 87,247, 81,169, 84, 56,121,242,228,194, 21, 43, 86,160,188,188,252,179,166, 10,241, -234, 42, 41,164,181, 29,161,159, 37,252,170,111,166,174,245,144,177,185, 3, 90,183,243,209, 90,152,144,220,154, 62, 68,118,206, -175, 10, 48, 19, 19, 1,168, 38, 56, 9,130, 76,127,145,245,178,149,147,189, 37,158,101, 23,194,174, 77,103,148,230,190,138, 7, - 54,155, 5, 78,109,211,161,185,169, 8,133, 5, 5, 32, 73, 86,147,194,248,235, 95, 98,113, 47,225, 5, 78, 93,125, 4,165,172, - 10,219, 14, 95,130, 82, 94, 9,165,172, 10, 74, 89,205,118,211,138, 79, 65, 16,200, 83,201,171, 58, 54, 39,221,217,108, 54,122, -244,232,161, 85,232,228,230,230,234,233,104, 49, 26, 71, 75, 42,107,102, 26,233, 87,115,106,210,177,170, 59,222, 82, 97, 80, 55, -229,131, 80, 40,236,118,232,144,246,105, 28, 26,131,189,189,253, 69, 99, 99,227,182,250,158,223,140,201, 75, 55,153,155,155,175, -119,119,119,247,216,182,109, 27,135,197, 98, 97,224,192,129, 29,237,237,237, 51, 1,192,203,203,203,177, 46,143,153, 59,119, 46, -115,247,238,221,132,154, 58,134,118,240,120,188, 20, 51, 51,179,110, 65, 65, 65, 40, 47, 47, 71,118,118, 54, 68, 34, 17, 60,183, -108, 65,252,220,185,240,221,183, 15,228,128, 1, 32, 8, 2, 60, 30, 15,241,241,241, 16, 10,133, 41, 50,153,214, 41,223,122, 0, -248, 22, 64,111,188,106, 46,100, 0,220, 70,205,180, 11,247, 26,201,239, 72, 0,160,104, 90, 87, 98, 77, 94,182,108, 25,202, 56, - 28, 96,248,112,112,211,211,161, 84, 42,209,179,103, 79,141,203,222,179,103, 79,176,217,108,248,248,248,192,209,209, 17,123,246, -236,153,220,148,208,146, 85, 42,145,153,158,131,128,128, 0,141,115, 53,124,248,112,141,163,197,225,112, 52,206, 22, 65,233, 22, -174, 4, 65, 48,245, 43,201, 20, 69, 17,108, 54,155,253,217,103,159, 17, 99,198,140, 97, 20, 10, 5,205,227,241,200, 83,167, 78, - 17, 55,110,220, 96, 87, 85, 85,233,172,136,123,143, 26,135, 47, 7, 15,171,121,247,219,218,128,195,229,128,199,229, 98, 89, 74, -142, 38, 93, 76, 15, 29,231,133,133,133,141,117,119,119,175,105,134, 7,216,134,121,180, 12,208, 97,244, 20, 54, 16, 73,138,122, -251,133, 0,136,218,253,194,122,130,170,144, 32,136, 7, 12,195,116,111,112,110,221,113, 69,131,109,221,241,199, 45, 8,126,221, - 90,135,111,136,175,166,106,196,105,119,238,220,113,243,243,243, 67, 86, 86,214, 27, 35,225,234, 10, 46,145, 72, 4,161, 80,136, -232,232,104, 0, 72,211, 70,118,227,198,141, 93,168,153,117,185, 38, 68, 14, 14, 1, 65,227,251, 71,251, 15,237,142, 95, 66,143, -149,139,197, 98, 31,188,154, 67,135,112,116,116,156,202,225,177, 39,184,122, 59, 7,130,166,191,189,118,254,246,186,166,238,208, -181,163, 87, 37, 0,105,221,168,195, 22,142, 62, 4, 73,146,227, 70,142, 28, 73, 38, 37, 37, 97,194,132, 9, 56,122,244,168,214, -115,167, 78,157,138,227,199,143, 99,228,200,145,228,202,149, 43,181, 78,239,240,186, 91,162,120,103, 15,101,234,211,199, 56,114, -252, 71,173,125,144,108,109,107,250, 99, 21, 20, 20,105,126,235,238,215,116,203, 8,173, 86, 92,137,141,185, 31,208,171,223, 64, -110,118,126, 25,104,181, 28, 50,201,171,235,171,203,242,193,168,101,224, 26, 89,194,222,218, 12, 15,239,252,174, 80, 42,100, 87, -154,226, 92, 56,210, 11,115, 71,120, 0, 12,141, 81, 75,127, 66,196,238, 5,154, 26,116,159, 49,139,112,237,228, 14,189,251,248, - 53, 4,135,195, 65,124,124,188, 84,155,155,197, 98,177,244,153,147,171,214,117, 84,161,186, 90,138,106,169,236, 93,230, 29, 54, -118,118,118,223, 91, 88, 88, 8,180, 8, 41, 27, 27, 27,155,239,173,172,172, 4,250, 54, 29,106, 19, 89,181,243,106,197,204,152, - 49,163, 89, 98,139,207,231,183, 77, 75, 75,211, 76, 86,218,212, 86,161, 80, 32, 40, 40, 72,223,201, 75,207, 3,120,238,224,224, -112,219,211,211,211,236,217,179,103, 56,118,236, 24,151,195,225, 56,215,229, 31, 18,137, 4, 44, 22, 11, 5, 5, 5, 42, 0, 31, - 67, 71,211,153, 92, 46,143,138,138,138,234, 50, 98,196, 8, 86, 74, 74, 10, 88, 44, 86, 77,184, 2, 2,224,187,111, 31, 18, 62, -251, 12,129, 47, 94, 64,166, 84, 66, 32, 16,224,242,229,203,202,234,234,234, 40,109,124, 66,161,240, 64, 70, 70,134,151, 64, 32, -128, 82,169, 4, 77,211, 32, 73,146, 96,179,217,125,204,205,205,119, 2,232,222, 32,177,108,125,187, 7,117,162,212,106, 74,156, -245,172, 80, 87, 4, 20, 23, 23,227,252,249,243,232,217,179, 39, 2, 3, 3,145,155,155,139,244,244,116,188,255,254,251,154,115, - 30, 63,126,140,216,216, 88,180,111,223, 94,183,163, 71,170,208,190, 83, 91,112,185,220, 26,135,136,195,173,173,248,112, 52, 78, - 22,151,195, 5,135,205,129, 64, 40,208,219,209, 34, 8, 2, 36, 73,130, 32, 8, 8,133,194,186, 74, 54,221,186,117,107,113, 73, - 73,137, 3, 0,150, 80, 40, 4, 69, 81,122, 85, 90,234,202,136, 58,145,197,229,113, 53,206, 22, 0,148,149,149,201, 70,142, 28, -249, 95,185, 92,254, 17, 90,182, 66,137, 1,255, 50, 16, 4,241,224,255,226,218,102, 96,120,173,176,122,163, 83,124, 83, 15,248, -251,189,122,245,218, 55,105,210,164,129,219,183,111,135,177,177, 49,196, 98,177,166, 64,228,241,120,112,114,114, 66, 73, 73, 9, -246,239,223,143,156,156,156,235, 0,102,235, 27, 34,177, 88,124,247,233,163,180,226,160,177,189,172,188,122,117, 50,207, 78,203, -233, 41, 22,139,163,107, 69,214, 79,147,150,188,255, 81,208,104,127,112,121, 28,100, 63,205,195,181,243,183,255,191, 36, 38,139, -197, 98, 17, 4,129, 9, 19, 38,232,117,254,196,137, 19, 17, 21, 21,133,166,154, 25,233, 58, 71,171, 90,134, 42,233,187,171,172, -205, 91, 48, 21,243, 22, 76,213,136, 9,125,154, 94, 0,192,209,241, 68, 19, 66, 75,185, 61,226,196,254, 89, 93,253, 3, 92,186, -121,181,197,189,152, 71,248,101,223, 43,147,225,224,174, 13,248,230,224,117, 56,217, 89, 64, 41,175,194,197, 95,127,200, 83,202, -171,183,183,208,148,171, 17,183, 4, 1,134,161,155,117,239,117,226,137,195,225,192,219,219, 91,171,163, 85, 82, 82, 34,213, 85, - 48,104,210, 72,161, 66,101,149, 20,210,234,119, 38,180,124,251,244,233,115, 37, 60, 60,220,202,214,214, 22, 47, 95,190,108, 40, -180,124,123,247,238,125, 37, 60, 60,220,202,206,206, 14,217,217,217,122, 79, 43,210,136,200, 66, 97, 97, 33, 81, 90, 90, 74, 91, - 88, 88, 52, 75,108,145, 36, 9,185, 92,142,228,228,100,125,255, 86,239, 17, 98,102,102,102,135,142, 31, 63,110, 86, 84, 84, 4, - 22,139,133,228,228,228,215, 70, 29,214,125,126,250,233, 39,238,168, 81,163,126, 44, 43, 43,107,114, 88,155, 90,173,222, 58,117, -234,212,153,185,185,185, 22,182,182,182, 16,139,197,224,241,120, 96, 24, 6, 68, 80, 16,250, 62,127, 14, 37, 69, 65, 40, 20, 34, - 53, 53, 21, 7, 14, 28,168,170,157, 42,166, 81,131,140, 32, 8, 55, 46,151,139, 41, 83,166,188,118,224,240,225,195,248,160, 27, -171,155,141, 25,187, 82, 13,129, 60, 95, 56,236, 34,139,197, 34,124,123, 12,232,216,163,223,112,239, 39, 9,247,158, 21,230,231, -232,202,148, 84, 10,133, 2,238,238,238,120,240,224, 1,174, 94,189,138, 1, 3, 6, 32, 48, 48, 16,113,113,113,248,253,247,223, - 17, 27, 27, 11,130, 32, 96,101,101, 85,215,253,162,201, 62, 24,138,106, 53, 10, 94, 22,191,225, 94, 53,220,231,114,185,144, 75, -149,122,165, 81, 74, 74, 10, 30, 60,120,160,153, 90,134,197, 98,169,167, 77,155, 6,134, 97,152,140,140, 12,152,152,152, 48, 51, -102,204,160,216,108,182, 58, 55, 87,191,254,193,117,162,170, 78,100,177,185,156,215, 4, 26, 77,211,146,184,184,184, 89, 0,226, -106,157, 44,192, 48,143,150, 1,255,219,184,128, 55, 23,150,214,233,104, 61, 7, 48,232,216,177, 99,147,207,158, 61,187,117,231, -206,157, 54,193,193,193, 40, 45, 45,133,139,139, 11, 28, 28, 28, 16, 17, 17,129,200,200,200, 34,138,162,150, 2,104,204,250, 25, -132, 38,230,172,201,125, 38, 14,151, 87, 86,206,245, 11,244,192,245,147,183, 66,237,237,237,103,179, 88,172,197, 51, 86,125,248, - 81,255,145,221,145, 26,155,129,187,191,199, 35, 63,171, 72, 39,103,195,206,240,230,230,230, 51,141,140,140,120, 0,148,141,212, -138, 27,142, 58,212,112, 82, 20, 69, 41, 20, 10,156, 56,113, 66, 47,177,117,236,216, 49,200,100, 50, 80,111,182,175,106, 56, 25, -154, 33,216, 28, 62, 28,157,220,161, 84, 86,129,166, 91, 60,160, 82,195, 89, 87, 3,125,198,227,193,182,168, 8,247,238,221,211, - 79,114, 15, 31,174, 43,141,100, 10,153,100,202,142,141,203, 34,230,135,124,107, 62,160, 87, 23,124,185,229, 48,148,202,131, 32, - 89, 36,132,124, 46,252,252,123,131, 5, 57,190, 15, 91, 94, 86, 93, 81, 58, 5,111, 46,197,243, 26, 39,211, 84, 11, 11, 3, 80, - 52,141,171, 55,239,235,125,239,154,210,158,162,192,102,179,241,244,233, 83,105, 99,163, 13, 89,172,154,102,206,186,154,122, 83, -156, 12, 77, 19, 28,174, 0, 78, 46,158, 80,200, 43,223, 73, 26,217,218,218, 46, 63,115,230,140, 85,221, 84, 9,113,113,113, 32, - 8, 34,249,149,227, 88,115, 92, 42,149, 34, 33, 33, 1,113,113,113, 64,205, 8, 55,189,223,163, 58, 39,171,176,176,144, 16,139, -197, 48, 50, 50, 34,227,226,226,228, 62, 62, 62, 49, 58,222,111, 13,167, 76, 38,123,161,173,255,164, 76, 38,107, 37, 16, 8, 56, - 13, 10, 81,199, 14, 29, 58,164, 54,210,132,248, 70, 56,203,203,203,239,173, 88,177,194,111,232,208,161, 88,190,124,121,137,133, -133,133,201,247,223,127,207,102,177, 88,196,252,249,243,169,130,130,130,202, 31,126,248,193,236,236,217,179, 40, 43, 43,139,214, -227,222, 37, 50,153,108, 86,175, 94,189, 14, 95,186,116,201,200,205,205, 13, 21, 21, 21, 96, 24, 6,135, 14, 29,194,252,249,243, - 33, 16, 8,144,154,154,138, 15, 62,248,160,186,186,186,122, 22,222,236, 59, 89,199, 73, 16, 4,193,208, 52,141, 53,107,214,104, - 38, 39,173,155,172,212, 68, 72,224,192,146,118,162, 69, 63,148,139, 38,127,249,195, 52, 0,160,212,106,234, 73,194,189,103,135, -118,127,121,131,203,229,222,212,145, 70,171, 23, 45, 90,244,253,240,225,195,133,198,198,198, 40, 41, 41,193,237,219,183,113,231, -206, 29,220,189,123, 23, 10,133, 2, 86, 86, 86,176,176,176,128, 88, 44, 70, 74, 74,138, 20,192,234,166, 56,121, 70, 28,184,118, -172, 27,249, 91,227, 96,113,234,141, 54,172,239,110,113, 57, 28,189,222,163,126,253,250,161, 71,143, 30,117, 2,136,202,204,204, - 20,203,229,114,162,158,232,207,173, 19,228,206,206,206,234,163, 71,143, 50, 77,113,222, 61,176, 7,151,190, 90, 13, 30,151,139, -165,201,217, 26,209,117,120, 64, 87,112,120, 92,120,140, 24, 83,255,218,189,168,105, 46, 68, 3,145,213, 84,217,241,214,239,166, -129,243,111,203,249,191, 12, 49, 90,176, 4, 79, 29,126,145,201,100, 23, 63,253,244,211, 48, 95, 95,223, 79,183,109,219, 70,112, -185, 92,172, 91,183,142,121,249,242,229,207,181,181,144,210,150,132,138, 97,152,159,255, 56, 29, 61,103,122,200, 72, 98,201,246, - 25,125, 98,174, 37,164,116,238,229,134,206,189,220, 16,115, 61, 9,187, 87, 29, 59, 74,169,168, 53,121,121,121, 89, 58,168,228, -131,122,119,106,216, 25,222, 42,234,198, 53,171,230,142, 58,164,105, 58,252,216,177, 99, 11, 71,143, 30, 77,222,191,127,255,141, - 62, 89,117,203,238,208, 52,141, 43, 87,174, 64,169, 84,226,231,159,127,166,105,154,214, 62,143, 22,152,115, 59,182,135, 77,255, -249,200, 57, 30,143, 75,224,206,205, 83, 40, 47,109,122, 84, 23,151,203,193, 79,135, 78, 43,185, 92,206,147,198,142, 43,149,202, -236,107,215,174,217, 13,161, 40, 14, 73,146,141, 9,168, 70, 17, 30, 30,174,162,105, 58, 83,199,105,209,249, 57, 89, 35,190, 94, -254,241,177,225,227, 63,181,235,213,171, 15,199,218,214, 14, 4, 65,160, 32,191, 0,169, 9,247, 85, 23, 79,253,152, 95, 85,173, -223, 18, 60, 31,127,247,135,166, 79, 22, 0, 4,207,223,169,233,159, 5, 0, 35,102,172, 64, 80, 79, 47, 16,250, 88, 79,175, 68, - 22,173, 86,171, 33, 18,137,160, 86,171, 27,157,226,193,204,204, 76, 40,147,201,164,181, 19, 49, 54,105, 21, 49,192, 59, 79, 35, -138,162, 60, 74, 75, 75, 81, 85, 85,133, 59,119,238, 48, 27, 55,110, 44, 44, 44, 44,212,116,218, 84,169, 84, 30, 37, 37, 37,168, -172,172, 68,116,116, 52, 19, 22, 22, 86, 88, 92, 92,188,170, 57,239,144, 80, 40,236,198,102,179, 99, 74, 75, 75,105, 35, 35, 35, - 82,165, 82,169,124,124,124,248, 66,161, 80,239, 5,213,197, 98,241, 80,109,199, 92, 93, 93,211,210,210,210, 58, 80, 20, 85,127, - 13, 68,174, 76, 38,115,235,213,171,151, 62,249,199,162,131, 7, 15,226,244,233,211,254, 21, 21, 21, 83, 51, 51, 51, 15, 3,240, -103,179,217,120,244,232, 81,178, 76, 38,155, 52,122,244,232, 67,165,165,165,247, 80,179, 4,143, 62,184,148,154,154, 58,197,195, -195,227,224,250,245,235,141, 3, 3, 3,217,142,142,142,232,222,189, 59, 82, 83, 83,113,225,194, 5,213,222,189,123,171,170,171, -171, 63, 6,112,165,233,100, 7,161, 86,171,193,227,241, 52, 31, 62,159, 15, 46,151, 11,137,148,193, 39, 91,210,165,106, 8,165, - 91,215,205,186,192, 0, 68, 94,118,122, 81, 65, 94,246, 61,130, 32,110,138,197,226,114, 45,113,198,147,201,100, 93, 24,134, 97, - 17, 4,177, 93,169, 84,206, 88,176, 96,129,195,166, 77,155,208,169, 83, 39, 20, 21, 21, 65, 36, 18,193,205,205, 13,133,133,133, -184,127,255, 62, 85, 93, 93,189, 15,192, 6,212,246, 31,209,134,178,162, 10,180,182,119,126,205,249,100, 24, 6, 12, 5,168,228, - 20, 40, 37, 3, 5,161, 2,135,163, 2,151,203,213,199,121, 98,104,154, 70,169,131, 3,232,132, 4,220,189,123, 23, 12,195,104, -117,213,220,221,221,245,200,216,105,240,248,188,215,154, 11, 9,130, 0,151,199, 3,135,199,109,108,228,140,193,197, 50,224, 31, - 13,125,219,198,203, 0,204,126,252,248,241,225,254,253,251, 71, 48, 12,195, 65, 77,123,228,173,183,249,243,188,188,188,135,209, - 23, 30,174,180,107,109, 17, 54,108,106, 31,116,234,226, 2, 74, 77,225,118,228, 35,252,188,233,236,241,220,236,220, 25,208, 99, -237, 51,154,166,111,244,238,214,137, 68,189,185,186, 29, 29, 29,233,150,140, 58, 44, 47, 47, 95,187,116,233, 82, 44, 95,190,188, - 37,163, 14, 27, 69,124, 74,225,108, 2, 76,235, 17,195,250, 14, 1, 65, 50, 10,133,188,137,140, 15,154,153, 75,185, 92,206,147, - 7,113, 98,159,198,206, 43, 44, 44, 28,242,209, 71, 31, 93, 97,179,217,109,155, 19,231, 52, 77,103,230,231,231, 15,212,125,166, -250,182, 92, 90,225,118,254,248,254,207, 46,157, 62, 56,132,166,169,246, 4, 0, 22,155,251, 76,165, 84, 94,150, 75, 43,182, 65, -207, 69,165, 55,207, 14,192,162, 29,191, 99,207,242, 17, 88, 16,118, 18, 63,174,249, 4, 43,183, 28,195,183,203, 23, 97,227,206, -255,226,203, 69, 83, 48,118,242, 71, 52, 67,144,127,234,123, 31, 44, 22,235,210,254,253,251,167,127,242,201, 39,154, 65, 11, 12, -195,188,150,177,171, 84, 42, 41, 77,211,216,183,111, 31, 13,224, 82, 83,124,175,167, 17,193, 52,213, 95, 74,223, 52,170,168,168, -248, 56, 32, 32,224, 16, 0, 62,195, 48, 79, 75, 75, 75,255, 3,188, 90, 26,170,178,178,242,227, 94,189,122, 29, 98, 24,134, 79, - 16,196, 27,199,245, 65,237, 84, 15,221, 44, 44, 44, 98,106,157, 44,126, 75, 58,196, 55, 21,213, 77, 52, 43,234,211,132, 72, 3, - 88, 80,111,198,247, 77,254,254,254,245, 23,149, 78, 46, 45, 45,237,214,130,112, 93,145, 74,165, 94,107,214,172,249, 76, 32, 16, - 4, 85, 87, 87,119, 4, 0,145, 72,148, 42,151,203,111, 72,165,210,109,208, 61, 55,149,130,166,233, 84,181, 90,237,109, 99, 99, - 83, 51,162,182, 86,108, 1,192,111, 49, 84, 12, 64,117,175, 49,197,127,209, 59, 96,145,145,145,109, 44, 44, 44,222, 35, 8, 98, - 44,195, 48,238, 18,137, 68,190,102,205,154,232,240,240,240,242,182,109,219, 14, 27, 62,124, 56, 97,105,105,137, 7, 15, 30, 48, -197,197,197,167, 0,172,130, 30, 35,173,105,154,206,220,188,121, 51,154,251,190, 55,117, 92,169, 84,230, 69, 70, 70, 90, 15, 45, - 40, 96,211, 52,141, 17, 35, 70,188, 38,224, 26,226,201,147, 39,144,203,229, 77, 78,230, 40, 47, 47,197,128,207, 86, 0,181,163, - 63,235, 80,227,100, 49, 96, 20, 6, 93,101,192,191, 11,127,245,130,158,122, 89,139, 14, 14, 14, 19, 4, 34,254, 60,151,142, 14, - 62, 47,211, 11,146, 36,229,213, 71,197, 98,241,126, 45, 25,185, 94,156,205,156,176,212, 96,255,254, 69,156,175,230,209,162,192, - 48, 20, 24,154, 1,195,208,160,105,170,102,193,107,134, 6, 67, 81, 4, 65,224, 79,133,180,201,153,193, 27,134,211,194,218,218, -122, 3,195, 48, 67, 89, 44, 22, 89,223, 12,171,255,189,214,201,186, 84, 88, 88,248,101, 35,206,235,255, 92,124,134,135,135, 55, - 42,254,245, 29,117, 56,110,220, 56,170,153,239,230, 13,145, 72,228,208,216,177,170,170,170, 44,177, 88,252,222,223, 36, 62,235, -143, 24,108, 14,103,179, 71, 29,234,226,116,113,113,225, 43,149,202,174, 0,220, 8,130, 48, 7, 80,162, 84, 42, 47, 23, 21, 21, -229, 3,232, 6, 96, 77,237, 53, 95, 1,136,249, 63,126,223,133,214,214,214, 7, 73,146,108,173,207,197,106,181, 90, 81, 82, 82, - 50,189, 65,133, 64,195,105,101,101, 21,195,102,179, 91,235,193,147, 83, 92, 92,220,205,144,127, 26, 56,255, 65,104,216, 9, 94, -235, 76,241,127,133,208, 50,112, 26, 56, 13,156, 6, 78, 3,167,129,211,192,105,224,252,167, 11,173, 70,247, 13,195,106, 13, 48, -192, 0, 3, 12, 48,192, 0, 3,222, 14, 23, 26,136,173, 11,117, 95,136, 38, 84,105,115, 44,193,150, 40,219,171, 6, 78, 3,167, -129,211,192,105,224, 52,112, 26, 56,255,117,156, 6,188, 67, 24,108, 85, 3,167,129,211,192,105,224, 52,112, 26, 56, 13,156,255, -116,104,109, 58, 36, 13,113, 99,128, 1, 6, 24, 96,128, 1, 6, 24,240,215, 64,111,161, 37,178,115,247,176,118,241, 57,100,209, -186,115,156, 69,235,206,113,214, 46, 62,135, 68,118,238, 30,255,210,120, 19, 2,152,204,102,179,175,216,219,219, 87, 64,203,210, - 59,255, 0,152, 2, 24,139,154,249,125, 70, 1, 48,122,151,228,129, 0,123, 2, 48,111, 26,144, 53, 13,200,154, 0,204, 11,252, - 7,246, 27, 92,183,208, 33,224,230,197,201, 23,215, 45,116, 8,104,244,248, 82, 7,171,187,191,143,219,177,105,158,163,229, 59, -250, 75, 19, 91, 91,219, 3,118,118,118, 47,108,109,109, 51,109,109,109, 15, 2, 48, 51,100,119, 6, 24, 96,128, 1,127, 25,234, -250,104,213,125, 52,125,180,216, 0, 16, 17, 17, 17, 8,224, 15, 0,253,131,131,131,163, 26, 94,109,225,236,253, 73,251,118,237, -151,127,189,110, 21, 97,111,107,109,164,166,104,101,198,139,108,207,181, 95,135,253,250,146,199,222, 90,154,149,240, 99, 11, 2, - 69,176, 88,172, 9,124, 62, 63, 24, 64,157, 96, 75,150,203,229, 17, 20, 69,157,128,126,195,180, 97,103,103,119,147,197, 98,181, -105,206, 31, 83, 20,149,149,159,159,223,167,133,145, 57,206,217,217,249, 96, 96, 96,160,145,191,191, 63,120, 60, 30,214,172, 89, -179, 84, 44, 22,111,211,151,192,194,194,213, 68,201, 23, 44,102,243,120,131, 25,149,194,155, 1, 3,144,252, 4, 90, 45,191,198, -149,203,183,150,150,166, 75,244,164, 90, 5, 96, 70,109, 92,253, 8, 96,243,219, 60, 37,211,187, 64,165,162,106,158, 9, 46, 27, -212,185,231,102,127,172, 94,189,154, 29, 28, 28,140, 31,127,252,177,207,129, 3, 7,102, 73, 36,146,107, 0,126, 3,240,236,109, -159, 74, 59, 96,118,175, 62,125,118, 76, 95,186,148, 37,189,121, 19, 59, 14, 30,220,142,154,249,150,246, 52,247, 89,226,114, 49, -214,218,154, 19,204, 48,232, 74, 0, 4, 1, 60, 42, 44,166, 35,149, 74,234, 4,244,152,139,173, 9, 76,198,235,195,241,127,105, - 46, 65,249, 51,230, 11,254, 8,143,190,229,207,110,124, 1, 96, 88,195,227,106,153, 96, 58,195,114, 10,150, 50,177,217, 0,182, -188,101,180, 26,217,216,216,196,157, 59,119,174,181,191,191, 63, 27, 0, 98, 98, 98,166, 5, 7, 7, 15, 40, 44, 44,244, 6, 80, -241,127,148, 9, 9,216, 36, 57,143,199,225, 12,166, 40,170, 51, 0,176, 88,172,120,133, 74,117, 69, 77,211,123,160,231,156,108, - 6, 24, 96,192, 63, 23,186,180,200,223, 28, 90,103,134,175,187, 57,166,254,182, 62, 68,182,157, 60,123, 14, 28,243,164, 92, 82, - 45,123,241, 34,183,116,201,188,141, 87,102, 45,250,238,236,150, 31, 34, 34,163,238, 37,223,245,240,127, 47, 73,100,219,201, 83, - 11,181,182, 54, 92,103,161, 80,248,112,239,222,189,202,212,212, 84,166,172,172,140,121,242,228, 9,115,234,212, 41,102,206,156, - 57, 50,161, 80,248, 16,128,179, 62,156,118,118,118,249, 79,174,255,206,228,196,197, 50,153, 49,247, 24,149, 74,197, 40,149, 74, - 70,169, 84, 50, 73,151, 34,152,184,223,111,128,202, 97, 0, 0, 32, 0, 73, 68, 65, 84, 78, 51,143, 78,157, 96, 20, 10, 5,163, - 80, 40, 24,185, 92,206,180,107,215,238,165,158,225,108, 8, 71, 47, 47, 47, 69, 68, 68, 4,243,235,175,191, 50, 75,151, 46,101, -124,125,125, 41, 0,243,245,189,119,145,173, 91,144, 73, 43,159,194, 79, 66,246, 40, 47, 68, 95,102, 18,159, 63, 98, 18,159,167, - 49,225, 87,147,153, 25,203,118, 42, 77, 90,249, 22,138,108,221,130,116,221,187,133,133, 69, 79,130, 32,152, 58, 0, 96,218,180, -105, 83, 89,255,227,236,236,252,218,199,201,201,169,178,109,219,182,207,172,172,172,186, 54,198, 57,169, 51, 24, 38,233, 23,134, - 73,250,133, 89,221, 15, 76, 98, 98,226, 93,134, 97,254,168,251, 72,165,210, 63,206,156, 57,243,199,135, 31,126,248, 7,128, 15, -154,136, 39,189,226,115, 26,144, 37, 57,119,142, 97,182,109, 99,152,192, 64, 38, 25, 96,166, 1, 89,205,228,108,103,111,207,121, -244,221,230, 89,138,115,231,126,102, 46, 94,188,192, 68, 70, 70, 48,103,207, 28,100,182,111,155,167,180,179,227, 36, 0,232,208, - 12, 78, 54,128,141, 0,182,162,198,185, 76, 45, 44, 44,100,242,242,242, 24, 0,169,181,191,109,181,177,177,217,130,198,221,183, - 65,245,157,172,207,134,218, 95, 28, 63,172, 15, 35, 41,127,201,140, 31,214,135,249,108,168,253,107,206,214, 80, 87, 87,147, 5, - 35, 58, 23, 38,198, 28,165, 22,140,232, 92, 56,212,213,213,164,133,241, 73,160,102,157,208,189,215,175, 95, 87, 51,245,160, 82, -169,152,195,135, 15, 83, 22, 22, 22, 63, 55,131,179,163,141,141, 77,166,165,165,101,106,253, 31,109,124, 70,245,114,239, 59,109, -173,149,231,135,129,205, 8,167,191,128,203,205,185,114,242,123,170, 56, 43,158, 81, 72,243,153,242,167,177, 76, 78,242, 93,230, -240,254,173, 42, 30,155,157, 3,192,255,109,158,165,102,194,192,105,224, 52,112,254, 13, 57,155,210, 34,255,203, 96, 55,188,193, -134,224,243,121, 33,107, 87,175, 32,202,138,203,164,178, 10,137, 66, 37,147,201, 72, 46, 35,139, 79,122, 94, 64,178, 89,101,159, - 45, 90,104, 18,178,114,117, 72, 21, 48, 69,207,255,116,246,245,245,189,127,250,244,105, 91, 75, 75, 75,148,151,151,163,184,184, - 24,247,239,223, 7,195, 48, 24, 61,122, 52,191, 71,247,238, 93,191, 88,179,230, 78, 78,110,110, 0,180, 23,188,175,196,139,165, - 53, 54,247,169, 89,139,246,203, 23,197, 53,165, 14, 65,224,192,184, 96,205, 57, 27,114,106, 86,203, 16, 8, 4,154, 5,137, 91, -128,128,129, 3, 7,114, 1, 96,230,204,153, 21, 18,137, 36,180,214,225,208,107,165, 85,145,173, 91,144,181,131, 99,196,247,251, - 54, 11, 59,183,119,131, 82,165, 70,102,222, 75,176, 57,230,104,221,154,139,143,166, 12,230,244,235,101,105,189,241,171, 3, 23, -242,104,140,170, 46, 74,187,172,141,203,220,220,252,240,137, 19, 39,112,242,228, 73, 0, 64,106,106, 42,220,220,220, 68,186,194, -144,144,144,224,250,193, 7, 31, 28, 47, 46, 46,238,160,235,220,134, 19,227,243,249,124,244,233,211, 7,158,158,158, 56,119,238, - 92,255, 90,103,235,173, 32,189,121, 19,198,143, 31, 3, 81, 45,170,188,180,243,243,115,185, 27,121,225,168,245,133,200,100,108, -217,114, 16,207,158,213, 24,109,174,174,174,152, 60,105, 28, 39, 62, 62,218,107,236,216,201,209,183,110, 61,235, 83, 43,148,116, - 97,253, 15, 63,252,176,170,109,219,182, 24, 59,118,236, 56, 47, 47, 47,123, 83, 83, 83,236,223,191, 31, 14, 14, 14,174, 10,133, -226,233,185,115,231, 28,243,242,242,176,112,225, 66,228,231,231, 47,213, 70,212,127, 72,255, 47,248, 35, 60,250,118,242,155, 14, - 99, 83, 7,252,112,236, 4,158, 60, 60,220, 87,174, 76,254,130, 75, 69, 77,149, 50,252, 25,133, 89,198, 33,109,186, 5, 90,117, -240,250, 0, 46,126,177,214, 50,234,214,243, 47, 6,183, 11, 99, 11,100,135,215,109, 17, 23,191, 65, 58, 54,156,229, 93,145, 98, -153,112, 5,197,192, 58,186, 78, 96,105,220, 90, 6, 31,244,235,215, 79,147,112, 47, 94,188,128, 92, 46,135,135,135, 7,169, 80, - 40,130,244,140,215,142,239,189,247,222,159,145,145,145, 86, 29, 59,118, 44, 44, 41, 41,209, 28,176,183, 50, 31, 18,117,122,251, -194,141, 59,254,235,126,132, 33,202, 10,147,207,198,235,224,242,239,221,211,239,234,197,211, 71,141,137,202,108,240,204,139, 0, -186, 24,233,199,127, 2, 97,100,137, 9,115,150,176,131, 6, 14,104, 53,120,216,152,171, 79,210,158, 13, 4,240,192, 80,175, 55, -192,128,127,181,171,197,252,211,238, 73, 35,180,130,131,131,137,198,110,144,102,104, 31, 59, 91, 43,225,246,239, 14, 61, 96, 41, - 21, 10,145,185,153,130, 99,102, 74, 19, 38,102, 44,165, 66, 85,233,226,234,194,163, 25,218, 71, 11,127,195, 33,158,132, 80, 40, - 60,253,219,111,191,217,114, 56, 28,208, 52, 13, 27, 27, 27,100,100,100,160,172,172, 12, 18,137, 4,207,146,147,209,214,217, 9, -235, 66, 86, 56, 44, 92, 17,114,186,186,186,186, 27, 94,111, 70,124, 99,216, 40,165,122,125,221,232,186, 37, 88,222,168,242,215, -254,214,200, 49,125,135,162,102,100,101,101,193,216,216, 24,222,222,222,198,183,111,223,190,213,132,200,122,141,211,194,194,213, -132,230,243, 78,238,253,126,141, 80,169, 74, 64, 82,122, 9, 58,181,237, 11, 59, 43,103,188, 44, 81,224,238,253,223,144, 16,247, - 11,218,183,114,198,252, 57, 3, 4, 97,155,127, 61,193, 85,183,117, 46, 43,203,168,104,140,179,162,162,194,184, 93,187,118,112, -118,174, 89,247,140,162, 40, 36, 37, 37,129,162, 40,205,126,253,237,161, 83,215,161,174,200,196,244,105,211, 80, 92, 92,108,220, - 24, 39,135, 5,245,146, 89,147,217, 66, 14,192, 19, 89, 42, 42, 43, 43, 53,203,112, 40,149, 74, 60,122,244, 8, 1, 1, 1,129, -225,225,225,186, 84,145, 94,241,169, 4,190,221,241,243,207, 59,167,148,151,147, 0,240, 35, 65,208, 74,134,249, 86,223,103,201, -214,150,115,234,210,197, 35,214, 44, 50, 5,150,102,223,224,254,253, 76, 40,149, 53,225, 45, 46, 46,192,130,121, 21,224,114, 76, -112,238,220,127,173, 60, 60,250,156,202,203, 83,122,227,245,102,196,198,194, 41,184,120,241, 34, 22, 44, 88,128,164,164, 36, 71, - 22,139,133,123,247,238, 65, 40, 20,226,187,239,190, 99,121,120,120, 56,138, 68, 34, 92,186,116, 9,249,249,249, 68, 83,225,252, -227,242, 31, 95,151, 63,187,241, 69, 30,113,105,232, 15,199, 78,224,211, 73, 19, 96,207,164,223, 50,107, 79,124,253,222,136,222, - 95, 50, 44,167, 96,145,137,143,133,155,247, 8,112,121,198,152,255,249, 6,164, 38,156,183,168,150,196,205, 35,168,108,167,117, - 91,194, 23,189, 17,206, 95,199, 81, 51,127,185,237,119,197,249,129,203,227, 71,179,238,137, 99, 15,196,189, 18, 90,174,108,130, -164,204,128,154,229, 83,158, 62,125,138,103,207,158,129,205,102, 67, 42,149, 66,173, 86, 55, 26, 78, 71, 71,199,217,106,181,250, -203,218,116, 62, 36, 16, 8, 62, 62,122,244,168, 85,125,161,109,227, 51,170,151,149,137,104, 96,126, 65,113,105,244,131,196, 39, - 75,102,143,237,127,243,110, 66,182,146,243, 97, 86,121,220,185,114, 45,241, 41, 16,242,120,167, 46,157,249,175,177,234,249,117, -136, 60,250,131, 99,236, 6, 74,149,139,234,210, 42, 72,158,137, 33,255,126, 55,186,204,251, 12,231,207,254,106,236,213,185, 91, -184, 92,165,114, 3,160,104,193,187,217, 28, 24, 56, 13,156, 6,206,191, 39,167, 86, 45,194, 48,140, 31, 0,187,218,221,226, 90, - 93, 96, 13,160, 8, 53,171,200,216,213,230, 29,188,122,151, 53,220,175,127,110,195,253,250,223,139,107,191,219,214,110, 31, 16, - 4, 81,162, 35,232, 14,168, 89,154,240, 66,237, 22,168,109, 74,212,217,241,152, 32,200, 10,138,162,249, 92, 27, 91,217,204,241, - 3, 59,255,126, 53,230,145,145,181, 41,123, 72,255,174,129,247,227,159,223, 33, 72, 66, 69, 16,164, 94,253, 62, 88, 44,214,132, -237,219,183,119, 54, 53, 53, 5, 77,211, 48, 51, 51, 67, 97, 97, 33, 20, 10, 5,202,203,203, 33,151, 84, 64, 41,169,192,227,236, - 23,232, 29,216, 31, 99,134,190,231,241,223,179,191, 77,160, 40,234,120, 83,188,142, 62, 93, 53, 78,214,134, 54, 86,175,172,137, -236, 50,141,232,250,166,171, 27,184,198,198, 24,188, 36,228,109,158,129,216, 11, 23, 46, 92, 28, 61,122,244,176,101,203,150,145, - 98,177,248, 82, 70, 70, 70,111, 0, 73, 58, 69, 5, 95,176,120,238,226, 96, 11, 11, 99, 6,225, 87,126, 67,191,174,147, 96,196, - 99,161,184, 66, 9,130, 0,146, 19, 79,131, 32, 44, 17,151, 42, 70,223, 46,166,120,111,136,135,241,217, 95,147,151,225, 85,255, -160, 55,146,166,180,180, 20, 5, 5, 5, 80,169, 84, 80,169, 84, 24, 59,110, 28,142, 28, 62,140,170,170, 42, 72,165, 82, 40, 20, - 10, 80, 20, 5,146, 36,113, 37, 34, 28,217,207,147,209, 43, 32, 0,208,178,244,210,225, 71,224, 0,184,251,228,201, 19, 36, 39, - 39, 35, 39, 39, 7, 2,129, 0,246,246,246,216,176, 97, 3,228,242,154, 53,202,198,141, 27, 23, 8, 32,254,109, 95,168,103,192, -129, 12,138,250, 98,216,153, 51,182,183,207,156,161,239,158, 63,159,195,151, 72,246,235,115, 45,151,139,177,155,191,157,211, 73, - 36, 18, 33, 39,107, 59,220,221,185, 88,250,153, 21, 66,191, 41, 2, 0, 44, 92,208, 26,221,187, 89,163,162,236, 87, 88,219,174, -194,206,157,139,218,207,152,177,117, 90,117, 53,117, 72, 7,245, 23,191,253,246,219, 24, 55, 55,183, 86,177,177,177, 4,143,199, -131, 80, 40,132, 80, 40,132, 64, 32, 64, 65, 65, 1, 50, 50, 50,152,205,155, 55,231, 2,248,162, 41,162,117, 59,197,119, 0, 12, -251,108, 40, 46, 62,121,120,184,111, 43,214,243,199, 99,230,247,121, 17,119, 55, 86,242,251,149,219, 95,169,101,130,236,178,156, -171, 43,218,117,143,181,158,183,124, 61,118,111, 94,139, 39,247,110,150,216, 57, 87,236, 17, 18,242, 70,195, 25, 24,184,142,237, - 96,103,169,158, 61, 99,140,249,121,187,232,217,145,108,162, 48,175,232,225,119,200,136,149,242, 59,116,157,218,209,149, 84, 92, -191,126, 93,216,175, 95, 63,200,100, 50,141, 51,121,244,232, 81, 90,173, 86,223,104,244,217, 84, 42,191,204,205,205,117,144, 74, -165, 24, 58,116,232,194,239,190,251, 78, 84,183, 70, 29, 69, 81,175, 57, 89, 95,111, 59,114,121,241,151,123,110, 92, 62,254,141, -227,215, 33, 31,247,159, 50,127,227, 13,104, 89, 71,146, 77,146,243,206,159, 57,104, 47,176, 80, 65,104,249, 30,100,249, 82, 60, - 57,240, 41,170, 43,100,232,254,245,122, 0, 60, 40, 84, 36,246,143, 24, 11,142,149, 35,214,126,242,177,227,234,253, 63,204,161, -105,122,187,161, 94,111,128, 1, 6, 52,128, 29, 65, 16, 17, 0, 16, 18, 18,178, 42, 52, 52, 52,145, 32,136, 8,134, 97,130,107, - 13,148, 8,134, 97,130,235,206,169, 21,103,111,236,215,157,219,112,191,225,247,149, 43, 87,122,133,133,133,109, 10, 8, 8, 56, - 30, 29, 29,253, 28,128, 46,161, 53,188, 86, 88,189,177,244, 14, 89,167, 32,235,111, 95,115,180,104,250,230,211,231, 47,170,223, - 27,212,163,117, 68, 84,252,131,143, 62, 26, 62,112,194,136,126, 67, 50,178,138,147,219,187,216, 91, 39, 38,198,155,210, 52,125, - 83,159, 88,226,243,249,193, 3, 6, 12, 96,151,150,150,194,200,200, 8,133,133,133,200,205,205,133, 82,169,132,172,188, 12,242, -242, 50,200,202, 74,161, 44, 47,197,179,152,251,240,105,239,202,175,237, 44,223, 36,234, 92,151,134, 78, 85,125,103,139,103, 98, - 2,190,137, 9,136,230, 55, 27,126,104,110,110,126,183,174, 80, 85, 42,149,243, 86,172, 88, 81, 68,211, 52, 54,110,220,104,106, -108,108, 28, 14,128,175,139,196,196,134, 21, 28,208,197,155, 76,201,136, 67, 31,223,233,232,216,238,125,100,228, 75, 81, 36, 81, -162,160, 76,137,238,253,118,161,141,239,122, 56,117, 9, 69,114,102, 9, 28, 91,185,145, 96,243,155, 92,252, 57, 59, 59,251,181, -253,227,199,142,161,186,186, 26,237,219,183,199,164, 73,147,176, 98,197, 10, 76,154, 52, 9,142,142,142,152, 50,254, 3,172, 93, -187, 22,121,121,121,186,130, 42,239,216,177,163,220,197,197, 69,238,226,226, 34, 87, 42,149,168,172,172, 68, 89, 89, 89,195,248, - 94,212,220,136,180,181,181, 93,105,111,111, 31,103,107,107,155,200,231,243, 35, 31, 17, 68,138,204,197,197,174,247,200,145,132, -231,248,241,172, 76,161,144,136, 2,140,245,225,178,182,228, 12, 15, 26, 48,140, 87, 86,122, 80, 99, 82,125,252,145, 13,254,140, -242,194,237, 91,221,176, 96, 94,123, 16,164, 0, 4,201, 67,117,213,117,244,240, 15,224,154,155, 19,186,158,165,201, 0, 30,245, -238,221,219,113,254,252,249, 4,159,207,199,194,133, 11,149,159,124,242, 73,218,164, 73,147,210,174, 93,187, 70,185,184,184,192, -201,201,137,112,114,114,114, 0,240,168,246,154, 38, 97,218,158,248, 90,174, 76,190,101,238, 38,122, 78,193,186, 87,165,138, 63, -118,221, 22,113,241,215,123,159,111,201,120, 82,237,250,228,222,205,226,180,132,243,116,198,131, 63,138, 94,166, 73, 92,191,222, -251,124,203,170, 61, 47, 27,125,169,163,162, 64,159,142,136, 82, 86, 87, 85,179, 71,142, 8,170,158, 61,115, 66, 71, 75, 99,175, -163,104,245,158,111, 27,231,214, 83,214,110,218,169,252,100,206, 98,229,143, 63, 29,100, 36, 18, 9, 42, 42, 42,176,115,231, 78, -245,249,243,231,115, 41,138, 90,172,173, 14, 4, 0, 42,149, 10,179,103,207, 22,153,154,154, 34, 59, 59, 91,227,136, 2,128,184, -176, 56,254,246,131,132,148, 37,255, 25, 23, 88, 37,151,203, 47,255, 17,147,236,233,230,210,154, 32, 24,173, 3, 81,120, 28,206, -224,110, 61,122,176, 24,166, 12, 4,219, 25,207, 14,111, 70, 69, 94, 9, 42, 10, 74,192,226,136,160, 6, 31, 42,154, 7,115, 31, -127,164, 62,136, 69, 43, 27, 59, 54,159,195, 25, 98, 40, 79, 12, 48,224,223,137,166,180, 72,125,177, 20, 22, 22,182,169,169,227, -245,182,138, 6,251, 26, 33,213, 80,132,213,255, 14, 0, 97, 97, 97,155, 24,134, 9,142,142,142, 62, 6, 64,170,231, 45,204,170, -183,213,127, 30, 45,150, 76, 17,186,108,197, 23,176, 48, 19,154,249,119,117,179, 63,119, 41, 42,230,102,116, 76,114, 27, 39,107, - 27, 70,165,176,248,118,235,238,214, 68,181, 52, 76,207, 64,120, 88, 91, 91, 67,169, 84,226,233,211,167,200,201,201,129, 82,169, -132,186,170, 10,242,178, 50,200, 74, 75, 65, 85, 73,192,165, 40, 72, 11, 11, 96,101, 36, 0, 94,141, 72,212,225,188, 17,141, 10, -173,186,173,192,212, 20,124, 19, 83,144, 28, 78,163,205,138, 90,224,231,239,239,127, 50, 33, 33,161,199,160, 65,131,190, 66,205, - 16,249,204,220,220,220,129,107,214,172,145,219,217,217, 97,246,236,217,157, 0, 76,215, 41, 50,121, 10, 15, 23,251, 78,232,232, - 58, 29,109,156, 6,160,172, 74,133,194, 10, 21, 10,202,148,216,191, 43, 0,167,126,244,199,159,167,250, 34,225,242, 96,148,169, -236, 97,236,248, 33, 24, 74,225,213, 20,231,149, 43, 87,176, 97,195, 6,124,245,213, 87,216,184,113, 35,190,250,234, 43,228,230, -230,194,219,219, 27, 89, 89, 89,184,120,241, 34,196, 98, 49,172,173,173,113,255,254,125,108,219,182, 13,127,254,249,167,206,155, -174, 19,174,122,156,211,172,182,116,181, 90, 61, 67, 60,114,100,231,124, 75, 75,207,174, 93,187, 14, 91,184,112,161,107,239,222, -189, 53,199, 93, 93, 93,157,133, 66, 97, 30,106, 70, 80,118,105,138,139, 6,186,218,216,120, 67, 33, 79,169, 77, 99, 14, 8, 66, -128, 1,131,147,209,187,111, 12,148, 42, 46, 72,130, 15,146, 20, 64,173, 46,134,133,133, 35, 24,134,240,214, 17,196, 53,133,133, -133,110, 87,175, 94, 37, 51, 50, 50, 32, 16, 8, 0,224,197,186,117,235,118,111,217,178, 37,201,202,202,138,138,136,136,192,217, -179,103, 17, 28, 28,204,250,228,147, 79,220,156,156,156,246,233,186,239,117, 59,197,119,126,217,122,113, 34, 71,101,209, 69, 32, -108,211, 22, 85,198, 31,206, 13,180, 22, 1,192,165,244,116,137,173,115, 69, 88,149, 36, 46,203,188,117,229, 55,151,210,117,141, - 56, 93, 71, 63, 76, 75,185,251,203,153, 75,229, 5,249,165,156,174,157,189,164,161, 27,150,115,219,180,237,240,237,218, 21,255, -177,207,173, 16,148, 13, 94,120, 49,229,244,165,251,149, 83, 63,250, 84, 61,115,214,124,217,197, 75, 87,206,208, 52,221, 25, 90, - 70, 28,210, 52, 13,177, 88,140,196,196, 68,164,167,167,163,176,176, 16, 69, 69, 69,144, 72, 36,154,230, 70, 35, 73,197,133,221, - 63,159,127, 44, 18, 10,141,122,116,118,115,190, 23,155, 84, 32, 18, 10,141,220,218, 58,119,196,255, 99,239,186,227,162,184,214, -246, 51,179,189, 81,150,206, 2, 42,160, 40, 42, 8, 68, 68,236,168,145,196,222,176, 68,177, 68,163, 73, 52, 70,147, 24,176, 36, -118,141,215,168,209,152,168,137, 61,118, 49, 42,118,197,222, 5, 84, 4, 20,164,247, 14,203,246, 50, 51,223, 31, 2, 23, 13,101, -209, 36, 55,247,187, 60,191,223,176,236,238,204,179,231, 76, 57,231, 57,239,251,158,247, 96, 73,157,237, 8, 69, 81,222, 2,145, - 16, 0,129,242,184,235, 80,148, 41,160, 40, 87,160,178, 84, 1,173,158, 5,141,150,132, 90, 71,162,101,239, 1, 80, 40, 53, 80, -148, 84,128,166, 40,159,230,238,166, 25,205,104, 70, 3,125,125,100, 88, 88,216, 2, 19,247, 53,217,189,249,186,240, 10, 11, 11, - 91, 64, 16, 68,100,120,120,120, 71,212, 63,161,170, 54,182,215,177, 1, 48, 33,189, 67, 73, 73,146,194,140,104, 63,114,238,252, -111,206, 30,216,177,217, 78,171, 85,101, 90, 75, 37,148, 68,196,179,249,112,198, 74, 84, 42,202, 70, 40, 77, 79, 71,128,178,178, - 50,164,166,166, 66, 40, 20,130,203,225,128, 82,171, 65,169,149, 80,151,149,128,212,107,193,165, 40, 88,137,132,104, 41,115, 64, - 43,123, 7,147, 56,147,163, 46,212, 4,190,215,118, 23,254,171, 75,123,240,196, 18,240,204, 36,248, 36,242, 42, 0,128,203,229, - 2,139,151,155,100, 52,113,114,114, 58,185,127,255,126,110, 81, 81, 17, 98, 99, 99, 31, 1,168, 0, 96, 6,128, 78, 72, 72,184, - 20, 23, 23, 55,216,195,195, 3, 0, 90, 55, 70, 38, 47, 38, 41,131,145, 65, 86,126, 58,210,178, 99, 96,101,225, 6,142,168, 45, - 10,203,245,224, 11,221, 96,208,254,219,251,168,145,103, 64,173,103,153, 84,119,157, 78, 7,163,209, 8,163,209, 8,157, 78,135, -143, 62,250, 8,183,110,223,198,193,223, 47, 35,245,197,115,180,115,117, 64,104,232, 68,116,233,210, 5,183,111,223,110,144,107, -146, 47, 12, 78, 18,176,215,191, 79,130, 39,177,214,118,253,250,252,189,198,196, 22, 65, 16, 12,234,113, 69,190,134,239, 3, 3, - 3,219, 60, 87, 42,241, 52, 49, 17,253,151, 44, 1, 0,156, 57,115,230,149,186,204,155, 55,143, 23, 31, 31,255,225,195,135, 15, - 63,204,205,205, 93, 15,160,238, 96,115, 6, 56,125,250, 14,102,206,140, 71, 81, 81, 17, 0,224,208,129,127,235,210,180, 84, 61, -222, 27,244,210,163,101,105,105,137,245,235,189, 76, 58,159, 20, 69, 97,251,246,237, 53,238, 66, 0, 96,179,217,221,231,205,155, - 55,178,174,253,219,180,105,195,109,140,115,238,104, 39,193,205, 71,204,167, 22,109, 90,117, 52,183,233,132, 18, 67,140, 87, 76, - 78,222,236,185,163,157, 54,110, 56,154,163, 17, 18,218,221, 4,149,229,194, 22,104,246,152, 82,198,148,115,155,117, 37, 45, 39, -239,201, 47,146, 47,156, 53,253, 3,107,115, 75, 59,229,175, 63,174,150,146, 44,146, 57,249, 80, 95,222,209,221,218,114, 88,215, - 31, 20, 51,231, 46,142,209, 25,179,102, 33,235,228,115, 52,144,226,130,162, 40,228,230,230,162,168,168, 8,153,153,153, 40, 46, -126,233,126, 45, 46, 46, 6, 77,211,111,211, 32, 66,157,153,137,140,227,191,162,213,196,137,240, 95,190, 12, 20,205,134, 90, 69, - 97,125,183,126, 40,171, 80, 67, 75, 19,144,189,211, 13,211,207,220, 0,201, 80,192,182, 45,205, 61, 73, 51,154,241, 63, 10, 83, -210, 59, 84, 11,162,213,171, 87, 15,254,179,127,191,182,216, 90,189,122,245,211,213,171, 87, 55,229,183, 94,119, 25,214,188,175, -142,209,186, 90, 43, 0,237, 15,157,102,101,113, 66, 74,124, 60, 59, 87,169, 86,138,236,237,108,181, 34, 1,159,174,144, 87,178, - 98,158, 60,210, 43,243, 95, 60,107, 66, 61, 18,226,226,226,188,114,115,115,145,153,145, 1,163, 90, 9, 82,171, 3,163, 81,161, -127,143,110, 16, 0, 16,144, 4,184,180, 30,108, 22, 15,149, 10, 57, 0, 36, 52,218, 57, 26, 12,127,176,108, 17, 4, 1,158,153, - 25,120, 98, 49,120, 18,179, 87, 44, 92,166, 88,108,248,124,254,254, 35, 71,142, 56, 58, 57, 57, 97,217,178,101,112,118,118,246, -148,201,100, 42, 11, 11, 11,161,189,189, 61, 58,116,232,128,110,221,186,225,236,217,179,128, 9, 57,165, 12, 70,193,227,103,233, -232, 94, 92,122, 27, 55,174,254, 12,157, 90, 11,191,222, 63, 67,207,110, 5,219,142, 75, 65, 39,239,131, 42,255,196, 75,235,129, -195, 16,100,103,166,131, 96,241,158,154,106,121,170,254,255,209,163, 71, 56,112,226, 26, 28, 91,182, 71,102, 82, 34, 18,175, 92, -194, 45, 91,107,180,108,223,161,198, 13, 84,111, 25, 41,176, 87,108,121,153, 38,106,209,167, 31,240, 75, 75, 75,249, 86, 86, 86, -218,234,115,231,232,232,248, 54, 98,235,131, 47,191,252, 18,229, 28, 14, 48,104, 16,184, 41, 41,208,235,245,232,218,181, 43,252, -253,253, 1, 0, 93,187,118, 5,155,205, 70,167, 78,157, 32,147,201,176,101,203,150, 15,234, 19, 90, 36,129, 88,163,177,196,211, -221,221,189, 70,104,237,217, 91,132,152,135,239,130, 0, 15,155,126, 76,174,217,183, 69,139, 22,200,207, 75, 1, 65, 48,113,141, -148,113,185,131,131,195, 98, 71, 71, 71,247,239,191,255,158, 37, 16, 8,240,241,199, 31,187, 41, 20,138, 86, 85,166,100,132,135, -135, 3, 0,190,253,246, 91, 44, 89,178, 4, 90,173, 86, 85, 31,217,158,245,222,178,194, 82,250, 67, 70, 33, 26, 17,100,211,202, -187,111,112,127,184,121,244, 69,223,224, 76, 0, 88,101,197, 78, 31,179,118,161,229,113, 75, 51, 98,231,133,115, 23,191,237,209, -187,239,194,175, 21, 87, 86,124,183,189,188,209,152,199,138,140,221,149,207,120, 99, 55,108,222,186,119,195, 55,225,115, 4,153, - 69,186,178,156, 50, 70, 33,225,179, 37,173,237, 9,201,236,249,203, 83,115,115, 83,190, 64,214,185, 70,103, 90,210, 52,141,148, -148,148,154,152, 62,141, 70, 3,165, 82,137,172,172,172,154,123, 70, 45, 54,127,111,214,148, 33, 62, 74,181, 90,117,239, 73, 82, -230,162,207, 38, 4, 42,213,106, 85, 82, 90,230,115, 96, 83,157,106,140, 36,201, 39,170, 74, 85,127, 85,185, 6, 69,177,207,224, -220,175, 37, 12, 70, 2, 58, 35,133,162,146, 74,104,141, 0, 69,114,208,113, 76, 40, 40,130,141,226,220, 28,144, 44,214, 35,188, - 26,180,223,140,102, 52,227,127, 7, 13,106,145,106,139, 86, 96, 96,224,193,218, 86,167,234,255, 1,104,209,112, 40, 79, 81,109, - 49, 85,237, 78,172,239,119, 94,227, 53, 21,127,136,209,106, 52,189, 67,245,111,186, 88,200,101,255,250,118,130, 51,109, 52,182, - 43, 44, 46, 48,178,217,124,142,139,133, 58,175, 52,211,244, 95,215,106,181,145,151, 46, 93, 26,254,238,187,239,242,147,158, 60, -130,174,162, 2,186,138,114,112,104, 35,172,132,157, 65,234,181, 32,116, 58, 56,121,210,208, 84, 10,113,237, 86,156, 65,171,213, - 70,154, 42,180, 72, 22,235,213,184, 44,137, 4,124, 51,115,240, 37,146,215, 93,139,141,137, 2,209,128, 1, 3,250,117,237,218, - 21, 12,195, 96,251,246,237,208,235,245, 60,189, 94, 15,157, 78, 7,189, 94, 15,185, 92,142,189,123,247,226,167,159,126,186, 5, - 96, 87,163,157,153, 81,119,233,252,197,168, 46, 83, 39, 12,230,156,137, 92, 15,163,142,130,154,112,134, 82,105,128, 66, 39, 2, -101, 61, 17, 40, 56, 13, 22, 91,128,192, 78,110, 56,113, 52, 66, 15,163,246,178,137, 42,252, 21,171, 80, 86,102, 58,178, 95, 60, -135, 68,158, 15, 91,115, 17, 84, 41,207,225, 23, 58,233,141,172, 19, 46, 46, 46,160,105, 26, 65, 65, 65, 53,193,213,111, 42,182, - 74, 74, 74,112,234,212, 41,116,237,218, 21,189,123,247, 70, 78, 78, 14, 82, 82, 82, 48,112,224,192,154,125, 30, 61,122,132,152, -152, 24,180,110,221,176,145,176,184,212,112, 38, 59, 43, 54,100,216,176, 97,220,187,119,239,130, 97, 24,120,120,152,195,220, 76, - 12,130,228,163,125,123, 59, 0, 47,199, 0,125,250,244,129, 92,158, 98, 44, 43, 99,206, 52, 82,221,253, 0,126,215,233,116,201, -189,122,245,146,189,120,241, 2,115,231,206,101, 31, 58,116,168,218,148,140,176,176, 87, 39, 83,168,213,245,187,238,219,121,123, -126,229,102,148,246, 22, 8, 91,185,154,219,116,130,155, 71, 95, 0,192,187,131,167,194,173, 77, 11,200,139, 31,187,106,212,233, - 35,184,236, 50,233,227, 77, 57,241,194, 65, 94, 83, 52,133, 87,147,240,210,117,218,232,101, 87, 39, 29, 42,200,228, 76, 60,252, -251,201,179, 51, 6, 14, 30,202, 49, 80, 70,163, 87, 75,142,229,145,227,167, 11,115, 50, 50,127, 64,230,185,184,127,219,255, 26, -180,226, 81,114,185, 28, 98,177, 24,113,113,113,218, 65,131, 6,241, 73,146, 68,114,114,114,141,208,178,179,177,234,208,221,223, -203,115,197,134,189,231,197,124, 62, 63,184, 79,231,246,241, 73, 25,217, 12, 67,164,215,107,109, 53, 24, 46, 62,137,125, 20,100, - 43,107,195, 74,185,122, 23,214, 61, 7, 66,171, 37,161,214,209,208, 26, 1, 35,139, 11, 71,223, 0, 88,182,110, 15, 6,192,131, -187,183, 12, 90,131,225,124,115, 95,211,140,102,252, 79, 91,181,152,134, 68, 82,213,255,165, 0,210, 87,175, 94, 93, 92,203,218, - 84, 4,224, 17, 0,159,170,253,138, 94, 59,174,136, 32,136, 7, 12,195,248,215,226, 41,170, 37,184,106,255,175,123,109,159, 71, - 77, 16, 89,181, 95, 95, 21, 90,245, 77,169, 4, 0, 27, 27, 27, 59, 63,191,206,173,127,217,113, 24, 12,195,224, 89,204, 58,148, - 21, 38, 98,241,170, 59,173,157,156,156,122,231,228,228, 92, 51,165, 4, 20, 69, 29,218,185,115,231, 23, 1,239,248,249,185, 58, - 59,227, 81,122, 26,184, 12, 5, 46, 69,129,212,107,193,166,116,112,246,162, 64, 18, 18,228,230, 86, 96,205,254,195,113, 85, 89, -226, 27,132,231,192,161, 88,150, 93, 1,130, 32,240,125,160, 23,120,102, 18,112,197, 18,124,114, 50,170, 70, 92, 69, 46, 11, 7, - 79, 34, 65,235, 0,147, 18,194,171,174, 92,185,242,240,201,147, 39,254, 94, 94, 94,248,226,139, 47,144,158,158, 14,154,166, 81, - 80, 80,160,201,203,203,203, 41, 42, 42, 74, 7,112, 28,192, 47, 48, 33,243, 56, 87,171,217, 24,121,108,207,172,192, 30,189,109, -134,141,248, 9,191, 31,157,135,242, 10, 57, 84, 70, 33,148, 26, 35,148, 90, 22,172,172,189, 17,208,169, 19,114,115, 10,241,244, -238,121, 5, 91,171, 90,215,148, 27,148, 32, 8,196,196,196,192, 93,102,134,231, 55,174,193, 70,196,129,143,204, 1,178,238, 61, -106,242, 75, 53, 4, 14, 11,198, 15, 62,248,160, 38, 51,252,128, 1, 3,210, 38, 78,156,232, 56,111,222, 60,236,216,177, 3,183, -110,221,250, 67,128,118,239,222,189,113,253,250,245,165, 0,190,109,204,168,167,211,233,224,233,233,137, 7, 15, 30,224,210,165, - 75,232,219,183, 47,122,247,238,141,199,143, 31,227,194,133, 11,136,137,137, 1, 65, 16,176,182,182,134,225,165,120, 54,212, 71, -166,215,227,200,119,107,119, 46,216,176,225,167,142, 19, 38, 76,192,177, 99, 7, 49,117, 74, 59, 16, 36, 31, 4,193,199,208, 33, -237,176,108,249, 3, 4, 4,244,129,141, 13, 7, 27,214,159, 72, 85,171,169,189, 38,156,198, 21, 23, 46, 92,144,105, 52, 26,148, -151,151, 51, 18,137,132, 40, 41,121, 57,163,181, 46,139,150, 74,165, 18,212, 71,244, 36, 58, 97, 93,121, 37, 83,198, 40, 98, 70, -148, 26, 99,188,251, 6,103,225,221,193, 83,112, 49,114, 23,162,206, 95,130, 21, 59, 61, 13,226,202,179,197,105,197,242, 60,165, -199,214,246,239, 76, 99,101, 43,207,111,157, 61,244, 57,203,209,145, 62, 18,254,179,188,188, 33,161, 5,128, 40,141,223,119,242, - 56,131,161,221, 2, 3,218,120,181,112,228,149, 21, 23, 50, 71, 79,156,141,211,167, 29, 59, 85, 75, 96, 49,141, 8,245,101, 97, - 97, 97,223, 84,253,191,123,209,162, 69,211,214,172, 89, 99,155,159,159, 95, 19,163, 85, 88, 92, 26,213,109,208,108,170,164,188, - 66,183,115,195,252,209, 66, 1,159,183,104,205,206,171, 6, 22,238,214,199,107,164,233, 45, 99,230, 46,158,147,244, 44,198,169, -149,144,135, 19,243,191,197,163, 11, 87, 96, 32,185,152,121,233, 30,180,122, 10,229,197, 37,184,252,225,167,144,216, 75,241,211, -213, 99, 5, 52, 77,255,220,220,213, 52,163, 25,255,187,168, 79,139, 16, 4, 81, 87,142,189,130, 58, 62,123,208,208,113,245,240, -252, 25,168, 55, 43,188, 73, 83,240,138,139,139, 11,175, 95,191,135,171,145, 43,112, 45,114, 5,158,198, 60, 66,110,142, 14, 57, - 5, 26,152,155,155,223,105,224,208,215, 51,199, 50, 42,149,106,228,162,197,223,228, 11,132, 34,244,234,215, 15, 14,182,118, 16, -113, 57, 96, 25,105,176, 8, 14, 20, 69,150,120,254, 88,133,175,119,238, 43, 84,168, 84, 35,235,232, 36,250,215, 39, 50, 8,130, - 0,223,220, 12, 60,137, 25,248,102,230,175,184, 17, 5,230,230, 16,152,153,131,205,227,213, 21, 12,255, 7, 78,133, 66, 49,106, -244,232,209,101, 21, 21, 21,152, 54,109, 26,174, 93,187, 22,115,254,252,121,243,199,143, 31, 11,139,138,138,218, 0, 24, 0, 96, - 91, 3, 34,235, 21,206,178,178,148, 74,198,168, 29,187,250,155,207,213, 26,163, 53, 66, 38, 29,130,152,204,130,145,162,193, 0, -144, 89,241,208,189,255,114, 20,234,186,225,208,214,149, 42, 90,175,153,240, 90, 14,173, 87, 56, 25,134, 97,236,237,237,255,112, - 14, 46, 93,186,132,144,209,163, 16, 60, 98, 56,108, 93,221, 97,215,127, 32,130,167,205,196,214,173, 91, 65,146, 36,108,108,108, - 94,239,120,107, 56,247,196,130,115,224, 9,136, 3, 79, 64,236,142, 1, 27, 64,232,190,125,251,190,243,241,241,185,114,235,214, -173,117, 0,198,214,254,173, 90, 88,242,154, 53,171,174,107,180,112,206,156, 57,234,164,164, 36,136,197, 98, 24,141, 70,220,186, -117, 11, 63,253,244, 19,190,255,254,123,196,196,196,192,218,218, 26,173, 91,183,134, 86,171,197,131, 7, 15,212, 0, 22, 54,192, - 73, 23, 21, 25, 71,109,218,180,166,100,240,224,158,216,185,243, 71, 56, 56,116, 3,135,237, 0, 54,199, 22, 98,137, 39,126,253, -229, 59,188,255,190, 31, 78,158, 56, 92, 90, 92, 98, 28, 5,192,104,194,189,164,185,119,239, 30,182,110,221,138,209,163, 71,231, -132,132,132, 80, 21, 21, 21, 53, 22, 45,134, 97,192, 48, 12,150, 84,197,152,105,181, 90,126,125,156,211,191,142,203,153,191,242, -233,178,130,252,156,174,215,174,220,249, 32,234,252, 37,164, 38, 69, 33,234,252, 37,220,136,186, 29, 86,144,159,211,213,175, 75, - 91,238,200,105,179,190,218, 19,113,140, 37, 49,119,196,158,136, 99,172,241,179, 63, 95,217, 57,184,239,194,198,238,249,170,235, -200, 40, 10, 11,194, 87,173,219,172, 48,234, 53,228,191,126,216,146,171, 46,202, 91, 88,235,190,100, 26,187, 63,213,106,245, 54, -141, 70, 35,211,104, 52, 50,173, 86,187, 48, 61, 61,189,215, 23, 95,124, 81, 68, 81, 84,141,181,180, 40,254,228,157,196,155,187, - 87,217,217, 72,133,221,252, 59,182, 91,191,237,232,213,204,172,130,223,106,229,208,170,171,156, 26,133, 90, 51,106,248,200,137, -202,242, 50, 45, 2, 63, 15, 3, 45,144, 64, 75, 1, 6,134, 5, 35,193,198,147, 21,235, 33,180, 50,195,254,180,104, 85,133, 65, - 63, 10,175,230,208,106,168,238,111,131,102,206,102,206,102,206,127, 38,231,127, 51, 28,241,234, 90,135,142,175, 88,180, 26,155, - 82,233,228,228,212,107,216,208,254,232, 51,120, 17, 24,134, 65, 98,244, 90,148, 21, 61,131,147, 3, 31, 41,153,242, 64, 0,215, -154, 80,152,204,244,172,172,174,115, 22, 46,138, 8, 25,208,175,189,151,171, 43,191, 85,171,150, 16,219,217,161,184,184, 8, 55, -239,198, 27, 86, 30, 56, 18, 87, 37,178, 76,114, 76,210, 52,253, 50,200, 29, 64,191, 57, 95,131, 96,177,128,170, 52, 14,213, 29, -163,171,127, 55, 16,108, 54, 40,134,134, 86,171, 53,101,182, 92,246,139, 23, 47, 70, 77,152, 48,225,114,100,100, 36, 25, 28, 28, -236,123,252,248,241,183, 89, 51, 15,202,194,164, 43, 0, 6,175, 12,159,113,168,107,223,225,230, 30, 29, 59,115, 59,183, 98, 65, -111, 32,144,155,147,129,200,136,251,250,248,123,231,229,140, 81, 51, 86, 85,156,116,165, 33, 46,189, 94,159,217,166, 77, 27,251, -173, 91,183,214, 4,195, 83, 20,133,226,226, 98,220,185,115, 7,222,254, 1,104, 63,229, 67, 20, 21, 21, 97,211,166, 77,104,209, -162, 5,134, 12, 25,130,210,210, 82, 24,141, 70, 83, 29,190, 20,128,243, 85, 27, 94, 19, 89, 68,213, 18, 64, 13,186, 13,221,221, -221,121, 26,141,198,151, 97, 24, 22, 65, 16, 27,117, 58,221,228,240,240,112,199, 85,171, 86,161, 93,187,118, 40, 46, 46,134, 88, - 44,134,135,135, 7,138,138,138,112,255,254,125, 74,165, 82,109,197,203,133,172,139, 26, 41, 95,242,253,251,105, 93, 63,251,236, -147,136,239,214,204,240,208,104,251,240,172,172,122,128, 97,140, 40, 42, 74, 71,165,252,150,126,249,178, 93, 47, 10, 10, 13, 35, - 1, 36,153, 88,231,111,103,205,154, 5, 0, 2, 0,139, 82, 82, 82, 98,219,183,111,239, 81,159, 69,203, 20,108, 56,154,163, 1, -112, 96, 84,176,108,174,188,248,177,135, 21, 59, 61,173,171, 23,189,105,195,209, 28,141,185, 76,185,162, 56,253,218,243, 60,229, -249,173,123, 34,142,177, 38,141, 24, 69, 57, 75,146,194, 4,118,204, 81, 19,168, 25, 31, 31, 31, 23,130, 40,117, 43, 44,121,246, -112,234,180, 25, 99, 44,184,234, 51, 62,206, 37,173,201, 22,126,130,152,152,152, 52, 52,113,102,104, 21,158,231,228,228,244, 10, - 15, 15, 63,207, 48,204, 43,177, 9,133,197,165, 81,129,131,103, 49,229,229, 21,177, 69, 9, 39, 77,201,165,118,255,126,116, 76, - 63, 47,111,191, 99,223,173, 90, 99,223,103,206, 23,236,231, 87,174, 2,148, 1, 25,215,174,130,226,235,232,245,183, 47, 22, 84, -232,245, 35,208,156, 21,190, 25,205,248,159,183,102, 53,164, 69,254,225, 24,132,122,130,225, 77,174,140,187,155,211,249,118, 30, -173, 6,180,112,182, 5, 0,164,164,229, 34, 37, 45,231, 66, 74,106, 78,112, 35,138,183,190,233,149, 53,139, 74, 19, 85, 41, 28, - 24,211, 22,149,126,133,211,218,218,250, 33,155,205,118,110,202,217,160, 40, 42,183,184,184,216,207,196,114,142,119,117,117, 93, -147,145,145, 17, 65,211,244,220, 38,170,253, 58, 57,171, 23,149, 38,217,188,254,140, 81,231, 13, 0, 4,155,103,202,162,210,181, - 57,189, 37, 18,201, 54, 14,135,211,162,250, 58, 86,199, 96, 81, 20,197,210,235,245, 2,138,162, 88, 0, 8,146, 36,141, 28, 14, - 71, 67, 16,132,209,104, 52,102,106,181,218, 25,248,119,194,209,134,234,222,104, 71, 95, 37,180, 80,135, 69,235, 18, 0, 36, 37, - 37,181,149, 74,165, 99, 9,130, 24,205, 48,140,103,101,101,165,118,241,226,197, 49, 71,142, 28,145,187,186,186,190, 55,104,208, - 32,226,241,227,199,136,139,139, 99, 74, 74, 74,142, 86, 89,177, 82,154,120, 47,145,124, 62,107,156,149, 21, 57,136, 97,224, 3, - 6, 4, 65,226, 73, 69, 5,125, 70,165,162,126,171, 18,140, 77,189, 63,171,241, 65,171, 86,173,118,165,165,165,113,234,179,164, -214, 87,247,215,177,118, 97,199, 69,129, 61,123,142,186,115,227,198,241,249, 43,159, 46,171,253,221,236,225,210,169,227, 63,157, -179,246,192,150, 31,230,111,254,189,108,167, 41,229,244,245,245,117, 39, 8, 98, 44, 0, 47,134, 97,218, 48, 12, 33, 32, 8,166, -140, 32,136,167, 0, 30,235,116,186,200,248,248,248,236,183,168,251,155,140,112,235,227,172, 89, 84, 26, 20,213,137, 2, 24, 19, - 23,149,254,187,203,217,204,217,204,217,204,249,159,227,252,111,198, 71,117,124,102, 90,102,248,106,164,164,230, 4,167,164,230, -160, 77,155, 54, 76,114,114,114,147, 68, 90,125,157, 52, 69, 81, 7, 85, 42,213,193,183, 33, 41, 41, 41,233,252, 23,159,188, 3, -105,105,105, 7,254, 76,194, 42, 33,181,172,106,123, 83, 60, 81, 40, 20, 1,166,238,172,215,235,255,138,115, 67, 84, 89,179,150, -214,183,195,128, 1, 3, 50,244,122,253, 37, 0, 89, 4, 65, 88, 2, 40,213,235,245,231,141, 70, 99, 65,114,114,114,231,245,235, -215, 87,103,190, 95, 14,224,225, 27,150,131,214,106,169,253,185,185,212,254,191,160,142,204, 60, 4, 45, 0, 0, 32, 0, 73, 68, - 65, 84,251,117, 58,221, 60,107,107,235,214, 26,141,134,167,209,104,184,181, 39, 31, 8,133,194,162,134, 2,226,107,195,210,140, -216,205,101,151, 89, 91,154, 17,175, 11, 41, 88, 57,225,152, 90, 25,215,206,202, 9,199, 76, 45, 88,108,108,108,138,143,143,207, - 62,146, 36, 93, 25,134,177, 7, 24, 11,134, 65, 17,195, 48,197,108, 54, 59, 39, 62, 62, 62,231, 31,212, 8,105,140, 52,189,206, -168,211,253, 59,238,176,121,118, 97, 51,154,209,140,255, 63,168, 55, 70,139,221, 84,166,228,228,100,162,249,124, 54,163,182,216, -106,232,203,140,140, 12, 45,128,219, 85,219,235,120, 8, 96,200, 63,189,130,121,121,121,126,245,125,103,170,200, 2, 94,198,108, - 1,113,117,102,103, 95,178,185,172, 18,155, 35,190,106,106,217, 30, 61,122,148, 9, 19, 93,236,205,104, 70, 51,154,209,140,191, - 12,111,111,209,106, 70, 51,154,209,140,102, 52,163, 25,205,104, 70,157,216, 94, 75,112,189, 98,221, 34, 80,255,204,129,166,248, - 94,223,100,246,193,165,102,206,102,206,102,206,102,206,102,206,102,206,102,206,255, 57,206,255,175,248,131,200,250, 59,208, 60, -245,181,153,179,153,179,153,179,153,179,153,179,153,179,153,243,127, 65,100,189,190, 1,104,118, 29, 54,163, 25,205,248, 31,198, -145, 35, 71, 76, 90, 84,116,220,252, 95, 7, 75, 36,210,197, 10,121,197,154,131,235,166, 30,175,254, 60, 36, 36,132,106, 62,139, -205,104, 70, 51,240, 38,193,240,110,110,206, 29, 72,138,238,206, 48, 36,139, 33, 25, 3, 33, 87, 31, 74, 41, 43,123, 37,237,128, -139,139,139, 37,135,196, 16,130, 97,196, 4, 65, 83, 52,139,188,149,154,154, 29,223,132,130,241,164, 82,233, 44, 46,151,219, 95, -167,211, 57,147, 36,153,173,213,106, 47,169, 84,170, 31,241,199,196,133,255, 49,180,109,219,118,252,213,171, 87, 45,123,244,232, -161, 21, 10,133, 70,181, 90,205, 62,119,238, 28,255,253,247,223, 47,127,241,226,197, 27,205, 72,148,201,100,125,127,253,245, 87, -183,224,224, 96,180,105,211, 70, 57,118,236, 88,110, 96, 96, 32,119,218,180,105,169,185,185,185, 81, 77,164,235, 64, 16,196, 94, -130, 32, 88, 52, 77,135,226,223,169, 27,254,108,144, 36, 73,206, 32, 8, 98, 4,195, 48,238, 4, 65,164, 48, 12,115,156,166,233, -134, 18,183, 54,132, 81, 0, 6,146, 36,233, 7, 0, 52, 77,199, 0, 56, 3,152, 62,243,238,239,228, 20,137, 68,190, 0,160, 82, -169, 98,255, 44, 78,130, 32,124, 1,128, 97,152, 55,229,156, 34, 20, 10,167, 3,128, 90,173,254, 5, 38, 44, 7,245, 58,152,173, -158,140,223,210, 68, 0, 64,204,183,158, 0,128,166,188, 39,102, 38, 18, 77,249,173,186,248,154,194, 81, 7, 6, 78,152, 48, 97, -213,111,191,253,246, 45,128, 19,127,197,141,239,224,224,242,227,247, 63,108,151,125, 62,235,195, 53,120,185, 34, 68,195, 15, 36, -240, 46,143,197, 26,170,163,168, 27,241,192, 17, 0,108, 43, 43,171,241, 60, 30,175,151, 78,167,115,100,179,217,121, 58,157,238, -122, 69, 69,197, 1, 52,176, 2,130,201,231, 53, 1, 82,189, 10, 14, 4,253,239,117,222, 24, 18, 90,174, 8,249, 68,123,148,253, - 3,154, 81, 18,192,156,170,186,238, 64,253,233, 60, 26,106,124, 62,151,201,100, 35,228,114,185,138,197, 98, 49,120, 57,235,249, -229,159,151,223, 19, 52, 77, 23,150,150,150,134, 54,198, 37,110,129,118, 60, 49,177,151, 50, 64,109,212, 50, 31, 43,179,144, 40, -113, 65, 55, 6, 8,101, 0, 87,146, 69,218,210, 52,157, 7, 32,138, 52,226,148, 34, 23,201,255,208,206,189,101,213,121,109, 85, -245,158, 3,192, 30,192, 99, 0,159, 3, 80, 52,235,159,191, 13,175, 7,195,159, 6,144, 87, 35,180,106,165,187,239, 51,120,240, -224,107,110,110,206, 29, 70, 15, 31,185,106,230,140,143, 9, 22,139, 68,220,211,167,236, 15, 66,167, 12,144, 74,165, 78, 18,173, -182, 61, 8,130, 86, 9, 4,113,114,121, 69,206,145, 3,191,153,121,182,107, 71, 81, 20,141,173,219,126,126,255,232,239, 17, 11, - 76, 20, 91,109, 29, 28, 28,246,134,133,133, 57, 12, 29, 58,148,229,224,224,128,244,244,116,203,131, 7, 15,182,219,188,121,243, -152,178,178,178, 80, 0,207,223,160,178, 61, 29,172,200, 1,102, 66,162, 31, 42, 41, 84, 26,112, 57, 95,141, 11, 0,110,188,233, -217, 83,169, 84,179, 85, 42, 85,128,191,191, 63,179, 99,199, 14, 98,242,228,201, 12, 65, 16,132, 90,173,222, 13,224,141,132,150, - 88, 44,222, 18, 28, 28,236,225,225,225,145,242,226,197,139,129,135, 15, 31, 62, 51,105,210, 36,119,177, 88,156, 4,160,109, 19, -233,118,149,148,148,248,168,213,106, 56, 59, 59,239, 0,240,206, 95,112, 19, 17, 44, 22,235,184,147,147, 19,179,118,237,218, 19, - 62, 62, 62,246,165,165,165,198,175,190,250,170,255,221,187,119,223,167, 40,106,104, 19,196,150,148, 32,136,109,246,246,246, 54, -107,214,172, 73,238,220,185,243, 99, 62,159,207, 75, 74, 74, 18,205,155, 55,111,238,243,231,207,199, 48, 12, 51, 3,104, 82, 7, - 33, 37, 8, 98,155, 76, 38,179, 89,181,106, 85,186,159,159, 95, 28,151,203,229, 38, 37, 37,137,191,254,250,235,207, 19, 19, 19, -223,136,147, 36,201,173, 1, 1, 1,210,111,191,253, 54,161, 93,187,118,183, 89, 44, 22, 47, 59, 59,155, 92,178,100,201,172,139, - 23, 47,134,208, 52, 61,243, 77,202,105,103,103, 39, 93,178,100, 73, 66, 96, 96,224, 93, 46,151,203,125,246,236, 25, 25, 22, 22, - 54, 43, 57, 57,217,228,114, 90, 89, 89, 5, 17, 4,177, 61, 63, 63,159, 13, 0,142,142,142, 93,204,205,205, 55,215, 94,211,178, - 58, 21,133,193, 96,168,212,104, 52, 19, 74, 75, 75,235, 76,132, 59, 57,124,211, 16, 0,216,172,175,126,255,242,181,177,247,192, -214, 83,166, 84,218,215,225,101, 94,188,239,149, 83,135, 3,192,248,170,165,194,191, 87, 2,108, 54,155,246,117,248,156,137,205, -111, 82,202,152, 97,125,251,246, 93, 18, 21, 21,245,115,159, 62,125,190,222,183,111,159, 93, 86, 86,214,119, 55,110,220,112, 25, - 55,110,220,228,203,151, 47,175, 46, 46, 46, 62,250,103,221,252, 60, 46,159, 79,144, 4,132, 2,145,185, 41,251,115, 72,114,240, -237, 97,195,166,255,242,236,153,223,230,196, 68, 55,165,163, 99,192,103,159,125,102, 63,114,228, 72,210,197,197, 5,201,201,201, -214,251,246,237,107,255,203, 47,191,140, 40, 47, 47,159, 3, 32,227,109, 68,150,178, 28,222, 90, 29,252, 24, 6,150, 53, 15, 44, -129,114,190, 30, 49, 76, 2,158,252, 3,196,214, 55,187,118,237,250, 54, 57, 57, 25,171, 87,175, 6,128, 31,155,120,252,188, 97, -195,134, 13,138,136,136, 16, 30, 57,114, 68,232,239,239, 15, 7, 7, 7, 84, 13,166,106, 18, 83,187,185,185,153,118,206,104,124, -191,241,204,212,119,226, 74,207, 98,203,200,252,213, 66,103, 24,187, 13,243, 24, 49,120,178, 31, 44,108, 69, 16, 72,216, 40, 47, -145,123, 61,139,201, 10,190,114, 56,249,187,228,232,162, 53,202, 76,124,131,250,115,242,253, 71, 96,109,109,189, 35, 53, 53, 53, - 72, 44, 22,191,242,121, 74, 74,138,175,135,135, 71, 5,128, 47,154, 42,220,108,109,109,247,211, 52,173, 45, 41, 41,249, 16, 0, -204,204,204,126, 19,139,197,210,188,188,188, 5,127,213, 64,166, 26,175,107,145,255,114,139, 86, 77,188, 86, 93,107, 29, 18, 36, - 69,119,159, 57,227, 99, 98,236,248,113,249,201, 41,169, 52,155,195, 27,127,238,252,121, 81,135, 14, 29, 72,237,143, 63,194, 88, - 84, 4,195,220,185,221, 46, 93,186,100, 8, 25, 63, 81,205, 97, 17,187,220,221, 92, 69,135, 14, 28,116,136, 56,118,180, 59,128, -198,132, 22,207,193,193, 97,239,213,171, 87,157,220,220,220, 80, 94, 94,142,244,244,116, 40,149, 74,140, 25, 51,134,211,189,123, -119,167,209,163, 71,239,173,168,168,232,209, 4,203,150,125, 27,103,118,228,140, 41, 35,219,190, 63,160,187,216,201,165, 53,152, -124, 13,178, 94, 36,250, 71, 94,189,251,217,174, 99,103,158, 39, 87, 48,131, 81,247,218, 72, 13,162,184,184,120,254,136, 17, 35, -142, 5, 5, 5,217,242,249,124,200,100, 50, 98,232,208,161,133,185,185,185, 75,223, 88,181, 84, 45, 97, 67,146, 36, 85,251,181, -142,229,129, 76,129,179, 84, 42,133, 84, 42, 5, 0,167,183, 29,121, 90, 90, 90,254,104,102,102, 54, 90, 46,151,171, 73,146,100, - 8,130, 96,116, 58,157, 80, 42,149, 62, 74, 72,124, 46,211,106,181,109,214,109,252,229,135,190, 61,125,204, 47, 94,188,136,145, - 35, 71, 50, 23, 46, 92,152, 97,234, 58,117, 4, 65,108, 27, 49, 98,132,106,241,226,197,154,228,148,116,167,132,231, 41,132, 88, -192,163,109,108,108, 56,247,239,223,103,111,216,176, 65,176,100,201,146,109, 12,195,140,110,194,249,220, 54,110,220, 56,253,151, - 95,126,153,247, 44, 57,213,238, 73, 66, 50, 35, 17,112,140, 54, 54,214,172,187,119,239,210,111,194, 73,146,228,214,249,243,231, -203,103,204,152, 81, 86, 82, 90,225, 80, 38, 87, 48,124, 14,203,224,224,224,192, 62,113,226,132,118,255,254,253,228,244,233,211, -183,210, 52, 29,210,132,243,187,117,232,208,161,149, 97, 97, 97,229, 73, 41,105, 14, 79,226,159, 67,196,231, 24,236,237,237, 88, - 15, 30, 60,208,175, 91,183,142, 92,177, 98,133, 73,229, 20,139,197,123, 14, 31, 62,204, 62,113,226,101,219,119,231,206, 29,210, -221,221, 93, 84,123, 31,181, 70, 11,146, 0,138,139,139, 69,129,129,129,123, 0,252, 33,185,175,223,210, 68, 76, 14, 7,102,207, -158,157,215,212,155,197,207,241,179, 70,247,161,126,246,100, 54,168,166, 14,103,179,217,244,244,233,211,243, 95,255, 94,163,209, - 16, 0,134,226, 59,211,197,214,192,129, 3, 23,158, 62,125,186,245,190,125,251,214,239,223,191, 95, 7, 0, 2,129,192,230,224, -193,131,171,199,140, 25,131, 49, 99,198, 44, 62,122,244,232,159, 38,180, 40,134,210, 3, 0, 95,192,231, 39, 38, 38, 18,158,158, -158, 13,102,220,215,211,244,195, 95,158, 61,235,252,137,167,167,127, 41, 77,183,225,190,255,190, 98,222,188,121,197,114,185, 28, -233,233,233,208,235,245,152, 60,121, 50,171, 79,159, 62,178, 49, 99,198,108,170,172,172, 28, 5, 64,111,194, 61,185,206,201,201, -233,163,138,138, 10, 69,181, 85,167, 71, 40,197,238,229,107,228,119,106, 99,224,113, 89, 70,238,144,185, 52,113,225, 71, 66,233, -233,134,155, 0,192, 85,161,168,137,131,129, 58, 97,238, 12, 55,138,131, 21,182,206,194,190, 69, 25,234,101,202,204, 6,197,210, - 40,177, 88, 60, 92,169, 84, 30,173,234,156,219, 14, 30, 60, 24,119,239,222, 5,128,238, 85, 66,171, 47, 73,146, 31,208, 52,253, - 43,128,134,150,114,251,108,216,176, 97,239, 70, 68, 68,152, 1,192,209,163, 71, 97, 48, 24,224,238,238, 14, 46,151, 11, 30,143, - 7, 14,135, 83,179, 58,136,137,112,180,181,181,129,141, 5, 7, 82, 43,241,251, 95,255, 52,140,221,162,131, 57, 10,169,167, 40, -101,202, 97,100,180,224, 90,139,209, 46,216, 18,126, 3,250,146,167,182,198, 45, 56,181, 37,161,179,138,196, 16,100, 64,251, 79, -233,217, 73,146,228, 63,126,252, 24, 50,153,236,149,207, 89, 44, 22, 0,244,122, 3,202,197, 41, 41, 41,129,209,209,209, 8, 10, - 10, 90,236,237,237,253,222,181,107,215, 28, 74, 74, 74, 16, 20, 20,180, 41, 59, 59,251,196, 95, 93,167,218, 90,228,255,139,169, -139,124, 77, 73,246,121, 57, 10, 38, 89, 44, 22,137,212,148,116, 67, 80, 80,191, 73,153,153,153,146,128,128, 0,146,195,225, 64, - 25, 21, 5,205,131, 7,144, 72, 36, 24, 49, 98, 4,231,250,245,235,230,230, 18,243,105,105,169,105,149, 44, 22, 9,134, 33, 27, -141,121,144, 74,165,179, 22, 44, 88,224,224,225,225, 1,163,209, 88,147,209,220,104, 52, 34, 43, 43, 11, 18,137, 4,161,161,161, -118, 34,145,104,150,137,245,104,213,214,221, 46,230,234,153,109,239,204,155, 57, 80,220, 86,116, 17,226,172, 57,144, 28,253, 4, -237,115,207, 33,108,120,128,248,194,150,197,126,173,101, 86, 49,181, 76,172, 38, 67,171,213,222,140,139,139,155,118,237,218, 53, - 26, 0,174, 92,185,194, 36, 36, 36,204,120,155, 81, 40, 77,211, 40, 47, 47, 7, 77,211,172,170,247,213,175,255,209,251,193,220, -220,124,235,123,239,189, 55, 46, 35, 35, 67,120,246,236, 89,235,204,204, 76,155,180,180, 52,219,182,109,219,178, 87,175, 94,125, - 90,163,213,179, 12, 20,163, 51, 82,134,202,188,167, 79, 83,202, 10, 10, 98,118,238,220,169, 38, 8, 98,132,137,191, 49,202,209, -209,209, 58, 60, 60, 28, 4, 71,212,165, 93,123,111, 15, 22, 71,104, 65,114,120, 22,106,181,134, 74, 77, 77,205, 10, 15, 15,119, -245,241,241,145,225,165,123,205, 36, 78,153, 76,102,243,229,151, 95,130,205, 55,243,237,228,227,215,154,199, 23,155,177, 56, 66, -179,128,128,128, 62, 41, 41, 41,185, 97, 97, 97,142,254,254,254, 77,226,244,247,247,151, 78,159, 62,221, 40, 16,154, 5,186,185, -185,183,239,212,177,253,160,182,109,219, 14,103,179,217,198,162,162,162,140,208,208, 80,199, 33, 67,134,216, 55,133,211,206,206, - 78, 26, 22, 22,102,116,105,233, 30, 28,252,238,128,174, 92,161,153, 5,155, 39,182, 84,169, 52,212,179,103,207, 50, 22, 45, 90, -228,232,235,235,107,103, 10,167, 74,165,226,216,216,216,192,203,203, 11, 29,220,221, 81, 81, 81,129,136,136, 8,236,218,181, 11, -191,254,250, 43, 14, 28, 56,128,206, 61, 6,192,204,204, 12,185,185,185,144,203,229,156,191,251,134,162,126,246,100, 54,235, 62, - 26,250,241,199, 31,231, 78,159, 62, 61, 95, 40, 20,210,175,111, 86, 86, 86,212,132, 9, 19, 10, 66,191,222, 56,180,218,181,216, -136, 37,235,241,153, 51,103, 94,236,219,183, 15, 29, 58,116, 64,112,112, 48, 15, 0,102,205,154,197, 27, 51,102, 12, 14, 31, 62, -140,163, 71,143,198,123,120,120,220, 2, 48,204,148,114,134,134,134,246, 8, 9, 9,185, 17, 18, 18, 18, 59,118,236,216,237, 51, -102,204,120,165,231,202,203,205,126,168,211,233,224,227,231, 47, 90,190,227,222,132,198,248, 18,128,125,219, 19, 19,119,173,121, -250, 52, 99,113,135, 14,150, 45,211,210,172,118,175, 91,103, 83,189, 72,183,193, 96, 64, 86, 86, 22,164, 82, 41, 38, 76,152, 96, -195,231,243, 67, 77, 40,230,134, 97,195,134, 77,201,204,204,148,252,242,203, 47,142,177,177,177,178,188,188, 60,199,203,151,206, -219,126,245,197, 44, 51, 11, 9,143,151, 91,196, 16, 0,144,150, 11,113, 98, 42,122, 48, 12, 44,107,187, 19,223, 8,142, 16, 10, -157,177,185,117, 15,203,231, 95, 30,246, 29, 27, 22,233,103, 35,117,228,135, 55,112, 68,167,181,107,215, 30, 57,117,234,212,248, - 30, 61,122, 28, 3, 32,172, 99, 31, 65,231,206,157, 35, 14, 31, 62, 60,165,103,207,158, 55, 1,120,213, 59,138,116,118, 30,241, -251,239,191, 91, 87,191,183,177,177,129, 64, 32,248,131,200,226,114,185, 32, 73,178,201,213, 91,121,112, 60,219,170,189, 22,113, -101,103,112,120,237, 99,172,125,255, 25,189,170, 91,154,246,199,208, 68, 92, 56,252, 24,133,120,140,129,159,180,198,248, 69, 62, -253, 69, 20, 86,252,147, 58,240,162,162,162, 15,122,245,234,117,100,224,192,129,218,232,232,104, 20, 21, 21,193,201,169,102,172, -157,255, 6,148, 86, 34,145, 8, 46, 46, 46,240,240,240, 24,127,253,250,117, 7,131,193,128,180,180, 52, 20, 22, 22,198,252, 29, -117,170,173, 69,254,203,240,122, 32,252,233, 63, 8,173,170,181,133,174, 2, 0, 67, 16,202,199,113,113, 28, 22,143, 55,241,183, -253,251,249, 92, 46, 23, 25, 25, 25,136,143,143,135,234,242,101,168,111,223, 70, 65, 65, 1, 20, 10, 5,236,237,237,177,109,199, - 14,177,142, 98,166, 62,123,254,156,197,144, 76,237,120,131, 58,167,120,242,249,252,254, 35, 71,142,172, 87,144,229,230,230, 98, -224,192,129, 28, 22,139, 85,215,172,134,215, 57, 9,153, 45,113,234,242,177,229,142,142,188,120, 32,121, 30, 80, 25, 3, 48, 90, -192,168, 3,114,158, 0,167,151,162,165, 34,145, 56,191,124,146,131,147,136,125,170, 14,165,220,216, 84, 84,119, 79, 79,207, 95, - 39, 78,156, 72, 2, 64,223,190,125, 9, 79, 79,207,237, 0,220, 27, 56,230, 82, 35,157,228,221,178,178, 50,140, 25, 51,198,186, -117,235,214,151,198,140, 25, 99, 93,253,249,155,114, 86, 91,147, 59,116,232, 80, 34, 16, 8, 14, 0, 38, 53,176, 53,156,150,150, -150, 63, 14, 28, 56,112,244,254,253,251,185, 0,112,245,234, 85,156, 58,117, 10, 79,159, 62, 69, 82, 82, 18,237,231,231,103,187, -241,215, 35, 91,127,252,121,207,134,225,221,125,100,125,186,248,181,151, 40,202, 20,246,246,246,221, 25,134,113, 55,177,156, 3, -151, 46, 93, 26,159,240, 34,195,130,100,115,216, 92, 14,155,111,110, 46,182,151,154,137,157,173, 68, 2, 39, 62, 73, 72, 84, 42, - 85,254,129, 3, 7,104, 0, 3, 77,229, 92,190,124,121,106, 66,114,134, 37, 65,178,217, 28, 54,135, 43,145,136, 44,223, 15, 14, -242, 7, 0, 46, 24,174, 92, 46, 47,216,181,107,151,190, 41,156,223,126,251,109, 92,105,185, 66,202,230,112, 56,108, 54,171,230, - 92,138,133, 66, 91, 17,159,207,211,106,181, 57, 63,252,240,131,186, 41,156, 75,151, 46,141,127,246, 34,211,138, 36, 8, 22, 65, -144,108,115, 51,177,181,181,133,200,214, 86, 34,180, 17,177, 89, 60,185, 92,158,179,119,239, 94,147, 56,245,122, 61,183,160,160, - 0, 9, 9, 9,112,241,247,199,197,139, 23,209,162, 69, 11,140, 25, 51, 6,227,198,141,131, 80, 40, 68,223, 64,111,132,135,135, -227,197,139, 23,208,235,245,252,186, 56,171,227,164, 94,135, 76, 38,139,110,236,230,121,237,216, 87,202,233,235, 0,102,179,238, -163,161,181, 5, 86,125,252, 86, 86, 86, 84, 93,214,174,215, 57, 7, 14, 28,184,240,242,229,203,173,247,238,221, 59, 52, 52, 52, -244,230,222,189,123,209,181,107, 87, 36, 36, 36,192,213,213, 21,187,119,239,198,184,113,227,110,110,218,180,105,104,116,116,180, -143,155,155,219,130,198, 56,199,142, 29,251,169,175,175,111, 84,126,126,126, 96,105,105,169, 87, 68, 68,196,212, 17, 35, 70,164, -142, 31, 63,190, 95,141, 96, 52, 24,246,159, 62,121, 12,131,134,142, 68,187,142, 94, 91, 39, 47,216,231,221,200,179,201, 60, 5, -182,239,202,203, 43,218,175,209,168,198,112, 56, 34,209,189,123, 86, 71,127,254,217,166,246,202, 2, 57, 57, 57, 24, 50,100, 8, -135,203,229,246,108,164,156,107,135, 15, 31, 62, 38, 34, 34, 66, 90,109,213,185,125,251, 54,158, 60,121,130,244,244,116,148,151, -151,163,223, 12, 5, 62, 94,253,146,251,227,213, 12, 6,204, 98,196,111,216,134,212, 64,216, 2, 14,214,230,236, 91, 83,127,104, - 55,235,163,173, 29,216, 18, 43, 14,126,251, 58, 9,197,105,218,163,245,112, 18,129,129,129,251, 66, 66, 66, 8,157, 78, 7,157, - 78,167, 3, 80,103, 86, 95, 39, 39, 39, 65,167, 78,157, 48, 99,198, 12,210,220,220,124, 83,125,229, 84, 42,149,218, 51,103,206, - 32, 52, 52, 20,115,230,204, 65,155, 54,109, 32,149, 74,193,225,112,176,103,223, 33,155,113, 83,103,182,125,167, 71, 47,159, 14, -239,116,237, 84,169,101,249,115,132,210,233,245, 88, 67,234,172,187,194, 46, 26,113,105,119,176,121,104, 54,125,127,183, 74,241, -213, 7,255, 74,124,118,173,224,233,130,144,237,113,204,157,110,197,251, 62,207, 68,129, 33, 1, 61,199,180,132,155,175,116,174, -216, 5,158,111,122, 62, 77, 68,147, 56,189,189,189,123,220,191,127,159,223,171, 87, 47,100,100,100,128,195,169, 25, 79, 81,111, - 83,206,165, 75,151,242, 53, 26, 13, 30, 61,122,132, 73,147, 38,229,232,245,250,185,111, 83,206,166, 88,180,170,181,200,127, 25, -182,191,182,229,213,103,209, 90, 10, 0, 6, 26,167, 38, 78,154,170,138,140,140, 20,241,120, 60,100,100,100, 32, 47, 47, 15,123, -118,237,162,250,218,217, 85, 6, 59, 57,201,247,236,218,197,232,116, 58, 48, 12, 3, 79, 79, 79,140, 30, 61, 90, 56,106,204,248, - 66, 66,174, 62,100,130,155,199,177,218,191, 62,117,234,212, 63,124,255,213, 87, 95,193,220,220, 28, 4, 65, 56,152, 80,185,144, -207,150, 14,119,150,186, 89, 22, 48,249,123, 74,193, 18, 0,108, 51,128,109, 14, 8, 44, 0,190, 25,192, 19, 65, 27, 29, 85, 74, - 50,193,233, 35,123,126,232, 4,160, 41,174, 30,200,100,178,197, 81, 81, 81,182,209,209,209,140, 92, 46, 71, 94, 94, 30,179,106, -213, 42, 91,153, 76,182,248, 77,175, 72,110,110,238,242, 65,131, 6, 21, 76,154, 52,201,226,220,185,115, 46,147, 38, 77,178, 24, - 52,104, 80, 65,110,110,238,242,183,185,210, 92, 46,151,245,244,233, 83,171, 21, 43, 86,140, 3,240,176, 99,199,142, 37, 78, 78, - 78, 15,241, 50,104,178, 65,152,153,153,213,136,172,106,235, 26,155,205, 6,135,195,129, 76, 38,211,149,150,150, 82, 61,223,113, - 23,122, 90,144, 6, 25,159, 43,180, 18, 10,156,205,204, 45, 2, 74, 74, 74, 30, 19, 4,145, 98,162,139,207,183, 75,151, 46, 28, -138,225,208, 31, 79,236, 43,155, 53, 37,200,238,167, 21,211, 91,252,176,252, 35,167,181, 75,166,121, 46,159, 63, 33,136,164,105, -141,171,171,171, 67,117, 64,187, 9,230,115,191,206,157, 59,179,105,112,144,240, 60,189, 32, 35, 59,167,242,221, 62,129, 53,150, -203, 14,190,126,193,182,182,182,189, 60, 61, 61, 59, 19, 4, 97,210,148,100,161, 80,232,219,174, 93, 59, 54,201,226, 16,214, 82, - 51, 23, 51,137,208,190,198,133, 98,105,217,205,202,214, 54,132,100,152, 10, 71, 71, 71, 59,161, 80,232,219,132,186,179,105,112, - 97,111,103,101, 97,107, 99, 41, 9, 14,234,222, 38,176, 91, 96, 91,239,128,174,129, 29,223,233, 60,138, 48, 26,229,238,238,238, -118,213, 65,242,141, 88, 90, 5,251,247,239,199,138, 21, 43,208,169,101, 75, 56, 57, 57,193,206,206, 14,183,111,223,198,253,251, -247, 33,149, 74, 81, 88, 88,136,117,235,214,225,248,241,227,208,235,245,102, 77,189,159, 76, 17, 91, 13,193,104, 52,146,175, 11, -172,250,248,133, 66, 33, 93, 29, 36, 95, 31,206,156, 57,179,175,218,146,245,249,231,159,247,216,184,113,227,205,196,196, 68, 72, - 36, 18,220,191,127, 31, 83,167, 78,189,185,105,211,166, 30, 51,103,206,196,174, 93,187,144,154,154,186,163, 33,190,177, 99,199, - 46,153, 54,109,218, 15,215,174, 93, 35,237,237,237, 33,149, 74, 49,124,248,112,236,216,177,131,109, 52, 26,119,134,132,132,196, -134,132,132,196, 82, 89, 23, 22, 30,249,117,213,237,184,199,177,248,244,179, 47,121, 58,163, 33,204,132,234, 51,106,137,164,210, -216,171, 87,233, 97,131, 65, 53,150,203, 21, 89,196,198, 90,157,218,185,179, 70,108,133,135,135,195,194,194, 2,120, 25,192,140, - 6,172, 58, 31, 29, 63,126,188,166, 61,180,182,182, 6,143,199, 3,151,203, 5,135,195, 1,139,197,194,165,173, 98,252, 28,254, - 82, 95,252, 28, 78,224,194,143,132,242,109,174,157,200, 9, 94, 82,123, 94,236, 39,187, 59,250,120,245,179,198,237,131,249, 88, - 53, 40, 58,251,254,225,162,121,154, 66,124, 95,207, 97,239,124,245,213, 87, 29, 10, 11, 11,241,224,193, 3, 60,120,240,160, 62, - 11,144,230,228,201,147,223, 41, 20, 10,184,185,185, 97,216,176, 97,189, 0,248,215,243,220,160,115,231,206, 24, 50,100, 8,130, -130,130,208,169, 83, 39,232,244, 70, 78,200,196,143,218, 61, 77, 45,114, 90,181,110,149, 40,234, 74, 4,121,243,230, 53,214,190, - 99, 23, 44, 2,131, 6,252,192, 53,115,188, 11,161,181,163, 41,245, 84, 81, 37,240,117,124, 31,219, 47,127, 70,110,190, 58, 73, -178,231,212,102,119, 51, 51, 51, 34,230, 65,172, 97,207,150,195,153, 94,226, 97,133,119, 15,150, 64, 69,228,163,223, 20, 55,146, - 6, 70,255, 83,122,118,129, 64,176,241,218,181,107, 14,122,189, 30,113,113,113,152, 51,103,142,230, 45, 41,107, 12, 32, 46, 46, - 46,184,122,245, 42, 38, 76,152,160, 41, 40, 40,184,243,119,213,169,182, 22,249,255, 2,118, 45, 5, 89,131,172,172,172,114,169, - 84,234,212,174, 93, 59, 82,167,211,189,116, 73, 28, 61, 74,253,186,115,231,105,141, 70,243, 25, 0,238,143, 63,253,180,213,201, -217, 57,104, 98,104, 40, 97, 48, 24, 48,104,208, 32, 94,100,100,164,117, 74, 97, 97,165, 9, 29,206, 43,191, 55,121,242,100,108, -220,184, 17, 0, 48,123,246,236, 26,211, 58, 97, 66,192,146,196, 2, 3,131, 7,119, 54,207, 18,111, 54,215,119, 51, 40, 90,189, - 48,187, 43, 86, 8, 59,131,228,177, 33, 96,129,214, 27,140, 73,133, 35, 30,190, 72,106,223, 65, 88, 90,226,218,191, 99,111,252, -122,113,239, 64, 21,165, 57,108,114,131, 35, 18,117,145, 72, 36,120,248,240, 97,105,231,206,157,203, 25,134,177, 88,190,124,185, -141, 72, 36,234,242, 22,231, 62,237,249,243,231,189,186,119,239, 62,139, 36,201,254, 52, 77, 95, 42, 40, 40,248, 17, 64,154,137, -199,127, 12,224, 91, 0, 53, 35, 75,157, 78, 7,146, 36,193, 48, 12,198,142, 29,139,240,240,240, 14, 79,158, 60, 65, 84, 84,148, - 85,255,254,253,239, 2, 40, 7,240, 33,128, 58,173,102,114,185, 92,125,255,254,125, 97, 84, 84, 20,104,154,134,149,149, 21,204, -205,205,193,231,243, 49,124,248,112, 73, 88, 88, 88,191,243,231,207, 23,202, 91,181, 96, 9,242,114,148,124,137,196, 12, 14, 78, - 61,103,142,255, 32,145, 97,152,227, 77,104, 28,120, 66,182, 81, 67, 80, 90,114,237, 55,155, 72, 17,151, 75, 8,184,108,240,105, - 21, 22,126,183,146,224, 50, 20, 27, 77,244,207,115,185, 92,174, 25, 31, 58, 22,143,101, 16, 17, 96,254,140,135,131,197, 98,241, - 4,220,250,227, 49, 56, 36, 73,146, 36,201, 5, 96,242,162,125,124, 62,159,107,198,103,234,229, 20,178, 8, 22, 65, 16, 60,212, - 51, 19,205,215, 1, 76,181, 21,137,247, 89,138,182,182, 40,238,217,179, 39, 78, 71, 61,196,209, 83,151, 80,156,241, 24,139,190, -254, 28,254,254,254,136,140,140,108,176, 76,213, 49, 90,245, 89,151,101, 50, 89,116,110,110,238, 59,245, 29,219,144,203,176, 30, - 43,213, 31,249,191,177,128,223,210, 68, 52, 18,163, 53,172,103,207,158,159,238,223,191, 95,247,222,123,239,241,198,142, 29, 11, - 47, 47,175, 30, 83,166, 76, 1, 0,244,239,223, 31, 27, 55,110,236, 49,101,202, 20, 28, 58,116, 8, 17, 17, 17,218, 62,125,250, -124,125,245,234,213, 28,188,156,209,249, 7,208, 52, 61,100,219,182,109,175, 91, 10, 97, 52, 26, 97, 48, 24, 28,141, 70,163, 99, - 85, 91,132, 31,126,216, 84,124,225,124, 36,190, 94,176, 20,118,182, 14,190, 38,222, 67,196,228, 47,191, 44,222,189,110, 29,214, - 29, 58,132, 47, 93, 93, 69,123,227,227,113, 65,163,193,225,168,168,226,170,223,105, 52, 54, 83,169, 84,170,207,156, 57, 99,126, -248,240, 97, 88, 90, 90,162, 77,155, 54,176,178,178, 2,135,195, 1,201, 18,130,197,149,162, 93,199, 46, 0,238, 3, 0, 92,101, - 80,122,186,225, 38, 65,160,156, 33,155, 30, 83,196,111,129, 86, 54,206,130,107,159,238,242,178, 52,183,227,226,220,143,153, 56, -191, 57,235,184,166, 24,235, 97,196, 51,212, 31,243,213,217,205,205, 13,133,133,133, 56,115,230,140, 18,168, 87,144,129,166,233, -239,126,250,233,167,175, 22, 44, 88,192,247,244,244, 4, 0, 95, 0, 15,234,218, 87, 44, 22,195,201,201,169, 70, 88,142,157, 52, -211,125,198,188,153,194, 17, 3,130,192,102,219,160, 92,105, 64, 73,165, 1, 82, 27, 9,190,158, 23, 34,184,212,217,201,127,219, -166,223, 78,170,213,240, 7,254,216, 30, 16, 4, 30,220,123,124,211, 91,224, 9, 16, 36,144, 69, 94, 1, 1, 2, 10,194, 0,130, -197, 98, 40,138, 66,102,102, 38, 24,134,193,132, 17, 83,179, 62, 90, 21, 97,215, 99,130, 28, 46,237,100, 32, 24,244,254,167, 8, - 1,107,107,107,223,146,146, 18,164,165,165, 97,210,164, 73, 57,197,197,197, 23,149, 74,229,212,220,220, 92, 0, 40,125, 3,202, - 26, 49,239,235,235,139, 46, 93,186, 96,204,152, 49, 2,149, 74, 21,226,238,238,238, 84, 84, 84,212,237,175,172,207,235, 90,228, -255,149,208,170,243, 65, 51, 24,218,105,183,110,133,242,210, 37,240, 46, 92,192, 97,153, 76,161,209,104,190, 0,144, 85,245,224, -127,190,107,247,238, 91, 67,239,220, 49,215, 37, 38,194,253,201, 19,112, 44, 45,125,155, 90,128,157, 59,119, 66, 46,151,163,162, -162, 2, 0,176,121,243,102,200,229,114, 24, 77, 92,112,150,205, 69, 15, 7, 59, 87,228, 35, 9, 52,155,148,164,183, 83,117,149, -104,204,114,157, 50,237,149, 21,164, 19, 18, 51, 2,196,234, 18, 93, 87,130,165,131,166, 88, 5,167,238,109,192, 6,187, 71, 83, -202, 88,237,247,103,179,217,165,207,159, 63, 31,210,182,109,219, 83, 0,108,222, 36, 30,224, 53, 36, 23, 20, 20,124,246, 38, 7, -178, 88,172,111, 83, 83, 83,237,118,236,216, 49,107,249,242,229, 76,109,161, 85,253, 63,155,205, 6,195, 48,176,176,176, 0,135, -195,177,191,125,251,182,125, 64, 64,192, 22,154,166,125,235,169, 39,227,229,229,133,212,212, 84,176,217,108, 88, 88, 88,128, 54, -234,177,116,222, 76, 80, 44, 62,123,254,252,249,190, 35, 71,142,140,219,177, 99,135,193, 60,176,123,183,146,146,146,167,159, 78, -152, 24,119,226,196, 9, 93, 85,138,135,198,135,248, 12, 19,155,148,148,196,114,150,217,179, 24,163,138, 22,115, 1,193,227, 31, - 24,158,196, 1, 2, 54,139,225, 18, 36,248, 2,161, 69, 90,118,118, 9, 77,211, 9,166,112,210, 52, 29,147,154,154, 42,180,183, -179,102,171,212, 58,133,144,195,240,210, 99, 30,166,180,242,235,236, 14, 0,154,152,251, 87,249,237,218, 11,211, 11,138,196,174, -174,174, 38,113,170,213,234,216,156,156, 28,150,189,189, 61, 59, 35, 43,251,164,165, 68,108,107,110,105,217, 21, 0,244,149, 21, -247, 73,173,182,136,197, 97,219, 23,149,148,148,170,213,234, 84, 83,235,254,226,197, 11,182,163,163, 29,235,220,133,203,167,236, - 69,124, 59, 51, 30,219,156, 79, 16,132,136, 69,200,185, 70,186, 88, 32, 18,217,165,101,103,151, 50, 12, 83,175,133,112, 77,249, -196, 17, 47,175,215,210, 67,181,184,241,248,241, 99,156,189,153, 0, 49,163, 3,161,169,192,133, 93,191, 96,194,252, 5,111, 29, -247,215,152,216,122, 35,107,214,182,246,209,175,241, 35,175,145, 64,248, 9, 19, 38, 44,221,183,111, 95, 77, 0, 74, 66, 66, 2, -250,246,237, 91,237,230, 64,112,112, 48, 2, 2, 2,144,144,144, 0, 15, 15, 15, 68, 69, 69,241, 89, 44, 22,127,226,196,137,171, -126,251,237,183, 51,141,218,253,183,111,199,212,169, 83,235, 10,172,126, 1, 64, 67, 72, 61, 21,225,107,246,216,148,150, 20,163, -176, 40, 63,214,212,243, 64, 16, 4, 38,127,249,101,241, 54,157, 14,251,239,221, 67,168, 88, 44,218,157,156,140, 65, 1, 1,240, -238,219,183,216,148,182,174,218,170,163,209,104,192,225,112, 96,110,110, 14,107,107,107,112,185, 92,176, 56, 50,176,121, 62, 32, -185, 92,248,245,244,193,186, 47,196,170, 73,239, 99, 19, 65,160,156,207, 67, 12, 87, 84,111,172, 14, 33,110,129,225, 12, 3,185, - 42, 11, 87,170, 5,137, 69, 75, 88,112,204, 56, 23,166,109,241,180, 52,183,227,226,236,166, 12, 92,216,146,125, 76,147,143, 69, - 85,231,130,110, 96, 32,225,109,105,105,137,172,172, 44,100,102,102,198,163,225, 0,127, 85, 66, 66, 66, 10,159,207,239, 96,107, -107, 11, 0,110,245, 13,204,105,154,174,137,195,218,187,255,136,141,111, 47,119,193,187, 61, 58, 96,207,169,149,248, 36,100, 19, - 56, 44, 2, 20,165,199,250,141,131, 65,105, 21, 8, 25,250, 17,209,187,191,135,207,165, 83,186,105, 6,117,217, 47,127, 24, 8, -176,177,226, 95,227,110, 91,242, 37,164, 55,104,194,210,198,198, 78,204,229,114, 97,109,238,168, 91, 48, 99,110, 30,195, 48, 53, -207, 13,135,197, 53,144,149, 86,234,146,124,133,208,146,163, 6, 24,178,213,155,101,179,249,243,145,157,157,253, 89,175, 94,189, - 86, 85, 86, 86,150, 41,149,202, 9, 0,224,230,230,214,146, 36, 73, 62,128,134,188, 35, 45, 81,119, 90, 8,238,147, 39, 79, 96, -102,102,134,156,156,156,218,198, 23,208, 52,253,143,153, 4,240, 15,133, 31,128, 24, 0,142, 0, 6,161, 86,122, 7,178,202, 84, -215, 59, 50, 50,146,137,140,140,236, 93,211,121, 49, 12,109, 44, 45, 5,163,125,121,110, 57, 28, 14, 3,160,246,140, 38,145,165, -165, 37,193,113,118, 6,193,127, 25,250,193,252,137, 83, 95, 13, 6,211, 82,203,208, 20, 88, 32,244, 96,106, 13, 90,148, 2, 2, - 43,109,250,225, 51,222, 98,228,243, 44,107,247,116,128,145, 1, 5,154,213,196,226, 48, 74,165, 18, 70,163, 81,218,186,117,235, -211, 70,163, 81, 90,213,185, 49,255,169, 43, 74, 81, 84, 10,139,197,194,172, 89,179, 80,109,253,209,233,116,200,207,207,135, 86, -171,133, 78,167, 67,106,106, 42, 42, 42, 42,160,211,233,240,244,233, 83,184,185,185,129,197, 98, 57, 54,208,152, 51, 12,195,192, -197,197, 5,173, 90,181, 2,139, 96,240,235,218, 37, 88, 56,103, 38,198,185,209,216,249,227,122,244,233,211,167,189,171,171,107, - 32,155,205,166, 28, 28, 28,184, 17, 17, 17, 39, 41,138, 26, 14,211, 91,158, 51,225,225,225,173, 58,118,236,104,103,105,110,102, -224,243, 88,224, 25,148, 12, 95, 91,194,176, 85,197,112,113,105,105,132, 80,228, 17, 26, 26, 74,213,103,133,168,139,243,139, 47, -190,112,244,244,244,180,144, 90,154, 41,121, 28, 86, 33, 23, 76,113,197,227, 7,119, 1,128,103,107,167,129, 64,212, 97,210,164, - 73,198,166,112, 46, 94,188,216,205,214,214,214,146, 4, 83, 73,233,245,255,246,183,107,117, 37, 4,135,163, 6,151,215,121,246, -236,217, 68, 83, 56,191,250,234, 43,215, 14, 29, 58, 88, 90,154,139, 21,108, 14, 43,143, 75,211,121, 2,208,249, 28,157,190, 76, - 96,107,163,130, 72,226, 23, 26, 26, 90, 47,103,181, 53, 43, 44, 44, 44,235, 53,225,141,210,210, 82,104,242,227,192,205, 73,132, -143,132, 3,127, 91, 41,248,124,126,205,212,247,250,110,215,250, 98,180,234, 18, 91,166, 30,219,121, 89, 3, 46,192,109,237,163, - 95,207,155,149,155,155, 11, 71, 71,199, 6,159,167,223,126,251,109, 65, 80, 80, 80, 97,112,112,176,238,244,233,211, 32, 8, 2, - 81, 81, 81,200,201,201, 65,112,112, 48, 24,134,169,158,213,134,216,216, 88,244,239,223, 95,215,171, 87,175,156,170,252, 90,141, - 98,234,212,169, 48, 24, 12, 80, 40, 20, 40, 45, 45, 69,100,100, 36,124,124,124, 24,145, 72, 52,146,229, 50, 96,101,200,180, 5, -221,188, 58,249, 98,203,166,117, 58, 30,155,179,166, 41,207, 43, 65, 16,152,244,197, 23,197, 21,126,126,165,123,149, 74,213,100, -115,115, 81,235,172, 44,171,135,231,207,219,232,245,122,147, 56,170,173, 58,206,206,206, 53, 34,139,203,229,130,205,179, 5, 75, -236, 13,158,117, 48, 68, 14, 35,113, 37,134,175,181, 16,227,184,153, 4,231,196,150,245,167,118, 16,185, 96,101,183,177,142, 17, -221,199, 57, 94, 22,181,192,142,170,254,128,100,216, 68,196,148,245,109, 91,219,182, 18,226,206,145,124, 92,216,146,253,187, 38, - 31, 75, 0, 36, 55,246,156,235,245,122, 13, 69, 81, 32, 73, 18,108, 54,187,118, 76,224,173,223,127,255, 29, 15, 31, 62, 4,106, -165,237,169,172,172,164, 88, 44, 22, 4, 2, 1, 0, 72, 26,104,239,192,225,112,192,225,112,112,245,238,117,235,113,163, 6, 19, -183, 31, 93, 68,119,159,241, 40, 81,232, 81, 80,161, 71,185, 10,232,232,191, 8, 94,253,143,227,113,106, 37,124, 59,121,177, 88, - 60,241,164,186,248, 52,105,200, 82,102, 98,116, 73, 60,221, 70,151, 45, 60,123,231, 68, 66,252,245,163,143,159, 30,252,233, 84, -114, 55,255, 94,202, 42, 99, 2, 20, 10, 5, 67, 16, 4, 51,119,250,130,148,189, 83,203,168, 77, 19, 30,211,108,173,224,197,223, -216,212,183,180,181,181,189,109,109,109, 29, 85, 37,142, 90,154,153,153,221,114,116,116, 76,196,203,137, 30, 39,242,242,242, 60, -149, 74,101,119,188,156,156,149, 81, 82, 82,210,183,202,242,148,209,128, 37,108,135, 92, 46,255,156,162,168,161, 85,219,251, 20, - 69,249, 38, 37, 37,117,240,245,245,141,119,119,119,143,117,119,119, 63,235,238,238,126,210,221,221,253,100, 80, 80,208,198,234, -116, 15,127,177,219,240, 15, 90,228,191, 76,104,161, 74,100,109,175,122, 69,141,208, 2,112,245,245, 0, 52, 35,159,255,212,248, -233,167,176, 60,121, 18,156,164, 36, 76,153, 52,201, 92, 36, 18,109,194,203, 28, 77,221, 37, 18,201,150, 37, 75,150,152,217,172, - 94, 13,217,245,235, 72,143,140,132,129,195,121,240, 38,165, 83,171,213, 96,179,217, 53,150, 24,177, 88, 12,138,162, 80,151,201, -247, 15, 15,160, 17,119,114, 10, 18,193, 67, 43,208, 96, 20,231,228,189,238,141, 79, 89,100, 23, 41,119,243, 72, 86,114, 61,150, -217,118,206, 99,233, 94, 0, 0, 32, 0, 73, 68, 65, 84,181,219,212,178,199, 61, 37,193, 86,240, 44, 5,200,204,204, 2, 5,186, - 73,254,102,141, 70, 83,161, 84, 42,225,235,235,107,253,240,225,195,214, 62, 62, 62, 86, 85,159,223,127,203, 11, 19, 40,147,201, -142, 56, 57, 57,165,201,100,178, 35, 0, 2,155,112,236,142, 27, 55,110,128,197, 98, 97,201,146, 37,168,172,172,132, 94,175, 71, - 73, 73, 9, 50, 51, 51,161,211,233,144,157,157,141,103,207,158, 65,167,211, 33, 61, 61, 29, 90,109,227, 3, 18,154,166, 97,110, -110, 14,141, 90,129,159, 87, 46,196,226,176,121,168,120, 17,141,236,220, 2, 88, 90,136,241,217,103,159,177,164, 82, 41, 77,211, -116, 43,138,162,250,211, 52,189,213,148,235, 84,235,126,187,233,226,226,226,181,118,237,218, 14, 11, 87,110,229,154,179, 21, 12, -223, 76, 64,243,204,248, 12,175,125, 87, 76, 93,180,137,251,195,134,239,159,223,185,115, 39, 7,166, 37,239, 36, 1,220,244,243, -243,107,155,147,147,227,227,233,233,217,206,166,165, 43,159,239,232, 84,206,117,108, 33,103,180,154,123,132, 83,139,158, 91,183, -110,141,187,117,235, 86,110, 83, 56,197, 98,113,251, 61,123,246,120,217,219,219,123,113,132, 66,129,170,162,226,176, 81,165, 60, -194,178,148, 10, 72,115,203,247,143, 31, 63, 30,125,236,216,177,252,166,112,122,120,120,120,174, 92,185,178,163,183,183,119, 71, - 7,183,214,124,161,147, 75,137,192,185,101,137,208,219,135, 15,231, 86,239,109,217,178, 37,246,206,157, 59, 38,113,178, 88, 44, - 35, 73,146,224,112, 56, 16,137, 68, 56,119,238, 28, 62,157, 54, 30, 46, 78,214,104,231,233,137,126,159,124,142, 99,199,142,213, -196,240,176, 88,172,122,123,244,221,171, 63, 59,229,231, 72, 68, 99, 91,251,104,108,107, 31,237,231, 72, 68,215, 43,182,170,190, -175,107, 31,147, 90,163,122,220,141, 38,136,173, 51, 87,175, 94,253,110,242,228,201,188,129, 3, 7,226,222,189,123,152, 58,117, -234,205,136,136, 8, 0,192,189,123,247, 48,119,238,220,155,151, 47, 95,198,204,153, 51,209,183,111, 95,222,141, 27, 55,182,192, -132,220, 63, 70,163, 17, 59,119,238,132,209,104,132, 68, 34,129,149,149, 21, 6, 15, 30,140,184,184,184,153,187,118,237, 74,100, -113, 56, 31, 12, 26, 58, 10,167, 79, 70,224,217,211,184,153,187, 87, 77,108,114, 82, 96,146, 36, 49,112,210,164,226,226,142, 29, - 75,119,203,229,170, 15,165, 82,145,103,126,190,213,149, 35, 71,108, 76, 16,106, 4, 69, 81, 53,226,170, 90,116, 84,111,108,158, - 45,216, 98, 47,176,205,252,241, 56,153,107,224, 6, 32,134,231,143,132,134,242,103,113,120,228,212,145, 11,221, 48,114,161, 27, -134,205,119,157, 34,106,129, 95,197, 45,240,241,192, 57,173,130,220,253, 45, 32, 47,212, 35,114,125,122,134,166, 4,171, 1, 60, - 51,229, 57,167,105, 58, 62, 39, 39, 7, 60, 30, 15, 45, 90,180,104, 11,160, 58, 46,112,199,244,233,211,103, 47, 91,182,108, 30, -128,101, 85,159, 73,130,130,130, 58, 42, 20, 10, 36, 37, 37, 1,192,195, 6,172,193, 53,179, 12, 75,229,233,124, 87,153, 55,124, -218,207,128, 84,218, 9, 57,165, 58,228,150,234,240,235,207,195, 17,125, 99, 5, 30, 94, 8, 69, 70,126, 62,132, 14, 35, 64, 25, -181, 94, 38, 12,234,101,143, 30, 61, 34,110,220,184, 65,208, 52, 13,131,193,192, 84,202,229, 76,204,205,155, 80, 95,187, 70,152, -155,155, 19, 61,186,244, 82,236, 94,113,250,254,241, 31,111, 62,212,171,154, 60, 80,127, 27, 44, 78, 73, 73, 9, 60,114,228, 72, - 16,128,197,222,222,222,119, 50, 51, 51,187, 93,191,126,189,157,179,179,243,166, 55, 37,173, 78, 11,145,158,158,254,202, 86,149, - 22, 66, 87, 37, 26, 6, 86,137,185, 97, 0,230,226, 45,102,217, 55, 1, 87,255,139,131,225, 79,227,181,217,134,175, 11,173,218, -137,194,224, 46,149,154, 25, 12,250,236,139, 23, 47,234, 73,146,132, 72, 36,194,228,169, 83,201,159,127,250,169,231,248,192,192, -168,143,222,125,247,108,212,229,203,126, 1, 1, 1, 96, 24, 6, 36, 73,226,208,161, 67,106,141, 70, 93,226,226,226, 98,105, 74, -163, 81,251, 1,146,203,229, 53, 66,171,162,162, 2,246,246,246, 38,187, 14,149,114, 92,186,124, 46,186,140,161, 62,201, 28,152, -188, 65,191, 38,127,120, 64, 57, 77,177, 43, 40, 3, 42,212, 12, 42, 53, 96,223, 35,173, 2, 38,123,140,208,167,246, 15,120,118, - 45,241,118,137,134,210, 52,105,182, 68, 97, 97,225,194,144,144,144, 18, 71, 71, 71,194,220,220, 28, 78, 78, 78,228,176, 97,195, -138,179,178,178,150,189,233, 21,177,182,182, 30, 23, 20, 20,116, 42, 39, 39,103,244,181,107,215, 90, 93,191,126,125,116, 80, 80, -208, 41,107,107,235,113, 38, 82, 28, 94,176, 96,129,146,199,227,161,107,215,174,168,172,172, 68,213, 44,159, 6, 55, 83, 92,164, - 92, 46, 23,219,214,126,139,197, 97,243, 80,154,120, 15,143,111, 94,196,213,124, 2,139, 86,126, 15, 46,151,251, 70,185,190,218, -216,138,188,189,101,102, 9,115,167,142,205, 13, 15, 11, 51,139,141,141,229,204,158, 51,151, 73,207, 43, 5,111,224, 58, 22,122, - 47, 36, 31, 41,109, 49,232,253,126, 88,178,248, 75,239,170,164,157, 13,162,189,173,200,219, 75,102, 22,255,229, 71,227, 83,230, -204,153, 35, 92,179,102,141, 38, 48, 48, 80, 93, 80, 80, 32, 20, 75,173, 60,217, 22,150, 94,233,121,249,146,192,192,192,212, 79, - 62,249,164,188,169,156,139, 22, 45, 18,157, 63,127,158, 29, 18, 18, 98, 44, 43, 43,147,112,132, 66, 95,130, 47,232, 82, 84, 86, -102, 49, 58, 36, 36,121,244,232,209,170,170,132,165, 38,115,126,243,205, 55,162,103,207,158,177, 3, 3, 3, 13,249,249,249,102, - 98,107, 27, 31,150,165,149,127, 90, 94,129,121,151,128,128, 23,179,103,207, 86, 54, 84,206,218, 34,197,204,204, 44,167,123,247, -238, 88,191,126, 61,126,248,225, 7,188,247,222,123,136,123, 26,135, 65,179,231,161,195,199,115,113,242,246, 93,228,228,228, 96, -249,242,229,240,241,241, 1,151,203,125, 86,231,243, 56, 51,145,136,205, 7, 17,155, 15,130,152,153, 72, 84,191,175,215,178,181, -172, 2,181,247,175,107,191,135,223,212,109,233,242,115, 36,162, 27,138,195,106, 76,108,141, 30, 61,250,211,234, 20, 14, 31,126, -248,225,205, 77,155, 54,245,248,240,195,151, 3,237,174, 93,187, 98,197,138, 21, 61, 22, 45, 90,116,115,229,202,149,232,215,175, - 31,220,221,221, 27,157,248, 66, 81, 20,140, 70, 35,198,143, 31, 15,163,209,136,162,162, 34, 60,127,254, 28,219,183,111, 7,195, - 48, 2, 0,112,148, 57,119,230,241,120,120, 20,243, 64,181,248,195,128,223,154, 96,201, 34,106, 15, 98, 20, 10, 5, 70,127,252, -113,113,118,155, 54,165, 91,139,139, 85,211,164, 82,145,107, 70,134,149,153, 78,231,132, 6,226, 18, 9,130, 0, 77,211, 53,194, -170, 90,112,189,190, 85,117,148, 38, 65,175,162,207, 92,223,151, 11, 0,232, 53, 81,134, 97,243, 93,167, 56,122,136, 54,247,156, -240,210,232,125,108, 69, 10, 83,153, 75,173,129, 1,241, 77,176, 88,223,187,119,239, 30, 44, 45, 45, 17, 18, 18,194, 39, 73,114, -117,245,120, 21, 47,115,103,109,168,230,226,243,249,235, 66, 67, 67,201,242,242,114, 60,126,252, 24, 0, 46,215,215, 46, 49, 12, - 83, 83,119, 69, 41, 1,138,230,225, 86,204, 57, 92,184,126, 20,105, 57, 69,200, 40,212, 0,108, 11,104,148,217,208,171,115,160, - 43,143,129, 92, 43, 50,169,192, 92, 46,183,200,219,219,155,241,247,247,103, 24,134,193,139, 23, 47,140,233, 25, 25,198, 7, 27, - 55, 50, 79,102,204, 32,204,158, 63,231, 10,133, 66,194,205,205, 13, 2,129,128, 22, 8, 4, 37,127, 99,231,253,151,164, 91,248, - 11,210, 66,252,153, 86, 45, 6,255,157,200,195,171,179, 13,107, 18,152,214,149,176, 20,140,185,112,236,209, 45, 63, 91,132,140, -159,168,244,241,241,145, 58, 57, 57,129, 32, 8, 12, 31, 49,130, 8,186,118,205,140, 35,147,193,250,157,119,106,220, 17,151, 46, - 94,196,185,115,231,148,167,127, 63,238, 52,117,218,180, 33, 0,246, 52, 80, 24, 54,159,207,175,249,221,188,188, 60,240,249,252, -154,152, 8,185, 92, 14, 91, 91, 91,228,229,229,193, 68,207,220,222,240,176,187, 97,133, 1, 11,221, 2,204, 56,196, 89,101, 62, - 40,134, 1,135,160, 0, 53, 3, 3, 5,104, 13, 12, 58,187,178,172, 46,168,141,210,200,123, 17,169, 0,246, 54,229,236,105,181, -218, 43,177,177,177, 51,104,154, 62, 10,128,188,118,237, 26, 29, 31, 31,255, 41, 76, 15, 92,255,163,217, 94, 36,154, 31, 21, 21, -101, 53,127,254,252,178,200,200,200,138,193,131, 7, 91,108,223,190,221,170,111,223,190,243, 75, 74, 74, 14,154, 98, 8,204,204, -204,220,147,149,149,245,169,191,191, 63, 74, 75, 75,161,215,235, 17, 29, 29, 13, 15, 15, 15, 60,124,248, 16,109,219,182,197,131, - 7, 15,208,174, 93, 59, 80, 20, 5,141, 70, 3,154,166,169,198, 26,243,210,226, 34,160, 36, 19,185,247,206,226,249,147,104, 68, -229, 18,248,241,224, 41,180,104,229,246, 70,121,106,218,218,137, 58, 58,218, 90, 95, 88,179,244, 27,187,244, 43,135, 16,177,243, - 71,250,234,217,179, 29,120,102,152,209,123,252,231,163,116, 6,180, 4,192,235, 22,224,143,129,210,103,148,168, 21,242,163,226, - 27, 78,176,216,214, 78,212,209,222,198,250,252,191, 86, 47, 51,123,113,110, 55, 14,111, 91,207, 28,219,119,192, 71, 3, 4,116, -236,216,113, 32, 73,146,150, 0, 52, 85,113, 94, 38, 45,109, 83, 23,231,165, 83,167,252, 52, 64,192,137, 19, 39, 6,138, 68, 34, - 7, 0, 6,149, 74,149,242, 54,156,151, 35, 35,253,170,203, 73, 16,132, 29, 0, 61,195, 48, 47,208,196, 37,120,198,140, 25,179, - 98,238,220,185, 97, 20, 69,217,214, 26,157,179,214,173, 91,199,166,105,154,197, 48,140,158, 36, 73,253,249,243,231, 41,163,209, -152,171,209,104, 62,126,155, 86,100,212,168, 81,184,123,247,238, 82,188,156,132, 97,170,181,250,149, 56,173,170, 37,123,222,152, -255,218,181,107,203, 63,248,224,131,240,131, 7, 15, 62,223,180,105,211,208,153, 51,103,226,208,161, 67,104,211,166, 13, 30, 61, -122,132,133, 11, 23, 2, 64,143, 69,139, 22,157,220,177, 99,135,123,122,122,250, 58, 19, 44, 26, 48, 26,141, 56,112,224, 0,134, - 15, 31, 14, 91, 91, 91,200,100, 50, 16, 4,113,101,218,180,105, 63, 1, 0,139, 96,113, 1, 64,171,209,106, 61, 61,253, 77,182, -224,114,185,220,154,182, 46, 63, 63,191,102,166,224,128, 15, 62, 40,254,117,205, 26,252,166, 86, 99,154, 84, 42,202,118,118,118, - 60,249,226,197, 71, 79, 95, 54,206, 76, 67, 86,157,198, 68,150,169, 33, 13,234, 60, 44,248,125, 85,154, 3,128,247,122, 77,148, -161,215, 68, 25,252,135,217, 17, 36,139,192,147, 11, 37,136,187, 84,122,204, 32,199, 21, 52,109,185,156,248,213,171, 87,159,236, -221,187,247,208,246,237,219, 99,250,244,233,159,236,220,185,147,107, 48, 24,230,224,223,105, 30, 44, 72,146, 92,182,109,219,182, -143,172,172,172,112,227,198, 13, 92,191,126,253, 10,128,204,250,218, 37, 0, 53, 57,179, 90,184,180,213, 60, 75, 87,136, 10,115, -110,225,230,141,223,209,198,231,115, 8, 29,134,192,202,115, 37,244,137, 63, 64, 87,114, 1, 86, 46,131,145,157,254, 2, 44, 54, - 63,174,177, 32, 20,134, 97,158,102,103,103,187,187,187,187, 19,105,105,105, 70, 0, 12, 69, 81,140,190,103, 79, 67,135, 53,107, - 56,113,159,124, 66,116,123,246,140,197, 16, 4, 29, 29, 29, 13, 0, 9,255,137, 94,188, 58,221, 66, 92, 92, 92,125,233, 22,154, - 4,111,111,239, 30,215,175, 95,231,107, 52, 26, 92,189,122, 21, 93,186,212,204,237,250,143,102,191,175,173, 69,254,203,240, 81, - 29,159,109,127,197,162,245,202,141, 77, 19,156,118,109,219, 82, 92, 18,187,134, 15, 25,162,138,141,141,173, 25,245,105,238,223, -135,242,220, 57, 80, 20, 5,134, 97,112,253,218, 53,132, 78,156,168,224,176,136, 95, 93, 93, 91, 49, 4,243, 74,238,150,254,117, -140, 30, 66, 66, 66, 66,106, 26,159,172,172, 44,136,197, 98,240,120, 60,208, 52, 13,163,209, 8, 22,139, 5, 11, 11, 11, 24,141, -198,186, 76, 48,175,115, 26,168, 82,229,232, 29,131, 38,228,201, 20,122,102,134,165, 43, 90,114,133, 53, 15,167,131, 57,129,161, - 62, 28,216,176, 11,153,203,235,222,205,165,181, 37,163,241,199, 25, 93,141, 77,249,111,219,169, 83,167,159, 66, 67, 67, 73, 0, -232,223,191, 63,217,169, 83,167,205,104,120,169,156, 6, 57, 5, 2, 1, 31, 0, 78,157, 58, 85,250,252,249,243,247, 78,157, 58, - 85, 90,251,115, 19, 57,183,175, 93,187, 22, 34,145, 8, 70,163, 17, 58,157,174, 38, 62,171,246,171, 94,175,135,141,141, 13, 78, -159, 62, 13,138,162, 78, 55, 86, 78,151,150,173, 64,216,182,198,158, 83, 81,184, 94,204,125, 19,145, 85,195,217,218, 65,220,206, -193,198,250,226,191, 86, 45,183, 45, 75,142, 70,118,118, 54,115,254,220,233, 59, 26, 32,167,162, 18,139,203,149,104,167,214, 65, -208,197, 29,153, 23,183,125,205, 44,234, 5, 3,234,158, 53, 88,195,217,193, 65,220,206,201,214,250,252,247,255, 90,101, 86,158, - 28,141,188,252,124,156, 57,125, 42, 86, 3, 84,187, 27,167,208, 52,237, 69,211,180, 23,128, 41, 13,136,151, 38,113,170, 84, 42, -111,149, 74,229,253,103,114, 50, 12,227,205, 48,140,201,156,181, 99,162, 54,108,216,144,152,151,151, 23, 90, 88, 88, 24, 92,189, -149,149,149,245, 87, 40, 20,125, 84, 42, 85, 79,245,134, 86, 22, 42,149,202, 78,161, 80, 56,106, 52,154,206, 0,162,155,112,207, -215,160,118,214,233,188,188,188, 37,121,121,121, 68, 99,229,100,125,156, 72,236,255,254,203,223,183,109,219,230,248,150,252,175, -148,179,184,184,248,232,193,131, 7,125,221,220,220,220,167, 76,153,130,173, 91,183, 98,211,166, 77, 90, 0,216,177, 99,135,182, -150, 37,203, 37, 61, 61,221,191, 30,183, 97,255, 90,214,146,189, 3, 6, 12, 96,174, 95,191,142,225,195,135,215, 36, 18,253,229, -151, 95, 96, 52, 26,229,253,250,245,163, 1, 64,173, 81,201, 25,154,129, 78, 95,175,255,253, 15,231,147,199,227,189, 95, 59, 95, - 96,117, 50,102, 30,143, 7,134, 97,208,174, 71,143,226,114, 31,159,210,157, 21, 21,170, 37,222,222,230, 31,121,122, 78,105, 15, - 76,172,139,147, 32,136, 87,172, 58,175,111, 77,176,100,213, 46,103,161, 58, 23,211,127, 95,149,118,174,218,178, 37,144,176,161, -169, 52,226,248,154,180, 34, 77, 17,126,169, 79,252, 52, 84,247,210,210,210,217,107,214,172,209, 74,165, 82,140, 26, 53, 10, 43, - 87,174,156,214,163, 71,143, 10, 59, 59,187,187,109,218,180,121, 50,118,236,216,188,232,232,232,217, 65, 65, 65, 72, 74, 74,194, -247,223,127, 95, 94, 86, 86, 54,161, 33, 78,130, 32,106, 44,121,195, 6,245, 47,253,121,243,122,186, 95,239, 79, 33, 18,154,195, -192,113, 65,169,194,128, 50, 37, 3, 29, 63, 0, 60, 46, 31,193,129, 29,113,247,252,110, 21,165, 83,238,105,236,158, 87, 40, 20, -199, 38, 79,158, 44,231,114,185,208,233,116, 12,135,195, 1,255,101,220, 49,205,121,239, 61,125,183,248,120, 35,197, 48, 52, 65, - 16,248,226,139, 47,148,101,101,101, 7,223,228, 57,106, 2,106,115,254, 89,233, 22,250,191,214,255,252, 25,105, 33,254,138,186, -255, 55, 99,123, 29,219,191, 45, 90,213, 83, 42,171, 95, 9,130,166, 40,138,134,171,155,171, 89,122, 90,230,143, 99,198,132,124, - 56,112,224, 32,209,160, 65,131, 4, 29, 19, 95,142, 70, 79,157, 58,133,136,136, 8,213,133, 11, 23,228,124, 14,107,135, 75, 11, - 23,123,138,162, 65, 16,116,131,106,216,204,204,108,206,130, 5, 11,132, 21, 21, 21,216,180,105, 19,237,235,235, 75,138,197, 98, -232,245,122,236,216,177,195,208,177, 99, 71, 14, 73,146,168,168,168, 0, 73,146,207, 76,172,224,227,138,204,156,224,159,130, 70, - 70,248,207,154,106,221, 33,168,155,180,143,139, 19, 12,239, 48,200,205, 74,195,243,203, 23,202,158,158,223, 88, 2, 77,193, 72, - 52,190, 60, 80, 93, 29,193,183, 23, 46, 92,176,155, 61,123, 54,163,209,104,136,204,204, 76,102,213,170, 85,118,211,167, 79,255, - 54, 55, 55,119,220, 27, 94, 20,162,188,188, 28, 4, 65,208, 85, 13, 73,245,168,191, 41,126,185,184, 61,123,246,156, 24, 49, 98, -196,176,126,253,250, 33, 49, 49,177,198, 69, 88, 91,104, 85,207, 62, 92,189,122,117, 57,128,240,198, 72, 57, 28, 14, 54,237, 57, -138,242,178, 98,216,219,203, 32, 16, 10,241,166, 51, 44,121, 36,185,228,187,229,223,216, 21, 39,220, 37,226,238, 68,209, 71, 30, - 23, 20, 26, 41,166,238,140,255,149,185, 76,149,250,111,120, 52, 67,178,150,124,183,106,153, 69,181, 91,243, 96, 76,158,156,160, -152,217,111,245,136,252,183,112,254,205,144,201,100,200,203,203, 35,100, 50, 25, 83, 21,163,197, 52, 32,180, 94,189,193, 95,186, -203,136,134,220,134,111,202,159,154,154,186,234,157,119,222,249, 50, 41, 41,233, 72,135, 14, 29,102, 2,104,161,213,106,203, 23, - 45, 90,244,175, 29, 59,118,124,104,138, 37, 11, 0, 14, 29, 58,180,113,234,212,169,231,134, 12, 25,242, 53, 77,211,157,106,117, -236,169,118,118,118, 53, 46,220,162,130,252,176, 25, 31,142, 15, 83, 40,202, 76,206,115, 39,145, 72, 62, 90,180,104,145, 64,169, - 84, 98,203,150, 45,116,199,142, 29,201,234, 65,209,190,125,251,140,109,219,182,101,135,124,250,105,241,134,252,124,172,184,113, - 67, 25,230,229,229,187,243,249,243,206,160,233,189,245, 89,117,234,178,100, 85,135, 93,188, 33,114,171,196,214, 47, 0,222,235, - 54,198, 1, 39,214,166,161, 44, 93,247, 47, 24,241, 2, 38, 44, 11, 84, 7,178,143, 29, 59, 22, 92, 80, 80,112,226,155,111,190, -177,232,220,185, 51,188,188,188, 56, 18,137, 36,160, 58, 93, 76, 69, 69, 5, 46, 93,186,132,173, 91,183,234,158, 62,125, 58,162, - 33,119, 21, 69, 81,133,109,219,182,173, 62, 15, 12, 65, 16, 37,114, 45, 97,113,184,125,128,100,202,140, 35,196,205, 7,183,145, -171,167,161, 53,208,112,117,243, 67,159,247, 54,224,228,217, 39, 84,110,122,124,188, 65, 93,246,171, 9,229,125,145,156,156,124, -124,249,242,229, 99,190,254,250,107, 97,113,113, 49,165,213,106,233,163, 71,143,178,166, 76,153, 66, 49,108, 54,205,101,179, 49, -103,206, 28,117,121,121,249,239,192,223,186,192,244, 95,146,110,225, 47, 72, 11,241,167, 89,179,106,191,254,127, 65,157, 79, 40, -205, 34,111,109,221,246,243,251,135, 14, 28,116, 96,177, 72,135, 23, 41, 41, 15,134,142, 28,157,115,241,226, 69, 43,174,133, 69, - 23, 0,180,110,230,204, 59,122,173,186, 52,242,196,137,150,174,174,173,124,170, 22,149,102,104, 22,121,171,161, 31, 84, 40, 20, -202, 27, 55,110,168,194,195,195,137,172,172,172,253,246,246,246, 99,207,158, 61, 43, 25, 57,114,164, 58, 49, 49,241,152,131,131, -195,176,160,160, 32,179, 47,191,252, 82,171, 80, 40,154,178,240,104, 60, 83, 84,214,254,254, 55,235, 62,184,191,246,231,119,193, -102,117,135,150, 3,208,134, 91,208, 87, 94, 4,176, 31, 77,200,119, 84, 27, 98,177,216, 71, 36, 18, 33, 54, 54,182, 44, 32, 32, - 64,167,209,104,184, 43, 87,174,180, 22,139,197, 62,111,122,226, 25,134, 97,202,202,202, 64,211, 52, 27, 0, 81,245, 10,186,233, -115,241,199, 13, 29, 58,244,196,225,195,135, 7, 12, 26, 52, 8,238,238,238, 48, 24, 12,104,219,182, 45,116, 58, 29, 60, 60, 60, -160,213,106,177,116,233, 82, 84, 84, 84,204, 67, 3,107,158, 17, 4, 1,163,209, 88, 19,108,235,228,220,242,101,158,158,183, 72, - 99, 33,230,144,238,207, 34,119,162,176,164,152, 62,252,168,160, 64,165,167,130,147,139, 84, 79, 95,223, 79, 69, 65, 25, 52,229, -179, 28, 0,208,210, 13,175, 56, 47,230,253, 31,123,215, 29,222, 84,217,190,239,115, 78,246,108,154,182,105, 83, 90, 90, 86, 1, - 41,171,236, 13,130,130,128,162,204, 15, 65,224, 3, 11,136, 34,160,224,192, 1,101, 9,226, 7, 10, 50, 42, 40, 67, 80, 89,178, - 81,134,148,150, 77,203, 44,101,143,238,145,166, 73,218, 52,205, 58, 57,191, 63,154,132,180,116, 36,165, 40,248,203,125, 93,231, - 74,206,200,157,247,172,247,189,223,231,125,222,231, 65,131,155,251,127, 64, 78,174, 10,191, 38,101,105,244,102, 91,191,155, 21, -112,122, 84,206,231,132, 51,106,110, 10,134, 78,117,255,216, 39,129,187,130,170, 50, 92,204, 6,113, 65,248, 35,131,181, 63, 86, - 24, 35,235, 9,249,119,223,186,117,107, 55, 0, 36, 39, 39,167,141, 28, 57,242,227,251,247,239,207, 3,112,224,193,131, 7,107, - 61, 33,250,241,199, 31,111, 1,248,111, 85,199,252,178,244,191,187, 0,236,242,132,183,176,176,176, 36, 49, 49,177,228,195, 15, - 63, 36,210,210,210, 14, 6, 5, 5,189,124,232,208, 33,225,224,193,131,141, 87,175, 94, 61, 26, 28, 28,220,189, 79,159, 62,226, - 3,103,207,102, 20,223,185,179,111,223,253,251, 33, 22,155,109, 95, 85,239,103, 45,139,172, 50, 98,107,215,252,251,139,119, 47, -190,223,199,102,196, 14, 83, 1, 78, 3, 72,127, 2,206, 19, 39, 79,158,108, 54,122,244,232,223, 6, 14, 28,216,185, 89,179,102, -168, 91,183, 46,110,222,188,137,188,188, 60, 92,190,124, 25,123,247,238,221, 91, 82, 82, 82,109, 66,109,181, 90,253,120,122, 34, -190, 60,120,195,247,115,246,158, 79,104,223,184,219,128,177,130,230,193, 54,152,204, 12,210, 30,222,193,220,207,215, 21,103, 61, -188,149,108,182,154,223,128,155, 19,117, 12, 6, 67,236,183,223,126,203,222,183,111,223,128,149, 43, 87, 74,194,194,194, 40, 14, -135, 67, 2, 96, 46, 92,184,192, 76,157, 58, 85,175, 82,169,246,235,116,186,216,191,185,141, 62,113,247,238,221, 40,138,162,106, - 53,220,194, 19,132,133,240,162, 54, 81,191,126, 72,179,134, 97,193,147, 26,212, 13,153, 82, 63, 44,116, 76, 69, 78,238, 13,124, -125, 37,245,195,235, 68, 55,168, 27, 50,165, 97, 88,240,164,250,245, 67,154,185, 97, 90,108, 32,149, 74, 15, 42,149,202,214, 0, -224,227,227, 51, 72, 38,147, 93,243,241,241, 25,100,239, 5, 14, 18,139,197,215, 35, 35, 35,223,254, 27,205,149, 85,114, 54,110, -220,120,100, 81, 81,209, 59,141, 27, 55, 30,233, 88,191,115,231,142,115,189, 38,156,161,161,161,189, 47, 92,184,240,159,165, 75, -151, 14,105,212,168,209,160,133, 11, 23, 14,249,253,247,223,255, 19, 18, 18,210,182, 6,156, 60, 0, 63,179,217,236, 28, 46,151, -155,203,102,179,115, 28, 11,139,197,202,161, 40, 42, 7,192,218, 74,172,101,125, 92,122, 57, 9,129,129,129, 15, 2, 3, 3, 31, - 4, 5, 5, 61, 8, 10, 10,122,160, 84, 42, 31, 91,252,253,253, 19,220,189,158, 77,131,196, 93, 59,212,149,156,108,161, 20, 39, -188, 16, 40,106, 90, 27,247,168,105,144,184,107,251,186, 62, 39, 91, 40, 37,241,255,223, 56, 91, 7,129, 97,214, 52,101,152, 53, - 77,153,214, 65, 96,170, 91,175, 77,179,191, 82,169,100,148, 74,229,156,167, 53,148, 80, 9,255,223,254,190,215, 34,103, 3,137, - 68,242, 75,221,186,117, 29,117,221,171, 82,169,244, 47,177, 88,252,170,189,174,123, 85, 36, 18,197, 69, 70, 70,142,173,142, 83, - 46,151, 95, 80, 40, 20,217,246, 37, 43, 48, 48, 48, 43, 48, 48, 48, 75,161, 80,100, 42, 20,138,204,128,128,128, 12,199, 34,147, -201,206,212,240,220, 21, 0, 58, 2,104, 11, 64, 90,139,215,179, 62,128,137,246, 58,232, 43, 0,111, 3,104, 89, 11,247,136, 96, - 11,228,147,121,178,208,147,108,113, 64, 33, 91, 28, 80,200,243, 9, 57, 89, 69, 10, 30,119, 56,155,200,229,242, 5, 82,169,244, -119,137, 68, 18, 47,145, 72,118,251,251,251, 47, 4,208,228, 31,122,150,196, 0,214,163, 52, 62,211, 1,148, 14,133,239, 70,233, -164,130,176,103,240,153,255,255,140,232,127,234,143,251,120, 57,189,156, 94, 78, 47,167,151,211,203,249, 28,114,146,222,235,233, - 21, 90, 30, 10,173,242, 11,128, 42, 34,195,123,225,133, 23, 94,120,225,197,255, 99,216,188,151,192, 11, 15, 81,225,208, 50, 81, -133, 42,245, 36,214, 84, 77,148,237, 17, 47,167,151,211,203,233,229,244,114,122, 57,189,156,255,239, 56,189,168, 69,120,205,170, - 94, 78, 47,167,151,211,203,233,229,244,114,122, 57,255,237,240, 14, 29,122,225,133, 23, 94,120,225,133, 23, 94, 60, 37,196,186, - 8,174, 50, 67,136, 94,161,229, 57, 72, 0,239, 0, 24, 10,160, 33, 74,179,217,111, 7,176, 10, 53, 27,211,151, 2,248, 24, 64, - 23,148,206,206,185, 7, 32, 30,165,179,115,138,188,151,187, 98,248,251,251,127,202,102,179,101, 64,105,106, 19,199,167,235,119, -154,166, 53, 58,157,110,225, 83, 42, 2, 5, 55, 35, 40, 59,202,234, 90, 54,215, 79,139,197,242, 52,203,233,197,179,137,198,114, -185,252,103,181, 90, 61, 10, 46, 73,150,189,240,226,223,128,128,128,128, 73,102,179,249, 51, 14,135,179, 32, 47, 47,111,245,255, -163, 83,127, 76,100,149, 17, 90,251,246,237,139, 3,128,129, 3, 7,246, 0, 0,153, 76,118,138, 36,201,250,158,252,131,205,102, -187,167,209,104, 42, 13,160, 38,147,201, 78, 81, 20,245, 24,167,197, 98,145,176, 88,172,194,138,126, 99,181, 90,211,117, 58, 93, -219,103,228, 34, 18, 0,246,249,250,250,150,204,155, 55,111, 85,207,158, 61, 67, 51, 51, 51,173,179,102,205,234,126,233,210,165, - 1, 0, 94,241, 80,108,117, 34, 8, 98, 67,235,214,173,119,141, 25, 51,230,183, 14, 29, 58,112,243,243,243, 37,219,183,111,175, -179,113,227,198, 68,155,205, 54, 10, 85, 36, 90,253,255, 12, 54,155, 45, 75, 79, 79,151, 0,165,169, 73,236,194, 10, 22,139, 5, - 22,139, 5,122,189, 30,173, 90,181,170,245,255, 13, 10, 10,138, 34, 8, 98,165, 88, 44,110, 91, 84, 84,116, 30,192,148,172,172, -172, 75,158,148,213,106,181,130, 97, 24,103, 57,155, 53,107,230,189,161,158, 97, 2,151,203,237, 23, 17, 17,209,222,104, 52, 22, -220,187,119,239, 28, 77,211, 95,160,246,114,180,249, 0,248,130,199,227,117,104,216,176, 97,232,173, 91,183,210,204,102,243, 89, -148, 38, 67,214,214,134,200,234,209,163, 71,194,247,223,127,239, 55,121,242,228,132,248,248,248,174, 94,177,229,197, 63,133,208, -208, 80,153, 94,175, 95, 7, 32,138,205,102, 7,241,249,124, 8, 4,130,108, 30,143,119, 81, 32, 16,140, 63,121,242,164,198, 83, - 78,154,166,191,120,240,224, 65, 80,199,142, 29,151, 40, 20,138,185, 42,149,170,196,108, 54, 31, 45, 40, 40,152, 1, 64, 87,213, -111,203,107,145,231, 76,100,185,126,194, 33,186, 88,246, 19, 99, 0,244, 44,163,192, 88,172,144,135, 15, 31, 42,248,124, 62,108, - 54,155,179, 49, 43,191, 56,182,155, 76, 38, 52,111,222,220, 92, 77,131, 19,154,150,150,166,224,114,185,206,109, 38,147, 9,117, -234,212,177,165,167,167, 43,236,105, 15,156, 48, 26,141, 8, 9, 9,121,150,114, 30,189, 35,151,203,181,169,169,105,173, 74,140, -230,152,183,223,251,228,211, 81, 67, 95,242, 61,117,234,148,237,149, 87, 94, 49,198,197,197,189,131,210,196,169,110, 85,230, 4, - 65,108,156, 53,107,214, 92,190, 80,234,119,236, 84,178,113,227,246,253, 25,173, 27,215, 35,102,204,152, 65, 77,157, 58,245, 68, - 84, 84,212,207, 54,155,173, 13, 60,176,108,249,250,250, 30,226,241,120,225,246,235,151, 90, 80, 80,240,242, 51,248, 64,178,240, -120,240,216,138,182, 85,139,252,252,124, 24, 12,134,199,150,102,205,154,185,155, 43,211,163,114,179,217,236,221,139, 22, 45,170, -147,157,149,133,255, 45, 91,214, 17,165,150,204,142,238,252, 56, 55, 55,247,177,114, 54,109,218, 20, 94,120,132,143,231,206,157, -187,232,205, 55,223, 4, 77,211, 48, 24, 12,193,183,111,223,142,252,236,179,207,222,184,115,231, 78,123, 0,119,159,180, 51, 30, - 17, 17,145, 50,109,218, 52,121,251,246,237, 97,207, 82, 17, 28, 31, 31,223,113,253,250,245,111,165,166,166, 54, 5,144,247, 36, -127, 32,151,203,127,254,225,135, 31,252,132, 66, 33,246,236,217,227,215,187,119,239,248,164,164,164,110, 79, 32,182, 72, 63, 63, -191,169, 0, 94,180,217,108, 92, 0,103, 11, 10, 10,230,195,243,168,238, 74,177, 88,188,131, 36,201,122,192,163,104,244, 36, 73, -250, 19, 4,161,114,108, 35, 8, 66, 97,179,217, 78,171,213,234,206,222,199,241,249,134,159,159,223,132,156,156,156,239,121, 60, - 30,199,215,215, 23, 66,161, 16, 44, 22, 11, 44, 22,171, 46,143,199,171,203,227,241,250,247,234,213,107,202, 95,127,253, 85,101, -132,253, 78,173, 3,199,129, 36, 98, 40,130,164, 0,128,100,139,164, 62, 62, 62,136,137,137, 17, 13, 26, 52, 72, 4, 0, 9, 9, - 9, 99,198,142, 29,219, 59, 61, 61,189,121,101, 98,171, 34, 45,242, 28, 33,182,170, 6, 15,118,245, 24, 87,230,205, 37, 73,112, -185, 92,156, 57,115, 6,238, 4, 43,119,164, 72,168,178, 54,176, 71, 24,191,116,233,145, 1,192,209,208,112,185, 92,156, 60, 89, - 54,168,124,167, 78,157,156, 47,251,223,133,161,205, 74,131, 60,110,123,183,180, 92,195, 86,150, 70,215,222,246,110, 83,116,255, -230, 33,134, 78,157, 51,162,184,196,220, 14,128, 94, 83, 80, 80,112,126,231,206,204,214,141, 27,115,126,254,249,231,246,117,234, -212, 25,234,129,208,250,184, 77,155, 54, 59, 40,129,143,255,152,177,227,198,140,103,145,230,183, 38,126,184, 32, 45, 75,165,143, -142,142,222,185,103,207,158, 49,139, 23, 47,190, 62,115,230,204,143, 1,204,118,183,252,124, 62, 63,252,198,141, 27, 17, 52, 77, -163, 89,179,102,207, 98, 26,131,214, 40, 13,190,247, 38,128,173,246,109, 35, 81, 26,185, 63, 10,192, 69, 79,200, 28, 22,172,138, -150,218, 70,157, 58,117,154,142, 30, 61,218, 95,173, 82,225,127,203,150, 57, 54,183, 69, 53,195,136,142,247,199,100, 50, 97,200, -144, 33,163,105,154,102, 57, 68,160,209,104, 52,105,181,218, 18, 60,114, 44,205, 3,240,146, 27,197,169, 47, 18,137,190, 6, 16, -101, 48, 24,234, 0,128, 72, 36,202,176,217,108,187,244,122,253,108, 60, 74,224,235,113, 7, 23, 64, 36, 42, 79, 5,197, 44, 90, -180,232,214, 39,159,124,114,247, 31,224, 12, 15, 12, 12, 92, 56,108,216, 48,236,223,191, 31, 7, 14, 28,176, 8, 4, 2,214,216, -177, 99,137, 41, 83,166,248, 78,155, 54,173, 63,128,111,159,240, 54,247,159, 59,119,174,252,133, 23, 94,192,246,237,219,113,249, -242,101, 67, 68, 68,132,160,103,207,158, 96,177, 88,242, 79, 63,253,244, 21, 0, 27,158,228, 15,212,106,245,252, 15, 63,252,112, -227,214,173, 91, 37,247,238,221,195,202,149, 43,253, 71,140, 24, 17,151,154,154,218,195, 3,177,197, 3, 48, 21, 64, 47,138,162, -186,141, 29, 59,214,250,222,123,239,177, 73,146,180, 44, 91,182, 44, 96,253,250,245, 35,216,108,118, 84,126,126,190, 59,157, 52, - 18, 64,204,248,241,227,255,251,215, 95,127,249,158, 59,119,142,235,231,231, 7,154,166,157,150, 98,155,205,166,112, 60,179, 86, -171, 21, 77,155, 54, 13,113,249,189,224,121, 21, 26, 36, 73,154,109, 54, 27, 27, 0, 31,128,177,186,245,127,147,200,146,203,229, -147,213,106,245,170,160,160, 32, 4, 6, 6, 62,214,214, 26,141, 70,240,249,124, 78, 80, 80,208, 15,131, 6, 13, 98,239,222,189, -187,210, 33, 64,130, 34,190,216,243,203,188, 58,114, 95, 9, 0, 96,249,154, 63,138, 1,224,247,223,127, 71,102,102, 38,124,125, -125,209,188,121,115,106,222,188,121,202, 25, 51,102,252,175,160,160, 96,124,101, 92,229,181,200,115,102,209,138,173,104,189, 74, - 31, 45,134, 97,156,121,242,220,124,104,203,111, 58, 82,142,143, 48,153, 76, 40,111,209,114,188,188,108, 54,187,188,249, 17, 4, - 65, 48, 85,113, 86,128,177, 34,145,168,149, 94,175, 95,225, 65,239,214,201,185,237,221,166,216,200,155, 53,210,145,137,180,255, -135,165,159, 27, 1,156,186, 63,126,229,247, 61,122,212,153,250,249,119,115, 12,249,153,170, 79, 71,191, 26, 30, 17,228, 39, 16, -105,114,181,242, 38, 77,250,150,179,200, 84, 87,206,238, 99,198,140,217,244,231,153, 7, 4,159,207,225,176, 40,138,221,181, 69, - 99,191, 80, 31,202, 71, 2,248,164,221,189,117,106,220,184,113, 45,102,206,156,217,205, 3, 78,216, 27, 92,108,222,188, 25, 4, - 65,144,158,156,123, 45,226, 72, 85, 34,139, 97, 24, 16, 4,177,197,165, 81,217, 98,223,150,228, 34,182, 88, 85, 93, 79,135, 53, -213, 33,170,198,142, 29, 59,218,106,181,178, 92, 42,137,242, 2,166, 34, 17,227,214,185, 43,149,202, 63, 1,188, 68, 16, 4, 76, - 37, 37,166,175,191,249,198,117,247,133,114, 34,235, 72,101,239,146,197, 98, 1, 77,211,172,164,164, 36,182,203,179,206, 6, 32, - 2,224,207, 48, 12, 72,146,188,226,198,245,108, 42, 20, 10, 79,237,221,187, 87,218,182,109, 91,130,203,229,194,106,181,226,234, -213,171,161,139, 23, 47,158,120,228,200,145, 87,244,122,125, 51, 60,158, 60,221,157,123, 20, 25, 31, 31,175,111,208,160, 65,133, -194, 81,167,211,177, 26, 55,110,220,163, 18, 81,244,180, 57,211,115,114,114, 94,127,233,165,151, 38,101,103,103,167, 88,173,214, -143, 0, 52,247,247,247, 79, 26, 60,120, 48, 4, 2, 65, 47,131,193,240,237,147, 60,243, 10,133, 98, 80,231,206,157,177,114,229, - 74, 44, 94,188,184, 15,128,163, 0,122,235,116,186, 35,175,189,246, 26,100, 50,217,235, 26,141,102,195, 19,188, 71,141,187,119, -239,254, 67, 76, 76,140,100,255,254,253,136,136,136, 64, 97, 97, 33, 62,248,224, 3,197,151, 95,126,121, 92,163,209,244,116,121, - 47, 42,227,108,198,227,241, 54,108,221,186, 85,220,160, 65,131, 6, 28, 14,135,108,208,160, 1,212,106, 53, 74, 74, 74,120, 11, - 22, 44,104, 33, 16, 8, 46,125,251,237,183, 27, 0, 12,174,166,156, 36,128,249,107,215,174,157, 20, 29, 29, 45, 27, 61,122, 52, -109, 50,153,240,219,111,191,129,162, 40,176,217,108, 8,133, 66,103,242,106, 14,135,131, 38, 77, 30, 11,146,190,167,138,243,213, -162,212, 15, 85, 6,207,134, 93,143, 84,193,231, 28,250, 96,179,217,224,243,249,224,243,249,224,241,120,184,113,227,198,231,124, - 62,127, 25, 65, 16, 86,119, 56,137, 71,234,162, 21,128,115,213,173,227,113,215,144,191,179,254,116, 32,132, 32,136,229, 0,122, -149, 54,187,100,156,191,191,255,251, 57, 57, 57, 15,221,229, 84, 42,149,126,249,249,249,223, 42,149, 74, 4, 6, 6, 58,219,239, - 58,117,234,192, 98,177, 32, 39, 39, 7, 12,195, 64,163,209, 64, 40, 20, 34, 56, 56,248,219,232,232,232,237,177,177,177,249, 21, -114,218,176,248,181, 17,159,125, 65, 81, 20, 9, 0, 20, 75, 44,158,246, 9, 16, 30, 30,142,174, 93,187,162,164,164, 4, 90,173, - 22,145,145,145, 44,130, 32,198, 16, 4, 33,101, 24,102, 53,128, 99,255, 66, 67, 97,165,206,240,115,203,143,139, 58,178,197,115, - 56, 28,183,132,150,253,248,234, 44, 40,164,197, 98, 1,135,195, 41, 99,145, 32, 8, 2, 52, 77,151,217,238, 16, 90, 53, 17,234, - 83,166, 76,177,253,240,195, 15,147, 10, 10, 10,214,160,134, 67, 9, 99,198,140,121,204,223, 99,198,140, 25,233,185,185,185,204, -144,190,173, 68, 41, 7, 51,179, 26,250,138, 5, 1, 18, 73, 61,190,175, 92,150,159,159,127,218, 94,153,184,139, 70,109,218,180, - 17,108,220, 25,159,254,246,244, 69,243,218, 54,240,147,182, 12,241,247, 13,242, 17,112,197, 36,161,231, 91, 45,233,114,185, 60, -194,211,114, 59,234, 5,161, 80, 8,146, 36,159, 37,139, 22,203, 33,178,212,106, 53,246,239,223,143, 1, 3, 6, 36, 57, 68,136, - 78,167, 67, 86, 86, 22,148, 74,101,146,221,242, 81,237, 48,162,205,102,131,217,108,134,217,108,118, 10, 24,151,103,200, 41, 96, - 28,199, 82, 20,117,165,134,101,159,231,235,235,219,189, 87,175, 94,220, 95,126,251,141,203, 48,140, 30,165, 57,212,138, 24,166, -146, 4,217,229, 96,181, 90,157, 86, 54, 54,155,141,212,212, 84,103,195,229,200, 45,201,231,243,221, 51,101,240,120, 31,254,250, -235,175,210,246,237,219, 19,249,249,249,176,217,108,206, 74,114,213,170, 85,252,161, 67,135,214, 73, 76, 76,252,212,104, 52,206, -173,193,185, 18,149, 9, 34, 0,144, 74,165, 86,184, 23, 49,187, 90, 78,171,213, 74,116,233,210,101,166, 74,165,106, 97, 48, 24, - 22,184,115, 25, 1,236, 73, 79, 79,119,109,216, 47,165,164,164, 24,134, 15, 31, 46,168, 87,175, 94,135,228,228,228, 39,122, 72, - 27, 55,110,220,137,205,102,227,236,217,179, 70, 0,142,158,117,220,229,203,151,141,131, 7, 15,230,133,134,134,118,210,104,220, -118, 89,105,220,180,105,211,195, 10,133, 66,224,168, 67, 3, 2, 2,216,177,177,177,146,140,140, 12,152,205,102,124,252,241,199, - 24, 56,112, 32,252,253,253, 49, 99,198,140,192, 37, 75,143,140,254,133, 0, 0, 32, 0, 73, 68, 65, 84,150,252, 92, 84, 84,212, -166, 42,163, 53,151,203,221,116,251,246,237, 8,165, 82, 41, 56,115,230, 12, 90,182,108, 9,149, 74,133,236,236,108, 20, 21, 21, - 33, 59, 59, 27,227,199,143, 87,252,239,127,255, 11,118,195,146,229, 20, 89,177,177,177,154, 29, 59,118, 80,235,214,173,147,176, -217,108,167,208, 98,177, 88, 78,161,229,200,173, 88,131,145, 6,141, 93,180,201,180, 90,237,147,248,185,241, 0,112, 93, 69, 22, -143,199, 3,143,199, 3,159,207,127,162,188,172,207, 9,234, 16, 4,145,204,225,112,120, 66,161,144, 67,146, 36,120, 60, 94, 95, -185, 92,126,173,121,243,230,205, 15, 31, 62,252,192, 29,146,146,146,146, 77, 60, 30,143,173, 80, 40, 0, 0, 17, 17, 17,104,217, -178, 37,244,122,189, 77,171,213, 66, 38,147,145, 15, 31, 62,132,193, 96, 64, 86, 86, 22,194,194,194,216, 36, 73,110, 66,169, 31, -242, 99, 56,149,148,189, 6,192, 26,199,186,191,191,127,142,171,165,147,207,231,163, 78,157, 58,200,200,200,128, 68, 34,161,190, -252,242,203,193,191,253,246,219, 27,167, 78,157, 26, 3, 96,179, 11,213,220,231,216, 71,203, 33,178, 92, 63, 31, 9,173,129, 3, - 7,206,217,183,111, 95,143,138,122,225,108, 54,187,214,124, 93, 28,130, 74, 42,149,150,183, 90,193,102,179, 85,102,209,242,248, -127,248,124,190, 96,242,228,201,133,171, 87,175,246, 88,108, 13, 91,153,226,180, 98, 61,214,141,108,214,236,212,167,159,126, 58, -232,175,191,254,202,104,219,160, 30, 75,148,249,176,136, 47,149,201, 16, 82,119,192,216,215, 7, 95, 70,233,236, 67,119,113,187, -176,176, 80,208, 48, 68,104, 34,201, 18,162, 46,143, 37, 81,138, 56,188, 32, 95,223, 58, 28,147, 49, 87,234,235,203, 53, 26,141, - 26, 84,145, 4, 26, 0, 2, 3, 3,255, 16, 8, 4, 97,142,117, 95, 95, 95, 31,134, 97, 32, 20, 10,161, 84, 42,197, 20, 69,221, -116,121,185, 30,230,228,228,244,173,174, 96, 50,153,236, 15, 30,143, 23, 70,146, 36, 8,130, 0, 69, 81, 32, 73, 18, 36, 73, 58, -191, 83, 20, 5,130, 32, 80, 92, 92,252,240,193,131, 7,125,221, 56, 95, 43,128, 40,130, 32,146,246,239,223,143, 14, 29, 58,224, -224,193,131,232,215,175, 31,180, 90, 45,174, 94,189,138,238,221,187, 3,165, 67,138,110,193,213,249,221,209, 41,184,113,227,134, - 83,184,184, 46, 18,137,228, 73, 76,236, 9,195,134, 13,195, 15, 63,252,192,216, 59, 19, 34,130, 32, 90,250,248,248,220,184,126, -253,186, 91,126, 48, 12,195,192,108,126,116,168,163,241,178,251, 67,120,148, 28,152,162,168,190,109,218,180, 33,180, 90,173, 67, - 64,130,197, 98,129,162, 40, 80, 20,133,239,191,255, 94,208,190,125,251,207,120, 60,222, 76, 14,135,163,179, 88, 44,191,148,148, -148, 44, 0,160,121,150,106,164,110,221,186, 77, 79, 75, 75, 27, 24, 22, 22,182,247, 9,104, 24,139,197, 98, 2, 32,160, 40,138, - 93, 11,117, 20,101,127,182, 74, 92,196,190,213,190,206, 67,233, 48,177, 91,240,247,247,255,249,192,129, 3, 33, 97, 97, 97,176, - 88, 44,176, 90,173, 40, 42, 42, 66, 92, 92, 28,140, 70, 35,172, 86, 43, 34, 34, 34,240,197, 23, 95,148,188,255,254,251,252,181, -107,215,230, 22, 21, 21,141,170,134,246,253,237,219,183,139,148, 74,165,192, 96, 48,224,238,221,187,104,211,166, 13, 10, 11, 11, -161,215,235, 81, 92, 92, 12,179,217, 12,157, 78, 39,163,105,218, 84, 13,215,231,174, 34,107,226,196,137, 87,184, 92,110,155,247, -222,123, 15,233,233,233,206,119,254,237,183,223, 70, 96, 96,160,243, 93,178,215,201, 30, 85,204, 44, 22, 11, 60, 30, 15, 28, 14, - 71, 83,183,110, 93, 16, 4,193,127,248,240, 97, 77,134,226,164, 0,116,108, 54,155,235, 42,176,120, 60, 30,206,158, 61,251, 41, -151,203,173,204,154, 85,217,123,201,120,178,254, 79,131, 32,136,229, 28, 14,135, 39,151,203, 57, 46, 29, 78,142, 88, 44,134, 66, -161, 88, 9,160,191,155,231,221, 90, 46,151, 59,235,247, 86,173, 90, 33, 45, 45,109,151, 86,171,125, 43, 55, 55, 23, 36, 73,110, - 34, 73,242, 13, 71, 39,181,160,160, 0,161,161,161,173, 43,227,235, 28, 21, 52, 9, 4, 83,198,162, 85,174,131, 6,169, 84,138, -251,247,239, 67,175,215, 51,183,110,221, 34, 38, 79,158, 76,152, 76,166,159, 18, 19, 19, 79,163,116,182,125,165, 90,228, 57,129, -231, 62, 90, 14,139,150,187, 13, 0, 65, 16,213,246, 38, 44, 22,139, 56, 50, 50,178, 34,135, 47,162, 34,161,101, 31, 78,170,209, -131,206,102,179, 37, 53, 21, 91,229,177,119,199,214,192,197, 95,124,252,133, 60,184, 94,195,153, 51, 63,103,189,250,234,171,103, - 54,110,220, 72,203, 95,232,223,251,216, 31,155, 3,191,253, 96,214,193, 3, 7, 14, 0,165,142,209,238, 34, 97,223,190,125, 65, - 51,166, 78,193, 23, 31,190,127, 72, 26,225,207, 21, 19,114, 17,223,168,207, 19,131, 49,240, 26, 53, 29,184,115,239,222, 44, 0, -137, 85,145, 8,133,194,176,228,228,228, 8,215,137, 4, 38,147, 9, 66,161, 16,199,142, 29, 11, 16, 8, 4, 1, 0, 96, 48, 24, -208,188,121,115,119, 45, 38, 97, 55,111,222,140,144, 72, 36, 40, 46, 46,134,209,104,132,197, 98,129,205,102, 3, 65, 16, 96,179, -217,224,114,185, 16,137, 68,158,206,236,187, 8,224,205, 1, 3, 6,108, 57,120,240, 32, 34, 35, 35, 81, 80, 80,128,148,148, 20, -135,200,242,200, 71,203, 97, 37,114,245,199, 98,177, 88,248,185, 65, 3,188,157,153,233, 20, 48,203,125,124,240,133,173,102,217, - 52,154, 55,111,206, 36, 36, 36,224,208,161, 67,120,237,181,215,136,221,187,119,155,105,154,230,100,102,102, 94,201,204,204,116, -139,195,102,179, 57,203,234,168,183, 93, 5,150,167, 66,203,106,181, 74,184, 92, 46, 74, 74, 74,224,176, 60,184, 46,245,235,215, -135, 90,173,102,233,116, 58, 86,102,102,166,112,254,252,249,239, 29, 63,126, 92, 89, 88, 88, 56,242,159,172,133, 86,175, 94, 29, -246,246,219,111,167,178, 88, 44,166, 95,191,126,163, 31, 62,124,248,186, 82,169, 60,250,215, 95,127,125, 3,160,177,167,124,254, -254,254, 23, 88, 44, 86,136, 78,167,227,108,219,182,205, 82, 88, 88,200, 9, 8, 8,200,113,212, 29,142,107,109,177, 88,220,154, -185,236,239,239,127, 65,165, 82,113, 86,172, 88, 97,201,207,207,231, 4, 6, 6,230, 56,120, 52, 26, 13,103,219,182,109, 22,157, - 78,199,241,241,241,185,160,213,106,171,229, 83,169, 84,163,198,140, 25, 19,127,244,232, 81,127,138,162,240,240,225, 67,228,231, -231, 67, 38,147, 97,211,166, 77, 8, 11, 11,195,246,237,219,213,106,181,122,194,215, 95,127,253,153, 93,100, 85,231,163,213,189, - 67,135, 14, 97, 26,141, 6, 50,153, 12,122,189, 30, 23, 46, 92, 64,179,102,205,144,153,153, 9,146, 36, 33,147,201,176,106,213, -170, 98,130, 32,212, 85, 17, 9, 4,130,215,163,163,163,101, 0, 16, 29, 29, 45,139,142,142,174,176,129,235,212,169, 19, 86,174, - 92, 89, 94,104,121,210, 49,112, 90,157, 92,196, 81, 73,199,142, 29,113,252,248,241, 89, 30,138, 35,147, 67,180,149,183,102,241, -120, 60,143, 39,211,216,108, 54, 14, 74, 93, 26, 8,119,214,159, 1,244, 16, 8, 4,156,242, 27,139,139,139, 57, 74,165,178,155, - 7,194,215, 79, 32, 40, 53, 56,133,133,133, 65,171,213,210, 38,147,105,196,230,205,155, 45, 0, 16, 21, 21, 53,130,166,233, 18, -171,213, 74,113,185, 92,232,245,122, 40, 20, 10,191, 42,108,163, 31,237,249,101,126, 80,121, 31, 45,165, 82,137,168,168, 40, 24, -141, 70,100,101,101, 33, 46, 46,206, 66,211,244,150,213,171, 87,219, 2, 2, 2,254, 59,100,200, 16, 42, 49, 49,241, 93, 0,211, - 43,211, 34,207,153, 53, 43,182, 82,161,101, 87,144,199, 1,244, 44,127,146,229,197, 79, 85, 66,171,186,161, 67, 46,151,171, 73, - 77, 77, 21,185, 54, 42, 86,171, 21,193,193,193, 54,134, 97,136,138,132,214,147,152,130,217,108,182,228,147, 79, 62,209,172, 94, -189,122,212,253,251,247,231,184,243,155,109,239, 54,197,198,114, 34,107,205,226,152,149, 43, 22,207,151,223, 57,244, 19,214,125, -183,148,166,105, 36,182,104,209,162, 91, 81, 81, 17,203, 71,100,129, 74,131,131,118,145,229,174, 40, 36, 1,252,120,238,220,185, -196,254,253,251,159,252,241,215,157,242,204,187,119, 79,243,116,170, 44,105,163, 8, 22,167, 78,216, 27,133, 37, 37,156, 17, 35, - 70, 4, 0, 24, 82, 93, 37,166,209,104,144,157,157, 93, 94,128,225,198,141, 27,143, 29,235, 86,225, 72, 18, 52, 77, 99,199,142, - 29, 16, 10,133, 16,137, 68,101, 22,135,200,170,225, 68,133,155, 0,208,175, 95, 63,168,213,106,136,197, 98,183,203, 85, 94,188, - 48, 12, 3,147,201, 4,147,201, 4,179,217, 76, 3, 96,179, 88, 44,140, 79, 79,119, 90,121, 60, 17, 48,229,209,162, 69, 11,230, -212,169, 83, 56,121,242, 36,244,122, 61, 86,172, 88, 1,165, 82,249, 34,128,207, 61,229,114,113,210,167,117, 58, 29, 91,167,211, - 57,173,131,108, 54,219,105, 61,112,211,146,199, 97,177, 88,206,222,168, 99,113,181,106, 81, 20,133,192,192, 64, 4, 5, 5, 97, -205,154, 53,156,122,245,234, 13,252, 39,107,160, 37, 75,150, 52, 90,190,124,249,250,141, 27, 55, 30, 28, 53,106,212,111, 87,175, - 94, 29,231,227,227,115,229,216,177, 99,243,121, 60,158,173,134,239,119, 72,102,102,166,194,117,147,205,102, 19, 90,173, 86,167, -176, 45, 46, 46,118,187,131,193,102,179, 67,146,147,147,133, 0, 48,127,254,124, 54, 0,161,195, 25,220,193, 89, 92, 92,204,110, -214,172, 89,136,187,207,122,124,124,124,183, 62,125,250,156, 58,124,248,176,111, 88, 88, 24, 50, 50, 50,144,145,145,129, 70,141, - 26, 97,225,194,133,122,157, 78,215, 5,192,205,162,162,162,221,110,114, 6,251,250,250,178, 83, 83, 83, 97,181, 90,209,186,117, -107,172, 90,181, 10, 35, 70,140, 64,243,230,205,161,211,233,144,156,156,140, 13, 27, 54,248,114, 56,156, 42,235, 14,131,193,176, - 59, 54, 54, 54,180,188, 69,107,244,232,209,162,156,156, 28,231, 51, 25, 19, 19, 83,102, 8,209,147, 58,217, 62,180, 85,233, 82, - 19, 88,173, 86, 41,159,207,215,241,120, 60,174,195, 63, 43, 46, 46,206, 99,107, 86,185, 14,160, 39,235,255, 24, 28,162,181,130, -182, 21, 65, 65, 65,110,243,240,120, 60,194, 81, 55, 90,173, 86,104,181, 90, 90,169, 84, 58,135,247,147,146,146,232,240,240,112, -154,162, 40,138,203,229,130, 32, 8, 8,133,194, 74, 43,124,134,102, 98, 94, 29,241,121,153, 89,135,211, 62, 1,204,102, 51,146, -146,146, 96, 54,155, 17, 23, 23,103,249,250,235,175, 51, 53, 26,205, 52, 0,172, 63,254,248, 99,204,172, 89,179, 40,133, 66,209, - 39, 55, 55, 23,213,105,145,231, 72,108, 61,102,229,114,180, 66,199, 7, 14, 28, 72,216,167, 86, 18, 14,225,228,137,208,178,191, -124,213,182,188, 4, 65, 32, 43, 43,203,185,174, 80, 40, 60,254, 47,119,225,231,231,167,239,212,169,147, 68,165, 82,237, 94,178, -100, 73,141, 44, 89,107, 22,199,172, 92, 52,239, 75,185,250,250, 25,164,103,102, 65,157,107, 73, 76,184,114,127, 23,128, 93, 0, -128,181, 47, 28, 39, 38,165,124,239, 46,103, 83,127, 65, 43, 54,135,181,235,165,254, 3, 67,135, 71, 79, 39,223,121,231,157,174, - 99,198,140,209,142, 26, 53,106,170, 88, 44,110,108, 54,155, 11,118,238,223,255, 96,248,240,225,245,104,154, 30,131,106, 98,142, - 24, 12,134,135, 61,123,246,116,189,158,210, 35, 71,142, 4, 62,120,240, 0, 83,166, 76,201,203,200,200,208,184, 30,235, 78, 25, -205,102,243,195, 86,173, 90, 85, 58, 92,232, 24, 82, 4,128,194,194,194,135, 30, 92,210,145,176, 59,190,231,231,231,227,198,141, - 27, 96,177, 88,232,216,177, 35, 18, 18, 18,208,181,107,215, 36, 79,172, 90, 37, 37, 37, 8, 11, 11, 67, 73, 73, 9,244,122,125, - 49, 0,222,166,122,245, 0, 0,239,230,231,227,194,215, 95,227,204,162, 69,112,125,158,221, 69,203,150, 45,153, 51,103,206,224, -202,149, 43, 48, 26,141,152, 48, 97, 2, 0, 16,246,103,215,147,144, 25, 13, 40,138,234,215,191,127,255, 96, 0,208,235,245,196, -185,115,231,192,231,243,157,239,194,222,189,123,145,145,145, 1,130, 32,224,235,235, 27, 82, 80, 80, 80, 15,192,253, 42,204,254, -196,253,251,247,241,213, 87, 95,193,102,179, 97,214,172, 89,136,136,136,112, 10,172,135, 15, 31, 98,254,252,249,160,105, 26, 95, -126,249, 37, 26, 53,106, 4,139,197,194, 71, 13, 67,104,212, 6,102,204,152,113,103,215,174, 93, 7,211,210,210, 94, 89,188,120, -113, 15,130, 32,108, 51,103,206,252, 74, 42,149,210, 79,194, 91,160, 45,196,141,219, 15,157, 66,168,252, 18,224, 47,247,152,239, -214,221, 52,231,239,105,218,149,143,134,159,220,215,211, 34, 22, 91, 44, 22,253, 27,111,188, 33,219,177, 99, 7,209,168, 81, 35, -220,187,119,207, 97, 25, 42,134,231, 33, 29, 50,212,106,117, 4, 69, 81,156,219,183,111, 35, 60, 60, 28, 29, 58,116,192,130, 5, - 11,160, 82,169, 96,181, 90,161, 80, 40,108, 22,139, 37,201,108, 54,159,168,134, 43,102,226,196,137, 28, 0,147,236,150,173, 22, -211,166, 77,179, 45, 93,186, 20, 73, 73, 73, 78, 11,150,171, 51,188,167, 67,135,174, 86, 39,215, 37, 46, 46,110, 22,151,203,101, - 0,156,133,231,129,158, 77,229, 45, 90, 53,177,102, 61, 45, 60,205,153,140, 74,165, 50, 78, 34,145, 12, 44, 40, 40, 40, 99,213, -234,210,165,139, 57, 48, 48, 48,222, 93, 30,177, 88, 92, 64, 81,148, 31, 0,100,100,100, 64, 36, 18,113,238,222,189,187, 8,165, -193,179, 81,175, 94,189, 69,106,181,154, 83,207, 94,159, 6, 5, 5,193,100, 50, 85,234,198,114,250, 98,206, 79, 0,126,114,172, -203,229,242, 44,173, 86, 43, 88,186,116,105,209,162, 69,139, 12, 52, 77, 27, 1, 28,211,104, 52,206, 56, 90,217,217,217, 90, 54, -155, 45,151,201,100,117, 28, 66,171, 34, 45,242,156,161,114,139,150, 93, 73, 50,229, 5, 17, 65, 16,143, 57,168, 87, 35,180,170, - 21, 89, 52, 77,151,177, 50, 56, 28,222, 43,250, 47,123,163, 94,163,161, 67,187,200,226,239,220,185,115,211,146, 37, 75,206,186, -251, 59, 87, 31,173,181,223,204, 91,236, 16, 89,151, 79, 30,198,238, 20,173,106,214,162,101,203,107,122, 7, 94,240, 23,182, 12, - 12,244, 59,254,245,194, 24,233,157, 67, 27,240,219,218,255, 49,151,207,159,111,127,254,252,249,183,166, 76,153, 82,215,254, 96, -169, 1, 92, 2, 48, 28,110,204,210,201,200,200,232, 91,174, 17,190,201,225,112, 2,133, 66, 33, 50, 50, 50,138,110,221,186,229, -241,144,140, 74,165,234,251, 20, 30, 64,150, 67,100,169, 84, 42, 36, 39, 39,163, 87,175, 94, 0,128,132,132, 4,116,233,210, 5, -137,137,137,104,211,166, 77, 18,128,118,168, 38, 80,171,197, 98,209,188,240,194, 11, 78,235,150, 86,171,181, 1, 64,116, 86, 22, - 98,149, 74,176, 88, 44,156, 89,180, 8,179, 45, 22, 44,240, 80,192,183,106,213,138, 57,119,238, 28, 30, 60,120, 0,171,213,138, - 65,131, 6,161,134, 47,125,243,166, 77,155, 30, 57,118,236, 88,128, 88, 44,134, 94,175, 71, 81, 81, 17,198,142, 29,139, 17, 35, - 70,192,104, 52, 98,219,182,109,216,179,103, 15, 36, 18, 9,244,122, 61,244,122,189,239,128, 1, 3, 78,221,188,121,179, 59,128, -219,149, 8, 45,166,111,223,190,136,143,143, 7, 69, 81,104,223,190, 61,242,243, 31, 77, 6, 10, 12, 12,172,104, 31,245, 79, 10, - 45, 22,139,197,196,197,197, 45,238,209,163, 7,210,210,210, 94,105,211,166,205,138,113,227,198,101, 60, 41,175,175,143, 4,173, -154, 53,128,209,104,132,209,104, 68,112,112, 48, 10, 11, 11,113,231,206, 29, 24,141, 70, 4, 42,100, 30,243, 69, 53,111,228,228, - 83, 40, 20,208,235,245,184,127,255, 62, 76, 38, 19,252,253, 61, 18, 90,161,125,251,246,253,107,203,150, 45,126, 27, 54,108, 48, -245,236,217,147,187, 98,197, 10, 66, 42,149,194,165, 97,241, 20,113, 9, 9, 9, 97,125,250,244,105,114,253,250,117,196,197,197, -193,100, 50, 33, 42, 42, 10,183,110,221, 66,167, 78,157, 80, 84, 84,116,246,252,249,243,123,220, 49, 12, 3,248,108,226,196,137, -112,136,173,248,248,120,100,101,101, 65, 34,145, 60, 38,180, 28,190,143,246, 89,227,193,238, 20,214, 33,136, 92, 44, 79,179,101, - 50,153, 25,192,242, 26, 90,159, 0, 0,105,105,105,188, 22, 45, 90, 24,249,124, 62,215, 46,218,150, 61, 9, 95,109,162, 22,102, - 50, 86,138,160,160,160,105,254,254,254,125,234,215,175,143,156,156, 28, 14,151,203, 69,151, 46, 93,204,237,218,181, 51, 7, 5, - 5,189,235, 46, 15,143,199,187,206,225,112,186,151,118, 38,104,164,166,166,130, 97,152, 89,205,155, 55,127,191,176,176, 16,249, -249,249, 92,169, 84,234,236, 84, 55,105,210, 4, 70,163,241,186, 7,150,183,152,240,240,240,207, 56, 28,206, 2,149, 74, 85, 81, - 88, 8,174, 76, 38,147,114, 56, 28,152,205,230, 50, 98,179,188, 22,121,222, 69, 86, 25,161,229,162, 34,203, 8, 29, 79, 44, 90, -238, 88, 13, 28, 14,246,174,235, 14, 81, 87,254,191,106, 26, 67,203,199,199,199,232, 16, 89, 11, 22, 44, 56, 91, 19,142,237, 91, - 54, 43,125,108,197,161,153,103, 15,224,230,149, 68,236, 74,214,168,102, 45, 90, 54,245,213, 33, 35,115,202, 11, 51,119, 16, 17, - 32,108, 30,168,240, 59,254,205,146, 69, 82,245,245, 51,200,202,206,198,129,179,231, 19,205, 64, 50,128, 89,181,105, 90, 6, 74, -135, 14, 41,138,122,150, 30, 88,167, 51,124, 86, 86,150, 67,100, 69, 1, 64,215,174, 93,147,236, 34, 11,238, 90,180, 52, 26, 77, -249,148, 53,125, 0,248, 59,206,159,197, 98,161,203,103,159,121, 44,178, 0, 48,137,137,137, 80,171,213,142,158, 98, 77, 69, 22, -130,130,130, 62, 60,118,236, 88,192,143, 63,254,168,219,184,113, 99,190,205,102, 99,183,106,213, 42,164,109,219,182,196,166, 77, -155, 0, 0,195,135, 15,199,172, 89,179,112,237,218, 53,136, 68, 34,116,237,218,149,158, 51,103,142, 98,218,180,105,239,230,228, -228, 76,173,176,117,180,217, 56,124, 62,255, 40,128, 23,175, 95,191, 14, 0,167, 80,154,194,201, 97, 69,168,116,159, 59,141,111, - 97, 97, 33, 91, 34,145, 84, 24, 26,130, 83,218, 27,242,212, 2,225,228, 60,121,242,228, 87,223,124,243,205,174, 15, 62,248,224, -246, 19,114, 86,104,209, 26, 56,112, 32, 12, 70, 51,210,115,180,160,105, 43, 12,230, 92,143,249, 92, 45, 90, 3, 7, 14, 68,113, -137, 9,169, 89,106, 88,173, 52, 10, 13,110,183,229,194,151, 94,122,233,143, 95,126,249, 37,232,244,233,211,160,105,218,118,235, -214,173,251,111,188,241,134,116,230,204,153,126, 79, 48,201,232,187,145, 35, 71, 14, 61,121,242,164,186, 73,147, 38,242,179,103, -207, 34, 55, 55, 23, 86,171, 21, 47,190,248, 34,184, 92,110,234,162, 69,139, 56, 0,190,115,247,222,216,197,150,249,252,249,243, -111,159, 57,115, 70, 46,151,203,185,182,166, 77,145,117,248, 48,118,236,216,241,216, 15,214,174, 93, 11,184, 25,133,223, 97,113, - 58,119,238, 92,173, 8,172, 50, 45, 53,151, 91,227,225,199,231, 21,231,206,157,203,120,231,157,119,154, 73,165,210,229,221,186, -117,235,229,231,231, 71,250,250,250,198,213,169, 83,231,253, 86,173, 90,185, 61,186,192,102,179,199,137, 68,162, 59, 86,171,149, - 42, 42, 42,130, 94,175, 47,173,164,173, 86, 46, 73,146,168, 87,175,158,179, 45,105,223,190, 61,130,130,130,232,148,148,148,113, -238,242,231,229,229,149,153,133, 88, 1, 38,118,233,210,133,101, 52, 26,241,224,193,131, 4,215, 29, 21,105,145,231, 4,209, 85, -138, 47,199, 73,185,158, 92,157, 58,117,210, 44, 22, 11,147, 12, 48,151, 46, 93, 98,162,163,163,171, 92, 74, 74, 74, 24,133, 66, -145, 85, 65,227, 7, 87, 78,163,209, 88,230,119, 70,163,145, 9, 12, 12,164, 13, 6,195, 99,156, 6,131,129, 9, 9, 9,201,168, -138,179, 2,140,189,120,241,226,234,217,179,103,119,240,224, 2, 57, 57,153, 53, 77,153, 13, 27, 54,252,135, 97,152, 30,221,154, -133, 93, 25,214, 42,144,233, 18,161,200,220,179,125,203, 8,134, 97,122,148, 95, 28, 1, 78,171,226,108, 26, 40,122,161,119,100, -221,130,203,135,182, 50,199,150,190,199,124, 51, 40,130,105, 19, 34,209, 52,245, 23,120,154, 35,166,218,108,233,145,145,145, 55, -109, 54, 27, 99, 50,153,152,200,200,200, 91,181,193, 89, 3, 84,197,217, 26,165,190,108, 35, 43,216,214,250, 9,202,121,153, 97, - 24, 70,173, 86, 51, 69, 69, 69,140,209,104,100,104,154,102, 92, 1,224,178, 27,156,140,217,108,102, 10, 10, 10, 24,184,239,115, - 87, 33,167, 82,169,188,127,247,238, 93,166, 97,195,134,105,118,115,252, 52,189, 94,207,148,135, 94,175,103,122,245,234,197,220, -186,117,139, 9, 15, 15, 47,185,117,235, 22,163, 84, 42,111, 84, 83,206,250,161,161,161, 71,253,253,253,227, 0, 68,120,176,175, -202,235,185,109,219,182, 6, 12,195, 76, 96, 24, 38,186,146,101, 2,195, 48, 77,255,105, 78,251,245,205, 97, 24,134, 41, 46, 46, -102,212,106, 53,147,153,153,201, 20, 23, 23, 51, 69, 69, 69,204,197,139, 23,153,211,167, 79, 51, 87,174, 92, 97,228,114,121,142, - 59,156, 14, 62,147,201,196,232,116, 58, 38, 55, 55,151, 49, 24, 12,140, 94,175,103,174, 94,189,202, 92,184,112,129,185,126,253, -122, 69,124,143,113,250,249,249,173,205,206,206, 46, 58,117,234, 84,241,154, 53,107,138,131,130,130,174, 3, 8, 3,208,216,215, -215, 55,251,189,247,222, 99,196, 98,241,195, 26,190, 71,205,216,108,246,197,197,139, 23,159,219,183,111, 95,206,158, 61,123, 76, -235,215,175, 79,159, 50,101,202, 9, 22,139,117, 17, 64,179, 26,190, 71, 10,153, 76,118,234,236,217,179,214,130,130, 2, 70,163, -209, 48, 58,157,142,209,235,245,140,193, 96, 96, 76, 38, 19, 99,177, 88,152, 19, 39, 78, 48,129,129,129,174,195,146, 31, 85,209, -177,158,206, 48,204,135, 12,195,176,106,187,174,115,225,238, 86, 91,156,181, 81,215,145, 36,105,182,215, 29, 29, 75, 87,171, 94, -255,167,202,217,187,119,239, 47, 71,140, 24,193,244,235,215,143,137,138,138,122,108,105,211,166, 13, 51,121,242,100,102,223,190, -125,204,215, 95,127,253,101, 45,148,147,133,210, 73, 47, 11,123,247,238,109,137,143,143,103,134, 15, 31,206, 0,232, 91,149, 22, -249, 55, 8, 46, 71,120, 7,194,245, 19, 0,204,102,115,218,205,155, 55,149, 77,172, 86, 10, 0,190,255,254,251,199, 44, 83,174, -136,143,143,183, 18, 4,113,167,170,127, 55,155,205,105,199,142, 29, 11, 92,185,114, 37,219,197, 4, 12,171,213,106,203,204,204, - 36, 87,172, 88, 81,230,248,227,199,143, 91,173, 86,107,170,135, 39,185,161,117,235,214, 27,106,227,106,157,184,246,224,253, 63, - 14,252,238,223,177, 67, 55,141, 84, 46,175,176, 23,182,237,221,166, 32, 38, 85,109,213, 34, 88,228,130,197, 11, 99,100,142, 33, -200, 95,147,178, 53, 37, 70,186, 87,138,202,112,185,182,239,112, 81, 81,209, 3,199, 76, 64,189, 94,159,250, 12, 62,132, 23, 81, - 26,227,202, 90,110, 91, 59, 60,161,211,169,205,102,131,143,143,143,211, 26, 90, 3,139, 40,227,176,176, 58,110,221,147,148,135, - 97,152,147, 87,175, 94, 13, 31, 59,118,172,100,227,198,141,119,105,154,102,143, 31, 63,222, 28, 20, 20,196, 73, 72, 72,176, 0, - 32,122,244,232,193,202,206,206,102, 50, 50, 50,212,175,189,246, 90,225,219,111,191,237,119,233,210, 37,174,205,102,171, 46,104, -225,189,180,180,180,222, 53,216, 87, 37,134, 13, 27,118, 23, 79,158,198,230,169,115, 58,160,214,232,112,247, 65,134, 61,130,185, - 13,244,195, 28,167, 95,149,197, 98,133, 90,151,239,177, 69,235,206,253, 12,123,138, 49, 26, 52,157,105,231, 43,117,136,103, 10, -138,171,111, 77, 88,172,174,115,230,204,233, 79,146, 36,121,230,204, 25,227,146, 37, 75,210,242,242,242, 6, 1, 72, 5,128,130, -130,130,158, 27, 54,108,248,217,141, 80, 14,149, 33,217, 98,177,116,250,232,163,143,166, 2,232, 10,160,174,157, 59,193,110,201, -170,105, 4,243, 92,141, 70,243,114,255,254,253, 15, 83, 20, 85,207,229, 61,242, 7,160,114,188, 23, 12,195, 40,114,114,114, 94, -113,135,144, 32,136,101, 79,171, 34,121,154,220, 79, 88, 15, 61, 23, 51, 25,143, 30, 61, 58,119,208,160, 65,172,176,176,176, 79, -195,194,194,200,130,130, 2, 20, 21, 21,129, 36, 73, 4, 5, 5, 33, 50, 50, 18, 65, 65, 65,182,235,215,175, 47,252,248,227,143, -171,141,201,247,194, 11, 47, 52,176, 88, 44, 13, 73,146,108, 0,160, 1,195, 48, 13, 8,130,104, 0, 64, 14, 0, 82,169, 84, 26, - 30, 30,206,234,216,177, 35, 58,116,232,128,227,199,143, 99,251,246,237, 63, 1,248,195,213,154, 85, 94,139, 60, 11, 72,110, 13, -166,217, 69, 16,215,218,160, 7, 97,195,113,134, 68,207,200, 68,103,156,189,242, 34,171,242,164,210, 21,152,254,250,190,248,226, -139,206, 23,206,141, 70,229, 65,117, 47, 95, 94, 94, 94,223,113,227,198,149,225,164,105,218,152,159,159,255, 78,231,206,157, 87, - 81, 20,197, 43,247,192, 62,204,205,205,253, 91,115,245,149,143,163,213,183,255,235,170, 39,229, 20,115,200,134, 55,247,255,128, -156, 92, 21,126, 77,202, 46, 40, 52,209, 61,111,169,138,175, 62,141,242, 63,124,248,176,223,115,160,248, 43, 18,173, 79,154, 60, - 59,207,141,128,164,213,229,168, 35,236,225, 68,106,229, 37,207,206,206, 94,250,217,103,159,189,188,112,225,194,128,131, 7, 15, - 74, 29, 29,148,193,131, 7,231, 94,189,122,181, 27, 0, 94, 73, 73,201,145,133, 11, 23, 6,196,196,196,248, 1,240, 3,128, 1, - 3, 6,228,228,228,228,172,132, 23, 85,194, 98,177,164, 71,190,208,196,217,241,115, 13,233,224,250,221,106,181,166,123,194, 87, - 17,143,235, 58, 77,211, 85,242, 81, 20,245, 65,135, 14, 29,168, 15, 62,248, 32,231,224,193,131,142, 68,186,174, 10,237,102, 53, - 65, 73,221,129, 17,192, 18,251, 82,155,208,171,213,234, 78, 30,254,134,246, 62,141, 21,118, 40, 61, 89,255, 71,176,123,247,238, -207,135, 15, 31,190, 65, 46,151,111,110,208,160, 65,147,192,192, 64,169, 64, 32,128,209,104, 44, 52,153, 76, 55,110,222,188, 57, -234,243,207, 63,191,231,150,133, 99,195, 6, 10, 0,199,102,179,241, 73,146, 20, 1,144, 18, 4,225,235, 16, 90, 4, 65,192,108, - 54,227,193,131, 7,152, 61,123, 54,125,244,232,209,175, 1,124,233, 65,199,181, 29,128, 0,151,122, 60, 0,128, 9,165, 1,108, -243, 8,130, 56,255,180,175, 23, 97,195,241,102, 23, 65, 36,183, 70, 69,237, 68,213, 73,165, 43,123,225,242,242,242, 58,213,246, - 75, 92, 25,103, 94, 94, 94,216,179,242,134,140, 49, 46,217,138,181, 75,202,228, 57,116,136,176,138,214,171,131,214, 96,157,242, -221, 31,215,150, 26,173,140,205,108,181,253,247, 86, 94,113,178,183, 30,170,117,188, 84, 91,239, 82, 45,150,233,106, 74, 74, 74, -231, 41, 83,166,124, 46, 20, 10,219, 3, 64,113,113,241,153,204,204,204,121,176,207, 42,172,110,191, 23,149, 67,165, 82,181,125, - 22,249, 76, 38,211,251,157, 59,119,254,150,166,233,111,172, 86,107,194,255,131, 91, 81,226,125, 26,159, 95,252,246,219,111,247, - 0,116, 2,128,161, 67,135, 82, 0,176,125,251,118,143,197,243,216,177, 99,105,134, 97,204,246,231, 65,143,210,217,133, 5,142, - 58, 85,175,215, 23,100,102,102, 94,167,105,250, 58,128,159,225,249,140,219, 0,130, 32,246, 49, 12, 51,208, 46,220,246, 49, 12, - 51,208,117,219,211,182,106, 85,115, 72,245,206,240, 94,148, 98,123, 50,136,242, 67,129,213,173, 87,135,155, 57,250, 56, 0,109, -188, 87,247,255, 37,238,102,102,102,142,121,130,253, 94, 60,127, 72, 53,153, 76,131,254, 31,157,175,214,123,203,255, 37,237, 95, - 13, 4,150, 3,215,175, 95,127,106, 46, 2,255, 52,154, 93, 44,219, 1, 47,191,238,130,232,138,132,151, 87,104,121,225,133, 23, - 94,120,241, 36,208,120, 47,129, 23,255,102, 56,124,179, 28,235,149,248,104,149,247,207,114,174, 19,168,124,230,128, 39, 89,201, -107, 50, 75,226,136,151,211,203,233,229,244,114,122, 57,255,113, 78, 25,128,112, 0,139,171, 57,174,252,236,194, 28, 0, 42, 0, - 22,239,245,244,114, 62,129,126,112, 11, 12,195, 12,168,106,232,144, 32,136,253, 79, 75,104, 57,157,225, 91, 99, 78,228, 69,204, -113,172,187, 43,180,158, 54,250,120, 57,189,156, 94, 78, 47,167,151,211,203,233,229,244,114, 62,161,208,234,245,241,199, 31,127, -130,210,208, 24,204,199, 31,127,252, 9,195, 48, 3, 74,119, 49, 3,158,230,127, 95,107,131, 30,201,173,193, 56,150,107,109,208, -163,146, 67,163, 93, 22, 39,188, 67,135, 94,120,225,133, 23, 94,120,225,197,179,142, 83,139, 22, 45, 42, 94,180,104,145,195,241, - 61, 15, 0, 97,183,112,229, 61,205, 63,182, 15, 19,186, 51, 81,170,234, 20, 60,255, 0,130, 73, 22,103, 52,155,195,235, 5,198, - 22, 9, 0, 32,169,107,180,169,228, 47,171,213,188, 25, 64,102, 77,137,155, 2, 47, 52,146, 9,246, 24,105,154,147, 86,104, 26, -154, 82,154,230,192, 99, 12, 5,186,240,184,220, 63,121, 50,153,160,162,253, 70,141,198, 96, 52,153, 94,222, 14,156,244,190, 3, - 94,120,225,133, 23, 94, 60, 39, 16,249,250,250, 30, 37, 73, 50,204,177,193, 53,238, 96,249, 24,132, 52, 77,103,169,213,234,151, - 81, 58, 84,252,119,114,186,254,222,132, 26,182,229,181, 13, 79,135, 14, 89, 64,153, 40,172,127, 75,198,108,138,205,123, 91,226, - 35, 91,240,159,113,239,251, 69, 52,110, 66,132,134,214, 1, 24, 32, 53, 45, 61,240,206,237, 91,189,127,219,248,221, 12,157, 86, - 61,219, 98, 52,254,224, 41,247, 11,128,168,174,152,151,240,195,199,111,202, 88,176, 98,228,252, 45,135,136, 34,115,232,245,210, -233,166, 30,137, 44,153,159,223, 31,139,142, 28, 17,248,182,108, 89,102, 31,195, 48,165,249,245, 46, 95, 22,124,250,242,203,127, - 12, 85,171,251,122,197,214,191, 18, 65, 82,169,116, 26,155,205,238,105, 54,155,195,184, 92,110, 26, 77,211,113, 5, 5, 5,203, - 1,100,120, 47,207,191, 27, 77,130, 68,221,154, 52, 8,219,146,153,157,147,164, 43, 49,141,191,153, 89,164,246, 94, 21,143, 81, - 85,126,205,127, 44,247, 38, 0,136,197,226, 11, 36, 73,134,184,138, 0, 71,206, 94,199,122,249, 79,155,205,118, 79,173, 86,119, -174,130,182,129, 92, 46, 95, 5,160, 93,117, 1,147,237,177,217,206,171,213,234,119, 80,249,108, 61,137,175,175,239, 92,130, 32, -134,145, 36, 73, 85,119, 78, 54,155,141,102, 24,102, 91, 65, 65,193,151, 0, 10, 43, 59,206,215,215,247, 72, 74, 74, 74, 59,133, - 66, 81,173,149,198,106,181, 34, 53, 53, 53,160,125,251,246, 39,212,106,117,211,167,201,249,119,107,145,154,162,138, 89,135,149, - 62,232, 0,202,228, 23,122,170, 17, 89, 57,124,241,158, 78,221,251,246,154, 60,245, 3,209,197,171, 55,240,231,241,211,208,233, -141,160, 72, 18, 50,137, 16,141, 27, 55, 36,150,197,238,240,255,105,205,178,111,206,196, 31, 30, 80,162,215,190,230,145, 76, 23, -178,102,207,122,163,189,200, 79, 78, 3, 54, 26, 31,246,111, 37,250,116, 95,210,108, 20, 91, 63,241, 88,100, 29, 61, 42,204,205, -201, 65, 76,112, 48, 88, 86, 43,248, 36, 9, 62, 65,128, 79,146, 16,241,249,232,183,126, 61,230, 29, 60, 40,252,252,149, 87,188, - 98,235, 95, 6,177, 88, 60, 46, 56, 56,120,201,186,117,235,252,234,215,175, 15,145, 72, 4,181, 90,237,127,243,230,205,214,211, -167, 79, 31,147,149,149,245,153, 78,167, 91,235,189, 82,255, 94,216,108, 24,253,227,130,119,234,100, 61,188, 93,103,226,194,173, -141, 9, 63,186,231,141,124, 67,182,247,202,184,141,214, 0,146, 80,113,254,210,170,246, 85, 10, 62,159,159, 83, 82, 82,162,168, -234, 24, 46,151,155,107, 50,153, 2,171,227, 34, 73, 50, 36, 35, 35, 67, 33, 20, 10, 65,211,180, 61, 27,128,205,217,145,118,205, -126, 98, 15, 84,139,166, 77,155,154,171,226,148, 72, 36,223,231,230,230,246,113,228, 9,116, 17, 84, 21, 34, 35, 35,163, 79,179, -102,205,190, 47, 44, 44,124,185, 18,241, 50,119,234,212,169,211,154, 55,111,238,176, 2,217,179, 32,148,126,170, 84, 42, 76,153, - 50,197,249, 31, 54,155, 13,135, 15, 31,158, 58,110,220, 56, 20, 20, 20, 76,175,226,220,195, 20, 10, 5, 97, 79, 40, 94, 41,230, -204,153,131, 57,115,230,224,187,239,190, 35,216,108,182,172,154,235, 89, 43,156,127,151, 22,169,137, 5,171,154,200,240,251, 81, -214, 55,107,255, 99, 66,235,239, 0,197,230,253,183, 93,231, 62, 61,167, 76,155, 37,218,250,251, 49,220,188,126, 25, 41, 9,191, -148, 57,166,237,203,227,144,173, 42,196,184,201, 31,138, 9,138,213, 51,254,200,238,255, 90,140,134, 31,221,180,102, 5,134,241, -184,239,117,108, 31,201,206, 16,220, 68,144,175, 0, 93,219, 52, 98,135,254,113,229, 61, 61,172,223, 94, 47,157, 37,227,145,200, - 90,247,230,155,232,102,177, 64, 65, 81,160, 8, 2, 20, 0,146, 32, 80, 98, 52,226,252,232,209,104,191,105, 19,190,220,187, 87, - 56,247,213, 87, 61, 18, 91, 34,145,232, 34, 65, 16,190, 69, 69, 69, 3, 80,154, 88,250,121, 64, 51,177, 88,188,159, 97,152, 2, -189, 94,223,250, 25, 42,151, 18,165, 99,244,229,123,199, 28,148,206,168,242, 40,179, 48,143,199,123,123,232,208,161,203, 86,174, - 92, 41,204,201,201, 65,102,102, 38,104,154, 6,159,207, 71, 68, 68, 4,113,228,200, 17,191, 89,179,102, 45,221,191,127, 63,175, -176,176,240, 91, 79, 58, 54,108, 54, 59, 86, 46,151,191, 18, 24, 24, 40,202,205,205, 45,214,104, 52,135,141, 70,227,219,168,121, -218, 20,146,205,102,143, 10, 15, 15,127, 61, 56, 56, 56, 48, 35, 35, 67,149,158,158,190,199,104, 52,254,132, 26, 38,106,118,185, -166, 45, 97,143, 86, 15, 32, 43, 60, 60,252,218,131, 7, 15,114,107,145, 51, 51, 60, 60, 60,185, 6,156, 34, 0,191, 1, 8,174, -230,184, 76, 0,195,225,161, 53,219,121, 97, 25,219,129,249,203,215,141,143, 25,219,149,248,113,122,159,136, 73,223, 29, 57, 77, -114,152,238,215,179, 74,210,188, 26,202, 61,145,101, 79,105, 85, 94, 80, 85,181,175, 74, 24,141,198, 0,179,217, 12,118, 37,201, -226,245,122, 61, 36, 18, 73,128,187,133, 20, 8, 4,248,229,151, 95,192,102,179,193,102,179, 81, 80, 80,128,144,144, 16,231, 58, -135,195,113,126,175, 91,183,110,181,124, 52, 77,183,167, 40, 10, 69, 69, 69,160,105,218,185,104, 52, 26, 48, 12, 3, 30,143, 7, -154, 46, 77,231,228,178,191,125,101,124, 4, 65, 12, 11, 14, 14,198,214,173, 91, 97, 50,153, 30,219, 47,149, 74,113,245,234,163, - 36, 35, 20, 69,161, 67,135, 14, 36, 65, 16,195, 0, 76,175,130,151, 1,128,232,232,104, 80, 20, 5,138,162, 64,146,164,243,187, - 99,161,105, 26,115,230,204, 65,185,212,100,127, 27,231,179,134,106, 34,195,103,161, 18, 31, 45,242, 41,151,203,117,138,103,176, - 80, 36,253,234,157,247, 63, 20,239, 63,113, 5,169,105,169,143,137, 44, 0,184,240,231, 79,200,202,204, 64, 82, 74, 58, 70,253, -247, 93,177, 84, 42,251,170, 92,133, 90,233,180, 81, 31, 9,231,235,143,135,119,229, 23, 89, 50, 81,232, 11, 80, 13,184, 96, 11, -245,152, 53,176, 37, 79, 42,225, 44,113,167,156, 60, 46,247,207, 69, 71,142, 56, 69, 86, 23,163, 17, 60,154,134,149,166,157, 34, -203,100,181,194, 96, 50, 65, 89, 84,132, 59,227,198,129,177, 88,240,217,174, 93, 66, 30,151,251,167, 59,229, 4, 0, 14,135,163, -220,179,103, 79,221, 22, 45, 90, 28,135,251,193, 76,143, 60,229,123, 84, 21,218,180,106,213, 42,110,211,166, 77,117, 57, 28,142, -178, 54, 56,249,124,254, 16,145, 72,148,199,231,243,135,212,176,156, 36,128,249,227,199,143, 79,108,216,176,225, 49,187,176,114, -138,154,134, 13, 27, 30, 25, 63,126,252, 69, 0,115, 42,121,214, 43,226,172, 19, 28, 28,188, 96,229,202,149,194, 91,183,110, 33, - 35, 35, 3, 22,139, 5, 35, 71,142, 4, 77,211, 48, 24, 12, 48,153, 76, 88,188,120,177,200,207,207,111, 54, 74, 19, 5,187,115, -238, 28, 31, 31,159, 91, 27, 55,110, 28,122,255,254,125,241,177, 99,199,136,171, 87,175,138,150, 46, 93, 58,200,207,207,239, 38, - 0, 94, 13,174, 39,169, 84, 42,127,220,189,123,247, 59, 87,175, 94, 13,217,185,115, 39,251,204,153, 51,202, 53,107,214, 76, 80, - 42,149,155, 0, 80, 53,188, 71,173,133, 66, 97,239,153, 51,103,218, 78,157, 58,149,113,234,212,169,140,101,203,150,161, 91,183, -110, 93, 98, 98, 98,162,106,200,217, 70, 34,145,188, 56,115,230, 76, 91,124,124,124,230,217,179,103,211,151, 46, 93, 74,190,248, -226,139, 93, 23, 44, 88,208,210, 67,206,223, 78,157, 58,213, 35, 45, 45,173,126,122,122,122,189,244,244,199,134,205, 2, 0, 0, - 27,138, 73, 68, 65, 84,244,240,244,244,244,240,140,140,140,176,172,172,172,186,217,217,217,161,185,185,185,161,113,113,113, 93, - 1,108,113,135,179, 73,160,232,157,233, 35,251, 20,207,254,111,127,230,147,183, 94, 98,102,141,236,193,188,210,189,197,239, 20, -139, 69,156, 77, 78, 69,136, 15,240,211,148,118, 97,161,254,162,171,145,114,113,227,103,236,221,124,214, 56, 89, 14, 33,165, 86, -171,177,127,255,126,216,173, 87,173, 93, 69,150, 78,167, 67, 86, 86,150, 99, 31,203,157,114, 74,165,210,163,235,214,173, 99, 74, - 74, 74,160,213,106,145,155,155,139,180,180, 52,220,185,115, 7,249,249,249,184,113,227, 6,132, 66,225, 81,119,202, 73, 16, 4, -104,154,118, 10,169,195,135, 15, 99,252,248,241, 80,171,213,206,109, 44, 22,203,249,221,241,155,234, 56, 29,150, 39,154,166,113, -246,236, 89, 76,156, 56, 17,203,150, 45,195,150, 45, 91,176,111,223, 62,168,213,106,167,216,178, 90,173,213,114,170, 84, 42,216, -108,238,245,153, 24,134,129, 86,171,117,251,190,187, 10, 32, 22,139,245,152, 40,114, 44,158, 60, 75, 79,200,249,204,194,141,200, -240,149,247,176, 29, 95,236,166,186,158, 79,171,144, 36,139, 51,106,216,216,169,126,233,185, 58,100,228,104, 65,145,143,218,189, -168, 62, 99,193,162, 72,156,251,163,212,112, 69, 82, 20,180,122, 35, 52, 69,102, 12, 29, 59, 77,254,195,178, 47, 70, 89,205, 37, - 85,198,120,105, 14, 68, 68,138,197,111, 52,107, 86,151,188,206, 75, 65,212, 43, 9,160,109, 0, 19,255, 42, 90, 23, 40,168,166, -127,114,223,208, 23,154, 23, 92, 5,110, 85,105,205,144,201, 4,190, 45, 91, 34, 38, 56, 24,221, 45, 22,112, 24, 6, 47,229,228, -224,242,180,105, 48,238,216, 1, 18, 0,103,200, 16,244, 90,190, 28, 39,130,131, 17,100, 48, 64, 51, 99, 6, 2, 14, 29, 2, 71, - 42, 21, 32,207,189,201, 15, 4, 65,160,103,207,158, 56,114,228,136, 95,191,126,253,254,184,114,229,202, 96,171,213,122,162, 38, -215,214,199,199,231, 2,139,197, 10,169,238, 56,171,213,154,174,213,106, 61, 78, 51,194, 98,177,186,119,232,208, 97,215,206,157, - 59,125,205,102,115,173,244, 66,184, 92,110,191, 65,131, 6,173, 91,189,122,181,116,194,132, 9,235,246,237,219, 87,108, 50,153, - 14,121,242, 72, 1,152,191,118,237,218, 73,209,209,209,178, 9, 19, 38, 48,119,238,220,113,181, 94, 5,116,235,214,173,225,186, -117,235,130,218,181,107, 55,117,226,196,137, 28, 0,159, 85,103,229, 17,139,197,147,215,173, 91,231,175, 82,169, 80, 84, 84,228, -172,100,211,211,211, 33, 16, 8, 64,146, 36, 72,146, 4,155,205,198, 87, 95,125,229, 55,121,242,228,105,106,181,122,154, 27, 86, -178,216, 85,171, 86, 5,188,252,242,203,228,253,251,247, 65,146, 36,248,124, 62,222,124,243, 77,210, 96, 48,248,198,196,196,108, -208,235,245, 35, 60,185,134,108, 54,123, 84,108,108,108,227, 46, 93,186,176, 82, 82, 82,208,169, 83, 39,156, 59,119, 14, 67,134, - 12, 97, 23, 22, 22,214,155, 53,107,214,120,163,209,232,105, 28, 23,165, 80, 40,108,254,215, 95,127,165,133,134,134, 58, 43,150, -122,245,234,209, 3, 6, 12, 80,167,164,164, 52, 57,117,234, 84,126,231,206,157, 61, 73, 88, 94, 71, 40, 20, 54, 61,112,224, 64, - 86, 76, 76, 76,239,181,107,215, 14, 2,128,246,237,219,239,153, 55,111,222, 49,181, 90, 29,121,226,196, 9,117,247,238,221,211, -221,228, 11, 86, 42,149,244,148, 41, 83,196, 85, 29,180,126,253,122, 13, 74, 19, 46,215, 7, 80,101,190,182, 38,225, 65,179,151, - 76, 27, 38, 0,109, 6, 99, 49, 0,230, 98,192, 92, 4,155,169, 24, 4, 71, 0, 88, 12, 8,224,169,241,219,228, 38,210,143,182, -222,189, 78,223, 32, 6,164,168, 10, 15,193,139, 10,171, 26, 0, 81, 4, 65, 36,237,223,191, 31, 29, 58,116,192,254,253,251, 49, - 96,192,128, 36, 87, 49,112,245,234, 85,116,239,222, 29,118,139,150, 91,190, 90, 90,173,246,227, 57,115,230,196,143, 26, 53, 74, - 88,166, 50, 32, 73,200,100, 50,244,239,223,191, 68,175,215,127,236,110, 65,105,154, 6,139,197, 66,122,122, 58,214,175, 95,143, -133, 11, 23, 34, 34, 34, 2, 22,139,229, 49,177,101,175,247,220,170,252,172, 86, 43,206,159, 63,143,205,155, 54,225,179,217,179, - 33,145, 72, 0, 0,102,179, 25,234,130, 2,240,249,124,167, 24,171, 70, 56,109,187,125,251,246,180,144,144,144, 50, 67,134,142, - 79,123,157, 5,155,205, 6,171,213,138,146,146, 18, 44, 91,182,204,202, 48,204,182,234,218, 31,135, 40,154, 54,109, 26,140,198, - 71, 6,245,150,118,159,228,240,240,112,180,106,213,202,185, 78,146, 36,227, 46,231, 15,157,155,195,224,114,116,147, 57, 75, 1, - 0, 33, 33, 33,104,210,164, 9,148, 74,101,165,156, 79, 91,139,212, 4, 30, 68,134,175, 92,104,253, 29,153,178,217, 28,126,175, - 6,141, 26, 19,169, 89,106,176, 88, 44,136,124,252,209,249,245,233,160, 40, 18, 98,153, 63, 8,218,240, 72, 17,147, 20, 88, 20, - 11,234, 66, 3,194,235, 55, 34,121,124, 65, 47,125, 53, 66, 75,234,195, 94, 53,115, 68,103,126,190, 53, 29,130,186,124,208,142, -230, 52,152, 11,210,175, 16, 31,244,139, 16, 68,239,185,178, 10, 90,203,139,238,148,151,178, 90,161,160, 40,152, 25, 6,151,167, - 77, 67, 84,108, 44,146, 28,194, 48, 54, 22, 73,209,209,144,179,217,224,145, 36, 24,139,229,177, 49,125,119,132, 22, 0,164,165, -165, 97,199,142, 29,242, 97,195,134,237,186,122,245,234, 40, 15,197,134,131,203,255,236,217,179,138,250,245,235, 87,122,204,189, -123,247,208,182,109, 91,143,135,167,184, 92,110,191, 23, 95,124,113,235,142, 29, 59,124,146,147,147,161, 80, 40,158, 88,104,241, -120,188,238,125,250,244,217,186,113,227, 70,105, 94, 94, 30, 98, 99, 99,165,175,190,250,234,150,196,196,196,215,141, 70,163, 59, - 98,179,140,200,138,141,141,213,172, 95,191,254, 7,148, 29, 34,204, 90,191,126,253,143,237,218,181,123, 39, 58, 58, 90, 6, 96, -146,221,119,160, 74,177,197,227,241,122, 54,104,208,160, 76,175,150,199, 43, 53, 54,137, 68, 34,248,248,248,128,195,225,192,104, - 52, 34, 42, 42,138,224,114,185, 93,221, 57,103,137, 68,210,231,141, 55,222, 32, 19, 18, 18,144,157,157, 13,153, 76, 6,177, 88, - 12,154,166, 49, 97,194, 4,106,217,178,101, 61,245,122,207, 70,184, 66, 67, 67, 7,245,238,221,155,117,237,218, 53,220,191,127, - 31, 70,163, 17, 55,111,222,132, 84, 42,197, 91,111,189,197, 89,178,100,201,171, 25, 25, 25,158, 10,173,230,209,209,209, 57,174, - 34,203, 1,145, 72, 68, 52,110,220, 88,237,231,231,215, 6,128, 39, 66,171,249,187,239,190,155,187,104,209,162,238, 71,142, 28, -113, 6,189, 60,114,228,200, 44, 0,248,246,219,111,227, 3, 2, 2,218, 0,112, 87,104,129, 97, 24,219,127,254,243,159,135, 92, - 46, 23,108, 54, 27, 92, 46,183,204,194,225,112, 64,146,164,196,241, 58, 87,199,119,253,126,246,226, 9,179,150, 46, 21,241, 41, -246,251,175,183, 64, 93, 25, 7, 16,200,193,233,254, 17, 8, 89,169,209,146, 81,223, 3,254,252, 8,223,188,161, 38,163,127, 46, -249,221, 76,251, 6,220, 45, 40, 40,252,135,219,128,118, 0,254,135,210,228,186,179, 1,156,125, 70,218,166,139, 0,162, 6, 12, - 24,224, 20, 91, 7, 15, 30, 68,191,126,253,160,209,104,112,237,218, 53, 87,145,229, 73,130,229,139, 22,139,229,210, 47,191,252, -210,121,216,176, 97,132,203,251,133,228,228,100,220,184,113, 35,201, 93, 62,146, 36, 97,179,217,192,102,179,177,116,233, 82,152, -205,102,252,252,243,207,216,190,125, 59, 72,146, 4, 65, 16, 32, 8, 2, 82,169, 20,223,125,247,157, 71,245, 30, 77,211,216,176, - 97, 3, 62,154, 53,203, 41,178,236, 35, 25, 8, 10, 12,132,159,191, 63,238,222,189, 91,173,208, 42, 40, 40,248,114,239,222,189, -168,202, 25,126,239,222,189,206,239,229,156,225,171,111,231, 40, 10, 70,163, 17, 47,189,244, 40, 85,236,187,239,190,235,252,174, - 86,171, 65, 81,148,227, 90, 16,238,114, 26, 24,224,117,254,163,109,253, 63,248,160,140,133,174, 50,206,191, 67,139,212,150,117, -171, 2,177, 21,101,183,206, 42, 1, 12, 64,169,143, 86, 22,240, 55,250,104, 49,140,173,105, 72,157, 96, 92,186,115, 21, 44,138, - 2,215,199, 31, 62,242, 64,216,172, 38,104,115,239,227,248,206,239, 1, 0,107, 55,108, 3, 73,146, 96,177, 40, 24, 77, 52, 34, -234, 6,195,102,179, 53,173,138,251, 5,160,115,207, 64,255, 14,161, 97, 50,226,154,239,125, 52, 86,248,149, 27, 8,225, 33, 34, - 83, 76,116, 18, 11,218, 23,104,117,157,175, 3,167,170, 21, 3, 36, 9,146, 32, 32,228,112, 96,220,177,163,212,107, 51,182,180, -205, 74,138,142, 6,249,251,239,144,240,120,160, 8, 2, 44,187, 9,186, 38,208,233,116, 32, 8, 2,155, 55,111,246,125,235,173, -183,182, 92,187,118, 45,186,164,164,100,135, 39, 28, 26,141,102, 64,151, 46, 93,142,109,216,176, 33, 32, 40, 40,232,177,253,217, -217,217, 24, 59,118,108,158, 70,163,241, 40,168, 27,159,207, 31, 50,104,208,160,117, 63,253,244,147,244,246,237,219, 40, 42, 42, - 66, 64, 64,192,147, 62, 10,109, 58,118,236,184,107,199,142, 29, 62,217,217,217,208,106,181, 48, 26,141,216,188,121,179,172,127, -255,254, 59, 82, 82, 82,250, 1, 72,172,134,227,115, 87,145, 53,113,226,196, 43, 0, 20, 0, 86,149,215,160,246,125, 45, 92,196, -150, 22,192,146, 42,122,162, 97, 34,145, 8,185,185,185, 24, 59,118, 44,110,221,122,100, 0, 13, 14, 14,118,246,244,238,222,189, -139,128,128, 0, 16, 4,161,112,231,164, 3, 2, 2,196, 38,147, 9,227,199,143, 71, 90, 90, 90, 25,206,244,244,116, 16, 4, 33, -244,244, 66, 6, 6, 6, 6, 26, 12, 6,116,235,214, 13, 37, 37,165,121,125,135, 15, 31, 14, 54,155,141,220,220, 92,176,217,108, -255, 26,220, 31,255, 1, 3, 6, 84, 26, 90, 69, 42,149,154,125,125,125, 95,240,144,211,239,213, 87, 95,205,136,141,141,125,108, - 98,203,185,115,231, 94,147,203,229, 71,228,114,121, 99, 15, 57,109,174,162,138,195,225,148, 17, 90,108, 54, 27, 36, 73,186,237, -163,118, 43, 87,191,146, 69,100,181, 90, 52,229,229,177,117, 21, 62, 96,138,114,192,121,241, 75, 92,202, 19, 96,233,178, 3, 0, -128, 15,223,108,139,150,125,230,195,244,211,203,152,214,137,226,142, 78, 55,206, 4,240,249, 63, 92,231,127, 13,192, 49, 11,110, - 53,128, 86,207, 80,123,228, 20, 91, 7, 15, 30, 68,100,100, 36, 10, 10, 10,144,146,146, 82, 83,145,229,168,239, 62,154, 59,119, -238,159,131, 7, 15, 22, 57, 58,173, 2,129, 0, 51,102,204, 48, 20, 21, 21,125,228,209, 67,100,179,129,197, 98, 57, 59,201,124, - 62, 31, 81, 81, 81, 78,145, 69, 16, 4,138,139,139,193, 98,177, 28, 51, 18, 9, 55,203, 8,101, 80, 16, 36, 18, 9, 26, 69, 68, -224,182,189, 30,113,124,231,241,120, 32, 8, 2, 86,107,181,134,188, 66,187, 83,251,244,218,110,146, 29,162,168, 74,211,113,112, - 48,108, 54,155, 67,100, 50,181,193,233,239,239,143,162,162, 34,119, 57,159, 73, 84, 98,209,114, 8,173, 1, 40,245,213,122, 44, -188, 67, 15, 0,199,241, 20,167, 84, 18, 96, 8, 27,195,128, 69,145,246,177, 91, 10, 20, 69, 66,157,151,133,229, 95, 78,178,139, -172,237,216, 31,159,130,144, 6,145,143,198,113, 9, 2, 96,170,126,184, 3,124, 56,177,147, 7,119, 20,228, 16, 89,144, 5, 11, -193,231,151,211,143,190, 28, 16,225, 36,166,244, 12, 17,158,223, 91, 18,123, 93,107,174,182,161,224,147,100,169,243, 59, 65, 84, -232,220, 67,218,247, 81, 4, 1,134, 97,192,216, 60,243, 59,118, 8,121,129, 64, 0,179,217, 12,138,162,176, 98,197, 10, 89,159, - 62,125, 86,121, 42,180, 0, 36,231,228,228,244,159, 48, 97,194,193,109,219,182,249,251,251,251,151,233, 61, 76,152, 48, 65,149, -147,147,211, 31, 30, 58,221,179,217,236, 85,171, 87,175,150, 62,120,240, 0,197,197,197, 16, 8, 4,206,202,167,166,207,103,251, -246,237,255, 56,116,232,144,175, 86,171,133,217,108,134, 64, 32, 0,195, 48,160, 40, 10,191,254,250,171,223,192,129, 3, 15,164, -166,166,190, 88, 85, 89, 5, 2,193,235,118,225,132,232,232,104, 89,116,116,116, 15,160,210, 72,189, 78, 68, 71, 71,203,166, 79, -159,254,170,193, 96, 88, 82,197, 57,167,169,213,234, 32,129, 64,128,157, 59,119, 66, 44, 22, 67, 40, 20, 34, 56, 56, 24,106,181, - 26, 66,161, 16, 12,195,192, 98,177, 56, 42,139,124,119, 78, 60, 47, 47,175,200,106,181,250, 28, 60,120, 16,249,249,143,126, 82, -183,110, 93,104, 52, 26,216,108,182, 98, 79, 47,102,102,102,102, 14, 65, 16,161,151, 46, 93,194,131, 7, 15,208,175, 95, 63,252, -254,251,239,104,219,182,116,116,216,100, 50,213, 36,136, 31, 77, 81, 20, 83,197,115, 75, 0,240,173, 77, 78,123,227,229, 17,167, -205,102,179, 57, 68,150,235,167,171,248,170,230, 63,203,188,206, 47, 4,138,215, 47,154,220,123,236,203,145,254, 48,228,221, 7, - 95,226, 15, 66, 22,142,165,203, 14,224,218,189,210,251,181,116,203, 5,108,141,233, 15, 8,228,104,226,163, 66,144,132,245,198, -141,220,127, 92,104,249,184,246, 19,158,213,134,169, 95,191,126, 80,171,213, 16,139,197,181,225,159,115,218, 96, 48,220,220,189, -123,119,155, 1, 3, 6,128,203,229,226,230,205,155, 72, 76, 76, 76, 1,112,218, 83,161,197,102,179, 49,119,238, 92, 76,154, 52, - 9,129,129,129,248,232,163,143,192, 98,177,156, 11, 65, 16, 78, 11,151, 39, 80, 4, 86, 61,241,209,225, 16, 95,157, 49,220,199, -199,103, 46, 73,146,195, 40, 55, 46, 28, 77,211,180,205,102,219,166,213,106,171, 12,239,224,112, 92,119,231, 94,184, 94,131,106, -218,180, 39,230,252, 59,180, 72, 77, 80,126,182, 97, 37, 22, 45,199,172,195,199, 82, 1, 57,206,242,184,221,100,119,252,105, 21, -148, 32,169, 27,233, 25,153,240,243, 21,219, 69,150,125, 33, 73,180,140, 44,237,204,238,143, 79, 65, 72,253, 72,176, 40, 10, 44, -138,130, 88,192, 67, 78,118, 22, 88, 44,242, 70,101,188,205, 41, 12, 30,220, 56, 52,220,215,143, 13, 85,128, 9,202,192, 74, 12, - 3,109, 36, 8, 81,114,209,215,143, 31,214,156,194,224,170,173,111,140, 83,104,153,173, 86,112,134, 12,113, 14, 23, 38, 69, 71, - 35, 42, 54, 22,244,160, 65,208,155,205,101, 76,197, 53, 21, 90, 2,129, 0,133,133,133, 24, 53,106,148,218, 98,177,188, 83,195, - 75,156,152,159,159, 63,116,244,232,209,249, 14, 1, 99, 54,155, 49,122,244,232,252,252,252,252,161,110, 88,137, 30,131,197, 98, -121,167,109,219,182,106,149, 74,229, 44,103, 77, 42, 28, 7,228,114,249,254,245,235,215,203,141, 70, 35,172, 86,171,147, 83, 32, - 16,128,162, 40, 4, 4, 4, 96,235,214,173, 1,114,185,188,202,156, 85, 6,131, 97,119,108,108,172, 6, 0, 98, 99, 99, 53, 4, - 65,196, 17, 4,177,134, 32,136,213,229,150, 53, 4, 65,196,185, 30,107, 48, 24,118, 85,197,109, 50,153,226, 82, 82, 82, 24,161, - 80, 8,138,162, 96, 54,155,193,231,243,157, 38,113,157, 78, 7,131,161,116,152, 59, 49, 49, 17, 22,139, 37,193,157,115, 47, 44, - 44, 60,186, 97,195, 6, 91,221,186,117, 17, 25, 25,137,168,168, 40,116,236,216, 17, 97, 97, 97,152, 55,111, 30,173,215,235, 61, -126,247, 50, 51, 51,247,255,246,219,111,150,208,208, 80,180,105,211, 6, 60, 30, 15, 45, 91,182, 68,112,112, 48, 22, 46, 92,104, -210,106,181, 7,107,112,155, 82,175, 94,189, 74, 85, 33,114,165,112, 99,246,110, 57,164,157, 63,127,158,234,216,177,227,158,242, - 59,218,183,111,191, 71, 44, 22,251, 56, 76,236,158,244,200, 93,197, 21,143,199,115, 46,142,237, 44, 22,203,157,222, 15,249, 66, -160,120,253, 87,147,122,141,125, 57,210, 23,123,142,158, 5,199,172, 1, 76, 85,140, 8,210, 22, 16, 28, 17, 2,125,216, 33,207, - 64, 27, 48, 13,192, 21,148,198, 97,250, 8,207, 22,156,142,239,249,249,249, 72, 73, 73, 65, 98, 98, 34, 58,118,236,136,132,132, - 4,224,145,131,188,199,208,106,181, 31,197,196,196,232, 29, 51,249,102,207,158,109, 40, 44, 44,252,200,211, 58,152, 97, 24,176, -217,108, 52,105,210, 4,211,167, 79,199,129, 3, 7,112,243,230, 77, 88, 44, 22,167, 16,114,248,100,122, 98,209,226,112, 56, 8, - 12, 12,132,197, 98,113, 90,179, 0,224,246,173, 91, 96,177, 88,176,217,108, 48,153, 76,213, 90,180,124,124,124,230,174, 91,183, -110,170, 74,165, 82,230,229,229, 41, 92,151,156,156, 28, 69, 86, 86,150, 34, 35, 35, 67,145,150,150,166,120,248,240,161,226,254, -253,251,202,197,139, 23, 79,245,241,241,153,235, 78, 57, 41,138, 66,203,150, 45,241,238,187,239, 58,151,149, 43, 87, 58,151,227, -199,143,123,236,188, 78, 81, 20,154,204, 89,138,254,121,140,115, 57, 16, 64, 56,151,107, 31, 78,172,138,243,169,107,145, 26,233, - 23,251,108, 67,215,196,210, 21,192, 49,235,208, 81,151, 57,221, 54,202, 59,195, 63, 53, 88, 77, 37,199,238,221,185,213,171, 73, -243,118,100,182,170,168,204,244,207,168,158, 67, 65, 16, 4,234,212,143, 4,197, 98,129,162, 72,176, 40, 10, 50, 41, 31, 41,151, - 46,217,140, 6,195,177,138, 56,123, 0, 44,174,128,187,242,205,190, 45,249,153,220, 92, 4, 40, 69,224,176, 75,181, 35,115,111, -104,185, 22,130, 5, 52,151, 96, 92,134,159,224, 88, 78,201, 74, 95,189,121, 79, 92, 37, 61, 64,155,205, 6, 49,143,135, 18,163, - 17, 6,171, 21, 61,151, 47,119, 14, 23,146, 4,129,139, 0, 90, 44, 95,142, 83, 59,118, 64,202,229, 2, 60,158,219,179, 66, 42, - 18, 90, 42,149, 10, 99,198,140,201,207,202,202,122,171, 38, 62, 90, 14, 24,141,198, 19,217,217,217,111, 13, 29, 58,116,243,206, -157, 59,229, 67,135, 14, 85,103,103,103,191,229,166,223,211, 99, 40, 41, 41,217,145,150,150, 86, 60,102,204,152, 77, 91,182,108, -241,243,247,247,119,246, 68,106,244,176, 18,132,170,119,239,222, 60,119,142,171,230,144, 24,187,115,251, 36,187,101,171,197,196, -137, 19, 79,161,212,255,202, 21,115,214,174, 93, 59,220,101,136,113, 13,128,229, 85, 17,235,116,186,213,211,167, 79,255,239,137, - 19, 39,252,249,124, 62, 8,130, 0,135,195, 65,163, 70,141,156,179,104,216,108, 54, 24,134,193, 7, 31,124,160,202,205,205,253, -214,205,123, 51, 49, 38, 38,166,123, 73, 73,137,239,152, 49, 99, 40, 62,159,143,156,156, 28, 44, 91,182,140,254,233,167,159, 52, -122,189,126,108, 13,132,240,134, 47,190,248,162,103, 81, 81, 81,253, 9, 19, 38,112,180, 90, 45, 12, 6, 3,102,206,156,105,250, -241,199, 31,211, 13, 6,131,199, 1,127, 59,117,234,116,231,225,195,135, 93,139,139,139, 11,132, 66, 97,121,107, 31, 33, 18,137, -218, 1,216,228, 9,103, 84, 84,212,221,212,212,212,142,243,231,207,143,179, 88, 44,236,115,231,206, 57,157,225, 87,172, 88,113, -156,207,231,247,134,135,201, 87, 9,130,176,241,120,188, 50, 22,172,242,223, 89, 44, 86,181,117, 90,211, 32,225,252,175,222,238, - 62,246,165, 23,124,176,251,232, 5,196,236,186,119, 35, 98,108, 64,147,134,190,121,176,229,165,224,195, 55,219, 98,233,150, 11, - 0, 74,135, 14,109,185,215,192, 20,220, 5, 35, 9,197,125,181, 42,243, 25,104, 3,142,163, 52,100,198,179,134, 50, 34,235,218, -181,107,232,213,171, 23, 0, 32, 33, 33, 1, 93,186,116, 65, 66, 66, 2,186,118,237,234,113, 44, 45, 59,254,210,233,116, 15,143, - 31, 63,222, 44, 52, 52, 20,167, 79,159,190, 15,224, 47, 79, 11,233, 16, 90, 44, 22, 11, 35, 71,142, 68,159, 62,125, 80,183,110, -221, 50,179, 13, 29,223, 61, 17, 27, 86,171, 21,205,155, 55,135,209,100, 2,135,195,113, 14, 77,178, 88, 44, 4, 40, 20,184,115, -231,142, 91, 22, 45,146, 36,135,189,254,250,235,100,114,114, 50, 70,140, 24,129,205,155, 55, 87,122,236,232,209,163,241,203, 47, -191,224,245,215, 95, 39, 63,249,228,147, 42,195, 59, 56,156,208,221, 57, 39, 71, 59, 93, 93,189, 95, 91,156, 79, 91,139, 60, 9, - 92, 66, 59, 84, 56,104, 82,193,182,216, 50, 66,203, 37, 72,216,211, 17, 90, 86,243,230,223,127,254,126,122,199, 85, 93, 3,148, - 10, 31,168,181, 6,167,216, 74, 58,190, 29, 0, 48,120,226, 2,176,168,210, 33, 69,169,152, 15, 1,135,194,142,141,223,170,204, -230,146, 10,159,174, 66, 54, 57,233,147,206,141,124,184, 34, 11,116, 65, 12, 34, 3, 30,101,202, 33,234,111,127, 92,112,181,246, -133,255,181, 2,188,217, 80, 44,253, 54, 89, 51, 9, 22,219,202,199, 26, 68,141,198,160,185,116, 73,208,111,221, 58,156,123,235, - 45,212,161,105,196, 5, 7, 67,206,102,195,135,199, 3, 73, 16, 48,236,219,135, 83, 59,119, 34,144,199, 3, 36, 18, 88,231,205, -131, 49, 37, 5,150,194, 66, 67, 13,122,102, 24, 62,124,184, 74,165, 82, 13, 53,153, 76, 39,158,244, 58, 27, 12,134, 67,105,105, -105,147, 58,117,234,180,202, 98,177,188, 99, 48, 24,158,104,102,148,201,100, 58,148,157,157, 61,100,248,240,225,219,119,237,218, -229, 47,147,201,106,204,149,159,159,223,182,150, 30, 39, 27,128,207,236,206,237,147,162,163,163,101,231,207,159,255,239,250,245, -235, 87,185,244, 38, 20,227,199,143,127,187,156,200,170,118,214, 33,128,212,220,220,220,121, 51,102,204, 88,240,205, 55,223,136, - 29,142,239,151, 47, 95,134,213,106, 5,155,205, 6, 77,211, 24, 63,126,124, 81,126,126,254, 82, 84, 30,209,249,177, 71, 75,167, -211, 53,154, 63,127,254,250,229,203,151,247,161, 40, 74, 68,211,180,190,184,184, 56,174,164,164,100, 44,106, 22, 71,203,150,151, -151, 55,230,243,207, 63, 31,179,108,217,178,215, 73,146, 84, 88,173, 86, 85, 97, 97,225, 94,131,193,240, 35,106, 48,148,116,250, -244,233,188, 55,223,124,243, 94, 94, 94, 94,211,144,144, 16,173, 88, 44, 54,153, 76, 38, 74, 32, 16, 72, 69, 34, 81, 20,128,211, - 4, 65, 92,247,132, 51, 41, 41, 41,123,194,132, 9, 15,140, 70, 99,147, 53,107,214,196, 75,165,210,163, 4, 65, 16, 28, 14,199, - 87, 32, 16,244, 2, 16, 71, 16,196,109, 79, 56, 73,146,180,185, 90,175,202,251,103,113,185, 92,183,124,180,234, 7, 8,199,245, -105,196,194,238, 99, 23, 16,179, 59,117, 3,205, 48, 59,119, 38, 21,236,251,168, 11, 96,222,246, 38, 90, 14,221, 84, 58, 92, 8, -192,150,123, 13,230,109,163, 65, 8,253, 17,159,193,134,214, 96,222, 15, 47, 42,130, 51,188,131, 74,165, 66,114,114,178, 67,100, - 69, 1, 64,215,174, 93,147, 28, 98, 43, 49, 49, 17,109,218,180, 73, 2,192,246,244,121,213,233,116, 51, 70,141, 26,117,200,222, - 57,158, 81,131,142,159, 83,104, 57, 4, 85,221,186,117,157,235,174,139,139,143,150, 91,160,105, 26, 28, 14, 7, 44, 22, 11,202, -224, 96,231,127, 49, 12,131, 59,119,238, 64,173, 86,187, 37,180, 40,138,162, 8,130,192,136, 17,238, 77, 72,254,207,127,254,131, -184,184, 56, 80,110,170, 66,138,162, 16, 30, 30, 94,237, 49, 14, 93,234, 46,103, 72, 72, 72,141, 57,159,182, 22,169,169,192,170, -232,123, 69,162,170,178, 23,226,239, 66,102, 81,145,246,179,141,235, 86,124, 51,126,242, 7,226,107,119,115,160, 45, 50,130,162, - 72,215,202, 19, 44, 22, 5,169,136,143,208, 32, 31,108,249,225,127,133,133, 58,205,231,168, 36,239, 97, 93, 9,103, 98,239,118, - 13,121, 28,165, 30, 77, 90, 12, 7,197,127, 36, 2,152,236, 74, 70, 7,187,252,137, 87, 82,245,252,223, 83,245, 19, 47, 22,152, - 30, 23, 90, 38,211,203,179,251,246,253, 35,230,192, 1, 97,251, 13, 27,112,119,252,120, 4, 27, 12,224,217,135, 18, 73,130,128, -152,195,129,152,195, 41, 21, 89,203,150,193, 96,181, 98,249, 91,111, 21, 27, 77,166,190,158,188,228,249,249,249, 24, 52,104, 80, - 94,102,102,102,127,212, 96,104,175, 50,232,245,250, 29, 0,118,212, 22,159,209,104, 60,145,158,158,254,202,160, 65,131, 14, 28, - 58,116, 40,224, 25, 9, 50,231, 16, 91,230,243,231,207,191, 29, 31, 31,127, 23,101, 19,139,106,226,227,227,239, 78,152, 48,129, - 88,191,126,253,143, 0,190,128,155, 1, 60,245,122,253,138,195,135, 15,163,123,247,238, 95, 44, 90,180,200,175,109,219,182, 80, - 40, 20, 40, 44, 44, 68, 98, 98, 34,166, 77,155,166,214,233,116,139, 52, 26,205, 55, 30,150,217,108, 52, 26, 71,187, 78,165,174, -141,235, 96, 52, 26,127,202,202,202,250,169,182, 8,167, 76,153,114,249,206,157, 59,249, 1, 1, 1, 29, 56, 28, 78, 11,148,250, - 1,101, 3,248,209, 83, 65,228,192,228,201,147, 47,221,185,115, 71, 85,167, 78,157,142,118, 78, 25, 74,211, 24,173,171, 1,103, -230,133, 11, 23, 66,218,181,107, 71,178,217,108,134,162, 40,176,217,108,134,197, 98, 49,118,191, 26, 6, 0,246,238,221,203, 3, - 80,101,218,156,187,185,134,249,163,255,119,242,147,235,217, 37, 59, 83,114,138,167, 3, 96,182, 93, 19,254,217, 50,128,122,249, -229,198,233, 48,198,118, 5, 33, 45, 13, 84,201, 20,101,129, 16, 5, 34,221, 86, 7,115,246,220,200,182,130, 88,226,213, 84, 21, -247,171, 97, 15,239,144,149,149,229, 42,178, 28, 86,171,168,174, 93,187, 38,217, 69,150, 99, 95, 77,252,203,142,216,108,182, 39, -106,195, 24,134, 65, 76, 76, 12,214,174, 93,139,234, 34,154,219,103,247, 17,213,241, 57, 44, 90, 52, 77,195,108, 54,227,218,181, -107,206,152, 93,142,225, 66, 71,104, 7,171,213, 90,229,108,117,154,166,105,147,201,132, 95,127,253,213, 45,177,181,117,235, 86, -148,148,148,128,174, 70,193,185,134, 98,104,213,170, 21,212,106,181,115,178, 79, 84,212,163, 80,121,102,179,217, 35,225,234,224, -108,210,164, 9, 84, 42, 21, 28,254,194,161,111, 61, 50,246, 88,245,250,127,235,115, 95,169, 69,235,111,111, 49,121, 66,233,161, -182,157,251,116,121,235,237,105,162, 34, 35,141, 7, 15, 30, 34, 47, 55, 11, 36, 65, 66, 89, 39, 4, 97, 97,225, 16,112, 73,108, -142,253, 70,159,116,234,232,201,162,194,130,126,149,113, 13,240,225,156, 90, 54,164, 75,199, 6, 13, 36, 4,172, 22,128,182, 0, - 86, 11, 96,179,127, 58,182,217,202, 62,115,201,201, 26,230,147,139,234, 51,251,181,230, 10,115, 86, 13, 5,186,200,228,242, 63, -230,236,221, 43,180,153,205,200,159, 49, 3, 66,171, 21,124,123,175,164,244, 68,120,176,206,155, 87, 42,178, 70,143, 46,214,106, - 52, 30,165,224,241,247,247,191, 64, 16,132,127, 94, 94,222,115, 21, 25, 62, 32, 32, 96, 63,195, 48, 42,149, 74,213,246, 25, 42, -151, 2,128, 6,128,185,130,142, 68, 0, 60,247,255,113, 32, 60, 32, 32,224, 19,146, 36, 59, 49, 12,227, 71,146,100,129,205,102, - 59,157,155,155,187, 24,192, 29,111,123,250,143,193, 17, 25,190, 94, 53,199,229, 2,120, 31,165, 78,193, 15,220, 37,111,233,227, -227, 99,228, 90,118,189, 22,201,235, 57, 44,202, 7,245,131, 36, 96,115,248,200,212, 89,113,228,186, 14,235,142,103,167, 25, 44, -244,192, 91,121,197, 87,189,183,162, 74,212,122, 10,158,218,132, 92, 46, 63,251,199, 31,127,180,173, 95,191, 62,233,234,240,238, -136,149,231, 24,222, 98,177, 74,181,220,137, 19, 39,172, 35, 70,140, 56,157,147,147,211,189, 50, 78,137, 68,242,231,149, 43, 87, - 94,210,106,181,143, 9, 42,215, 72,241,142,117,189, 94,143,201,147, 39, 31,174, 44, 5,143,143,143,207,178,111,190,249,102,234, -224,193,131, 73, 71, 56,138,255,107,239,124, 94,155, 8,162, 56,254,221,164,219,212,180, 77,193, 4,148, 84,193,104,192, 20,193, - 67, 17,188,120,216,160, 69, 60,139,246, 34,245,230,165,254, 9, 66,227,127, 96,132,122,232,205,226,201, 67,207, 22, 20,189,122, -240,100,109,107, 69,186,136,105, 66, 80,168,177,166,205,207,245,224, 46,172,211,221,184,211,125,179,217,141,251, 96,161, 61,244, -211,239,204,123,143,188,125,147,153, 49, 63,198,117, 65,198,211,108, 54,177,188,188,220, 45, 22,139,143,119,119,119,109,151, 14, -211,233,244,151, 82,169,116,218, 56,106,193,201,161,162,153, 76,102, 71, 85,213, 73, 47,153, 1, 46,184,254,234,110,245,165, 53, - 33,199,227,243,137,241,227, 11, 55,239,220, 79,101,178,231,165,147,233, 83,144, 16, 65,165,252, 21,234,231,143,218,202,179,197, -111,123, 63,190, 63,172,215,247, 22,123,113, 46, 0,217,179, 19,195,207, 99, 29,228, 96, 20, 64,204,253, 84,135,222, 56, 0, 52, -229,200,198,118,173, 53,251,161,199,178,143, 81,108, 61, 88, 89, 25,141,229,114,135, 14,138,235,118,187, 56, 88, 95,199,163,185, - 57,238, 34, 43,180,208, 66, 35,177,115,248,247, 25, 89, 45,252, 57,159,139,183, 99, 34, 77,157, 24,155,213,128,219, 17,116, 47, - 70, 36, 41,214,214,176, 9, 13,171,163, 67,191,158,188,219, 65, 61,156,126, 71,230,219, 75,165, 1,140, 37,147,201,151,209,104, -244,140,209,145, 49,119,235, 45, 46,148,222,174, 84, 42,215, 0,244,218, 33,156, 77, 36, 18,139,157, 78,231,178,147, 75,165,163, -209,232,219, 90,173, 54,143, 30,151, 74,139,216,117,152, 74,165, 62,169,170,154, 53,118, 81,155, 63, 43,173,118,150,111,109,109, - 65, 81, 20,181, 92, 46,103,188,100,250,213,108,118, 29,250,167,163,101,178,201,225,145,241,187,177,248,177,171,221, 86,123, 10, - 18, 48, 36,203, 27,141,253,250,171,131,250,207,167,176, 89, 46,244,210,110, 1, 87, 70, 98,177,213,225,137,137,184, 85,209,214, -170,213,234, 7,141,198,245,176,200, 10, 45,180,208, 66, 11, 45, 64,150, 75, 38,147, 47,100, 89, 30, 49, 23,147,236,207,134,181, -219,237,253,106,181,122, 3,192,166,199,204,255,211, 56,191,164, 54,227,148,169, 63,138,223,153, 2,199,174, 17, 50, 21,157, 89, - 8,136, 78,197,175, 76, 99,188, 28,220, 25,158, 56,162,154, 79,147, 78,141, 90,167, 40, 38, 85, 30, 89,232,212, 4,248,189, 16, - 16,157,138,223,152,108,252, 56,228,114, 49, 29,198, 20,175, 78,141, 90,167, 40,166,219, 60,234,161, 83,115, 27, 75, 54,190, 47, - 32,128,182, 54, 13,109,109, 26,218,251, 75,150,231, 54,222,179,251, 59,174, 47, 18,138,218, 9, 96, 28,187,175,243, 37,191, 50, -205,243, 64,121, 85,128,128,107, 7, 94, 83, 51,153,249,164,178,130,190,195,228, 13, 28, 28, 56,202, 51,118, 10,191, 51, 99, 37, -225, 30,161,200,226, 98, 82,197,189,104, 38, 85, 46,177, 76,138,184,183,242,187, 64, 31, 81,233, 36,201, 37, 17, 49,111, 17, 63, -174,185, 44,147, 34,151, 88, 38, 69,220,123,193,164,200, 37, 43, 38, 69,220,219,249, 62,168,141, 38, 99,185, 80, 63,226, 65,114, - 80,108, 45, 1, 64,228, 40,147, 38,176, 83,150,167,102, 82,107, 22, 81,108,114,116, 96,250,206, 36,246, 81, 65,103, 82,190,221, -228,169,124, 36, 34,222,205, 76, 42, 62,203,161,240,147, 21,211,173, 94, 27,157,228, 99,119, 27,247, 94, 49,137,125, 68,146, 75, - 12, 51, 79,252, 50,144, 55,253, 94,160,100, 82,229,146,133, 78,215,126,178, 98,186,213,107,163,147,124,236, 20,159, 33,162,184, -253,236,104,105, 17,219,152, 88, 98, 30, 79, 10,141,190, 45,201,113,178, 7,138,201,185, 60, 51, 35,192,247,125,213, 73,201,100, - 53, 82, 46,247,136,212, 73,201,228,208, 58,112,204,160,249,221,143,243,105,199,115,179, 44,101,215, 29, 21,161,147,146,233,144, - 61, 16, 76, 23,190, 31, 56, 27,242,139, 16, 99,226,137,223, 76, 64,220,129, 17, 54,110, 98,157,121, 17, 29, 66, 1, 70,174, 83, -127, 83, 94, 16, 48,246,160,204,105,152, 75, 97, 46,249, 46,151,152,152,204, 19,118,138, 72, 59,207, 44,147,226,127,152, 25, 84, - 49, 42,122,236,148,185, 36,194,247, 65,179,223,196,219, 78,253, 18,230,201,232, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +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, 9, 8, 18, 45, 9, 58,221, +153,135, 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, 67, 81,148,135,213,106,101,245,122,253, 3,163,209,120,218,106,181,158, 6,112,173, 58,137,245,242,242,106, 53, +110,220, 56, 81, 81, 81, 17,132, 66, 33,172, 86, 43,114,115,115,209,169, 83, 39,193,161, 67,135, 90,212,228, 6, 20, 22, 22, 46, +255,230,155,111,206,238,220,185,179,143, 82,169,124, 73, 42,149, 6, 3, 96,180, 90,109,142, 94,175,255,163, 38,233, 44,211,206, + 49, 76,206,181,107,215, 34,148, 74, 37, 30, 62,124, 8,134, 97,114, 30,183, 14,200,196,228,163,155,231, 15,213,109,230,223, 0, + 23, 47, 95,133, 76, 76, 62,226, 67,125, 61,247,176,251, 80,193, 81, 64,185, 16, 72,151,227,226,226,228,139, 22, 45, 66, 92, 92, +220, 45, 87, 22, 45,187,224,138,139,139,187,101, 63,206,225,248,243,143,145,198,138, 45, 90, 21, 41, 72,160,100,118,161, 90,173, +246, 81,169, 84,165, 2, 43, 51, 51, 19,153,153,153,144, 72, 36, 72, 75, 75,131, 68, 34,201,114,167, 19, 34,151,203,127,107,211, +166,205, 11, 41, 41, 41,226,249,243,231,215,189,118,237,154,178, 83,167, 78, 47,202,229,114,134,227, 56,152, 76, 38, 50, 49, 49, +209,115,217,178,101,161,237,219,183,183,180,111,223,254,250,238,221,187,141,168, 36,254, 21, 65, 16,191,100,101,101, 53,172, 95, +191,190, 93,180,149, 17, 87,142,130, 11, 40, 25,242, 20, 10,133,215, 43, 75,168, 80, 40,188,153,148,148,212, 91, 33,147,194,162, +213,192,170,211,128,214,106,193,104,139,193, 20, 23, 3,122, 13, 36, 52, 13, 17, 67, 65, 46,147, 33, 35, 61, 29, 66,161,240,102, +101,156, 18,137,228,102, 78, 78, 78,111,149, 74, 85,250, 18,165,104,186,100, 97, 24, 88,104,186,212,162, 37, 18,137,240,232,209, + 35, 72, 36,146,155, 79,186, 38,147, 36,201,216, 67, 56, 84,144, 15, 4, 5, 5,177, 29, 58,116,192,148, 41, 83,192, 48,140,173, + 24,136,238, 0, 46,162,196,191,229,153,132, 43,113,107,119, 90, 55, 26,141,208,233,116, 40, 44, 44, 20,202,229,242, 23, 66, 67, + 67,175, 90, 44,150, 61, 52, 77,111,121,240,224,129,166, 34, 78,155, 48, 43, 21, 93, 44,203,130,227, 56, 48, 12, 3,138,162, 32, + 22,139,217,115,231,206, 99,217,138, 37,136,223,178,157, 27, 52,104, 16,113,232,208, 33,176, 44,155,254,132,179,111,177,137,150, +202, 26, 13,231,144, 10, 31,161,242,144, 10, 21,113, 58,246,254, 28,183, 17, 46,142, 41,135, 15, 62,248,224, 4, 74,134, 12,243, +108, 98,238,113, 56,191, 44,250,238, 11, 25,104, 70,111, 62,183, 83,247,237, 93,141,126,222,183, 43,127,179, 72, 4,154,151,187, + 5,181,108,216,224, 5,129, 74,229, 67,174,223,184, 42,127,199,246,189,201, 15, 31, 62,212,172, 93,187,182,227, 11, 47,188,224, +253,199, 31,127,132, 86, 36,180, 20, 10, 69,227, 55,223,124,115, 92, 97, 97,161, 56, 62, 62,126,119, 86, 86,214,111, 40, 9, 45, +227, 56,131,122, 0,128,173, 54, 33, 26,100,107,231, 46, 2,152, 95, 89,127,141, 32, 8,252,244,211, 79,229,102, 7,178,143,167, +206, 85,141, 26, 53, 26,145,146,146,114, 33, 39, 39,103,152,243, 78,177, 88, 60,175, 73,147, 38,125,111,221,186,245, 57,128, 99, +213, 33, 54, 24, 12,177,123,247,238, 93, 42, 16, 8,234, 48, 12,147,105, 52, 26, 99, 31,219,162, 69,177, 19,226,214,239,218,100, +180, 48,225,114,137,224,161,137, 98,223,226,117,200,243,107,205,178, 65,237, 96,141, 82, 3, 32,156,214,255,176,189,140, 44, 28, +199,217,143, 85, 59, 88,177, 44, 78, 86, 48, 87,251,212,143, 17, 44,157,171,168,141,171,200,162,245, 9,128,246, 0,126,201,201, +201, 89, 53,118,236,216,101, 59,118,236,240,210,104, 52,200,201,201, 65,110,110, 46,132, 66, 33,148, 74, 37,214,173, 91,103,204, +201,201, 89,229,120, 14,202, 71,144, 7, 0,147,191,191,255,111,219,183,111, 15,254,250,235,175,133, 49, 49, 49,105, 3, 6, 12, +104,186,110,221,186, 20,177, 88,204, 49, 12, 67,152,205,102,226,237,183,223,142, 88,177, 98, 69,170, 64, 32, 80,140, 24, 49,130, +240,240,240,248, 5,149,132, 13, 80,171,213,167,190,255,254,251,161,211,167, 79,151, 90, 44, 22,151,150, 44,251, 54,149, 74,133, + 75,151, 46, 89, 10, 11, 11, 79, 86, 97,197, 56,245,195,177,163, 93,255, 51,114,164,152,210,106, 64,105, 53,160, 53, 26, 48,218, + 34, 16, 58, 13, 68, 12, 13,185,152, 69,112,152, 12,180,209, 19, 71,127,253,131, 50,155,205,149, 6, 54,212,104, 52,167, 46,198, +199,119,111, 95,175,158,240,210,180,105,176, 82, 20, 94, 73, 74, 42, 21, 87, 86,171, 21, 7, 91,182, 4, 67, 16,104, 61,113, 34, +238,209, 52,173,209,104, 78,253, 47, 62, 12, 55,110,220,200, 29, 61,122,244, 53,150,101,219,226, 9,125, 52,243, 73,128,162,168, +114,214, 40,134, 97, 74,172,142, 37,150, 3,201,209,163, 71,187, 38, 38, 38,138,255,252,243, 79, 92,184,112,161,245,142, 29, 59, + 62, 9, 15, 15,111,249,240,225,195,236,170,196,155,171,160,191,176,249, 31,238,222,185, 7,239,188,243, 14,145,157,157,141,239, +190,251, 14, 85, 5, 79,253, 59, 16, 19, 99, 98,227,227,101,117,225,228,247,228, 34,164,194,239,112, 51,164, 66, 69,156,166,152, + 18, 43,153, 44,190, 36,216,168, 41,166,100, 56, 80, 22, 95,165,165, 12, 49,166, 24,141,205, 33, 62,171, 22, 56,245,160, 25,185, +229,220, 78,221,128, 99, 15,181, 87,178,140,243, 1,156,128,137,225,238, 93,231,110,188,244,146,143, 63, 0,152, 77, 76,112,227, +198,141,187, 9,133, 66, 9, 0,120,122,122,190,228,231,231,183, 46, 63, 63,191,179,171, 50,141,142,142,238, 16, 24, 24,216,230, +248,241,227,127,100,101,101,221, 2,240,179,243, 65, 17, 17, 17,115,110,223,190,221, 78, 36, 18, 17, 85,212, 17, 0, 64,183,110, +221, 94,144, 74,165,126,199,238,122, 67, 35,110, 4, 78, 80, 12, 8,101, 96, 84,173,144, 38,110,142,176,176,171,126,133,133,133, +173,139,139,139,255,168,102,209,247, 24, 58,116,232,150,248,248,248,176,110,221,186,113,215,175, 95, 39,157, 71, 17, 34, 34, 34, +250, 92,185,114,165,237, 91,111,189,181, 97,215,174, 93,147, 81,118,166,109, 85, 72,179,197, 27,172, 53,156, 74,198,105,128,169, +103,179,153,241, 10,229, 31,128,234,132, 92,120,140,240, 12,143,149,196, 10, 13, 24, 21,108,111,111,139,137,213,158,162,168,223, +111,220,184,113,112,196,136, 17,186,252,252,124,248,249,249,161,126,253,250, 32, 8, 2,235,214,173, 51, 62,120,240, 96,159, 45, +150, 86,251,204,204,204, 65, 54,177,229, 10,218,213,171, 87,239,218,182,109,155,234,218,181,107, 2,154,166,149, 77,155, 54, 53, + 92,190,124,217, 83, 36, 18,113, 98,177,152,189,118,237,154, 34, 34, 34,194, 68, 16,132,244,199, 31,127,204,191,122,245,106,248, +140, 25, 51,190, 65,217,105,226,206,216,185, 96,193,130,140,148,148, 20,152,205,102,104, 52, 26, 20, 23, 23,151, 46, 69, 69, 69, + 40, 46, 46,134, 72, 36, 66,118,118, 54,246,239,223,159,101,139, 18, 95,153,101, 99,237,154,117,235,213, 89, 15,211,160, 84,200, + 65,107,138,192, 20,231, 3,218, 98, 72, 40, 43, 60, 68, 12,234, 54,146, 67,166, 80, 34, 71,163, 67,252,229, 95,179,109, 81,226, + 43, 54, 23, 88, 44,107,223, 93,177, 34,135, 22,139, 81,111,248,112, 88,109, 67,133,142, 66,139, 33, 8,132,247,234, 5,210,219, + 27, 11,247,237,203,177, 69,137,127,162, 96, 89, 86, 96,177, 88, 42,203, 7, 88,150, 77, 79, 76, 76,220, 5,224, 44, 65, 16, 28, + 65, 16, 28, 74,130,181,233,158,229, 7,153,162, 40,204,157, 59, 23, 98,177, 24,115,231,206,197,167,159,126,138,101,203,150, 97, +253,250,245,248,246,219,111,113,244,232,209, 6, 23, 47, 94, 20,159, 63,127,158,139,139,139,203,139,136,136, 16, 76,156, 56, 81, + 37,151,203, 63,168,140, 51, 54, 54, 22, 94, 94, 94,136,141,141,197,146, 37, 75,176,121,243,102, 28, 60,120, 16,151, 46, 93,130, + 64, 32, 96,211,211, 31,193,100, 50,113,171, 87,175,206, 56,120,240,160,113,213,170, 85, 16, 10,133,196, 83,106, 36, 62,176, 9, + 42, 71, 75,144,115, 72,133,124, 0, 43, 81,181,111, 84, 69,156,144,197,199,215,181,137,163,100, 7, 65,116, 24,192,116, 84, 62, +189,218,206, 49, 25, 64,112, 45,112,206,150,143,254,191, 68,213,166, 59,247,175,100, 25,103, 3,248,193,158, 39,165, 82, 41, 63, +112,224,123, 33, 0,236,219,187, 95,148,148,148,228,253,253,247,223,203, 2, 3, 3,241,237,183,223,202,228,114,121, 96, 5,156, +204,193,131, 7,205, 18,137,196,111,194,132, 9,253,218,181,107,247,190,173, 35,218, 11, 64, 11,148,204, 94,140,186,127,255,126, +130,191,191,255,221,147, 39, 79,234,221, 41, 32,173, 86,251,205,214,173, 91,235, 23, 48,190, 56,166, 31,138,120,118, 41,142,170, +182, 32,173,222,167, 80,212,121, 25,175,191,254,122, 29,134, 97, 54, 85,179,220, 95, 31, 50,100,200,214,248,248,248,176, 9, 19, + 38,100, 95,191,126, 61, 7, 64, 60,128,237,142,203,237,219,183,243,198,142, 29,155,181,105,211,166,144, 17, 35, 70,172, 7, 48, +140,127,245,243,224, 81,182, 47,132,170,102, 29,186,120,225,150,254,207,205,205, 93, 93, 88, 88,120,233,222,189,123,239, 89, 44, +150, 16,130, 32, 56,177, 88,156,157,147,147,179,202, 33, 96,169, 43,191,146,222,176,197,218, 32, 8,130,226, 56, 46,189, 71,143, + 30, 31,244,234,213,235,171, 35, 71,142,152,186,119,239,142,189,123,247,250,247,232,209,195,192,178, 44,119,236,216, 49,255,190, +125,251, 26,206,158, 61,171,127,251,237,183,155, 54,105,210,100, 98,108,108,172,154, 32, 8,214, 21,167,253, 93, 86, 84, 84, 52, +164, 95,191,126,151,246,237,219,167, 84,169, 84,160,105, 26, 6,131, 1, 6,131, 1, 28,199,193,219,219, 27,106,181, 26,243,231, +207,215, 20, 23, 23, 15,118, 33,220,156, 57, 77, 38,147,105,216,228,247,167,159, 90,245,249, 92,175,240, 6, 13,144,127,199, 4, +218,100,128,136, 35, 81,247, 5,111,136, 37,114,220, 75,210,226,163, 93, 7,180, 70,147,233, 53, 23,189,229,114,156,197,197,197, +195, 98, 62,253,244,244,134, 25, 51, 60,219, 4, 5, 65, 32, 16,192,108, 54,131, 97, 24,136, 68, 34, 68,198,196, 64, 28, 16,128, + 57,187,118,233, 53, 26,205, 48,148,255, 20,143, 51,103,109,192,145,115,242,141, 27, 55,198, 54,107,214, 12,147, 38, 77,194,144, + 33, 67,202, 28,248,253,247,223, 99,253,250,245, 48,155,205, 99, 1, 92, 7,176, 14, 37, 67, 29,112, 18, 89,127,119, 58,107,157, +147, 97,152,194,164,164, 36,229,210,165, 75, 9,171,213,138,207, 63,255, 28,118,193,105,175,215, 83,166, 76,169,227,229,229,133, +207, 62,251,204,146,151,151,215,115,201,146, 37,103,182,111,223,238,255,205, 55,223,188, 14, 32,214,153,147,101,217,220,155, 55, +111,122,109,216,176,129,164,105, 26,203,151, 47, 47, 55, 60, 57,126,252,120, 88,173, 20, 4, 2,161,197,100, 50,183,144,203,229, +201,126,126,126,114,174,172,115,215,147,188,159,161, 40, 9, 97,224,232,248,110,113,244,207, 66,197, 33, 21,170,195,169,150,197, +199,119, 55,197,196,156,181, 9,162, 68,219, 49,123,237, 38,253,106,112,218, 5, 97, 77, 56, 79,217,150, 42, 97, 50,153,160, 86, +171,145,151,151, 7,149, 74, 5,129, 64, 64, 84,148, 78,179,217,252,231, 71, 31,125,116, 99,211,166, 77,189,175, 92,185, 50,240, +252,249,243, 61, 78,159, 62,109, 74, 75, 75,163, 41,138,226, 66, 66, 66,132,157, 59,119,150,245,239,223,223, 67, 42,149,146,179, +103,207,206,251,226,139, 47,252, 81,214,135,205, 57,239, 2,130, 32,240, 97, 87, 45, 98,123, 8, 96,177, 88, 81, 84, 84,132,140, +140,116, 36, 36, 36,224,202,149, 59,224, 56,142,172, 70,185,251, 1,152,253,221,119,223,133, 74, 36, 18, 98,215,174, 93,117,118, +237,218, 85,165, 37,117,199,142, 29,117,118,239,222, 61,207, 54,122,145,254, 44, 62,239, 60,231,255, 44,231,179, 12,231,200,240, +168, 82,104,217,218,249,246,176,125,148,148,162,168, 95, 92,132,112,248, 4,192, 92, 7, 43, 88, 85,230, 60, 13,199,113, 23,122, +247,238, 61,165, 87,175, 94, 43,250,244,233,147,149,149,149,213,112,249,242,229, 97, 52, 77, 91, 19, 18, 18,200,228,228,228,180, +223,126,251,173, 81,147, 38, 77, 38,222,190,125,251, 28, 65, 16, 86, 55, 50,152,144,156,156,220,169, 71,143, 30,251, 39, 78,156, + 24,222,161, 67, 7,137, 74,165,130, 80, 40, 68, 74, 74, 10,254,248,227, 15,203,238,221,187,211,139,138,138,170,243, 9,158, 95, + 82, 51, 50,162, 70, 76,125,111,223,196, 33, 3,253,255,213,244, 5, 73, 72, 72, 8, 96, 52,226,206,195,108, 92,189,243,135,117, +243,133,171,106,179,217, 60, 12,238,127,130,231,151,223,238,221,235,221,115,198,140,125,243,254,243,159, 32,100,101, 9, 67, 66, + 66, 32,145, 72,240,224,193, 3, 36,179, 44,189,120,227,198, 28,155,200,122,210, 81,225,165, 0,150,178, 44, 43, 4, 0,185, 92, +142,119,223,125, 23,142,159,220, 89,191,126, 61,140, 70, 35, 0, 8, 9,130, 88, 10, 96,203,179,110,197,178,163,160,160, 96,206, + 43,175,188, 18, 39, 20, 10, 43,140,122,235,227,227, 3,173, 86, 11,154,166,153,140,140,140, 59, 62, 62, 62, 16,137, 68,224, 56, +206,229,115,148,159,159, 63,103,216,176, 97, 11, 72,146,172,200,242, 1,165, 82,153,118,230,204,153,198,111,189,245, 22,249,223, +255,254, 55,101,194,132, 9,210, 51,103,206, 48, 28,199,237,127,210,247,160, 75,151,157,192,134,152,215, 0,188, 6,148,115,120, +207,176,109,171, 86, 72,133, 46, 93,118, 98, 3,254,226,116, 28,198,179, 11, 34,155, 21,170,185, 44, 62,126, 5, 74,252, 44, 42, +229,238,178,179, 11, 54,196,160, 86, 57,221,129,163,246,213,235,245, 96, 24,166, 50,107,222,239,123,247,238, 93,241,219,111,191, + 5, 76,153, 50,165,225,127,254,243, 31,101,143, 30, 61, 60, 29, 15, 48, 26,141,236,225,195,135,245,235,215,175, 47,190,112,225, + 66,234,248,241,227, 59, 84,150,206,135, 15, 31, 30, 93,184,112,161,119,255,254,253,155, 0, 40,245,207, 82,171,213, 72, 75, 75, +195,159,127,254,153,102,181, 90, 15, 85, 35, 75,249, 0,230,141, 26, 53,106,233,182,109,219,234, 76,152, 48, 33,123,247,238,221, +127,162, 36, 96,177, 51, 84, 67,134, 12,105,185,109,219,182,144, 9, 19, 38,100,163,196,143, 44, 29, 60,120,240,176,163, 59,202, +251,105, 85, 58, 50,177,213, 98,177,112, 38,147,137, 51, 24, 12,156, 78,167,227,224,250, 43,240, 7, 51, 51, 51,185,244,244,116, +238,225,195,135, 92,106,106, 42, 7,224, 91, 39,197,235,170,193,242,216,177, 99, 71,163,208,208,208,207, 21, 10,197, 9,129, 64, +160, 17, 8, 4, 26,169, 84,250,131,159,159,223,167,139, 23, 47, 14,229, 56, 78, 92,137,138,174, 8, 66,145, 72,244, 86, 96, 96, +224, 65, 95, 95,223,116, 31, 31,159,244,192,192,192,131, 34,145,232, 29, 0,162, 42,148,121, 69,144, 9,133,194,143, 60, 60, 60, + 78, 73,165,210, 92,169, 84,154,235,225,225,113, 74, 40, 20,126,132,202, 3,169, 86,202, 41,145, 72, 62, 10, 8, 8, 56,165, 84, + 42,115,149, 74,101,110, 64, 64,192, 41,137, 68,242, 56,156,143,211, 43,177, 11, 45, 3,103, 3, 65, 16, 84,235,214,173, 55,180, +109,219,118, 93,219,182,109,215,181,106,213,234,107,155, 85,146,179, 89, 91, 12,168, 56,120,227,223,153,206,167,198, 25, 25, 25, +185,125,219,182,109,236,156, 57,115, 52, 77,154, 52, 41,152, 51,103,142,102,219,182,109,108,100,100,228,246,154,114, 6, 5, 5, +213,139,140,140, 44,216,180,105, 19,157,148,148,196,109,218,180,137,142,140,140, 44,112,138, 12,255, 36,242, 78, 0,136,176, 89, +127, 14, 1,216,131, 18,231,247, 80, 0, 68,140, 41,134,179,205, 62, 60, 1,160, 79, 5,101,239, 46,103,152, 41, 38,134,179,249, + 84,157, 4,144,232,176,222, 13,101,253,191,158, 4,167, 75,180,104,209,226, 30,231, 0,139,197,194,169,213,106, 46, 41, 41,137, +187,112,225, 2, 23, 22, 22,118,207, 13, 78, 63, 0,111, 3, 56, 28, 28, 28,124,187, 99,199,142, 15, 59,117,234,244,176, 94,189, +122, 41, 34,145,232, 10, 74, 34,188, 71,218,150,165, 0,154, 84,193,217, 81,165, 82, 45, 12, 11, 11, 59,212,184,113,227, 75,245, +235,215,191,226,235,235,123, 68, 38,147, 45,194, 95,145,177,171, 91,231,123, 12, 29, 58, 52, 77,167,211, 49, 47,189,244,210,109, + 87, 39, 53,107,214,236,162, 78,167, 99, 70,142, 28,153, 14, 32,250,159,240,188,243,156, 79,133,243, 31,133,198, 54,193,116,208, + 97,249,196,197,113,159, 56, 29,179,213,118,110,149, 5,193,113,156,128,227, 56, 15,142,227,188, 57,142,243,229, 56, 78,197,113, +156, 39,199,113,210, 42,204,223,124,197,254,251, 56, 39,219, 4,148,193,246,223, 25, 85,237,127,174,239,103,104,104,168, 79,187, +118,237,166, 30, 56,112,224,163,251,247,239,127,116,224,192,129,143,218,181,107, 55, 53, 52, 52,212,231,113,210, 25, 20, 20, 84, +175,121,243,230, 95, 53,107,214, 44,189,121,243,230, 95, 57,137,172, 39,153,119,137, 77,196, 52,179, 45, 13,109,219, 8,148,196, +194, 90,107, 19, 54, 17, 21,244,212,170,195,105,231, 59, 4,160,175,109, 57,100,219, 22,246, 20, 56,203,161, 65,131, 6,199, 91, +182,108,121,175, 85,171, 86,201,173, 90,181,186,215,162, 69,139,123, 77,155, 54,189, 23, 17, 17,113,175,110,221,186,247,252,253, +253,143,215,160,140,124, 1,132,160,252,103,192,158,118,157,239, 30, 25, 25,121, 85, 38,147,185,140, 13, 38, 20, 10,231,181,106, +213,234, 38, 74,102, 74,242,237, 39,207,201, 11,173,255, 33,240,149,240,217,227,148,162,242,207,140, 84,181,159,191,159,207, 54, +167,203,111,117,217,132, 76, 67,155,192,145,212, 2,167, 35,159,189, 78, 69, 56,136,166,167,193,201,215, 37,158,147,231,228,133, + 86,173, 67,200,223, 2, 30, 78, 48, 63,230,126, 30,207,197,104, 60,126, 0, 0, 32, 0, 73, 68, 65, 84, 54,170, 19, 19,235,113, + 56, 93,241,221,127,202,156, 60,120,240,224, 81, 91,109,103,119, 0,231,236,189,194,138, 84,105,117,102, 19,212, 68,217,158,230, + 57,121, 78,158,147,231,228, 57,121, 78,158,243, 31,199,105,199,138, 10,182,223,113, 90,255,250, 25, 21, 94, 79, 36, 76, 15,111, + 86,229, 57,121, 78,158,147,231,228, 57,121, 78,158,179,166,152,248,140,138,172,110,246, 21,126,232,144, 7, 15, 30, 60,120,240, +224,193,163,246, 80,117, 28,173, 61,123,246, 8,236,255, 71,141, 26, 53,158, 97,152,169,246,117,129, 64,176,230,187,239,190,219, + 82,217, 21,134, 15, 31,206, 84,198,233, 10, 85, 93,199, 21,103,139, 38,202, 73,126,222,138,247,138,138, 13, 43, 83, 50,153, 11, + 38,147,169,185,125,159, 76, 38, 75,220,178,101,203,221,218, 78,231,248,241,227,155, 56, 95,167,126,152,168,187,175,151,236,221, +130, 34,221,242, 91,247,116, 95,243,117,236,169,192, 31, 64,180,151, 76, 60,168,133, 74,220,241,207,124,211,101,189,149, 57,140, +146,217,176,133,207, 99,134,131,131,131,155, 42,149,202, 49, 0, 90, 24, 12,134, 64,133, 66,145, 11, 32, 65,163,209,108,207,206, +206,190,227, 46, 79,183,250, 72, 3, 16,110, 91,125,120, 46, 21,245,220,217, 87, 21,250, 68,192,196, 1, 82,130,128,245,100,242, + 95,206,232,125, 27,193,196,114,229,183,247,105, 4, 11,199, 65, 76, 0,230,147,247, 33,123,142,138, 74, 9, 32, 10, 37, 33, 28, +110,160, 36,252,132,129,127,100,121,240,120,174,224, 60, 84, 88,186, 46,172, 64, 76,116, 21, 11,137,175, 56,112, 42,128,243, 51, +155,205, 34,137, 68, 2,139,197, 2,133, 66,190,246,237, 9,227, 63, 7,137, 34,138,198,187, 91,182,108,169,241,151,174,171,115, + 29, 0, 63, 57,159,239,163,148, 47, 56,123,248, 99,159,174, 3, 22, 47,178, 60,200,139,213,106,181,164, 84, 42,133,217,108,134, +183,183,119,167, 73, 19, 39,190, 68,138, 56,139, 88,236,113,121,197,138, 21,217, 53, 77,231, 7, 31,124, 16,108,181,154,254,205, +178,172,196, 98,177, 72,157,175,227,173,240, 88,124,246,240,199,138,110,209,139, 62, 7,120,161,245, 20, 32,169,231,227,113,110, +229,168,238,205, 58,182,104, 12, 54,225, 60, 76, 22,235,160,179,233,186, 65,159, 94,201,156,158,174,179,182, 69, 45, 4,172,252, + 31,130,160, 97,195,134, 83, 2, 2, 2, 70,110,220,184, 81,220,176, 97, 67,200,100, 50, 24,141,198,144,251,247,239,135, 76,154, + 52,169,155, 92, 46,223,149,146,146,178, 22,238,125, 8, 46,252,236,214,255, 3, 0,116, 26, 51, 63, 28, 37, 31,139, 54, 56,239, +235, 62,110,126, 56,128, 25, 40,251, 97,228, 44,148,132, 80,112,213,234, 72,142,108, 91,134, 65, 99, 63, 18, 2,152, 84,154,120, + 18,248,225,219, 85,232, 55,234,189, 50,219, 9, 14,194,195,219,150, 33,122,236, 71, 21,126, 71,177,111, 99,130, 98, 89,174, 66, + 75, 60, 73, 18,244,137,123,156,171, 15, 12,231,160, 36, 6, 88, 57, 74,148,124,208,217,229,241, 3,154, 10,114,172, 20,227, 50, +224,172, 88, 36,200, 61,122,135, 41,119,110, 76, 27, 80, 20, 83,210,182,138,133, 96, 14,166,120,159,157, 61,123,182, 48, 58, 58, + 26,155, 55,111,238,252,245,215, 95, 79,212,106,181, 63,218,238, 91, 50,255,248,242,224,241, 92, 11, 46,215, 66, 75, 40,192,134, + 67,251,182, 52,202,201,205, 67,204, 91, 31, 98,231,206,157, 40, 44, 44,132,143,143, 15, 36, 98,177,104,229,210,255, 11, 86, 42, + 61,130, 99, 38,198,110, 0,208,180,166,169,169,230,117, 26, 59,159, 79,216, 62,165, 35, 20,144, 34,137, 68, 66,238,218,181, 11, + 69, 69, 69, 80,169, 84,144, 72, 68,228,138, 69,159,200,149, 74, 79,249,155,147,103,118, 70, 73,252,159, 26,193, 98,209,117, 62, +176,115,139, 82,173, 86, 99,220, 59,177,112,190,142, 88, 44,102,236, 47, 22,190,142, 61, 21,204,222,248,238,216,102, 47,122, 1, +214, 91,151, 32, 18, 8,160,240,246, 65,148, 80, 0, 1,129,230, 49, 39, 82,103, 1,248,244,121,201,108,195,134, 13,167, 12, 31, + 62,124,228,130, 5, 11,196, 36, 89, 18,114, 78,175,215,195,104, 52, 34, 52, 52, 20,103,207,158, 21,207,153, 51,103,228,247,223, +127,143,148,148,148,213,213,229,191,117,235, 86,253,240,240,112, 19, 0, 12,108,233,229,188,175,158,125, 31, 0,120,121,121, 85, +201,231,167,242, 48,223,186,117,181,133,253,188, 41,189, 66,153, 10,182,155, 0, 40, 42,227, 98, 89, 78,120,242,171, 73, 21,238, +127,107,193, 14,250,198,158, 11, 77, 27, 54,108,104,116,220,238,233,233, 89,209, 41, 65, 58,157, 46,220,121,163,253,120, 43,197, + 4, 86,116,189, 62,239,174,119, 41,192, 40, 6,194, 29, 59,118, 0, 0,190,252,104,180, 96,211,207,121, 66,161,176,164,169, 93, +186,116, 41,230,205,155, 39, 57,113,226, 68,255,109,219,182,245, 63,120,240,224,202,138,132, 42, 15, 30, 60,158, 73,145,229,248, + 91,177,208, 34, 9,194, 75,233,229,137,215, 94,127, 27,199,143,255,128,174, 93,187,150,238,107,208,160, 1,134, 15, 27,140,239, +182,174, 0, 0,175,199, 73,209,227, 94,167,176, 88,255,105,191,145, 95,205,127,152,173,187,114,228,200, 17,116,233,210,165,204, +249,175,143,120, 13,223,126,179, 20,149, 68,153,119, 11, 4, 71,138,189,148, 30, 24, 21,243, 14, 92, 93,103,226,184, 33, 71,250, + 14, 95,213, 59, 39, 95,191,130,175,103, 79, 30,141,130,253,250,180,108,214, 20,133,251,215,226,143, 34, 19,142,103,154,240,102, +212,191, 16,233, 43, 71, 23,154, 65,176,135,168,103,182,158,122, 46,132, 86,112,112,112,211,128,128,128, 50, 34, 75,171,213, 66, +167,211, 65,163,209, 64,171,213,130, 36, 73,196,198,198,138,207,157, 59, 55, 50, 56, 56,248,180, 27,195,136, 15,109,150, 44, 64, + 32,210,205,157, 59,215, 28, 24, 24,104, 86, 40, 20,156, 80, 44,213,118, 31, 55,223, 11, 0, 72,161, 88,187,114,229, 74, 75,104, +104,168, 73, 40, 20, 74,222,123,239, 61,210,157, 52,155,205,102,206,145,211, 98, 49,151,110, 95,188,120,177, 37, 40, 40,200,172, + 80, 40, 56,171,213,125,163,227,205, 7, 5,144,138, 5,144,138, 5,144, 73, 68,240,170,223, 14,210,194, 63, 65,211, 52,150, 44, + 89, 98, 13, 14, 14,182, 40, 20, 10, 78, 34,145,136,167, 77,155, 86,101, 58,199,143, 31,207,169, 84, 42,171, 66,161, 16,207,155, + 55,175,220, 76,161, 51, 55, 50, 32,151,136,160,144, 10,209,184, 65, 24,164,156,209,237,180, 10, 4,101,189, 17,164, 82, 41, 58, +119,238,140, 22, 45, 90,224,224,193,131,221,121,161,197,131,199,115,129, 10,103, 24, 10, 1,224,200,145, 35,221, 80,242, 65, 68, + 68, 71, 71, 19, 37,103,112,152, 49,101, 24,222, 28, 55, 10, 12,195,150,126,231,139, 32, 9, 76,126,163, 63, 88,214,157, 17,137, +170,167,120,214,224, 58,165,156, 28, 65, 10, 0,160, 81,189, 16,110,226,155,255, 1,195,178,127, 13,148, 8,128,183,199,245, 43, +217, 86, 11,233, 20,128,193,135,147, 94,133,171,235, 52,109, 84,135,164,173, 38, 16,101, 63,246,248,119,124,108,147,231,116,129, + 22,117, 67, 34, 40,163, 17, 38, 19,133,248, 59, 5,198, 83, 25,250, 64, 82,149,170, 94,245, 90, 7,153, 64,157,137,122, 94,146, +198,217,122,234,185,200,187, 82,169, 28,179,113,227,198,114, 34, 43, 39, 39,135,212,233,116,176, 90,173,172, 86,171, 5,195, 48, +152, 57,115,166,104,206,156, 57, 99,178,179,179,231,217, 53,143, 43, 78,155,223,213,140, 91,183,110,213,155, 61,123,182,181,103, +207,158, 15, 27, 52,104,160, 23, 8, 4, 8, 9, 9, 89, 21, 21, 21,229,187, 96,193, 2,107,255,254,253, 83, 5, 2, 1, 26, 55, +110,172,255,243,207, 63,235, 1,144,187,155,119, 71,206, 45,103,214,112, 0, 64, 16, 4,162,162,162,210, 26, 55,110,172, 23, 8, + 4,184,123,120, 49,231,238,253, 20, 9, 73, 52, 9,245,182, 53, 34, 4, 32,247, 44,245,196,139,138,138, 74,111,218,180,169,142, + 36, 73,220,188,121, 51, 12,229, 63,107, 85,142, 83, 46,151, 83,175,191,254,250,195, 59,119,238,184, 58, 30, 66, 1,137, 14, 77, +109, 6,172,208,182, 64,250,197, 10,211, 41, 18,128,158, 51,101,180, 80, 37, 3,164, 94,254,102,141, 70, 3,165, 82, 89, 98, 33, +179, 90,241,251,239,191,163, 99,199,142,221,246,236,217,115,142,127,222,121, 78,158,243, 47,184,210, 34,207,160, 53,203,241, 67, +247,101,124,180,206, 58,103,138, 97,104, 52, 8, 15,194,226,255, 27, 15,134, 97,193, 48, 12,104,219, 47,195, 48,160,172,214, 90, + 73,217,227, 92,199, 71, 41, 95,240,195,174,119,125,122, 14, 89,218, 43,110,246,184, 83, 12, 3,176, 44, 5,138, 2, 24,150, 2, +203, 48,160,168,218,113,205,161, 88, 22,245,194,130, 17, 55,123, 28,156,175,179,253,187, 61, 3,207, 28,138, 85,116,141, 94,244, +225,221, 52,195, 18, 94,216, 63, 89,200,196, 82, 33, 39,148,193, 98,161,161,181,176, 22, 0,122, 19,197, 90, 57, 15,127, 25, 0, + 8, 73,226,121,154, 93,219,162, 97,195,134,101, 68,214,178,101,203,252,215,173, 91, 23, 10, 0,195,134, 13,203,232,213,171, 87, + 94, 82, 82, 18, 66, 66, 66,136,188,188,188, 1, 0,222,179,157, 59, 3,192,186, 10,120,245,225,225,225,166,128,128, 0,179, 93, + 16,145, 36, 9,161, 80,136,240,240,112, 83, 96, 96,160,185,113,227,198,122,177, 88, 12,146, 36, 97, 23,122,110,117,243, 8, 2, + 2,129, 0,118, 78,103,107,143,157,179, 58, 16, 9,201,242,205,155, 3, 39, 73,146, 46,175, 87, 97, 29,146,201, 56, 0, 21, 30, + 47, 32, 29,154, 71, 97,229, 30, 2,241,191, 67, 4,224, 44,199,113,184,126,253, 58, 82, 82, 82, 32, 22,139, 17, 28, 28,140,121, +243,230,193,108, 46,209,187,195,135, 15,239, 6,224, 38,255, 4,243,224, 81,138,179,207,160,192,114,182,106, 85,238,163,117,228, +200,145,110,209,209,209,231,236, 2,168, 68,236,184, 16, 63, 20, 13,138,178, 2, 28, 87, 43, 66,171,162,235, 48, 12, 91,233,117, +236, 62, 90, 44,203, 9, 93,138, 44,150, 5, 77, 81,181,114,247, 88,134, 2,203, 82,112,117, 29,130, 32, 25, 91,131, 47,230,159, +147, 39,143,224,240,122, 36, 21,222, 0, 23,104, 19, 66,253,164, 18,228, 25,209,240,133,102,130,223, 13, 20, 46,221, 72,132,191, +167,242,185, 41, 23,131,193, 16, 40,147,201,160,215,235, 75, 45, 89,235,214,173, 11,181, 88, 44, 36, 0, 8,133,162, 48, 53, 27, + 42, 99, 88,192, 91,153,133,194,194, 98, 63,142,227, 8,155,224, 89, 10, 96, 11, 42,137,238, 47, 22,139, 75, 5,138,163, 0,146, + 74,165, 53, 18, 48,118,216,197,153, 88, 44,118,185,221,121,120,173, 42,136, 29,133, 22,184, 18,171,150,147,216, 18, 8, 4,176, +251, 70, 85, 5,137, 68, 82,154,119, 87, 16, 10, 28,174, 39,168,190, 43,166,213,106,133, 78,167, 67, 81, 81, 17,100,178, 18,131, + 25,199,113, 32, 8,226, 61, 0,239,243, 79, 49, 15, 30,174,181,200, 51, 44,182, 92, 11, 45,148,152,236, 8, 0,160, 41,171, 75, +241,179,231,240, 37, 60,204,214, 35,216,255, 23,112,213,140,122, 58,114,228,200,173, 33, 33, 33, 29,236,235, 82,185,167,223,196, +119, 63, 3, 77, 91,225, 37, 39,241,214,152,126,101, 68, 86,137, 69,203, 82,225, 55, 65, 10,139,245,159,246, 27,190,122,190,183, +210,239,138,179,248,137,139,191,246, 90,161,198, 28, 70,146,191,162,144, 8, 97,134,191,253,217,120,135,198,253,198,174,245,115, +167,187,109, 15, 36, 72,209,107,147, 86, 77,228,132,158,205, 21,164,246,252,199,227,254,117,192, 81,204,249,250,250, 30,233,243, +218,202,222, 57, 5,188,143,214,211,128,151,183,138, 12,123,185, 59, 94,126,239, 43,156,249,228, 99, 14, 40,132, 95, 72, 40,217, + 99,202, 23,240,124,121, 32,174,190, 53,134, 5, 10,158,139,188, 42, 20,138, 92,131,193, 16, 98, 52, 26,161,209,104,160,209,104, +202, 10, 2,145,136,152,248,206, 84,127,145, 88, 2,202,106,193,241,237, 95, 84,201,105, 15,225, 48,176,165, 23, 4, 34,137, 54, +161, 97,195, 85, 66,161, 16, 36, 73,226,240,218,143,223,219,191,252, 93, 47, 0,184,113,100,173,102, 84,236,154,213, 36, 73,194, +108, 54, 75,171,147,238, 71,143, 30,133,153,205,102,147, 77,160,217,133, 31, 30, 60,120, 80,215,108, 54, 27, 29,183,187, 3,185, +194, 11, 80, 53, 0, 20,129,229,172,103,169,169,169,117, 40,138, 50, 8,133, 66, 88, 44, 22,183, 84, 17, 73,146,226,155, 55,111, +134,177, 44,235,242,248, 22, 17,117,128,224,150,128,196,219,237, 60,115,110,116, 68,109, 98,235,137, 69,144,230,193,227, 89,177, +108, 61,131,207, 4, 81,193,255, 82,161,213,253,200,145, 35,156, 99, 15,145,166, 40,155,200,250, 75,244, 48, 12,139, 76,181, 9, + 73, 73,119,177,114,229, 74, 92,186,250,145,247,130, 5, 11,164,115,230,204, 49,143, 28, 57,114, 57,203,178,173, 72,146,188,129, +191,134, 42,202, 90,133, 88,182,238,181,107,215, 26,218,215, 41,138,130,151,151, 23,188,188,188,208,180,113, 88, 57,145,197, 48, + 12,172,149, 12, 29,218,125,180, 8,142,229, 40,138, 1,195,178,165,226,167, 80, 99, 14, 59,116,250,122, 35,135,195, 95,176,255, +233,220,174,121,197, 98,112,210,188,210,124,236, 90, 63,119,250,130,205,155,165,133, 76,192,180, 81,175,189, 25, 57,124,212, 24, +188,254,234, 43,221,204, 22,203, 65, 1,201,177, 84,233,245, 64,130,131,179,143, 22,143, 39,132,228, 34, 61, 37,146,202,225, 25, + 92, 31,119,117,140, 88, 32, 16,252,114,191,200, 32, 38, 5, 66,144, 66, 49, 18, 10, 77,212,115,148,221,132,228,228,228,144,186, +117,235, 66,163,209,128,166,105,118,216,176, 97, 25, 66,161, 40, 76, 40, 18, 17,209,163,166,178,217,217,153, 20, 73, 10,192,113, + 12, 94, 25, 62,137,144,202,228, 98,171,197, 66,163,100,232,208,149, 53,203, 49,132,131, 87, 84, 84,148,175,125, 38,224,254,229, +239,122, 57,236, 83,190,244,210, 75,190,142,179, 14,221,180, 22, 17, 35, 71,142,148,135,135,135, 19, 0,240,235,246,217,118,235, + 25, 49,112,224, 64, 89,120,120,137, 31,254,143,107,223,117,155,211, 95,193, 1,197, 15,128,226,212,114,150,172,129, 3, 7, 74, + 27, 54,108, 88,173,103,209,230, 0, 95, 97,236, 46, 15, 33, 13,100, 95,119,139, 43,166, 13,168, 80, 79, 8,151,191, 66, 66,226, +233,103,238,240,241,137,159,121,177,197,131,135, 91,112,210, 34,207, 20,186,217, 4, 98,119,219,111,169,224, 18, 2,128,205, 68, + 71, 56,232, 44, 80,180,181,156,200, 98, 24, 6, 34,194,140,149, 43, 87,226,253,247,223, 7, 0,241,244,233,211, 15, 44, 88,176, + 96, 40,203,178,173, 56,142,235, 66, 16, 68,101,189,198,179, 33, 33, 33, 57, 28,199,137, 72,146,236,178,118,237, 90,223,254,253, +251,195,203,203, 11, 28,203,149, 19, 89, 12,195,194,106,181, 84,248,153, 91, 31,165,124,193, 15,123,166,249,244, 28,188,180, 23, +195,178,167,236, 34,139,101, 24,128, 45, 57, 41, 63, 55, 3, 39,143, 31,196,134,245, 27, 10, 65,112,183,193,129,181,137, 65, 84, + 32, 6, 91, 93,252, 53,177, 75,231,118,205,177, 96,243,102,233,173,107, 89, 7,166,126, 48, 43,114,248,168, 49,216,243,221,118, +144,116,209,117, 71,145,197, 80, 44,138, 11,243, 6,254,196,251,104, 61, 45,248,158, 60,117,138, 24, 51,102, 12,171,213,106, 33, +150, 72, 88,138,162, 4,255,254,247,191,153,247,223,127,159,204,206,206,134, 70,171, 19, 2,240,197,115, 96,214,210,104, 52,219, + 39, 77,154,212,237,252,249,243, 98,146, 36,161,209,104,208,163, 71,143, 60, 53, 27, 42,155,248,206, 84,255,204,204, 12, 90, 41, + 23,154,197, 98, 17,114,115,115,217,110,253, 71, 27, 71,141,127,191,206,251,179,227, 54,102, 93, 94,191,206,157,107, 56,206, 4, +116,222,183,105,211, 38, 75,104,104,168, 73, 42,149, 74,198,141, 27,231,214,248,161,197, 98,225, 22, 47, 94,108,118,158, 93,104, +177, 88,184,149, 43, 87, 90,194,194,194,204,114,185,156,163,168,170,253, 62, 73,146,160,223, 90,176,131,166,105,186,140, 21,203, + 46,178, 40,150,208,125,245,213, 87,214,176,176, 48,139, 66,161,224,164, 82,169,216,157,116, 78,157, 58,149,243,241,241,177,122, +120,120,136, 99, 99, 99, 31,107,214, 33,197, 64,184, 96,109,105,120, 7,169,151,151, 23,180, 90,109,105, 90, 67, 66, 66,120,177, +197,131,135, 11,148,211, 34,207,166, 21,206,189, 56, 90, 44,160,203,201,205, 11,244, 15,170, 15,154,166,109, 11, 5,154,162, 48, +237,237, 81, 88,190,254, 43, 0,176,139,173,168,233,211,167, 31, 0, 80,101, 99,182,107,215,174,249,211,167, 79, 87,230,228,228, +156,216,186,117,171,239,232,209,163, 49, 99,198, 12, 44, 93,186, 20, 34,137, 12,190, 1,117, 75,175, 99,191,110,158,186, 0, 28, + 56, 93, 5,118, 58,107, 73, 35, 5,161, 95, 64, 61, 80, 12, 5,150,162, 64, 81, 20, 8, 65, 73,214, 78, 30, 63,136,209,111, 76, +133, 72,170,244, 89,179,114,137, 49,242,229,144,161,115, 38, 76, 48,187, 97, 4, 36,111, 93,203, 58, 48,245,253,216, 40,187,200, +218,183,125,253,237, 47,103, 14,222, 41,149, 8, 75,175, 67,177, 44, 72, 82,192,251,104, 61, 37,145, 37,149, 74,247, 30, 59,118, +236, 94,219,182,109, 9,189, 94, 15,138,162,144,151,151,135, 3, 7, 14, 36,112, 28, 7, 31, 31, 31, 28, 59,118,140, 29, 61,122, +244, 94,179,217,252,218,179, 46,182,178,179,179,239,200,229,242, 93,179,102,205, 26, 53,115,230, 76, 17,203,178, 72, 74, 74, 2, + 8,130, 19,137, 37, 32, 73, 18, 34,145, 16,197,197, 26, 86,225,169,202,178,114, 2,133, 72, 44, 1, 41, 16, 87, 54, 77,248,161, + 45, 24, 41, 72,161, 88,107,159, 9, 40, 22,139,113,117,207, 50, 77,247,113,243,149, 0, 32,150,202, 11,251,244,233,147,214,188, +121,115,253,111,191,253, 86, 15,229,103, 29, 58, 63,159,244,144,113,177, 2,133, 92,166,143,138,138,122,104,231, 76, 61,181, 70, + 51,102,242,108,130, 16, 72,244,209,209,209,105,145,145,145,122,129, 64,128,196,131, 75, 52, 67,198,197,202,136, 74,130,172,158, +184,199,189,117, 99,207,133,166, 95,124,241, 5,213,191,127,255, 71,118,127,177,212,212,212, 58, 3, 6, 12,144,174, 88,177,130, + 26, 48, 96, 64,250,139,255,207,222,117,199, 53,113,254,225,231, 46,155,189, 71, 16, 68, 69, 81, 20,112,139, 11,197, 58,107, 29, +173,226,194,189, 71,157,173,179, 14,220, 74,221,168,117,214, 90,220, 84,171,162,214, 81, 23, 42, 46, 16, 7, 67, 69, 1, 25, 97, + 67,128,144,157,187,223, 31, 36, 52, 32, 35, 65, 91,107,127,121, 62,159,124,146,220,189,247,220,123,251,185,239,251, 29, 94, 94, +197, 36, 73, 34, 50, 50,210,185, 58, 75,149, 6, 70, 70, 70,138, 9, 19, 38,188,123,254,252,121,109,163, 14,171,133,139,139, 11, + 40,138, 66,183,110,221, 32,145, 72, 12,150, 45, 3, 12,248,111,162, 98, 30,173,170, 51,195, 43,148,138,111,167,204, 94,185, 19, + 32, 76,181,238, 2,127, 25,150,104, 16,223,127,255,157, 9, 0, 35,141,216,154, 59,119,110,141,101, 78,180, 68, 86,155,128,128, + 0, 44, 94,188, 24,155, 55,111, 86,253,248,227,143,140,248, 87,137,242,177,211, 87, 20, 84, 88, 15,104,208,197,148,130,250,182, + 50,190,124,161,104,133,239, 87, 27, 86,166,101,150,220, 25, 59,109,105,217,221, 75, 5,160,144,224,171, 0, 96,207, 79, 63,137, + 88, 92,115,147, 33,195, 71, 1, 64,207,157,219,130,206,172,193,129,154,197, 22, 77,120,124, 59,119,129,149, 70,100,237,218,186, +246,185, 5,145, 25, 60,243,187, 24,133,246,122, 0,192,218, 12,103,124,191,218,208, 59, 43, 79,180,221,112,158,253,115,224,112, + 56,171,175, 95,191,110,226,237,237, 77,228,230,230, 66,165, 42, 61, 34,114,185, 28, 66,161, 16, 69, 69, 69,144, 74,165,104,221, +186, 53,185, 99,199, 14,147,153, 51,103,174,150,201,100,211, 63,247,237,126,251,246,237,174,115,231,206,225,214,173, 91,195, 22, + 45, 90,196,114,116,116, 36, 44, 44, 50, 9,133, 92, 6,128,166,179,179,179, 41, 99, 83, 75,129,173,131,243,187,244,140, 44, 15, +133, 92, 6, 74, 37,175,210,219, 92,157,222,225,251, 23, 47, 94,212,219,180,105,147, 76, 59, 18,112,248,130,157, 59, 90,183,110, +109, 29, 28, 28, 44,235,215,175, 95,178,198,121, 93, 23,103,248, 43,111, 48,251,197,139,103,205, 42,114,250, 77,222,116, 80,195, +169, 29,141,216,255,187,189, 7, 27, 53,106,100,237,233,233,153, 92, 29,111,131, 6, 13,196,124, 62, 95,214,164, 73,147, 98, 22, +139, 85,106,201, 82, 40, 74, 26, 52,104, 64, 57, 56, 56,200,154, 54,109, 90,172,175,211,190,145,145, 17,173,177,138, 85, 6,125, +162, 14, 89, 12, 40, 3, 2, 2,202, 50,195,127,223,168,145, 96,212,168, 81,252,121,243,230,225,224,193,131,184,123,247,238,123, + 98,191,107,215,174,184,125,251,246, 74,252,135, 18,235, 26, 96,192,255, 25,170,207,163, 85, 17,135, 14,133,252, 9, 45,159,166, +202,176,102,205, 26,174,218,146,213,115,206,156, 57, 16,139,197, 86,149, 52,235, 1,117,174,141,202, 68, 86, 80, 80,208, 49,154, +166,157, 1,116, 86,169,168, 7,251, 15, 28,234, 86,213,250,134, 12, 25,242, 30, 39, 77,144, 12,146, 36,138, 57, 44,250,201, 79, +251, 14, 30, 41,215,190,212,249,189, 49, 8, 60,221,185, 45, 72, 12,160,103, 69,177,133,191,202,140,148,113,106, 48,117,218,212, + 50,145,181,115, 91,208, 85,207, 54,117,191, 89, 58,113,117,165,226,108,245,138, 41, 38, 36, 73,116,172,224,163,245, 30,231, 71, +128,129,243, 47,116, 11, 8, 8,104,238,227,227, 67,106,139, 44,153, 76, 86,150,184, 83,227, 44,158,150,150,134,174, 93,187,146, +205,155, 55,247,122,248,240, 97, 55,252, 85,206,233,115,221,118,213,219,183,111,119, 56, 58, 58, 94, 91,190,124,249,168,156,156, +156,175,242,243, 11,108,194, 14,173, 70,159, 33,211,136,174,125, 71,136,100, 52,147,151, 42,200,108,114,243,226, 81,235, 75, 39, +118, 65, 46,147, 77, 1, 16,135,191,210, 59, 84,228, 44,209,164,113,104,210,164,137, 72, 91,168,212,173, 91, 87,226,228,228, 36, +245,244,244, 44,155, 94, 69, 52,223,123,219,174, 47,167,218,255, 75, 84,211,254,212,136,182,138,105, 35,140,141,141,161, 17, 95, +250,244, 83, 59,218,178,210, 27,101,205, 81,135,101,156,234,244, 14,229,116, 90, 72, 72, 72,143,144,144,144, 54, 0,158,160,180, +214,161, 2, 40, 29, 74,212,114,154, 15, 84,127, 12,215,187,129,243,255,149,243,115, 70, 87,252,229,155, 5,148,250,106,221,170, + 82,104,213, 4,141,227, 59, 0,114,238,220,185,249, 98,177,216,106,212,168, 81,213, 46,147,145,145,113,240,240,225,195,229, 68, +214,160, 65,131,198,133,134,134, 94,203,202,202,170,213, 86, 89,153, 27,173,185,117,126,161, 85,215,126, 27,230, 0,248,177, 10, + 67, 30,229,217,134,255,205,206,109, 65,103, 42,136,173, 95, 1, 12,170, 74,149,246,250,114, 32,142, 30,218,169,241,237, 50,122, +254, 56,237,210,176,168, 85,149, 70, 43, 90,154,114, 87,169,251, 49,207,224,163,245,207,128,205,102,251, 45, 90,180,136, 45, 18, +137,222, 19, 89, 21,133, 86, 97, 97, 33,158, 62,125,138,177, 99,199,114,163,163,163,253,228,114,249,141,255,194, 62,200,200,200, +136, 87, 39, 35,157,173, 73,225,192,229, 25,177, 71,140,159,227, 92, 22,117,120, 98, 23,164, 18, 49, 0, 48,117, 73,239,192,100, + 50,217,209,209,209,174, 26,171,149, 92, 46,231,106,166, 63,126,252,216, 85,147, 91, 75, 34,145,232, 28,117,248,119,113, 62,123, +246,204, 89, 19, 29,169,137, 46,100, 50,153,236,200,200, 72,103, 13,167, 84, 42,213, 41,234,144,195,225,176,163,163,163,157, 85, + 42,213, 71,139, 58,212, 22,198, 40,173,179, 88,174,214,162,218,183,140, 32, 8,130, 54, 12, 27, 26, 96,192,103,143,138,145,146, +213, 23,149,174, 9, 26,199,119, 61, 22, 97,186,184,184,244, 26, 62,124,120, 57,145,229,239,239,175, 58,125,250,244, 77, 62,159, +159, 73,146,100,188,190,253, 40,243,209,194,123,111,144, 32, 73,242,105,231,182, 77, 65,146,228,211,165, 19, 39, 74,215,224, 64, + 57,177,117,246,204,201,222,169,249, 49,149, 75, 51, 0, 54,246,117, 16, 48,238, 91, 4,140,251,214, 10, 64, 39,160,234,104,197, +234,250, 97,192,223, 3,130, 32, 56, 78, 78, 78,207, 37, 18, 9, 8,130,128, 84, 42, 45, 19, 88, 69, 69, 69, 16, 10,133,101,255, +229,114, 57,178,179,179, 81,183,110, 93, 16, 4,241,159,246,163,147,203,229,202, 69, 43, 55, 29,102, 48,217, 74,138,146, 19,114, +185,124,188, 62,215,249,162, 69,139, 72, 84,226,123, 53,115,230,204, 74,167,127, 42,206, 37, 75,150, 84, 26, 37, 56,115,230,204, +106,163, 7,171,194,119,223,125,247,209,162, 14,117,191,125, 25, 96,128, 1,255, 49, 84, 26,186, 87, 43,161, 69,146,228,211, 74, +162, 11, 9, 0, 52, 73,146, 79, 43,201,114,160,124,247,238,221, 74, 75, 75,203, 41, 34,145,232,143, 65,131, 6,205,245,247,247, + 87, 1,165, 14,242,181,221,162,124,161,104,133, 95,255,141,243, 10,138,165,193, 21,231, 85,180, 60,105,196,214,174,237, 65,187, +207,132, 30,247,207, 72, 79,221, 93,213,182, 85, 37,168,170,138, 86, 20, 22,138, 87,250,245,223, 56, 39,191, 80,108,240,209,250, +135,160, 82,169,174, 24, 25, 25, 17,154, 98,202,218,214,171,194,194, 66,148,148,148, 64, 93,146, 6, 0, 80, 92, 92, 12, 11, 11, + 11,168, 84, 42,250, 63,182, 43,164, 0,230,171,173, 85, 0, 48, 63,241,230, 14,237,115,251,153,246,188,106,172, 89, 2, 93, 10, + 68, 87,182, 92,117,243,254, 6,206,204,106, 10, 68, 87,135, 76, 61,249, 50, 1,128,205, 98,100, 85, 85, 60,154,205, 98,100, 85, +227,183,175,231,123, 3, 65, 3, 88,105,184,178, 13, 48,224,243,125,255,255, 84, 43,238, 97,224, 52,112, 26, 56,255, 17, 78,174, +250,163,235, 60,195,254, 52,112, 26, 56, 13,156,255, 54,206,202, 48,249, 51, 17, 90,116, 37, 31, 0,181,180,104, 25, 96,128, 1, +255, 58, 72,107, 57,207, 0, 3, 12, 48,192,128, 15,199,123,197,164,181,103, 84,165, 74,245,137, 38,168,141,178,189,102,224, 52, +112, 26, 56, 13,156, 6, 78, 3,167,129,243,255,142,179, 38,110,237,229, 39, 3,216,247,153,136,173, 79, 18,208, 98, 48,171, 26, + 56, 13,156, 6, 78, 3,167,129,211,192,105,224,172, 45, 12, 67,135, 6, 24, 96,128, 1, 6, 24, 96,128, 1,255,231,208, 47, 97, +169, 1,149,160,238,192,165,160,176, 68,189, 59,131,144,114, 54,240,191,182,137,254,254,254, 12,125,218, 39, 38, 90,146, 81,224, +111, 54, 55, 97,247, 47, 22, 41, 54, 83, 81, 43,130,107, 58, 17,109, 27,180, 26,109,204, 51,158, 46,147,201,234,155,154,153,101, +229,229,102,239,201,123,247,108,151, 86, 27,243, 7, 15, 30,240,125,124,124,210, 1, 20,105,189, 41, 24, 96,128, 1, 31, 19,150, + 77, 93, 64, 16,227, 1,250,175,176, 75,138,142,129, 48,238, 80,185,118, 22, 30,227, 64, 18,205,180,166,136, 65, 99, 63, 10, 98, + 83,106,120,224, 88, 38, 36, 36,184, 54,108,216, 48, 25, 64, 65,197,181, 87, 50,207,112,157, 27,240, 57,163, 43,202, 39, 44, 45, +187, 22, 62, 92,104, 53, 26, 84, 31, 74,114, 12,104,140, 4,129,104, 36,134, 14,174, 21,143,219, 55,117, 64, 49,219, 1,104, 5, +208,173, 76,140,120, 45,197, 50,121, 22, 69,211,163,241,230,228, 19,189,249,234,251, 79, 67,213,229, 44, 86, 34, 49,244, 39,189, +248, 40,250,135, 71,183, 79,115, 45,141, 9, 52,108, 61,104, 1,202,103,112,174, 45, 56, 0,124, 73,146,108,102,108,108,204, 47, + 41, 41,201,166, 40, 42, 5,165,227,211,249,181,228, 36, 1, 76, 48, 53, 49,233,227,106,198,105,245, 46, 71,152, 86,164, 80,133, +163, 52,161,107,254,199, 58,163, 74, 69,150,227,190, 57, 35,124,198, 6,205,234, 1, 75,191,141, 11, 74,128,234,132, 22,225,220, +184,227,217, 97,195,135,248,205,152, 60,214,180,142,157, 41, 4, 57, 34,155,159, 14,134,108, 10, 9, 57,218,111,226,176,158,125, + 0, 96,245,234,213, 95,187,184,184,212, 99, 48, 24,137,203,150, 45,251,117,197,138, 21, 52, 81,117,165,114,190,250, 28,214,220, +240, 77, 0,120, 2,104, 0,224, 45,128, 23, 40,159,101,188, 54,248, 44, 56,235,212,169,227, 68, 81,212, 68, 7, 7,135,175, 50, + 51, 51, 47,144, 36,121, 32, 45, 45, 45,253, 83,222,117,104,154,222, 75, 16,196,100,154,166,247,233,241, 61, 69,159,117,240,120, +188, 76,137, 68, 98,175,254,157, 37,145, 72, 28,254,174,237,249, 39,215,245, 15,189,127, 79,186,114,231, 69, 31,237, 73,189, 58, + 55,171,228,142, 66, 52,187,114, 39,166, 75,249,118,158,170, 42,238,129, 4, 77,211, 88,185,114, 37,177,106,213,170,113,110,110, +110,141, 72,146,124,185,124,249,242,114,169,111, 42,206,211,186,206, 13, 98,203,128,207, 21,250, 21,149,174, 17, 77,253, 77, 32, +161,253, 1, 98,108,215,182, 45, 59, 79, 25,221,159,160, 25, 60,140,152,180, 80,169, 55,151,235, 88, 46, 24,226, 53,222,205, 26, +207, 29,210,191, 7,217,198,179, 30,248,118, 22, 0,201,194,222,139, 73, 54,193, 65,203,118, 3,240,169, 69, 47, 87,188,137, 56, +102, 47, 40, 80,129, 32, 0,130, 0, 72, 2, 40,150, 80,232,245,245,152, 21, 0,126,210,243,174, 68, 90, 26, 19,152,123, 76, 2, + 0,140,143,112, 80,234,217,217,217,141,155, 61,123,182,137,167,167,167, 37,143,199,227, 72, 36, 18,135,132,132, 4,187,101,203, +150,121,138,197,226,243, 0, 30,233,201, 89,183,161,179,211,201,224,185, 19,218, 53,111,224, 10,150,172, 24,148, 84,228,242, 42, +225,117,135,169,187, 79, 77,138,201,147, 12, 71, 45, 74, 38,228,228,228, 16, 0, 96,107,107, 75,151, 23, 89,237,199,110,157,215, + 11,115,183, 92, 65,137, 68,118,164, 58, 14,235,122, 45, 70,125,243,205, 64,191,181, 63,204, 52, 77,203,149, 35, 58, 81, 12,107, + 83, 54, 86,204,159,198,145, 74, 21, 29,118,255, 26, 50,121,231,134,133,251, 85, 42,213, 23, 0,218,168, 84,170,199, 0,126, 93, +185,114,101, 85, 55,223, 85, 0,150,168, 79,232,163, 12, 6,227,106,183,110,221,234, 79,156, 56,145,104,221,186, 53, 34, 35, 35, + 27, 28, 59,118,172,199,133, 11, 23, 18, 85, 42,213, 51, 0, 47,161, 46,123,162, 3, 88, 0, 26, 51, 24, 12,239,127, 51, 39,159, +207, 55,146,201,100, 99,156,157,157, 39,119,236,216,209,187,127,255,254, 68,227,198,141, 17, 31, 31,223,250,210,165, 75, 43,194, +195,195,159,165,166,166,238,227,112, 56,135, 5, 2,129,248, 31,127,142, 19,196,100, 0, 78,106,157,188, 82,135,239,116,148,230, +146, 18,232,186, 14,137, 68, 98,175, 41, 97, 67, 16,132,253,223,185, 61,122,174, 43,150, 32, 8,107,117, 91, 84,247, 77,146, 36, +148, 74,165, 72,165, 82,185,213,192,217, 88,253, 34,165,179,214, 5, 80, 93, 34,104, 35, 0,232,213,169, 89, 30, 8,196,148, 89, +180,222,127,201,140, 41, 19, 96, 52,154, 93,185, 27, 99, 93,206, 10, 86,241, 45,118,229, 74, 98,197,138, 21, 8, 12, 12,236, 15, +192,151,162,168,112, 15, 15,143, 29,229, 40, 41,170,108,222,138, 21, 43,182, 87,115,157, 27, 96,192,231, 2, 63,232, 83, 84,186, +202,247, 31,183,193, 93,160,194, 88, 87, 27,123,255, 89, 19,135, 26,121,122, 52,132, 4,166, 72,202, 81,225, 98,216, 37, 0, 56, +161,159,213,105,104, 27, 38, 83,114, 56, 40,112,126, 19,223,118,158,120,158,166,192,227, 52, 21, 74, 18, 21, 96,144, 10,168, 40, + 26,160, 33,169,237, 86,167,230, 43,113,231,165, 12, 36, 1, 48, 72,128, 36, 9, 48,200, 90,146, 81,178, 87,171, 15, 69,121,230, +100, 82, 0, 37,123,245,129, 7,164,153,187,187,251,168, 85,171, 86, 89,102,100,100,152, 68, 70, 70,130,203,229,194,202,202,138, +193,231,243,157,182,108,217, 34,158, 53,107,214, 87,114,185, 60, 9, 64,142,142,156, 30,125,219,120,223,219, 23,180,218, 66,241, +224, 18, 10,142,255, 6, 6, 73,131,109, 98,138,250, 70, 70,184,244, 77, 67,107,255,176,196,211, 15, 51, 69, 30, 0,210,106, 34, +139,139,139, 99, 72,165,210,225,230,230,230,237, 89, 44,150, 3,207,170, 30,149,206,108,147,155, 77, 52,120,155,101, 95,210,101, + 94, 15,135, 62,155,231,116,195,220, 45, 87,176,237,216,253, 95, 90, 33, 99,121,117,121,179,141,141, 77,167,204,154, 62,209, 52, + 53, 71,142, 53,167,115,112,232,118, 33,198,248,154, 97,238,151, 22, 8, 24, 49,204,228,212,111,161, 83, 0,236,215, 90, 36,222, +195,195,131,136,139,139,171,236,230,107, 5, 96,161, 76, 38, 35,217,108, 54,193,227,241, 70,173, 93,187, 86, 62, 98,196,136, 84, + 77, 3, 95, 95, 95,248,250,250, 18, 69, 69, 69, 13,110,220,184,209, 32, 36, 36, 68, 25, 17, 17, 17, 11,224,108,213, 22, 11,163, +119, 18,137,216,133,103,100, 84,242,211,238,221,155,187,116,233, 66,113,185,127,165,159,170, 13, 39, 0, 88, 88, 88,236,183,183, +183, 39, 22, 47, 94,156,254,177, 56,235,213,171,119,165, 93,187,118,221,122,245,234,197,236,212,169, 19,156,156,156,202,230,217, +218,218,194,215,215,151, 72, 73, 73,105, 30, 30, 30,190,251,202,149, 43, 59,158, 60,121,114, 35, 41, 41,169,215, 63,108,209,218, +167, 22, 19, 2, 61,219,127,246, 32, 8,194,116,239,222,189,246,154,154,140, 10,133, 2, 42,149,170,236, 91,243,161, 40, 10, 42, +149, 10,107,215,174, 85,137, 68, 34, 93,246,145, 72,235,173, 89,243,161, 42,251,230,112, 56,182,154,132,189, 53,220,217, 99,248, +220,130,166, 38, 38, 38,174, 0,250,194,174,209,194,242, 13, 74,223,159, 69, 34, 81,178, 64,106, 25, 3,160, 75, 53,108,150,171, + 86,173, 26, 19, 24, 24, 56, 80,203, 74,235, 61,100,200,144,138,101,175,188,213,223, 34,130, 32,110,146, 36,121, 30,192, 33,124, + 68,171,187, 1,255, 45,208, 52,221, 22,128,157,214, 36, 25, 74, 71,133,160,126, 78, 18, 0,108, 42, 76,215,110,167,249,206, 86, + 79,183, 83, 47, 71,107,241,102, 19, 4,241,168,150, 93,188,133, 42,252,180,152, 0, 16, 22, 22, 70,247,235,215,143,208,124, 87, + 46,138,252, 47, 78, 24, 49,160,207, 87,221, 59,130,228, 89,225, 85, 22, 16,241,142, 6,147, 84,128, 4,141, 7,119,111,208, 96, + 82,135, 43, 44, 85,181,245,164,222,224,239,188, 61, 61, 54, 30, 8,154,205,136,205, 98,226, 80,120, 9,228,146, 98,100,103,188, + 67, 86,122, 50, 4,169,111,145,246,238,237, 51,128, 88,161, 51,231,123, 7, 6, 80, 81,234,119, 64, 10,168, 38,242,178,102, 78, +185, 40,174, 65, 99, 79,207,124,142, 10,144,139,226,116, 88,125, 85,156, 94,141, 26, 53, 26,241,195, 15, 63, 88,191,120,241,194, +168,164,164, 68,122,233,210,165,248,164,164, 36,115, 62,159,159, 55,109,218,180, 70, 78, 78, 78,230,131, 6, 13,226, 28, 63,126, +252,107,148, 15,107,173,138,211,115, 64,251,150, 17, 7,119,108, 53,201, 61, 21, 12, 89,194, 83, 92, 20,136,112, 55,179,132,110, + 96,193, 37,190,109,110, 7, 83, 46, 19,171, 59, 57,153,246, 61,147,176, 81, 65, 81, 1,213,113,222,187,119,143,111,108,108,188, +101,228,200,145,252,153, 51,103,114, 85, 76, 75,102,104, 68,174,197,194,221, 17, 78, 37, 82, 57, 99, 68,183,122,152, 55,210, 27, +243,182, 93,215,136,172,201,245,235, 23, 80, 81, 81, 85,115, 42,228,242,250,206,246,230,136, 78, 18,227,208,237, 66,252,249,131, + 19,186,175, 77,199,160, 86, 76,120,212, 53,133, 82,174,104, 60,100,200,144,195,234,183,246, 71, 0,190, 30, 50,100, 72, 19, 6, +131,113, 29,192,239, 53, 29, 35, 30,175,242,234, 41, 86, 86, 86,232,218,181, 43, 60, 60, 60,152, 93,186,116,241,174, 32, 96,202, +113,202,229, 50, 62, 69,209, 48, 51, 51, 51,178,177,177,177, 50, 51, 51,203,173,236, 65,165, 15, 39, 0, 88, 91, 91, 15,238,218, +181, 43,243,216,177, 99, 57,137,137,137, 15, 70,140, 24,241,214,220,220,188,156,245,215,196,196, 4,141, 26, 53,194,178,101,203, +152,125,250,244,169,145,211,193,193,161,103, 72, 72, 8, 8,130, 40,123,104,191,103, 44,118,117,133,163,163, 35,250,246,237,203, + 28, 60,120,112,207,164,164,164, 90, 93, 71,122,224, 90, 37, 22,173,149, 21,142, 83,149,195,111,149,181,215,225,184,103,105,172, + 75,106, 62,124,192,181, 89,237,112, 39,143,199, 43,179, 66, 85,178,174,247, 56, 73,146,196,210,165, 75, 65, 16, 4, 88, 44, 22, +216,108,118,165,223,126,126,126,250,246, 51,133, 32, 8,146,205,102, 47,100, 50,153, 19,165, 82,169, 51,143,199, 75, 87,169, 84, +191, 72,165,210,181, 0, 20, 52, 77, 91, 86, 33,178, 42,229, 52, 49, 49,113,125,245,234,149,123, 85, 29,145, 74,165,240,246,246, + 6,164,136,173,142, 51, 33, 33,193,213,205,205,173, 49, 0, 77,137,182,219, 52, 77,119,209,250,175,141,219, 52, 77,127,169,254, +253,242,205,155, 55,174, 13, 27, 54,204,255,167,206, 79, 3,231,191,143,179, 6, 45, 98, 71, 16, 68,152,113, 48, 25,151, 0, 0, + 32, 0, 73, 68, 65, 84,214,181,218, 79,243,127,209,162, 69, 75,214,175, 95,255,130, 32,136, 48,237,233,218,237,180,191,213,247, +155, 48,154,166,251, 45, 94,188,216,115,195,134, 13,235, 52,109,255, 14,145,168,143, 69,203, 60, 91, 98,130,240,119,230, 96, 50, + 84, 96,146, 4,152, 12, 0, 52,129,228,164, 4, 20, 21, 22,220, 65,226,233, 68,221, 44, 89,254,157, 90,180,240, 10, 58,186,109, + 1,249,115,120, 9, 10, 68, 18,196, 61,185,137, 71, 55,127,207, 80, 41, 85,191,131,160, 31, 3,100, 36,222, 82,241, 64,104,237, +106, 92, 16, 52,179, 84,104,169,197, 85, 57,177,245,201,208,188, 73,147, 38,195,150, 45, 91,102, 27, 21, 21,197, 19, 10,133, 69, + 71,143, 30, 77,151, 74,165, 73, 0, 46, 39, 39, 39, 55,217,190,125, 59, 39, 40, 40,200,203,203,203,139,127,242,228, 73, 89, 37, +229,140,222,227,156, 63, 54, 32, 98,226,172, 57,188,216,147,187,192,137,141,196,210,167, 57,170, 63, 5, 37, 63, 0,216,134,148, +226, 78,217, 18,229,213,173, 93, 93,200,122,102,108, 52,180,228,248,197,229, 73,170,181,100, 25, 27, 27,111, 9, 9, 9,113,109, +219,182, 45, 9, 0,225, 47,149,220,133,187, 35,156, 46,175,239, 68,116,106,102,131,172, 2, 41,102,239,138,198,165,136,172, 63, + 52, 34,171,166, 78,154,153,153,101,167,102, 21, 58,216,152,242, 48,186,179, 41,186,175, 77,135,127, 27, 46,184,108, 2,241,137, + 25,104,232, 86,143,136,190,115,182,141, 90,100,181, 21, 8, 4, 0,208, 6, 64, 98, 74, 74, 10,223,199,199, 71,168, 69,151, 15, + 96, 35,135,195, 89, 74, 16, 4,221,182,109,219,104, 47, 47,175, 98, 43, 43, 43,136,197, 98, 72,165, 82,176,217,108,136,197, 98, + 36, 39, 39,227,193,131, 7,176,178,178,210,235, 64, 21, 23, 23,195,204,204, 12, 20, 69,125, 48,167, 74,165, 34,246,236,217, 99, +242,226,197, 11,147,208,208, 80,135,185,115,231,230, 54,109,218,244,241,176, 97,195, 94,219,219,219, 75,159, 62,125,138,123,247, +238, 33, 63, 63, 31,237,219,183,215,137, 83, 38,147,129,201,100, 66, 44, 22,131,203,229,130,201,100, 66,169, 84,130,162,168, 50, +241, 85, 92, 92,140,188,188, 60,176,217,108,200,100,178, 79,241, 6,250,158,133,170,186,225,183,218, 88,180,180,133,154,142, 34, +171, 38, 75, 84,149,195,157, 5, 5, 5, 70,150,150,150, 11, 1, 8,106, 90, 23, 65, 16, 96, 48, 24, 96,179,217, 32, 8, 2, 93, +186,116,193,132, 9, 19,208,170, 85, 43, 36, 36, 36,224,248,241,227,120,244,232, 17, 88, 44, 86, 89,123,157,199, 39,252,252, 24, + 60, 30,239,222,128, 1, 3, 60,127,248,225, 7, 94,189,122,245, 16, 27, 27, 91,119,195,134, 13, 11,175, 93,187, 54, 80, 36, 18, +181,209,220,237,170,183,210,171,135, 4, 75,135, 11,251, 74,165, 82,196,198,198,234,179,204,123,104,216,176, 97, 50, 73,146,175, + 41,138, 10, 7,224, 77,211,116, 23,130, 32, 46,161,212, 47, 81, 27, 34,154,166,191, 36, 8,162, 16,192, 51,146, 36, 95, 82, 20, +149,108,176,219, 24,160,195,125,165, 95,197,255, 4, 65,132,173, 95,191,190, 95,101,226,170,146,107,179,220,244, 13, 27, 54,172, +211,250,255, 33, 22,213,174, 40,239, 12,239,167,182,114,253, 37,180,194,194,194,170, 87, 32, 20, 6,133,157, 62,118,191,187, 28, +174,158,173,125,181,172, 67, 52, 34, 31,220, 3, 64,255,162, 83, 87,248,253,140, 72, 6,243,151, 61,235,102,146,123,111,150, 32, + 37, 61, 11,247, 46,254,130,108, 65,210, 33,128,158,139,196,208,194, 15, 62, 18,245, 6,121,217,219,216, 90, 74,228, 52, 40, 26, +192,123, 98,235,147,160, 85,227,198,141, 7, 71, 68, 68,216, 74, 36, 18,222,157, 59,119, 74, 66, 66, 66, 50,228,114,249, 77, 0, +119,213,109,162,178,179,179,135,168,133, 9,131,201,100,114,228,114,121,117,190, 11,173,230, 79, 28,115,103,227,158,131,188,215, +207,163,177, 61,244, 34, 10, 74, 74, 84, 55,179,196, 95, 3,208, 40,250,235, 81, 57,226, 52, 26,180, 11,139, 36,192, 55, 97, 57, +198,229, 73,120, 64,229, 67,178, 82,169,116,196,200,145, 35,249, 26,145, 5, 0, 57, 69, 10,102,137, 84,193,232,212,204, 6,173, +187, 13, 65,228,141, 83, 56,121, 59, 13,110,118,198,183,235,155, 20,232,180, 71,179,179, 4,123,182, 6,239,221,186,113,229,124, +206,188,190, 22,240,111,195, 2,143, 77,192,220,152,133,181, 59,246, 43,162, 30,220,126,202,231,243,195, 0,124, 45, 16, 8,192, +231,243,139, 1,188,100, 48, 24,137, 42,149,170, 50,167,238,229, 0, 28, 14, 31, 62, 76, 42, 20,138,226,132,132, 4, 56, 58, 58, +194,193,193, 1, 22, 22, 22,136,139,139,195,159,127,254,137,248,248,120, 80, 20,133, 22, 45, 90,232,117,176,114,115,115,241,244, +233, 83,244,237,251,213,220,236,236, 44,115, 43,107, 27,209,157,240,219,155,106,195, 73, 81, 20, 1, 0,158,158,158,240,244,244, +228,165,165,165, 57,135,133,133,217,175, 89,179,230,157,171,171,235, 81,177, 88, 92,206,114,160,171,208,210,136, 11,141, 8,228, +241,120, 96,179,217, 40, 44, 44, 68,102,102, 38,138,138, 74,131, 54, 45, 45, 45, 63,137,208,170,194, 66,245,209,218,255,205,226, +240,189,225, 78, 75, 75,203,145, 0, 22,234,184, 45, 80, 42,149, 96,179,217,240,241,241, 65,112,112, 48, 30, 61,122,132,223,127, +255, 29,117,235,214,197,216,177, 99, 65,146, 36, 94,188,120,161,111, 23,169,136,136,136,133, 95,127,253,181,231,225,195,135,121, +201,201,201,136,143,143,135,165,165, 37,130,131,131,185,147, 39, 79,110,120,227,198,141,229, 40, 13,126,169, 30, 90,209,133, 34, + 35,254, 80,111,111,239,247,154, 56, 58, 58, 90, 92,190,124,217,190, 76,128, 85,140, 72,124, 31, 5,203,151, 47,223,234,225,225, +177, 77, 61, 92,232, 11,192,132,166,105,191,208,208, 80, 2, 0,252,253,253,105,130, 32, 52, 15,164,103,167, 78,157,234, 22, 23, + 23, 71, 7, 6, 6, 26,124,180, 12,168, 74,139, 76,214, 92,147, 85, 9, 40,125,132,154,182,197, 75,131,197,139, 23,123,174, 95, +191,254,225, 7,138, 44,237, 55, 38, 90, 35,182,202, 30,166, 85, 14, 25,150,217,190, 72,190,163,189,141,245,162,177,157, 64, 81, +128, 82, 5, 40, 85, 52, 68, 37, 98,196, 62,127, 84, 2, 30, 17,170, 83,119,184,156,160, 53, 63,204,105, 16,157, 74, 34, 61, 95, +142, 91,103,247,210,217,130,164,193, 72, 60, 53,254,227,136,172,161,222,142, 14,246,183,142,237, 93, 77, 62,122, 43,131,138, 42, +213, 89, 20, 69,151,253,254, 4,112,180,179,179, 11,184,127,255,190, 29,151,203,229,189,122,245,138, 58,117,234, 84,190, 92, 46, +191,166, 37,178, 0,160, 83,155, 54,109,148,166,166,166, 16,137, 68,114,185, 92, 46,169, 70,100, 57,251,181,106,126,123,227,158, +131, 60,137, 76, 6,161, 88, 10,134,141,125, 69,145, 5, 0, 29,187,185,215,169, 67,240,204, 64, 3, 72, 42,148,167, 87, 37,178, + 0,128,203,229,246,152, 57,115,102,185,186,120,182,102, 44,165, 49,151,165,186, 27,147, 67, 69,222, 56,133,240, 23, 57, 20,143, +205, 80,217,209,111, 27,232,186, 3, 10, 82, 99,246,252,126, 46,236,234,119,203,130,138, 75, 68, 69,112,115, 50, 66,113,145, 16, +107,215,111, 84, 68, 68,132,223, 92, 56,119,106,135, 83,167, 78,109, 64,169, 51, 56, 0,188, 60,117,234,212,152,101,203,150,253, +138,191,210, 60, 84, 68,122, 64, 64, 64,106,179,102,205,132, 30, 30, 30,194,220,220, 92,196,196,196, 32, 63, 63, 31,219,183,111, + 71,108,108, 44, 52, 22, 65,157,124, 85,222, 23, 72,200,207,207, 51,165,105, 26,249,121,185, 38, 63,252,240,131, 69,109, 56, 85, + 42, 85,185,107,171, 78,157, 58,152, 54,109, 26,187,164,164,196,242,221,187,119,230,218,243,116,229,148,201,100,208, 88,134,104, +154,134, 76, 38,131, 80, 40,132, 76, 38,195,235,215,175,203, 68,150,122,253,159,204,162,165,249,205,227,241, 50, 53,231,178,102, + 8,142,199,227,101, 85,213,254, 67,160,181, 46, 90,253, 91, 95,113, 88,227,246,232,120,220,193,102,179, 49, 97,194, 4, 60,124, +248, 16, 9, 9, 9, 96, 48, 24, 16,137, 68, 40, 41, 41, 65,207,158, 61,193,225,112,244,181,104,209,108, 54,123,228,146, 37, 75, +120,137,137,137,200,201,201,209, 56,211, 67,165, 82, 97,238,220,185, 70, 92, 46,119,164,190,166,123,129, 64,208,251,245,235,215, +141, 43,126, 50, 50, 50,132,218, 62,133,181, 69,104,104, 40,225,239,239, 79,251,251,251,211, 26,193,101,128, 1,149,161, 10, 45, +178,175, 42,139,214,199,176,138,105, 44, 91, 80, 7,136,212, 2, 26,145,213, 85, 75,120, 17, 26, 11,151,110, 67,135,110, 67, 91, + 58,216, 88,223, 56,188,107,149,105,216,115, 2,169, 41, 73,200, 22, 36,163, 77, 7, 63,196, 62,143, 6,165, 80,157,198,235,208, +154, 61, 57,235,249,187,123,120, 52,157,222,181,131, 23,130,194,138,241, 42,242, 50, 10,178, 5, 59,145,116,234,244, 71, 57, 66, +174,254,205, 29,236,173,111,252,186,107,149,229,165, 24, 18, 41, 41, 73, 56,251,235, 86, 90, 33,151, 22,160,124, 36,151,222,111, +205, 70,148,140, 83, 92,144, 9, 89,145, 10, 60,178,132,167,231, 32, 69, 6,128,240,173, 91,183,118,111,223,190, 61, 39, 32, 32, + 32, 35, 63, 63,255, 44,128,251, 90,109,154,185,187,187,247, 13, 14, 14,118, 72, 73, 73,193,181,107,215, 50, 80, 26,250, 95, 21, + 82,111, 71, 63,223,253,231,175,251,231, 27, 53,104,130,237, 75,190, 83,134, 62,138, 25, 0,224,146, 86, 27,143, 30,222,238, 97, +107,190,159, 65, 82, 81,127,224,105,114, 38,222, 10,165,127, 86, 69,152,147,147, 67,148,148,148,184, 90, 90, 90,106,159,144,224, +155,136,164, 11,134,186,167,247, 92,120,199, 73, 34, 87,129,203, 34,233,217, 3, 93,211, 31,158, 13,181,201,145,228, 16,154,104, +196,154, 48,105, 88,143,129,187, 66,206,140, 14, 11,187, 48, 93, 46,149,120, 53,105,210,152,126, 28,113,227,233,194,185, 83,251, +212,242,136,155, 62,124,248,144,100, 48, 24,229, 4,186,182,133, 72, 95, 75,145, 62,208,149,179,162,208,210, 64,169, 84, 18,181, +229,148, 74,165,101, 66,171,226,195,189, 50,193,248,119,108,191, 62, 22, 42,237, 33, 67,141, 63,157, 68, 34,177, 87,251,108, 57, +124, 76,139,214,135, 68, 34, 86, 55,124,169, 79,255, 72,146, 4, 69, 81, 96,179,217,104,209,162, 5,194,194,194, 96,109,109, 13, +115,115,115,152,155,155,195,200,200, 8, 54, 54, 54,101, 66,139, 36,117,142,210,161,165, 82,105,221,186,117,235,226,245,235,215, +224,241,120,101, 31, 46,151, 11, 79, 79, 79,136, 68,162, 58,248,148,182,123, 3, 12,248,123,239, 43, 97,218, 98,137, 32,136,176, + 69,139, 22, 45,169, 45,223,162, 69,139,150, 84,102,225,250, 64,193, 85,206,186,197,212, 86,144,149, 42, 73,181,200, 58,180,115, +165,249,153, 39, 64,106,106, 34,174,158,220, 81,164,144,203,242, 41, 74,225,250, 54, 62, 26, 32,241,139, 78, 93, 32,233,118, 3, +251,118, 35,174,190,144,161,176, 32, 27, 47, 31, 95, 78,130,152,179,248,163,137, 44, 7,219, 27,135,119,173,180, 60,255,156, 64, + 74, 74, 18, 46, 29,219, 94,168,144,203,123, 32, 49,244,241,135, 80,143,100,179, 7,178, 93,222,245,155,232,155, 14, 21,161,194, +200,216,184, 47,179, 50, 48, 80,112,167,250,200, 48,109,100,103,103,159,221,186,117, 43,241,227,143, 63,118,149, 72, 36,191, 1, +208, 54, 81,122,185,185,185, 13,223,183,111,159,117, 74, 74, 10,235,206,157, 59,162, 27, 55,110,208, 0,206,215, 96,113, 89,208, +115,252, 52, 70,171,122,117,102, 70, 37,165, 13, 0,240,135,214,108,207,126,173,155,221, 61,184,126,185,153,226,110, 40,138, 5, + 41, 88,124, 55,181, 16,128,206,251, 91,161, 80, 64, 40, 20, 66, 81,156,171,108,195, 23, 9, 3,135,216, 75, 51,243, 37, 76, 22, + 85,162,244, 48,207,146,222,200,125,203, 48, 54, 54,214,107, 95,238, 90, 63, 63, 4, 64,200,144, 33, 67, 14, 63,139,184,208,134, +207,231, 95,240,240,240, 32, 0,160,138, 8,195,170,176, 10,192,220,142, 29, 59, 18, 62, 62, 62, 15,182,109,219,118,165, 58,177, + 82, 27,139, 86, 77,208,149,147,162, 40,178,138,253, 75,212,150, 83,219,162, 85,147,208,250,148, 22,173,202, 68,139,182, 72,212, + 22, 66,255,134,168,195,234,196,148, 62,253,211,248,201,177,217,108, 68, 71, 71,195,197,197, 5,114,185, 28,102,102,102, 48, 51, + 51,131,169,169, 41,138,138,138,192, 98,177,160,231, 54, 83, 60, 30,239, 93, 76, 76, 76, 99, 59, 59, 59,168, 84,170,114, 98,235, +213,171, 87, 48, 49, 49, 73,211,215,162,197,231,243, 47,171,163, 14,203,193,209,209,209,226, 99,236, 87,109, 75,150,191,191,191, + 97,136,208,128,106,173, 89, 85, 88,181,178, 43, 88,162,100, 90,255,179, 81,154,195,173,159,250, 55, 42,249, 45,171,100, 90,238, +250,245,235,111,104,249,119,101,127,224, 38,104, 82, 60,148,139,112, 97,214,100,201,178,183,182,186,113, 96,123,160,249,201, 72, + 32, 45, 37, 17,183, 78, 7, 11,149, 42,249, 23,160,104, 65,196,181,211,161, 32, 80,130,183,161,183,116,187, 69,160, 85,171,166, +174,248,253,133, 2,217,169,175, 64,211,212, 33,100,133,148,124,240,209,113, 27,212,194,222,218,246,198,161,224, 64,139, 51,209, + 4, 82, 83, 18,113,245,100,112,161, 82, 81,210, 29,137,167, 35,107, 75, 59, 1,176, 98,152,240,118, 15,246,107, 53,212,213,205, + 25, 20,173, 0,197,166, 49,104,129, 45,243,101, 84,201,239,225, 60,225, 73,170,152,154,158,118, 95, 55, 7,186,226,226,226,223, + 1, 60, 70,249,244, 10,205, 27, 53,106, 52,116,247,238,221,118,169,169,169,188,168,168, 40,241,222,189,123,179, 40,138, 58, 3, + 64,151,161,212,239,162,146,210, 14,160,124,190,156,230,243,199, 7, 68, 4,140,155,200, 75,188, 22, 2,171,196, 88,124,127, 55, + 93,245, 50, 95, 54, 66,109, 93,171, 20,182,182,182,116, 78, 78, 78,114, 65, 65, 65, 99, 19, 19, 19,228,230,230, 34, 47, 47, 15, + 66,161, 16,210,194, 60,165,141,170, 64, 68, 40,243,192, 98,177,144,149,162,128, 74,165,202,208,213,154, 5,192,106,213,170, 85, +147, 40,138,210,100, 68, 44, 23, 93,168,213, 78,115, 62, 52, 30, 50,100,200, 97,173,168, 67,109,103,120, 77,122, 7, 66,157,222, +161,253, 31,127,252, 17,215,167, 79,159,212,202,196, 10,151,203,213,219, 81,186,170, 40,198,218,112, 86,101,209,170, 56, 93, 31, + 78,205,240,165,198, 9,190,226,116, 13, 24, 12, 6, 40,138,130, 14, 65, 21,127,171,104,209,142, 14,172,141,200,169,112,108,170, + 77, 28, 90,203, 72,196,143,106,209,210, 28, 11, 54,155,141,115,231,206, 97,220,184,113, 80,169, 84, 48, 54, 54,134,169,169, 41, + 76, 76, 76,112,250,244,105,104,210, 63,232,163, 95, 21, 10,197,145,245,235,215, 47,217,179,103,143, 17, 77,211,224,112, 56,101, + 66, 43, 48, 48, 80, 44,151,203,143,232, 36,180, 52, 25,223, 41, 58,198,196, 68, 89,109,212, 97,101,203, 84,225,175,101,185,106, +213,170, 49, 20, 69, 13, 68,133, 20, 14, 21,218,149, 75,253, 96, 72,239, 96,128, 14,247,147, 71,255,226,238,105, 4, 22,161,101, +201, 42, 19, 92,100,117,226,197,206,202,242,198,254,237,129,230, 71, 31, 17, 72,124,251, 22, 55,127,219, 81, 42,178,222,156,124, +130,228,208, 76, 36,134,118,198,219,208,222, 58,191, 61, 17, 68, 43, 39,123, 75,228,137, 40, 20,230,188, 3,104, 68,125, 12,145, +101,103,101,119,227,231,224, 64,139, 83, 79, 72, 36, 38, 38,226,234,201, 29, 66,165, 82,242,197,135,136,172,145,108,246,192, 70, +238,206, 9, 75, 39, 13, 28,234,211,208, 17, 54,239,226,112,126,236, 80,172, 62,254, 13,204,236, 24,104,215,215, 12, 19,214, 58, + 14,229,123,114, 95,243, 59, 99,160, 30,212,218, 34,171, 85,253,250,245,135,222,191,127,223,214,219,219,155, 23, 31, 31, 47,217, +187,119,111,150, 88, 44,190, 2, 32, 90, 15, 78,109,145,213,106,209,228,177, 17, 27,247, 31,230,145,108, 14,130,142,156,199,172, +219,169,170, 11,201,133, 67, 80,126, 88,177, 82, 72,165,210,107,193,193,193, 82,146, 36,145,151,151,135,156,156, 28,100,101,101, +149,125, 23, 20, 20,128,193, 96,224,250,245,235,178,194,194,194,251,186,118,240,222,189,123,245,211,210,210, 60, 4, 2, 65, 27, +245, 39, 30,165,209,133,166, 90,211,218, 8, 4,130,174, 0, 30,105,166,167,166,166,214,123,240,224, 1,191, 38,126, 51, 51, 51, +176,217,236,114, 22, 45, 46,151, 11, 7, 7, 7, 40,149, 74,156, 56,113, 2, 0,242,170,227, 96,179, 57, 2,146, 36, 64,209,148, +148,199,227, 81,124, 62,191, 82,129,165, 15,167, 26,169, 95,126,249,165, 36, 50, 50,178, 82,139, 86,109, 56,105,154, 46,233,213, +171, 23,210,211,211,193,227,241,202, 30,214, 26, 65, 69,146, 36,184, 92, 46, 50, 50, 50, 48,101,202, 20,208, 52, 93,242, 79,223, +121,180,125,154,212, 98,136, 0, 64,168,133,208,123,126, 90,186,250, 64,105,134, 6,105,154,134, 70,112, 85,152, 95,182, 46, 93, +178,183, 87,240,233,154, 92, 80, 80,176,177,180, 59,244,222, 10,223,251,244,120, 40,148, 9,173,216,216, 88, 28, 62,124, 24, 5, + 5, 5,224,112, 56,200,207,207,199,193,131, 7, 17, 19, 19, 3, 14,135, 3,205,190,208, 85,191,249,248,248,108, 12, 15, 15,143, + 25, 49, 98,132, 56, 58, 58, 26, 98,177, 24,209,209,209,232,221,187,183,228,238,221,187, 9, 98,177,120, 21,116, 25, 58,212,100, +124, 87,151,215,145, 74,165,136,138,138,170,244, 83,213, 50, 21,145,144,144,224,170, 82,169, 26,211, 52,237, 75,211,180, 57,212, + 41, 28,212,255,181, 63, 95,170,231,153,211, 52,237,171, 82,169, 26, 37, 36, 36,184, 26,228,132, 1,159, 41,110,105,137, 45, 90, + 75,100,221,170,222,162, 69,145,193, 7,118,172, 52, 63,242,144, 68, 74,114, 2, 30, 95,220, 45, 84, 81,138, 47,244, 44,135,211, + 3, 90,185, 54,120, 70, 38, 94, 20, 81, 26,206, 92,152,147, 2,208,140,218, 8,173,114,156,160,200,224,131, 59, 2, 45,142, 61, + 38,144,158,242, 6,119,207,238, 18, 42,149,210,238,120, 27, 26, 85, 27,206,145,108,246, 50, 22,131, 88,218,171, 83, 75,118,231, +150,238, 48,201, 74, 66, 70,106, 58, 78,196,102,231, 37,228, 75, 39,222, 37,228, 72,126, 35, 61,208,119,146,181,181,149, 35, 11, +253,166,218, 88,223, 63, 95,248, 59,193, 18,201,105, 57,189, 94,112,183,172, 44, 69,249,126,190, 15, 71, 51, 51,179, 17,143, 31, + 63, 54,231,241,120, 70,143, 31, 63,166,246,238,221,155, 43, 22,139, 47, 2,136,208,105,219,223,135,115, 91,119,183, 91,235,118, +237,231, 21,139, 74, 32,146,201,193,117,224,171,206, 68, 60, 31,140,170, 19, 96,150,227,228,114,185,199,142, 29, 59,214,183, 75, +151, 46,174, 94, 94, 94,100, 94, 94, 30,138,139,139,203,156,171,237,236,236, 16, 27, 27, 75, 37, 38, 38,166,115,185,220,227,186, +246,179, 99,199,142,137, 36, 73,198,171,135,209,226, 81, 33,186, 80,171,105, 99,129, 64,208,150,207,231,223, 2, 96,172, 21,117, +168,205,169, 73,239,176, 4, 0, 73, 16,196,163,232,232,232,226, 62,125,250,192,200,200, 8, 34,145, 8,117,235,214,133, 82,169, +196,197,139, 23, 17, 25, 25, 41,162, 40,234, 86, 37,226,181, 92, 63, 37, 18,113, 93, 0,164,184,164,164,197,152, 49, 99,186,206, +155, 55,175, 92, 72,186,189,189, 61,172,173,173,245,226, 4,128,188,188,188,166,127,252,241,199,156,232,232,232,239,250,246,237, +107,177,100,201, 18,110,253,250,245,161, 82,169,200,218,114,230,231,231, 91, 68, 69, 69,109,234,220,185,243,140, 62,125,250, 48, +215,173, 91, 7, 11, 11, 11,168, 84, 42, 24, 25, 25,161,176,176, 16,171, 86,173,194,157, 59,119,148, 52, 77,239, 18, 10,133,223, +235,121, 46,225, 67,175,205,170, 44, 64, 85,165,100,168,162,253,223,222,207, 10, 62, 93, 80,167,112, 88, 88, 69, 6,123,232,122, +206,107,132, 22,131,193, 64, 82, 82, 18,246,238,221,251, 94, 30, 45, 77,250,135, 42,184, 43,219,118,250,230,205,155, 42,130, 32, + 58, 60,126,252,120,225,232,209,163, 39,138, 68, 34,103, 19, 19,147,116,133, 66,241,139, 88, 44, 94,139, 82,127, 84,182, 62,247, + 16,145, 72,148, 92, 89,212, 97,197, 54,128,101,181,156, 21,210, 59,148, 75,225, 80, 97,153,114,169, 31, 42, 73,239,240,183, 31, +119, 3,231,191,146,243,115, 23, 91, 85, 39, 44,125, 15,173, 38,179, 88, 98,133,119,120, 2,241, 33, 34,235,125,107,137,164, 36, + 97,249,177,119, 45,101, 82, 9, 68,194,204,151, 72, 58,145,245, 65,155,165,238,231,237, 4, 2, 73,137,111,240, 48,108, 87,105, + 63,223,134,214,186,159, 4,176,248,167, 75,161,108,194,194, 26, 79,231,140, 67,122,129, 8,151,222,230,159,164, 75,164,211,143, + 0,249,184, 3,144, 74,105,248,193, 31, 50,118,251, 14,178, 24,106, 91,135,133, 45,243,127, 1,111,145, 13,187, 93,247, 46,250, +212, 64,204,224,241,120,225,219,183,111,239,225,235,235,203, 29, 50,100, 72,101, 14,242,250, 34,245,209,171, 55, 63, 93,216,179, +121,190,141,119,123,236, 92,182, 64,117, 44,226,121,197, 40,196,106,225,225,225,161,186,119,239,222,188, 41, 83,166,108,233,209, +163,135,211,128, 1, 3, 56,117,235,214, 5,151,203,197,155, 55,111, 16, 30, 30, 46,123,251,246,109,122, 73, 73,201,188,230,205, +155,235,147,227, 44,127,249,242,229, 27,213,235, 32,212,195,133,109,160,142, 46,212, 52, 82, 39, 45,109, 3,192, 56, 48, 48,112, + 52, 0, 84, 17,246,189, 28,192, 30, 0, 76,154,166, 51, 66, 66, 66, 58,156, 61,123,182,195,220,185,115,217,125,251,246,197,253, +251,247,113,245,234, 85,185, 92, 46,143, 80, 11, 87, 93, 75,229, 80, 0,162,148, 74,229,243,160,160,160, 14, 12, 6, 99,185,102, + 70, 76, 76, 12, 14, 29, 58, 84, 27, 78, 37,128, 77,153,153,153, 63,133,132,132, 44,191,118,237,218,248, 49, 99,198,152, 43, 20, + 10,196,198,198,226,231,159,127,174, 21,167, 80, 40,156, 99,107,107,187,244,226,197,139,191, 92,185,114,229,235, 81,163, 70,145, +179,102,205, 66,112,112, 48,126,251,237, 55, 74,165, 82,157,101,177, 88, 99,114,114,114, 68,159,226,174,163, 30,134, 75,215,179, +214, 97,141,188, 31, 50, 52,168, 35, 4, 31, 74,160,217, 14, 63, 63,191, 50, 43,163,198, 10,167,221,134, 32, 8,189,135, 14, 1, + 88,210, 52, 77, 1,216,133,210,250,162,218, 89,225, 25,248, 43,115,188,174,140,205, 4, 82,203, 24, 72, 17, 91,125, 81,105, 75, +128, 70,179, 26,216, 10,150, 47, 95,190,117,197,138, 21, 91, 43,166,112,208,110, 84, 49,245,195,202,149, 43, 97, 72,239, 96,192, +127, 21,149, 11,173,168,125, 10, 69,131,193, 75,182,175, 91,176, 66,169,144, 9,105,200,253,241,230,116,244,135,174,140,166,232, + 69,215,143, 6, 6,131, 70, 62,173, 82, 46,252,224,222,255, 77,253, 36, 44,172, 81,180,106, 26,126,123,145, 78,103,136, 20,223, + 28,145,203,203, 89,131, 74,125,178,168, 97, 55, 36,249, 39,172,156, 88,103,230,124, 97, 67, 92,200, 27,173,247,122,178,178,178, +206,109,221,186,149,220,188,121,115,215,146,146,146,138, 14,242,181,197,130,254, 51, 23, 49,218, 53,114,157,249,240,117,242, 64, +232, 48, 92, 88, 17, 29, 59,118, 20,196,197,197, 5, 92,185,114,101,196,237,219,183,123,136, 68, 34, 87,130, 32, 96,108,108,156, + 44,149, 74,175,113,185,220, 99,122,138, 44, 0,192,138, 21, 43,232,149, 43, 87, 18,113,113,113, 52,131,193,248, 19, 64, 34,131, +193, 72,210,118,130,215,158,174, 89, 38, 48, 48, 80,151, 7,226,237,226,226,226,200, 85,171, 86,117, 89,181,106, 85, 11,181, 85, +232, 54,254,242,249,210, 23, 10, 0,183,217,108, 78, 58, 65, 16,206,108, 14, 87,116,239,222,189,107, 31,200, 89, 34,151,203, 23, +166,164,164,108,217,178,101,203, 90, 19, 19,147,182, 49, 49, 49,127,126, 8,167, 90, 68, 13,182,182,182,118, 58,124,248,240,169, +131, 7, 15,182,103, 50,153,247, 9,130, 24, 34, 20, 10, 63,105, 81,105,117,129,232,149,122,212, 58,212,137,247, 99, 39, 41,253, + 59,132,155, 74,165, 42, 94,186,116,105, 86, 69,225, 85,209,122,165,249,175, 78,229,162,203, 62,213, 39,138,178, 6,225, 66, 20, + 3, 64,105,237,194,210,178, 58,186, 22,149, 6, 32,174,233, 58, 39, 73,242, 44,128,151, 36, 73,190,174, 24,232,162, 61,111,229, +202,149, 53, 93,231, 6, 24,240, 89, 67,135, 59, 91, 32, 9, 4,214,214,147,246, 31, 52, 87,126,156,126, 6,176,217, 43, 73, 96, + 62, 0,130, 6,182, 28,145,203,127,168,110, 65,199,142, 88, 75, 19,152,171,222,153,235, 50,238, 98, 77, 45,182,189, 14,116,168, + 63,168, 39,103, 19, 84, 95, 80,246, 61, 78,127,127,127, 70, 21, 15,243,114, 69,165,171, 66,104,104, 89, 22,255,170,250,169,125, +190,153, 61,120,240,192,201,199,199, 71,128,242, 78,255,149, 77,167,245,220,118, 6, 0,213, 71,222,159,159, 5,167,155,155, 27, +231,205,155, 55,178,127,215,181,105,224,252, 87,114, 90, 54,117, 1,129, 73,208,206, 29, 84,173, 69, 75, 75,160,209,244,207, 40, +136, 77,169,162,159,154,235,220, 50, 33, 33,193,181, 97,195,134,201, 0, 10, 42,244,163,178,121,180,225, 24,253,223,115, 86,134, +201, 40, 95,138,206,128, 74, 14,132,129,211,192,105,224, 52,112, 26, 56, 13,156, 6, 78, 3,103,109,133,214,103, 13, 18, 6, 24, + 96,128, 1, 6, 24, 96,128, 1, 6,252, 45, 32,170, 81,165,250,152, 4,107,163,108,175, 25, 56, 13,156, 6, 78, 3,167,129,211, +192,105,224,252,191,227,172,137, 91,123,249,207,117,232,240, 31,235,183,193,172,106,224, 52,112, 26, 56, 13,156, 6, 78, 3,167, +129,243, 67, 4,203,103, 13, 38, 12, 48,192, 0, 3, 12, 48,192,128,207, 6, 61,220,193,103,170, 64,254,241, 70,167, 32,170, 26, +209,199, 13,117, 0,224, 99,241,253,159,130, 15,224, 43,173,255, 23,160,142,140, 55, 8,173,207, 23,141, 0, 44, 1,160, 93,139, +236, 33,128,245, 21,218, 29, 5,160, 93,144, 80,132,210, 58,129,175,245, 89, 25, 73,146,235,187,116,233, 50,253,206,157, 59,155, +149, 74,229,170, 90,244,215,149,207,231,111, 36, 8,162, 53, 0, 22, 65, 16,111, 50, 51, 51,215, 43,149,202, 15,137, 90,105,224, +232,232,184, 1, 64, 75,146, 36, 89, 4, 65, 36,100,102,102,174, 81, 42,149, 55, 63,128,211,204,193,193,161, 19, 77,211,142, 0, + 24, 44, 22, 43, 55, 45, 45,237, 1,106,153, 91,201, 63, 48,150, 93, 40, 82,178, 0,192,220,132,169, 8, 13,108, 42,215,117,154, +225, 20, 55,192,128,255,111,208,165,145,201,229,208,219, 13,107,105, 37,190, 87, 1, 68,175,250,216,113, 57, 17,223, 87,181, 60, + 81, 73, 84,115, 69,206,222,110, 88,171,162, 75, 57,122,185, 97,211,229, 55,168, 54,210, 94, 23, 78, 13,246, 1,228,100, 29,170, + 20, 16,186, 69, 95,255,219,241, 21,202, 15, 21,150, 13, 29, 86, 43,180,134,185,131,175, 98,130, 25, 26, 11, 77, 24,175, 25,128, + 22,234,135,252,107,148,230, 42, 42,250,192,206,125, 46,156,255, 54, 44,167,105, 58,160,220,201, 90, 73, 30,162, 47,190,248, 98, +192,149, 43, 87,140, 53,245,238, 40,138,130,145,145,145, 18,192, 88, 61,214,101, 63,108,216,176, 69, 7, 14, 28,192,208,161, 67, +151,134,133,133,109, 5, 80,172,235,194, 86, 86, 86,254,150,150,150,193,251,247,239,183,107,223,190, 3,193,225,112,240,230, 77, +130,243,148, 41, 83,188,226,226,226,206,102,101,101, 77,212,119,227,173,173,173, 71, 90, 90, 90,110,217,187,119,175,109,231,206, +157, 65, 16, 4, 34, 35, 35,157,231,204,153,211,226,221,187,119,199, 51, 51, 51,103,232,203,105, 99, 99,227,110, 97, 97,209,109, +231,206,157, 70,157, 58,117, 2,143,199, 67,116,116,180,233,212,169, 83, 29,211,210,210, 98, 51, 51, 51,111,233, 43,178,158, 69, +158,255, 90, 41,151, 6, 1, 0,147,205, 93,208,126, 75,196,249,103, 55,206,247,175,105,154,127, 96,236,239, 6,177,101,128, 1, + 6,104, 99,164, 19, 28,105, 26,243,175,252,188,140, 4,128, 94,227, 87,207, 26,233,132,205, 71,210,171,174, 97,171, 39,223,247, + 99,234, 32,248,112, 26, 50, 63,164,159,251, 0,114, 14,147, 57,171,157,143,143,237,183,119,239, 38,200,129, 95,254, 79, 14, 81, +165,195,156, 85, 10,173,193, 77,177, 74, 89,106, 49, 33,250, 52,196,241,171,137,140,240, 47,190,248,162,225,132, 9, 19,136, 86, +173, 90, 33, 50, 50,210,253,248,241,227, 95, 93,184,112, 33, 65,165, 82, 69, 2,120, 1,221,179, 90,179, 0,120, 50, 24,140,214, +255,114,206,127, 51, 76,212,226, 42, 19,127, 37, 58,125, 47,225,233,245,235,215,207, 49,153, 76,141, 69,171,157, 72, 36,114,168, + 96, 5,211, 5,245, 20, 10, 5,226,227,227, 65,146, 36, 11, 64,125,188, 95, 82,163, 42, 56, 27, 27, 27,239,142,120, 24,105, 67, + 48,141,144, 47, 1, 32,145,131, 99,234,128, 3,135, 66,172,231,205,158, 49,248,230,205,155,225, 69, 69, 69,191,234,209,159,250, + 38, 38, 38, 91,159, 62,125,106, 99,108,108, 12,138,162, 80, 84, 84, 4, 71, 71, 71,236,223,191,223,114,222,188,121, 1,133,133, +133, 55, 37, 18,201,111,250,136,115, 11, 11,139,110,207,159, 63, 55,210, 20,148,150,201,100,112,118,118,198,209,163, 71,185,179, +102,205,106, 90, 80, 80,144, 42,147,201,222,234, 74, 88, 40, 82,178,148,114,105,208,225, 93,129, 46, 0, 48,102, 70, 96, 16,167, +200,252,162, 46,211, 10, 69,202, 11, 0, 12, 66,203,128,127, 26,173,109,109,109, 67,115,114,114,110, 1,152,136,143, 99,105,112, +231,241,120,205, 41,138,114, 36, 73, 18, 12, 6, 35, 67, 36, 18, 61, 5,240,170,182,132, 54,110,126,253,193, 53, 30, 7,154,106, + 65, 2, 32, 72, 50, 90, 37, 47, 57,148,251,234,230,249, 15,226,228, 24,141, 7,232, 22, 36, 64, 17, 36,249,148, 82,150,236,207, +137,191,121,233,223,114,112,238, 11,209,216,205, 81,247,194,152, 31,131,111,120, 3,240, 73, 10,228,209, 36,221,135, 21,103, 2, +125,103,207,158,237, 56, 99,250,116, 98,220,216,177,141,110,221,185, 67,116,213,167, 90,193,231,137, 42, 29,223, 43, 21, 90,254, + 77, 97, 69, 3, 11,143, 7, 47, 33,153, 12, 6, 49, 98,246,250,128,131,187, 54,145, 61,251, 15, 41, 27, 62,241,245,245,133,175, +175, 47, 17, 20, 20,212,232,207, 63,255,108,116,244,232, 81,101, 68, 68,196, 83, 0, 39,170, 90, 89,111, 55,136, 41,128,199,102, + 49, 69, 35,150,253,186,215,199,199, 7, 92, 46, 23, 31,194, 9, 0, 61, 27,146,111, 89,214, 13,158,142,152,185, 60,185,125,251, +142,244,199,224,252,140,240, 16, 40, 43,106,109,229,226,226,210, 73,169, 84,242, 0,128,201,100, 74, 82, 82, 82,102,162,180, 54, + 32, 0,156,165, 40,106,128, 30,220, 36,128, 21, 3, 6, 12, 88,250,237,183,223,162,110,221,186,152, 53,107, 22, 20, 10, 69,228, +165, 75,151,150, 3,216,128, 26, 46, 30,123,123,251,229,187,119,239,182,102,114, 76,208,106, 97, 34, 4, 5, 74, 0,128, 41, 23, + 56, 55,141,198,172, 89,179,204, 31, 63,126,188, 70, 31,161,101,111,111,191,106,255,254,253,214,198,198,198,160,105,186,172, 22, + 99,113,113, 49,138,139,139, 49, 99,198, 12,243,216,216,216,141,250, 8, 45, 7, 7,135, 78, 59,119,238, 52,226,241,120, 40, 46, + 46,102,203,229,114,162,168,168, 8, 37, 37, 37,180, 76, 38,147,207,156, 57,147,251,226,197, 11, 63,129, 64,240, 22, 6,252, 91, +192, 0,240, 13,139,197, 26,212,176, 97,195, 54,175, 95,191,126,162, 84, 42, 79, 3, 56,253, 17, 94,166,186, 59, 57, 57,173, 77, + 79, 79,223, 9, 32,228,255,101,135, 58, 56, 56,156,190,119,239,158,203,238,221,187,199,110,222,188,249, 34,128,223, 62,128,142, +205,102,179, 7,119,237,218,213,101,204,152, 49, 28, 7, 7, 7, 72,165, 82, 36, 38, 38,154,159, 60,121,210, 53, 58, 58, 58, 85, + 93, 17, 67,231, 23, 10, 27,247,142,166, 96,154, 31,239,208,177, 83,231,161,131,191, 49,115,176,177,128, 88,166,194,235,100, 65, +221, 63, 46,158,235, 26,199, 54,186, 39,151, 11,135,231,190,186, 87,172, 47,103,183,110,221, 59,247,232,222,221,204,194,210, 2, + 66,145, 28,111,146,210, 92,111, 92, 61,239,203,100, 26,221,166, 8,197,168,172,231, 87, 75, 62,229,177,153, 5, 48, 69, 60,155, +230, 45, 58,182,122,220,107,194,154, 54, 52, 77,131,164,177,163,162, 53,107, 22,192,220, 81, 90,246, 75, 47, 62,208, 52, 77, 16, +216,164,109,205,234,237,134,181, 52,141,239, 65,130,232, 93,195, 48,165, 6,189, 0,174,165,181,181,207,212,201,147,137,162,194, + 66, 68, 71, 71,151, 84, 20, 89, 91,235,128,125,155, 68,189,179, 41,181, 23,219,255, 82,107, 86,165, 67,135, 58,231,209, 50, 54, + 54,174,116,186,133,133, 5,186,117,235,134,245,235,215, 51, 1,180,174, 48,187,124,145, 85,128, 27,182,103, 49, 44, 76,184,100, +221,186,117,205,204,205,205, 63,152, 19, 0, 64, 83,245, 59,214,165,191,124,244,235,146,177,215,142,110,241, 20, 21, 21,176, 42, + 54, 49, 53, 53, 69,227,198,141,177,116,233, 82,221, 56, 63, 28,255, 40,167,163,163, 99, 19, 95, 95,223,214,215,111,221,178, 76, + 79, 79,231,166,167,167,115,175, 92,191,110,217,161, 67,135,214,142,142,142, 77,202,118, 21, 77,235,211,207,213,187,118,237, 90, +126,246,236, 89,210,215,215, 23, 86, 86, 86,232,214,173, 27, 46, 94,188,200,220,188,121,243, 58, 0, 75,107,234, 39, 73,146,157, +125,125,125, 9,208, 52, 50,132, 74, 60, 88,223, 4,209,155, 60, 80, 36,161,145, 39, 44,132, 88, 44,129,177,177, 49, 15,165,195, +189,186,110,123,199, 14, 29, 58, 16, 0,202,196, 85, 81, 81,233,167,184, 88, 4,153, 76, 14, 46,151,107, 6,128,167, 43, 39, 77, +211,142,157, 58,117, 2, 0,200,229,242,178, 55,188,130,130, 2, 66, 40, 20, 66, 38,147,129,197, 98,177, 81,179, 95, 99, 25,167, +185, 9, 83,193,100,115, 23,140,153, 17,152, 50,102, 70, 96, 10,147,205, 93, 32, 51, 43, 84,233, 50,205,220,132,169,248,196,231, +167, 29, 73,146, 63,187,185,185,197,146, 36,121, 24,128,227, 7,114,182, 5,176,206,200,200,232,154,135,135, 71,138,177,177,241, +117,181, 80,239, 80, 75, 78,142,177,177,241,245,117,235,214,157,122,242,228,201,208, 63,255,252,179,254,179,103,207, 6, 7, 5, + 5, 29, 55, 53, 53, 13, 71,121,191, 68,189,175,205,250,245,235, 31,124,240,224, 65,219,142, 29, 59, 30, 0,192,253, 72,215, 59, + 3, 64, 75,232, 84,145,227,147, 28,119,167, 86,173, 90,185,240,120, 60,244,232,209, 3, 0,252, 62,132,147,205,102, 15, 94,186, +116,169,219,178,101,203, 56, 2,129, 0,215,175, 95,199,195,135, 15,161, 84, 42, 49,109,218, 52,238,152, 49, 99, 26,152,153,153, + 13,214,171,159, 76,243,227,179,231,204,237, 51,127,214, 36,179,167,239,228, 56,116,237, 29,126,143, 16, 32,171,132,131,254,131, +199, 88,244, 30, 56,172, 55,135,107,113, 92, 95,206, 69, 11, 23,246,153, 60, 62,192, 44, 70, 64,225,220,253, 12,220,143, 23, 66, +201,178, 68,223,193, 19,173, 90,116,234,243, 21, 19,172, 95, 62,245, 49,218, 15,180,159, 61,123,182,221,130, 77, 71,238, 58,181, +253,102, 71,118, 62,124,181,133,143, 59, 96,105,109, 98,242, 77,124,215,174,147,140, 74,235,197, 86,203, 89,142,175,245,192,224, +172,124,116,209,246,207,234, 98,141, 70,234, 97, 69,198,149,159,151,145, 52,129, 89, 35,157,202,221, 7, 42,237,231, 77, 96,232, +236,185,115, 89, 22, 86, 86,216,181,107, 23,164, 34, 81, 57,159,217,238, 46,232,115,205,152,153,218,192,195, 57,182,155, 43, 17, +254, 31,124, 95,153, 92,165, 69, 43, 44, 44,140,238,215,175, 31, 1, 0,161,177,200, 31,220, 20, 27,135,125,187,110, 41, 65, 18, +116, 61,207,142, 49,117,220,154,137,108,108,108, 80, 82, 82, 2,169, 84, 10, 54,155, 13,137, 68,130,119,239,222,225,254,253,251, +176,178,178,210,171, 39,133,133,133, 48, 53, 53,133,169,169,233, 71,225, 92, 60,182, 7,247, 77, 74, 54,247,242,253,155, 93,183, + 79,255,173,189, 91, 75,191,103,221,135,205,122,110,110,231, 36,121,246,236, 25,238,221,187,135,252,252,124,248,248,248,252, 87, + 14,230, 67,181, 79,214, 67, 0, 86, 13, 27, 54,116,190,124,237,182, 85,177,132, 50, 79,202, 84,176, 40,138,130,177, 49, 95,121, + 34,244,156,112,232,224,254, 68, 70, 70, 70, 22,128,135,106,113, 91, 83, 77, 69, 30,128, 38,254,254,254,139,166, 79,159,142,132, +132, 4, 76,154, 52, 73,252,240,225,195,220,142, 29, 59,218,236,223,191,223,104,222,188,121,184,117,235,214,138,176,176,176, 51, + 0, 18, 1, 84, 90,171,141,166,105, 54,155,205,134, 82, 45, 27,228, 42,170, 76,223, 23, 22, 22,130, 22,231,131,205,102, 51, 0, +216, 65, 71, 63, 58,138,162,216, 44, 22,171, 76,100,189,203, 44,196,187,172, 18, 20, 22,203, 32, 22, 43, 33, 19,211, 96, 24,219, + 48,129, 36, 7, 0, 73, 80,170, 87, 0, 0, 0, 32, 0, 73, 68, 65, 84,186, 90, 71,120, 60, 30,148, 74, 37,138,138, 74,187,161, +177,148,201,100, 50, 8,133, 66, 48, 24, 12, 83, 0,230, 0,242,116, 33, 84, 59,185,255,174, 30, 6,196,163, 35, 3,108, 95, 95, + 88, 92,110,154,185, 9, 83, 17, 58,175, 41,195,198,185,197,157,150, 67,127,241, 40,155,246,105,253,179,184,118,118,118, 55, 78, +157, 58,213,180, 81,163, 70, 72, 76, 76,244, 24, 50,100,136,143, 64, 32,104, 9,253,107, 50, 26,147, 36,185,113,204,152, 49,211, + 71,140, 24, 65,184,187,187,131,201,100, 66,169, 84, 58, 39, 36, 36,116, 59,121,242,228,194,131, 7, 15,238, 87,169, 84,223, 65, +119,191, 63,146,195,225,156,216,187,119,111, 23, 31, 31, 31, 28, 62,124, 24, 15, 31, 62,164,218,182,109, 75,142, 30, 61, 26,174, +174,174, 62,163, 71,143,254, 93, 42,149,246,173,165,101,203,181, 67,135, 14, 46, 12, 6, 3, 29, 59,118,100,223,187,119,175, 21, +128,123, 31,184, 79, 77,157,157,157,111,249,249,249,181,188,118,237, 90, 84, 70, 70,134,159, 30,219, 11, 0, 3,157,156,156,130, + 44, 44, 44,172,244,184,199,150,164,165,165,125, 15, 32, 84,199, 69,218,183,110,221, 26,201,201,201,104,210,164, 9,216,108,118, + 7,185, 92, 62, 5, 64, 31, 0, 63, 0,136,213,163,191,238,221,187,119,119,241,243,243, 35, 66, 67, 67,203,252, 67, 73,146,132, + 82,169, 4,155,205, 70,251,246,237,201,200,200,200, 58,143, 30, 61,114,135, 14,195,136, 54,110,126,253, 59,118,238,218,185,139, + 79,115,114,115,232,107,168, 40, 21, 24,132, 18, 76,130, 2,165,224,130,203,102,192,221,179, 13, 35,254,197, 83, 31,153, 84,222, + 63,247,213,181,243,186,112,246,233,213,211,183,105, 19,119,114,251,239,111, 80,144, 22,171, 74,139,187,157, 67, 50, 72, 52,109, +253,133,173,123,179,150,140,150, 62,126,172,244,196, 23,221, 36,146, 46, 61,242, 19,110, 95,251, 20, 23,228, 74,128,225, 92,199, +246,155,126, 61,253,216,130,244,116,209,201,208,243,207, 75, 20,184, 15, 0,183, 0,162, 47,208,220,187, 93,187,174,251, 55,108, +176,225,243,249,172, 81, 35, 70, 40,247, 69, 69, 69,161,138,161,223,149, 0,195,214,209,177,199,212,169, 83, 25,130,244,116,250, +228,233, 11,207, 52,124, 40,125, 75,241,110,238,236,209, 15,162,120,189,134, 41,251, 3, 28, 7, 71,199,166, 83,166, 76, 65, 70, +122, 58, 14,135,132, 20, 75,128, 8,141, 21,235, 28, 3, 59,155,185, 57,142, 91, 48,113, 0,225,194,183,197,212, 21,251, 58,116, +147,103,185, 65,240,215,241,215,214, 34,159,177,200,154, 92,169,208,170,136,223, 98,177,220,140,141,250, 39, 79, 30, 35,179,139, +228,162,132,132, 4,216,218,218,130,207,231,195,194,194, 2, 49, 49, 49,184,126,253, 58, 94,190,124, 9,138,162,208,162, 69, 11, +189,122,147,147,147,131,167, 79,159,194,202,202,234,163,113,186,185,216,225, 91, 23, 59,118,102,110, 33,251,218,195,151, 62,251, + 22, 15,110, 70,122, 12, 62,168, 93, 36, 86, 38,147,225, 63,130,178,232, 66, 23, 23,151, 78,135, 14, 29, 98, 75,149, 48,115,159, + 18,241,163, 72,162, 50, 1, 0, 19, 30, 67, 20, 25,212,248,187,213,171, 87,139,198,143, 31,239,145,146,146,178, 94, 7, 91,255, +218,238,221,187,207,167,105,154, 53,123,246,108, 0,192,152, 49, 99, 10,239,223,191,239, 14, 32,235,250,245,235, 78, 19, 38, 76, +120,117,227,198, 13,227,185,115,231, 50,148, 74,101, 12,147,201,164,195,194,194, 86, 1, 8,124,239,137, 72,146,143,163,162,162, +234, 57,185, 54,134,171, 13, 9,223,165, 47, 75,111,112,198, 20, 82,147,222, 32,238,217, 67, 56, 58, 58, 90,240,249,252,216,212, +212, 84,121, 90, 90,218, 66,145, 72,180,187,134, 62, 70, 71, 70, 70,242, 93, 93, 93, 81, 92, 92,140,212,236, 18,204, 58,109,140, + 66,113,169, 17,131, 5, 49, 90,186, 52, 54, 51, 34,101, 15,179,178,178,228, 50,153,108,153, 80, 40, 60, 84, 29, 39,139,197,202, +125,246,236,153,105,221,186,117, 33,145, 72,232,188,188, 60, 66, 36, 18,161,168,168,136,184,112,225,194,215, 2,129,160,109,253, +250,245, 9,103,103,231, 85, 2,129, 64,156,150,150, 54, 73,151,161, 73,181, 96, 82, 49,153,204,205,147, 39, 79, 30,122,230,204, +153,199,161,129, 77, 7,106, 13,151, 88,120,122,122, 94,110,222,188,153, 83,200, 38,239, 29, 0,126,252, 23,156, 91,227,150, 44, + 89,210,212,218,218, 26, 83,167, 78,197,202,149, 43,177,124,249,242, 70, 83,167, 78,157, 12, 96,171, 30, 60, 70,142,142,142,143, +182,111,223,238,209,169, 83, 39, 92,188,120, 17,199,142, 29,195,219,183,111,149,245,235,215,103,250,248,248, 96,197,138, 21,232, +221,187,247,164,153, 51,103,118, 77, 79, 79,111,165,163,248, 24,191, 98,197,138,129,157, 59,119,198,216,177, 99,165, 55,111,222, + 28, 10,224,202,213,171, 87,191,184,117,235, 86,232,145, 35, 71,140,214,173, 91,215, 99,222,188,121, 83, 1, 4,215, 98,251,191, +238,210,165,180,134,114,231,206,157, 17, 20, 20,212,251, 3,133, 22,199,198,198,230,194,225,195,135, 91, 54,110,220, 24,163, 70, +141,106, 53,116,232,208, 11,249,249,249, 61, 1,232,116, 67,170, 83,167,206,198,179,103,207, 54,172,106,100,161, 50, 72,165, 82, +235,111,190,249,102, 67, 82, 82,146, 94, 66,235,232,209,163,248,254,251,239,209,162, 69,139,230,237,219,183,223, 51,101,202, 20, +248,251,251,119,143,137,137,113, 64,105,212,114,141,224,241,120,205,135, 15, 31,206,121,240,224, 1, 0,192,211,211, 19, 45, 91, +182, 68,114,114, 50, 30, 63,126, 12,169, 84, 10, 7, 7, 7, 12, 26, 52,136,151,148,148,212, 60, 39, 39,167, 70,161, 69,114,141, +199, 13,236,215,215,236,220,125, 1, 84,148, 18,109, 26,154,195,199,195, 30,241,169,133,136,140, 77,133, 74,198,134,185,181, 13, + 58,116,237,101,157,145,246,118, 92, 46, 80,179,191, 22,215,120,220,160,129, 95,153,158,139, 72, 71, 65,122, 28,253,250,225,153, +235, 10,137,104, 18, 0, 60,254,243,248, 30, 71, 27,163,158,238,173,219, 48,252,122, 14,176, 58,125, 44, 99, 92,254, 63, 83,219, +239, 61,220,114,193, 94, 87, 86,206,152, 5, 1,190, 52,203,202,249,161,153, 66,177, 83, 51,175, 55,208,107,225,146, 37,237, 39, + 78,158,204,163, 40, 10, 71,126,253,181,240,105, 84, 84,252,100,128,154, 82, 5,223, 78,192,117,232,192,129, 92, 51,115,115,204, +153, 53, 11,102, 10,197,141,178, 93, 2,116,159, 51,127,126,167, 25, 51,102, 24,237, 89, 53,253,113,239, 9,107, 90, 83, 52, 77, +104,134, 41,143, 86,111,138,107, 59, 97,224, 64,152,153,155, 99,246,236,217, 32,228,242,203,101, 2,138,137, 27,227,191,246,245, + 9,232,223, 25, 4, 8, 28, 11,187,131,215,201,217,207,110, 8,240,230,115, 85, 85, 21, 80,165,143, 86,181, 67,135, 69,114,100, +118,255,106,176,192,221,221,189,168, 81,163, 70, 69,185,185,185,120,254,252, 57,242,243,243, 17, 28, 28,140,184,184, 56, 80, 20, + 85,107, 1, 67, 81, 20, 62, 54, 39, 0, 56,216,152, 99, 84,223,118, 76,169, 68,196,203,206,206, 46, 55,124,244, 31, 18, 90,101, + 80, 42,149,188,250,245,235,131, 4, 8, 97,137,194, 52,227,104, 23, 34,227,104, 23, 66, 88,162, 48,149,201,100,164,169,169, 41, +164, 82, 41, 79, 7, 42,214,151, 95,126, 57,255,204,153, 51,172,181,107,215,194,203,203, 11,114,185, 28,247,239,223, 79, 5,144, +165,110,147,126,251,246,237,116,141, 16, 94,191,126, 61, 78,159, 62, 77,244,232,209, 99, 97,101,231,147, 64, 32,216, 56,101,202, +148,188,146,162, 60,236, 29, 38, 70,232,168,108,252, 60,240, 45, 70,216,156, 66, 94,230, 59,236,219,183, 15, 87,175, 94, 35,174, + 92,185,202,190,121,243,166,201, 87, 95,125,181,163, 78,157, 58, 97,213,117, 50, 61, 61,125,237,140, 25, 51, 10,138,138,138, 80, + 84, 84, 4,177, 88,130, 60, 17,240,108, 75, 83, 60,219,210, 20, 18,202, 8,187,118,238, 38,159, 61,123,102,251,246,237, 91,167, +254,253,251,111,225,243,249, 7,171,227, 76, 75, 75,123,240,237,183,223, 74, 10, 11, 11, 33,147,201,228, 42,149, 74, 38, 22,139, + 21,199,143, 31,159,107, 99, 99,211,225,226,197,139,172,171, 87,175, 49,111,222,188,197,190,126,253,186, 69,183,110,221, 78, 56, + 56, 56,252,162,139,165,140,193, 96,108, 11, 9, 9, 25,183,107,215, 46, 7, 31, 31,159,102, 21,134,162,248, 61,123,246,172,247, +235,175,191,214, 9, 10, 10, 90,136,210, 0,148, 79, 10, 91, 91,219,153, 3, 7, 14,196,174, 93,187,112,254,252,249,121, 59,118, +236,192,151, 95,126, 9, 39, 39,167,111,161,251,176, 23, 0,252,184,117,235, 86, 15, 15, 15, 15,140, 25, 51, 70, 54,105,210,164, +239, 14, 29, 58, 84, 63, 60, 60,156,253,203, 47,191,212,155, 58,117,234,236,128,128, 0, 73,131, 6, 13, 16, 28, 28,220,144, 36, +201,109, 58, 93,223, 14, 14,115, 71,140, 24,129, 77,155, 54,225,230,205,155,131, 81,250, 64,149, 1,184,116,247,238,221,254,235, +214,173,195,224,193,131,225,236,236, 60,187, 54,150,167,166, 77,155, 46,235,211,167, 15,194,195,195,209,170, 85, 43,116,232,208, + 97, 30, 0,219, 90,238, 78,210,212,212,244,196,161, 67,135,124,235,213,171,135, 53,107,214,192,205,205, 13, 7, 15, 30,244, 53, + 49, 49, 57, 1, 29,221, 55, 44, 44, 44, 76,141,141,141,177,112,225, 66,122,240,224,193,121, 53,125,230,205,155, 71,115,185, 92, + 88, 89, 89,233, 26,248, 98,196,227,241, 58,122,121,121,225,254,253,251,184,122,245, 42,150, 46, 93,138,185,115,231, 34, 59, 59, + 27,195,135, 15, 55, 6,224,175,199,118,219,219,217,217,161,176,176,180, 46,188,151,151, 23,158, 60,121,130,236,236,108, 56, 59, + 59, 35, 35, 35, 3, 54, 54, 54,104,220,184, 49, 40,138,178,215,141,146,246,178,181,182, 64, 86,190, 20, 76, 40,209,218,221, 22, + 55,158,231,226, 93,182, 12,246, 54,150,200,200,202, 70, 29, 27, 30, 92, 92,234,130,166, 41, 47,157, 20, 48,131,108,205,229, 25, + 33,175, 72,142,180,216,155,185,114,149,116, 74, 65,226,221,148,130,196,187, 41,114,169,100,202,227, 59, 87,115,235, 57, 24,193, +197,197, 5, 4, 77,181,251, 20,215,227,144,186,112, 49, 49, 98,142,185,250,243, 50, 34,108,255, 98, 66,154,251,174,109, 31,135, + 82,203,178, 29, 80,127,200,240,225, 29,191,251,238, 59, 94,102,102, 38, 21, 48,108, 88,222,218,192,192,107,127,212,240, 98, 80, + 12, 52,234,217,179, 39, 72, 0,127, 92,185, 34,202, 0, 82, 1,192, 1,112, 25,240,205, 55, 93,150, 44, 90,100,148,147,155, 75, +221, 79, 40, 62, 23,151, 69, 15,178, 86,161,190, 46,254, 89, 42,192, 91,195,123,249,242,101, 90, 12, 60, 6, 0, 63, 23,124,219, +171,147,167,207,232,129, 93, 32,200,202,199,236,181, 63, 99,207,201, 91,151, 45, 20,244, 23,255,161, 71,241,228, 90, 9, 45,245, +208,207,123,211, 74, 74,222, 31, 61,248, 80, 1,243,119,112, 86,134,255,162,208,210, 64,161, 40, 29, 37,145, 41, 40,200, 20,148, +230,173, 22, 98,177, 88,103,138,203,151, 47, 31,158, 53,107, 22,182,108,217,130, 87,175, 94,129,205,102,195,203,203,139, 15,192, + 84,115,207,111,221,186,181, 61, 73,146,136,143,143,199,230,205,155, 49,126,252,120,250,222,189,123, 7, 81,121,190,148, 39,121, +121,121, 59,167, 76, 26, 95,144,159,249, 14, 10,113, 62,178,210,222, 64, 42, 42,192,154,245, 27, 81,162, 96, 34, 67, 40, 71,134, + 80, 14,146,107,141, 61,251, 15, 49,154, 54,109,218,135,193, 96,244,171,166,159,247, 51, 51, 51,247, 79,155, 54,173, 32, 35, 35, +163,108,251,100, 10, 26, 50, 69,249,243,213,216,216, 24,219,182,109,179,112,119,119, 31,200,100, 50,187, 85,195, 41, 72, 73, 73, +137,155, 54,109,154, 44, 51, 51, 19, 66,161, 16,231,206,157,235, 95,175, 94, 61,171, 13, 63,110, 33, 68,114, 38, 50, 10,228,200, + 40,144,131, 99,106,143, 19,161,103, 24,141, 27, 55, 14, 96, 50,153, 29,106, 18, 89, 71,142, 28, 25, 61,108,216, 48,179, 31,127, +252, 49,239,236,217,179,187, 0,104, 31,144,248,109,219,182,157, 60,113,226, 68,209,252,249,243,173,131,130,130,230,125, 98,177, +213,109,216,176, 97, 77, 40,138,194,169, 83,167,158, 1,216,122,230,204,153, 71, 82,169, 20,195,135, 15,175,175, 30, 70,210, 5, +109, 3, 2, 2,166,251,250,250, 98,206,156, 57,242,107,215,174,181, 6,176, 5,165, 67,185, 52,128,100, 0, 59,110,221,186,213, + 98,230,204,153,210,118,237,218, 97,236,216,177,227, 1,248,214,192,219,113,196,136, 17, 30, 20, 69,225,248,241,227, 79, 1, 92, +172, 48,255,122,104,104,232,125,153, 76,134,145, 35, 71, 54, 0,160,207,141,156,205,229,114, 79,173, 94,189,218, 50, 45, 45, 13, +163, 71,143,150,198,199,199, 35, 48, 48,208,200,194,194,226,162,214, 53,160, 51,184, 92,238,190,159,126,250,105,160,183,183, 55, +166, 77,155, 38,219,189,123,247,172,233,211,167,203, 90,183,110,141, 93,187,118, 13,228,112, 56,122,149,232, 72, 79, 79, 47,136, +141,141,181,169,233,147,154,154,170,107,120,190,177,169,169,105,132,167,167,103,161,151,151, 87, 27,165, 82,137,152,152,152, 55, +135, 15, 31,166,188,188,188,176,115,231, 78, 4, 5, 5,161, 95,191,126, 96, 48, 24, 58, 11, 45, 6,131, 1,185, 92, 14, 99, 99, + 99, 48,153, 76,188,121,243, 70,147, 90, 6,108, 54, 27, 0, 96, 98, 98, 2, 35, 35, 35,144, 36,169, 83, 52, 26, 65,128, 46, 44, + 81,128,197, 34,193, 36, 41,196, 37, 11, 33, 87, 80,224,177, 25, 96, 49, 9,128,166, 96,105,194, 2,143,195, 0, 73, 16,148,142, +156, 16,138,228,224,176, 73,176,216, 28,130, 84,170,140,202, 30,142, 76,149,145,145, 17,135,176, 53,231,130,199,254, 23,149, 5, + 38, 74, 29,203,199, 1, 44,147,186,117,135,110,218,188,153, 83, 88, 92,140,193,131, 7,231, 37, 61,122, 20, 34, 6, 30,117,173, + 33, 72,137,100, 50,221,253,186,118, 69,100, 84, 20,138,242,243, 95, 3,165,206,241, 28, 39,167, 97,219,182,109,227,136, 37, 18, + 12, 30, 52,168,224,213,157, 59, 71, 82,138, 17,118, 60,185, 84,136,213,120,220,217,108, 71, 13,175, 48, 63, 63, 31, 40, 77, 33, +225, 96,103,186, 97, 70, 64,111, 20,149, 72,176, 96, 99, 8, 21, 21, 39,248, 54, 60, 21, 95,157, 73,135,240, 63,246, 24,158, 92, +225, 3, 64,135,132,165, 26,235, 82, 77, 98, 69, 42,149,126,116, 1,244,161,156,149,137,196, 15,229,252, 55,130,201,100, 74, 94, +190,124,201, 49,183,113,162,108,204, 88,249,245,198,223,177, 0, 0,107, 83,166, 80,174, 82, 80,233,233,233,224,114,185, 18, 29, +135, 27, 38,237,219,183,111, 13,128,102, 76, 38, 51,236,208,161, 67, 68, 72, 72,136,213,136, 17, 35, 18, 98, 99, 99,211, 60, 61, + 61, 93, 15, 29, 58,100, 14, 0, 59,118,236,160, 79,156, 56,209, 27,165, 41, 51,170,204,227,146,153,153, 25,152,155,155,123,111, +198,140, 25,193, 28, 14,199,202,196,196,196, 38, 60, 60,156,144,200,105,180, 93,146, 92, 22,137,104,110, 68,226,246, 98,115, 76, +158, 60,153, 17, 27, 27,187, 62, 45, 45, 45,172, 26,206,133, 5, 5, 5,225,175, 94,189,218, 98,225,220,210,206,196,117,137,133, +207,226,120, 0,128,171, 45, 11,164,250,190, 88, 80, 80,128,236,236,108, 76,159, 62,221, 42, 33, 33, 97, 97, 90, 90,218,141,106, +172, 90,183,114,114,114, 82, 95,188,120,225,199, 98,177, 56, 38, 38, 38,109, 35, 34, 34, 8,137,140, 66,243,133,201,200, 43, 46, +237,167,181, 41, 19,143, 87, 59,224,219,111,191,101,190,126,253,122,163, 64, 32,232, 92,233,205,140, 36,131,180, 69,214,130, 5, + 11,162, 1, 52, 0, 80,110,104, 84,165, 82, 17, 35, 71,142,124, 14,192,107,254,252,249,214, 52, 77,207, 91,184,112, 97, 30,128, +189,255,244,185,100,110,110,190, 97,202,148, 41, 56,113,226, 4,242,243,243,183, 1, 64, 97, 97,225,214,163, 71,143, 30,159, 52, +105, 18,126,253,245,215, 13,217,217,217,127,160,230, 80,237, 47,135, 15, 31,142, 75,151, 46,225,207, 63,255, 92, 6, 32,166,138, +118,175,194,195,195, 23,158, 61,123,118,251,136, 17, 35,240,243,207, 63,247, 1, 80,157,131,108,207,222,189,123,227,226,197,139, +200,205,205,221, 85, 89,131,130,130,130,221,231,206,157,107,223,187,119,111,172, 95,191,190, 39,128,235, 58,108,186,135,133,133, +197,161,237,219,183,183,245,246,246, 70, 64, 64,128, 68, 46,151,247,153, 63,127,254,249, 99,199,142,153, 29, 62,124,184,205,228, +201,147, 31,168,115,190,221,215,201,148, 69,146,235, 54,111,222, 60,193,207,207, 15,243,230,205, 83, 94,190,124,121, 0,128, 43, +127,252,241, 71,194,130, 5, 11, 46,108,222,188,153,177,105,211,166, 9,179,103,207,206,166, 40,234, 83,137,235,213, 59,118,236, +104,223,171, 87, 47,188,121,243, 6,247,239,223,135, 92, 46,255, 53, 34, 34,226,118,163, 70,141, 86,203,100,178,243, 38, 38, 38, + 99,204,204,204, 60, 91,182,108,249,197,227,199,143,141,161,155,159, 94,102, 98, 98,162,165,133,133, 5,148, 74, 37,158, 61,123, +134,186,117,235, 66, 46,151,227,237,219,183,240,246,246, 6,155,205, 70,102,102, 38,180,172,229, 53,136, 34,242, 89, 66, 82,122, + 3,107, 51, 19, 64,197,195,147,248, 84,216,217, 90, 65, 69,144,200,200, 16,160,101, 19,103, 16, 4,129,130,220, 12, 16, 4,241, + 92, 23, 78, 21, 77, 69,190, 75,207,170, 99, 99,198,133,119,251, 94, 54, 17,127,100,135,152, 55,232, 52,153,201, 32, 24, 28,174, +233,222, 9, 99,199,218, 82, 20,141,130,220, 76, 48, 73,242,225,167, 56, 64,167,222, 33,165,171, 27,239, 73,175, 9,107, 90, 18, + 52,104,177, 28,135,127,206, 68,190, 49,208,114,199, 15, 63, 88,218,216,218, 34, 32, 32,128,202, 77, 75,187, 86,162, 99, 98,229, + 6,141, 26, 57,152,154,153,225,238,221,187, 96,148,250,216,226, 32,224, 17,180, 96,129,141,189,163, 35,198, 79,152, 64,101,190, +123,119, 93, 12,164,235,211,215, 6,110,110, 44, 13, 47,169,230, 21, 48, 48,107,254, 0, 95,174,137, 17, 23,235,246,156, 65, 74, +142,232,120,132, 0,123,254,163,246,142,125,213, 90,180,170,114, 62, 43,117,170, 54,174, 86,172,240,120,188, 50,107,138, 30,111, +122, 31,157,179, 38,252, 29,156,159, 16,139, 1,156, 5,176, 56, 37, 37, 37,110,194,132, 9,114,165, 92, 90,116,111, 77,131, 69, + 81,235,235, 77,139, 8,228, 79,251,125,150,197,162, 18, 97, 94,209,142, 29, 59, 20, 41, 41, 41,113,218,203,212,192,253, 14,192, +197, 95,126,249,101,247,169, 83,167,224,229,229,133,152,152, 24,123,145, 72,212,234,249,243,231,214, 30, 30, 30, 8, 9, 9,193, +137, 19, 39,182, 0,184, 90,157,200,210, 64,169, 84, 94,203,200,200,104,156,156,156,220,208,210,210, 82, 97,105,105,137,138,145, +136,133, 98, 10,185, 5, 66, 88, 91,219,192,220,220,188,190, 14,226,252, 98, 70, 70,134, 59,101,213,164,139,123,206, 54, 97,228, + 58, 23, 68,174,115,193,197,133, 78,224, 91,114,144,159,159,143,236,236,108,100,103,103,131, 32, 8, 40, 20,138,166, 58,112,190, + 21, 8, 4, 7,222,189,123,119,214,193,193, 1,102,102,102,160, 1,100, 20, 40, 16,189,201, 3,209,155, 60,144, 81,160, 64, 97, + 81, 17,234,213,171, 7, 51, 51,179,170,134, 40,200, 58,117,234,244, 29, 54,108,152, 25, 0,168, 5, 84,119,154,166,167, 85,242, +153,170, 84, 42, 59,105,218,126,255,253,247,214, 0,122,255,195,231, 19, 3,192,140, 73,147, 38,181,225,241,120,216,185,115,231, + 91, 0, 71, 52,247,250,221,187,119,199, 3,192,172, 89,179, 60, 1,204, 67, 21,153,160,203, 76, 67,108,118,235,166, 77,155, 34, + 34, 34, 2, 0,206,212,176,238,208,123,247,238,161, 81,163, 70,224,241,120,109,107,104, 91,223,197,197, 5,241,241,241, 0,240, +164,138, 54, 79,226,227,227, 75,135,123, 8,162,190, 14,219, 62,176, 87,175, 94,207,110,220,184,209,182, 99,199,142,152, 48, 97, +130,236,193,131, 7,125, 1,220,126,242,228, 73,183,145, 35, 71,138,220,221,221,113,235,214, 45,143,145, 35, 71,222, 35, 73,114, +141, 14,156,227, 87,173, 90,181,248,235,175,191,198,170, 85,171,232,147, 39, 79, 6, 0,184,162,158,119,249,248,241,227,163,215, +174, 93, 75, 15, 26, 52, 8, 43, 87,174, 92, 12, 96, 90,117,100, 34,145, 72,168, 82,169, 32, 18,137,116, 50,201,235,218,222,214, +214,246,203, 94,189,122, 97,233,210,165,168, 83,167, 14,206,159, 63, 79, 3, 8, 3, 16, 46,147,201,186, 0,216, 44, 18,137,126, +143,136,136, 64,207,158, 61,217, 40, 95, 98,164,186,245, 63, 59,122,244,168,212,194,194, 2,174,174,174,104,208,160, 1, 50, 50, + 50,144,148,148, 4,111,111,111,180,110,221, 26, 74,165, 18, 7, 14, 28,144, 20, 21, 21,233,148,147, 79, 41, 19, 29,190,122,225, +180,208,198,140, 11,103,123, 11,212,171, 99,141,226,130, 28,100,103,164,163,117,211,186,232,218,186, 30,114,132, 50, 92, 14, 59, +157, 95, 84, 84,114, 88, 39, 19,190,180,228,208,181, 63,206, 11,173,204,216,104,220,196, 19, 35, 39,204,106,217,178,149,207,213, +118,237, 58, 93,254,113,195,186,230,221, 59, 52, 37, 82,115, 36,184, 20,118, 38, 95, 88, 88,120,232, 83,220,232, 87, 2, 12,137, +133,251,237, 93,103, 35, 15, 52,235, 51,233, 64, 92, 42,182, 1,128,130,193,240,232,251,229,151, 72, 77, 77,197,233, 83,167, 4, + 37,192, 83, 93,249,140,140,140, 72, 0, 16, 10,133,224,170,253,238,148, 64,147,175,190,250, 10,217, 57, 57, 56,122,228, 72,246, + 37, 32, 74,159,126,246, 7, 56,198, 70,165, 6, 65,161, 80, 8, 2, 40, 4, 0,130,137,190,237,188, 26, 33, 59,175, 16, 55, 30, +198, 21,215, 19, 99,122,117, 60,159,177, 35,124,237,124,180, 0,228,204,155, 55, 15, 92, 46, 23,124, 62,191, 76, 28,105,196, 10, +135,195, 1,159,207,135, 82,169,196,241,227,199, 1, 32,167,218, 55, 60, 64, 58, 96,218,122, 74,170,160, 75, 88, 44,214, 71,225, + 84,191, 57, 74, 7, 47,248,153,250,227, 94,229, 65, 49,181,225,252, 12,208, 78,157, 19,171, 29,128,252,164,164,164,212,161,131, + 7, 8,147, 19, 94,100,136, 10,210, 5,133,185, 41,130,148,183,207, 51,150, 44,156, 39, 76, 77, 77, 77, 65,105, 46,173,118,233, +233,233,154,101,116,193,188,161, 67,135,254, 52,105,210, 36, 58, 58, 58, 26, 0, 16, 25, 25,137,177, 99,199,210,163, 71,143,222, + 6, 96, 81, 45,250, 45, 18,139,197,229,172, 33,114, 21, 85, 54,228, 87, 88, 88,136,244,244,116,200,100, 50,157, 21,241,171,203, +155, 94,230, 37, 61, 86,120,186,154,192,211,213, 4, 30, 46,198, 32,148,197,101, 34, 43, 59, 59, 91,243,230, 44,209,163,159,133, + 82,169,180, 92, 63,181,135, 38, 11, 11, 11,145,145,145, 1,149, 74, 85,213,131,140, 74, 75, 75,187,124,226,196,137, 34, 0,248, +241,199, 31,243, 8,130,248,147, 32,136,159, 42,249,236, 97, 50,153,119, 53,109, 55,109,218,148,135,247,135,196,254, 78,124,237, +237,237,157,191,120,241,226,157,179,103,207,198,158, 61,123, 32, 16, 8, 22,225,175, 92, 60, 84, 78, 78,206,130, 93,187,118, 97, +220,184,113, 88,190,124,249,166, 86,173, 90, 21, 2, 24, 89, 21,161,157,157,157, 51,147,201, 68, 84, 84, 84, 33,128, 55, 53,172, + 63, 35, 42, 42, 42,147, 32, 8,240,249,124,183,234, 26, 90, 91, 91, 55, 52, 51, 51, 67, 90, 90, 26,160,126, 99,174, 4, 73,233, +233,233, 52,135,195,129,147,147, 83,163,154, 54,222,202,202,106,193,129, 3, 7,152, 47, 94,188, 64,247,238,221, 83,111,221,186, +213, 19,128, 38, 36, 61, 42, 50, 50,210,183, 91,183,110, 47,175, 94,189,138,141, 27, 55, 18, 45, 90,180,152, 86, 19,167,171,171, +235,212,241,227,199, 35, 56, 56, 24,123,247,238,157, 6,224, 84,133, 38,199,118,237,218, 53,107,239,222,189,152, 48, 97, 2,234, +215,175, 63,178, 58,190,228,228,228,133,126,126,126,145,175, 94,189,210,169,226,129,142,237,187,249,248,248, 52, 20,139,197, 56, +116,232,208,155,134, 13, 27, 62, 58,117,234,212, 60,188,255,192,254,253,244,233,211, 24, 53,106, 20, 90,180,104,113, 8,192, 8, + 93, 46,203,216,216,216,148,235,215,175, 83,108, 54, 27,174,174,174,232,215,175, 31, 2, 2, 2,208,188,121,115,200,229,114,156, + 62,125,154,122,254,252,121,170, 76, 38,211, 41,151, 82,238,171,155,231, 19, 19,255,199,222,121,135, 55, 85,253, 97,252,189,217, + 59,105,218, 52, 29,148,150, 2,165,147, 85,160,236, 81, 40,101,149,141,162, 34, 56, 1, 5, 68, 5,197, 1, 40,202,146, 37, 67, + 86, 5, 5, 17, 20, 16, 89,101,169, 40,200,166, 5, 74,129,178,186,103,210,221,166, 73, 51,239,249,253, 65,203,175,212,142,164, +197,129,222,207,243,220, 39,201,185,185,111,206, 93,231,190,249,158,117,231,236,149,139,167, 45, 28, 54, 11,222, 30,206, 24, 29, +209, 17,175,140,235,137, 78,129,205,144,166, 53,224,228,201,159, 44, 41, 41, 73,231,237,233,113, 88,165,153,120, 51,254,220,141, + 43,103,172, 92, 14,133,192,128, 54,152,251,193,187,202, 69, 31,205,113,106,211,202, 27,241,201, 37,248,233,196, 81, 75,118,102, +198,175,127, 87,143,195, 83, 0, 79, 42,160, 36,108, 22, 11, 54,150,160,156, 93,217,145,166,109,112,176,191,155,187, 59, 98, 98, + 98,192,114,160, 71,232, 41,128, 39,149, 62,168, 5,215,233,116,168,210,107, 29, 16, 16,224,237,227,131, 35, 49, 49, 96,211,244, +173,190, 14, 14, 48,122,251, 65, 53,244, 67, 93, 10,168,120,189, 57,100,173,155,171, 3,148, 10, 9, 46,198,223,131,209, 66, 46, +125, 91,132,191,117, 60,178, 63,145,201,104,100,213,225,242, 77,155, 54,133,109,217,178,101,224,219,111,191, 45,157, 52,105, 18, +132, 66, 33,244,122, 61,188,188,188, 96,179,217,112,236,216, 49,196,198,198,234,104,154,254, 9,127, 28, 54, 32, 2,213,122,105, + 28, 79,130,232,129,223,210,135, 29,120,234,169,199,162, 9, 0,210,123,180,188,160,133,105,199,218, 61,103,198,236, 60,126,133, +122,243,217,190,172, 78, 1,205, 1, 0,110,110,110,144,203,229, 14,107, 62, 6,254,116,205,234,213,186,185,185,185,183,115,115, +115,181,175,190,250,106, 96, 85,195,119,129, 64, 80, 81, 25,201, 42,170,109, 27, 59,242,105, 6,240,250,150, 45, 91, 14,150,148, +148, 28,127,231,157,119,176,104,209, 34, 28, 58,116,168, 55,128,179,141,220,119, 91, 81, 81, 81,241,165, 75,151,220,252,130, 66, +209, 82,205, 69,159,121,119, 65, 8,129,139,152,160,172,184, 16, 87,175, 94, 65, 89, 89,217, 69, 71,242,105, 54,155,139,181, 90, +173, 74,173, 86,163,176,176, 16,249,249,249, 15, 77, 86, 81, 81, 17, 10, 11, 11, 9, 69,253, 97,204,150,250, 52,203,181, 90,173, + 62, 49, 49,145,239,214,220, 15,173,212, 60,116,253,224, 54, 64, 8,188,157, 89, 40, 43, 45,198,249,243,231, 81, 82, 82,242, 91, + 93,154, 52, 77,207,154, 48, 97, 2, 27,192,196,119,222,121,199, 25, 64,135,119,223,125,247, 39,212,232, 89,200,225,112, 62,223, +177, 99, 71,219,170, 42,198, 57,115,230,172, 2,176,229,175,186,150, 92, 92, 92,102,197,196,196,200,204,102, 51,214,174, 93,139, + 85,171, 86,109,197, 31, 7,170,140,249,226,139, 47,214,179, 88,172,105,211,167, 79,199,148, 41, 83,196,157, 59,119,126, 59, 39, + 39,231,219,218, 52,179,178,178,230,118,234,212,105,190, 86,171, 93,108,151, 89,190,123,119,114,167, 78,157,230,106,181,218,101, +245,157, 35,137, 68, 34,177,217,108, 72, 73, 73, 41, 2,234,108,223, 81,145,146,146,146,101,179,217,188,196, 98,177,115, 67,215, +103, 81, 81,209,226,206,157, 59,127,172,209,104, 78, 0, 88, 88,139, 33,191,150,147,147, 19, 50,115,230,204, 25, 75,151, 46, 29, +147,155,155,251, 93, 67,154,105,105,105,139,195,195,195,231,221,185,115,103, 27,234,174, 2,254, 98,193,130, 5,230, 29, 59,118, +188,150,146,146,178,164, 1,205,195,249,249,249,135, 29, 56,191,117,125,255,161, 38,155,205,126,119,233,210,165,172, 77,155, 54, +129, 16,178,194,102,179,213,149,207,248,253,251,247,111,239,217,179,231,164, 61,123,246, 8, 67, 66, 66,166, 24,141,198, 93, 13, + 93,159,122,189,126,223,158, 61,123,198,196,199,199,123, 77,154, 52, 73,232,239,239, 15,179,217,140,156,156, 28,108,218,180,169, + 34, 33, 33, 33,179,184,184,120,159, 35,101,136,213, 84,250,236,185,147, 7,118,165,222, 77,232,222,111,240, 72,165,201,236, 5, + 65, 1, 27,197, 5,185, 56,118,120, 95, 81, 74, 74,210,121,189,190,248, 89, 71, 52,205,198,146,103,206,255,122,240,187,204,148, +196,110,125,194,135, 42, 43, 76, 62, 16,240, 88, 40,208,100,225, 88,204,129,194,148,148,228,223, 43, 44,198, 23,254,174,114,158, +237,139,133,236,220,216, 87,167, 14,239, 8,145,210,235, 42, 23, 88,219, 19, 16,169,220,220,120,149,247, 14,164, 15,218, 60,218, +165,169, 1,248,126,149,181, 84,122,189, 30, 92,192,244, 34,192,117,117,117, 21, 1,192,157, 59,119, 32,126, 80,171,225, 80, 62, +117,128, 68, 92, 77,151, 5,232, 11, 56,104,214, 90, 46,161, 0, 32, 51,183, 0, 38, 75,189,207,141, 39,157,232,106,134, 43,186, + 49, 2, 60, 0, 17, 82,169,116,209,252,249,243, 87, 92,188,120,113, 69, 84, 84,212, 10,129, 64,176,168,242, 96,243,234, 57, 17, +127,153,102, 23, 79, 56,135,183,162, 78, 71,182,166,232,169,189,149,182, 23,186, 74, 76,253,251,247, 95,223,196,124, 54,229,102, +249, 51, 53, 15, 88, 44, 22,130, 7,213,118, 7, 80,119,149,224,251,213,214,231,166,167,167,147,202,247,142,228, 83, 53,126,252, +120,186,172,172,140, 60,253,244,211, 4, 13, 79,225, 83,175,166, 64, 32, 8,239,211,167,143, 69,147, 87, 72,110, 39,103,145, 11, +113, 55,201,241,147,231,200,119,251, 98,200,186,245,155, 73,251,246,237, 77, 0,124, 28,209,228,112, 56,253,195,195,195, 11, 52, + 26, 13, 73, 76, 76, 36,167, 79,159, 38,123,247,238, 37,155, 55,111, 38, 27, 55,110, 36,205,155, 55,215, 0,112,115, 68, 83, 36, + 18,141, 28, 50,100,136,165,184, 84, 79, 82,178, 10,200,245,196, 20,114,246,210,117,114,236,228, 89,242,237,174, 61, 36, 56, 56, +184,194, 14, 77, 54,155,205, 94,247,221,119,223,149, 18, 66,200,200,145, 35, 51,241,232, 64,170, 45,103,205,154,165, 37,132,144, +101,203,150, 21,160,246,134,240,127,246,181, 52,184, 89,179,102,183,121, 60, 94, 12,128,137, 13,108,247, 12,135,195, 57,228,238, +238,126, 25,192,232,191,225, 62,138, 82,171,213, 23, 0, 52, 52,195, 65,213,247, 70,253, 75,238,247, 63, 67,179, 63,135,195, 57, + 13,212, 63,137,112,181,242,250, 83, 54,155,125, 4,192, 0, 7,243,217, 70,165, 82, 61,173, 84, 42,223, 84, 42,149,111,170,213, +234,167,249,124,126,155,166,236,187, 75,155,136,225,222,161, 35,246, 55,239, 48, 44,205,187, 99, 84,154,111,167,145,251, 93,218, + 68, 12,111,170,166, 79,167,145, 7,188, 59, 70,165,123,119, 28,158,218,178,203,200,253,170,128,136, 33,127,231, 57,154,216, 12, +158, 3, 91,194, 74, 78,207, 35,228,244, 60, 18,209, 18,116,119, 39, 4,135, 1,178, 65, 17, 17, 43,137,205,182,114,204,168, 81, + 43,253, 0, 23, 2,176,107, 46,181,105,134, 2,242,135,219,142, 28,185,178, 21,160, 26, 8,136,251,246,238,189,130,216,108, 43, + 39, 60,243,204, 74,111,192,189, 54,189,186, 52, 9,192,110, 6,120, 86,215, 85, 1,173,199,249, 34,228,253,225,190,132,156,158, + 71, 22, 60,229, 79, 58,185, 97, 98, 3,154,117, 69,138,158,232,136,150,163, 72, 42, 11,215, 37,149,175,146,199,112, 17, 62,118, +205,110, 30,240,143,104, 77, 37, 14, 13,224, 20,226, 65,151,100,201,191,176,144,220,102, 50,153, 72, 69, 69, 5,209,235,245, 68, +167,211,213, 52, 80, 15, 13, 89,118,118, 54,201,204,204, 36,233,233,233, 36, 53, 53,149,224,255,109,111,236,206,167, 92, 46,223, +242,212, 83, 79,217,184, 92,238,186,199,177,239,206,206,206, 75,186,118,237,106, 94,179,102, 13,217,191,127, 63,249,242,203, 47, +201,244,233,211, 73,219,182,109,141, 78, 78, 78,207, 54, 70,211,221,221,125,110, 64, 64, 64,193,214,173, 91,201,183,223,126, 75, + 86,175, 94, 77, 62,252,240, 67,155,151,151, 87,174, 76, 38, 27,212, 24, 77,181, 90, 29,221,171, 87, 47,115,116,116, 52,249,233, +167,159,200,206,157, 59,201,172, 89,179, 72, 96, 96,160, 81, 34,145,140,181, 83,147,205,225,112, 86, 78,157, 58, 53,215,211,211, + 51,166,198, 58,113,112,112,240,229, 9, 19, 38,100, 3,152,243, 47,186, 62, 25, 77, 70,147,209,252, 19,140,214,115,158,104, 70, + 0,182,152,199,123,166,111,239,222, 43,120,192, 51,142,154, 34, 33,155, 61,174,103,215,174, 43,120,192,179, 85,223, 21,178,217, +227,250,246,238,189,130,203,102, 63, 95,151, 94,125,154, 4, 96,243, 56,156, 57, 61,187,119, 95,201, 1, 62,168, 74,235,223,146, +186, 53,107,112,115,210,219,135,186,247,188, 26,226,127,177,209,122,236,112,254,132,139,240, 73,209,252,167,220,212,126,149,134, +233,128, 3, 17,173, 3,120, 48,139,186, 95, 35,243, 41,122,204,251,222, 78,165, 82, 29,245,243,243,203,107,209,162, 69,182, 82, +169,220, 5,192,171,137,154, 33,238,238,238,223,184,185,185,221,245,240,240,136, 87,169, 84,159,227,193,168,243,141,214,228,114, +185, 93,221,220,220,126,243,245,245, 45,246,241,241,209,168, 84,170,239,106,137,100,217,163,233,129,218, 11, 21, 94,229, 58,230, +161,195,104, 50,154,140,230, 35, 6, 38,178, 21,150, 14,108, 9,235,192,150,176, 69,250,226,243,234, 6, 37, 10, 16, 53,214, 20, +189, 0, 8,106,126,191, 33,189,134, 52, 9,192,238, 1, 72,107,110, 51,212, 11,193,118,106, 62,233, 17,173,170,114,222,177,225, + 29,234,192,250, 39,100,242, 73,209,252,167,112, 15,245, 52, 70,174,198,146,199,248,155,134,199,188, 15,215,243,243,243,135,228, +231, 63,214,190, 9, 55,114,115,115, 39, 62, 78, 65,139,197,114, 81,163,209,244,123, 12, 82,117,117,189, 54,195,206,110,217, 12, + 12, 12,255, 29, 40,192,134, 36,188, 23,209, 6,107, 57, 54,176,142, 37, 35,171, 70,151, 60, 3,213, 24,205, 7,216,182,213, 82, +198, 83,141,205,231,255,209,253, 65, 35, 19, 55,169,255,206,105,203,193,131, 54, 90, 77, 54, 90, 12, 12, 12, 12, 12, 12, 12,127, + 1, 63,223,101,254,136, 61, 1,196,224,209,232, 91, 76, 53, 35, 90,103,232,211,145,158, 20,141, 9,159,254,204,104, 50,154,140, + 38,163,201,104, 50,154,140,230,127, 78,179,138,186,230, 78,189, 93,227,115,163,122,241,253, 87, 96,234,217, 25, 77, 70,147,209, +100, 52, 25, 77, 70,147,209,252,183,211,232,113,180, 24, 24, 24, 24, 24, 24, 24, 24, 24,234,167,206,168, 27, 99,180, 24, 24, 24, + 24, 24, 24, 24, 24,154,134, 7, 30, 76, 81, 21,131,255, 79, 85, 21, 13, 52, 60, 5,207, 35, 44, 93,186,148,229,231,231, 39,229, +243,249,109,147,146,146, 88,175,191,254,122,147, 59, 18,172,248,124, 29,203,199,199, 71, 10,160,109, 65, 81, 25,235,165, 87,222, +161,152,243,197,192,192,192,192,192,192,240, 4, 49,172,210, 88, 85,189, 62,140,112, 57,100,180, 22, 46, 92,136,244,244,116, 9, +128,241, 33, 33, 33,252, 13, 27, 54,144,221,187,119, 55,201, 24,125, 48,103, 22,210,210,210, 36, 0,198,171, 85, 78,252,175,182, + 44, 39,123, 14,157,121,236,102, 75,165, 82,185,252,149,219, 49, 48, 48, 48, 48, 48, 48,252,167,152, 92,237,117,114,163,140, 22, +135,195, 97,243,249,252, 86, 44, 22,107,136, 80, 40,236, 2, 0,149, 83,178, 52, 26, 14,135,195,230, 11, 4,173,216,108,246, 16, +129,224,129,230, 83,195,123, 53, 85,115,128, 68, 34,201, 16,139,197,177, 0, 68, 50,153,236,138,217,108,190, 41,147,201,206, 57, +162, 35,147,201,206, 85,110,119, 5,128, 72, 44, 22,199, 74, 36,146, 12, 14,135, 51,128,185,158, 24, 24, 24, 24, 24, 24, 24, 42, +137,174,101,249, 35,135, 15, 31,174,211,224,240,249,124, 86, 72, 72, 72, 47, 31, 31,159,179, 65, 65, 65, 38, 47, 47,175,189, 98, +177, 88,210,196,140,177,252,252, 3,123,121,122,184,157,237,216,202,195,164, 86,171,247,114,185,220,166,104,178,101, 50,217,234, +200,200,200,146,179,103,207, 18,185, 92,174, 1,224,228,234,234,154, 77, 8, 33,238,238,238,180, 35, 98,238,238,238, 52, 33,132, +184,186,186,102, 3,112,146,203,229,154,179,103,207,146,200,200,200, 18,153, 76,182, 26, 13,143,104,203,192,192,192,192,192,192, +224, 0,245,121,145,127, 48, 85, 81, 44,143, 70,239, 28,159,207, 15, 85,169, 84, 9,111,189,245,150, 45, 58, 58,154,248,248,248, + 92, 82,171,213,221, 85, 42,213, 35, 13,234, 95,124,241, 69, 71,170,253, 66,101,114, 69,194,182,153,131,109,134,175, 70,146,102, + 30,234, 75, 78, 78, 78,221,229,114,249, 35,154, 19, 94,154, 98,143,166, 44,251,138,210, 0, 0, 32, 0, 73, 68, 65, 84,167, 66, +161,136, 95,186,116,105, 69,113,113, 49, 33,132, 16,133, 66,161, 1,160,116,115,115,203, 78, 78, 78, 38, 42,149,138,192,254, 40, + 30, 75,165, 82,145,228,228,100,226,230,230,150, 13, 64,169, 80, 40, 52,132, 16, 82, 92, 92, 76,150, 46, 93, 90,161, 80, 40,226, + 1,120, 50,183, 5, 3, 3, 3, 3, 3,195,127,218,104,213, 52, 92,246, 85, 29,118,233,210, 69,224,230,230,214, 93, 38,147,141, +146, 74,165,235, 71,140, 24, 17, 50,102,204, 24,150,209,104,180,133,132,132,120,250,250,250,206, 80, 42,149, 19,133, 66, 97,123, + 62,159,255,188, 92, 46,247,216,181,107,151, 95,125,154,237, 58,116, 22, 56, 57, 41,187,243,249,130, 81, 82,169,108,253,212,113, +253, 67, 38,190, 61,150,197, 51,165,218,250,183,247,246,108,219,202, 99,134,187, 82, 50,145,195,102,181,167, 40,234,121,161, 80, +232,241,237, 87,155,253, 26,216,177, 86,158,158,158, 87,118,237,218,213,118,252,248,241,130,196,196, 68, 0,128,205,102,227, 3, +176,176,217,108, 8, 4, 2,152,205,230, 34, 0,246,158, 64, 98, 54,155,139, 4, 2, 1,216,108, 54, 0, 88, 42,245,144,152,152, +136,241,227,199, 11,118,237,218,213,214,211,211,243, 10,128, 86,204,173,193,192,192,192,192,192,240,159,165,202, 92,197,160, 70, +213, 33,167,202, 61, 70, 69, 69, 61, 18, 53,226,243,249, 27,238,220,185,211,211,217,217,185, 21,151,203,181, 61,243,204, 51,130, + 9, 19, 38, 32, 47, 47,143,214,233,116,236,208,208, 80,183,203,151, 47, 15,177, 90,173,189,157,156,156,244,197,197,197, 42,163, +209,120, 15,192,140,122, 50,178,225,238,237,132,158, 46, 74,231, 86,124, 46,219, 54,253,229, 9,130, 15,230, 12, 6,101,140,163, +109,218, 2,246,167,157,156,220, 62, 63, 87, 62,228,142,217,214,187, 92, 33,212,231,150, 24, 27,212, 84,169, 84,157,120, 60, 94, +236,209,163, 71, 33, 22,139, 81, 82, 82, 2, 62,159, 15, 0,208,233,116, 10, 0, 28,138,162,192,231,243, 81, 90, 90,170,116,228, +168,149,150,150, 42,249,124, 62, 40,138, 2, 0, 78,165, 30,248,124, 62, 74, 74, 74,224,231,231, 71, 29, 61,122, 84, 61,100,200, +144,251,102,179,185,115,126,126,126, 28,115,173, 49, 48, 48, 48, 48, 48, 56, 78,109, 94,228, 9,162,193,113,180,250, 85,134,234, +170, 79,156,187,221,213,213,213, 93, 42,149, 6, 77,158, 60,153,165, 82,169, 16, 27, 27, 75,151,151,151,179,184, 92, 46,184, 92, + 46,187,127,255,254, 82,171,213, 42, 62,114,228, 8,117,255,254,253, 60,139,197,242,105, 65, 65,193,229,122, 50,178,189,181,147, +192, 93,228,196, 15, 58,244, 78, 31,150,171, 95, 1,112,124, 1, 77,116, 90, 22,135, 38, 80, 73,104,246,202,222,148, 52, 87,225, + 43,158,254, 93, 30,245,251,253,226, 60,139,197,242,105, 89, 89, 89,125,154, 89, 0, 80,153, 39,200,229,114,216,108,213,231,183, + 4, 97,177, 88, 16, 8, 4,141, 58,114, 2,129, 0, 44, 22, 11,168, 22, 9, 83, 40, 20, 96,179,217, 96,177, 88,224,114,185,143, +228,131,129,129,129,129,129,129,161, 81,212,230, 69,158, 20,170,143,163,101,223,220,148,110,110,110,148, 92, 46,247,232,208,161, +195,199,145,145,145,201,163, 71,143,214,175, 89,179,134,172, 90,181,138,172, 92,185,146,108,221,186,213,246,235,175,191, 90, 94, +121,229,149,138, 54,109,218,220, 91,191,126,125, 16, 0, 12, 29, 58,180,206,234, 72, 39,165, 51, 37,229,115, 60,130,131,218,125, +252, 92,191,182,201,243, 70,249,235,205,219, 66, 9, 61,191, 57,177,173,243, 37,182, 61, 3,108,228,206,114,203,226, 87, 7, 84, +180,240,105,113,111,227,214,239,131, 0, 32, 34,114,104,189, 85,156, 42,149,170,139,151,151,151,230,196,137, 19,116, 81, 81, 17, + 41, 40, 40,168,106,163, 85, 12, 64,225,227,227,147,109,181, 90,137, 82,169, 44,116,228,168, 41,149,202, 66,171,213, 74,124,124, +124,178, 31,248, 43, 69, 49, 33,132, 20, 20, 20,144,162,162, 34,114,226,196, 9,218,203,203, 75,163, 82,169,186, 48,247, 7, 3, + 3, 3, 3, 3,195,127,150,201, 53, 94, 27,166,103,207,158,148, 92, 46,103,181,107,215, 78,234,233,233,217,205,211,211,243,226, +231,159,127, 78, 86,173, 90,101,221,180,105, 19,249,230,155,111,172, 47,188,240, 66,169, 68, 34,137,225,243,249, 74, 0,240,245, +245,173, 55,228,215,165, 91,119, 74, 36, 20,176, 2, 2,130,165, 42, 23,151,110,174, 46,206, 23,205,171,218, 18,178,160,153,149, +108,233, 72,200,158,193,214,229, 79,135,149,114,185,188, 24, 0, 74, 0,240,242,244,176, 55,140,232,169, 86,171,227, 23, 44, 88, + 80,110, 54,155, 73,101, 47, 67, 13, 0, 39, 31, 31,159,108, 66, 8,241,242,242,202, 0,160,178, 83, 79,229,229,229,149, 65, 8, +169, 50, 90, 78,238,238,238, 26, 66, 8, 49,155,205,100,193,130, 5,229,106,181,154,105, 12,207,192,192,192,192,192,192, 80,231, + 92,135,117, 70,138,206,158, 61, 75, 74, 75, 75,233,172,172, 44,155, 78,167,147,135,134,134, 42,217,108, 54,220,220,220,216,108, + 54,155, 46, 47, 47,103,171, 84,170,108, 46,151,251,173,201,100, 42, 26, 53,106, 20,149,146,146, 82,111, 67,243,203, 23,206, 19, + 67,133,145,206,204,204,176,233,117,165,242,137,237,157,149, 28,171, 25,116,104, 79,118,169,168, 13, 77, 27,138,216,129, 30,130, +108, 30,143,251, 45,128,162,209, 81,195,168,204,236, 28,123, 27,175,103,107,181,218,208, 13, 27, 54,108,233,211,167, 79,145, 94, +175,175,106, 91, 85,115, 8, 6, 39, 59,245,106,126,143, 77, 81, 20,244,122, 61,250,244,233, 83,180, 97,195,134, 45, 90,173, 54, + 20, 64, 54,115,125, 49, 48, 48, 48, 48, 48,252,167,169,115, 28,173, 6,135, 58,208,235,245, 74, 30,143, 23, 17, 22, 22,214,162, +188,188,156, 94,184,112, 97,198,154, 53,107,118,220,187,119,207,226,228,228,212, 74, 36, 18,189, 57,126,252,120,213,254,253,251, + 73,239,222,189,107, 70,159,106,157,221,219, 96,208, 41, 5, 60,110,196,155, 93,101, 45, 50,204, 74, 58,232,205, 75, 25,125,231, +159,219,241,227, 13,142,165,157,179,161,149, 51,159,122,115,252,248,167, 85, 63, 30,142, 33,221,187,119,179, 75,179, 18,155, 86, +171,125, 51, 54, 54,246,233,150, 45, 91,102, 90, 44,150, 76, 0, 5, 6,131, 65,227,233,233,169, 53,155,205,153, 0,204,181,108, + 87,155,166,217,108, 54,103,122,122,122,106, 13, 6,131, 6, 64,129,197, 98,201,108,217,178,101,102,108,108,236,211, 90,173,246, + 77, 0,182,122,242,194,204,234,206,104, 50,154,140, 38,163,201,104, 50,154,255, 29,254, 16,205, 2,236,152, 84, 90, 32, 16,244, +241,246,246,238,117,227,198, 13,219,249,243,231, 75, 88, 44,214,198,161, 67,135,238,221,183,111, 95, 87,103,103,103,117,243,230, +205,221,126,249,229,151,112, 0,187,127,255,253,119,187,162, 79, 34, 1,175, 79, 71, 47, 69,175,232,107,196,246, 85,236,221, 18, + 27, 91,176,177,255,216,177,123,223,216,177,179,171,167, 74,166,238,232, 33,119, 59,114,228, 88, 56,128,221,231,207, 95,112,120, + 60, 13,171,213,250,139, 86,171,109, 94,245, 57, 47, 47, 47, 84,165, 82, 5,225, 65,244,169,196, 78,153, 52,154,166,135,210, 52, +237,153,159,159,127, 11, 0,242,243,243, 59, 51,215, 17, 3, 3, 3, 3, 3, 3, 67, 45, 38, 43,186,182,207,245, 70,180,248,124, +126, 51, 54,155, 29,156,153,153,153,118,228,200,145, 27, 93,186,116, 25,146,150,150,182,148, 16,146, 42, 22,139, 39,103,100,100, +220,205,200,200, 48, 25, 12,134,169, 14,100,166, 25, 88,188,224,216,108, 67,218,103,191,220,188,209,174,251,160, 33,185,185,217, + 75,109,132,164,242,197,242,201,119,210,243,238, 94,208, 26, 77, 21, 21, 14,105, 54, 72,126,126,254,173,252,252,252, 18, 7,183, + 41,169, 50, 89, 12, 12, 12, 12, 12, 12, 12, 12,142,210, 80, 68,203,108,179,217,150, 27,141, 70,229,143, 63,254,152, 21, 25, 25, +105, 4,128, 13, 27, 54,208, 47,191,252,242,153,164,164,164, 1,183,110,221, 26,226,238,238,126, 18, 0,149,156,156,108, 79,244, +201, 76,211,182,229, 38,147, 81,249,203,175,113, 89,125,122,181, 51, 2,192,166, 47,214,210,207, 76,158,121, 38, 41,241,198,128, + 59, 9, 87,134,184,187,187,159,180, 89, 57, 84, 78,110, 42, 97, 78, 19, 3, 3, 3, 3, 3, 3,195, 63,152,104, 60, 90,101, 24, +109,151,209, 50,153, 76,121, 38,147, 9, 0,138, 34, 35, 35, 31, 89,183,117,235, 86, 2,160, 28,192,158,130,130, 2, 71, 50,147, +103, 48, 24, 0,160,168, 79,175,118,143,172,248, 46,122,205, 67, 77, 93, 89, 41,115,218, 24, 24, 24, 24, 24, 24, 24,158, 36,179, +245, 7, 88,204,113, 97, 96, 96, 96, 96, 96, 96, 96,104, 18,147,235,250, 76,161,238,158, 3, 63, 59,240, 3,141,233,125,240, 51, +163,201,104, 50,154,140, 38,163,201,104, 50,154,255, 57,205,134,180,127,198,147, 71,157,141,225,255,108,152,174,175,140, 38,163, +201,104, 50,154,140, 38,163,201,104,254,219,241,192,163,195, 59,120, 84,173,224, 48,199,134,129,225,201,134,236, 1, 27, 69, 1, +190, 32,196, 19,108,126, 14,114,174, 39, 81, 31,131,110,178,166, 38,216, 7, 34,139, 27,172,194, 60,104,226,147,155,170,201,192, +192,240,239,195,189,199,235,163, 41, 22,123, 35, 69,104, 24, 52,137, 2,158, 33, 85,172,205, 73,251, 47,122,139, 28,212, 17,193, + 98,140, 22, 3,195,147, 78, 94,160, 63, 56, 88, 2, 22, 60, 64,204,247,225, 26,188, 4,184,153,208,100, 77, 30,189, 16, 54,150, + 23,136,249, 14,212, 1, 75,129,219, 55,153,131,253,239, 99,198,244,215,200,173,132,139, 72, 79,207, 70,171,214, 30,240, 15,236, +129, 53,107,215, 83,204,145, 97,176,239, 95, 25, 21, 29, 49,124,130,179, 72, 44, 3, 0,208, 86, 11,182,190,221,241, 39,171,213, +186, 29,192,126, 0,134,255,250, 33,250,203, 27,195,115,185, 92, 13, 0, 90, 40, 20,238, 67,181,208, 26, 3,195,159,128, 71,229, +117, 70, 87, 94,119,142, 32,229,112, 56,243,197, 98,241,175, 2,129, 64, 43, 16, 8,180, 18,137,228, 87, 14,135, 51, 31,128,244, + 31, 83,198,125,211, 86, 12,150,109,136,201, 66, 55, 59,118,189, 88,173, 55,218,252,193,178, 14, 37, 91,219, 72,155,164,201,161, + 34, 43,204,180,247,183,151,244,110,229, 38,107, 16, 8,154,164, 89, 13, 39, 30,143,119, 12,246,207, 57,202,240, 39,147,150,156, +128, 35,135, 87, 98,225, 39,147,240,117,244, 84,220,190,117,161, 73,122, 65, 64,231,206, 28,206,236, 64,160, 63, 30,180, 3,102, +248, 55, 67,145,201, 63, 31,250, 54,239,208,174, 47,242,190, 95, 57,149, 28, 88, 18,133,181,107,215, 70, 76,154, 52,233, 91,111, +111,239, 60, 0, 79, 49, 70,235, 47,198, 98,177,168,243,243,243,169,237,219,183,143, 80, 40, 20,247, 57, 28,206,251, 0,120,255, +149, 3, 46,149, 74,207,201,229,114,141, 66,161,208,200,229,242, 43, 13,165,255, 75,241,119,117,117, 77,115,118,118,190, 83, 61, +209,181,253,232, 30,126, 61, 39,126,228, 18, 60,178,111, 19,245,121, 28, 14,231,125,133, 66,113,127,251,246,237, 35,178,178,178, + 40,139,197,162,118, 96,251, 62, 74,165,242,214,197,139, 23,231,229,231,231,247,205,184,176,213, 53,247,226,102,215,180,223, 86, +246,139, 61,178,110,158,147,147,226, 38,128, 62,255,136, 35, 89, 65,187,129,197, 14,191,145,163, 23,231,148, 90,220,226, 82,245, + 50,128,221, 15,166, 38,252,137, 41,161,221, 0,210,255, 90,166, 65,114,174,208,213,237,247, 36,163, 28, 44, 86, 56, 42, 40,247, + 38, 23, 56, 44,214,107, 52, 77, 15,228,241,120,111, 50, 79,168,127, 6, 2, 1, 15, 32, 4, 82,137, 16, 0, 1,171,137,214,136, +207, 98,245, 60, 55, 98,196,194, 57,237,219,207, 8, 4,134,215, 97,182, 40, 0,111, 4, 6, 6, 30, 5,240,204, 99,220,157,207, + 2, 2, 2,178, 0,204,124, 92,229, 82,167, 78,157,122,132,135,135,127,212,177, 99,199,190,143, 75,243,223, 68,238,185, 13, 63, +230,156, 89,167,206, 62,187, 94, 93,156,124,250, 13, 15, 55, 37,157,156,156,140, 97,195,134,225,139, 47,190, 16,135,132,132,236, + 0,224,249, 31,184,149, 66,171,254,224,163, 70, 27, 45,187,141,214, 56, 95,244,124,182, 37, 78, 61,237,139,178,241, 45,161,123, +190, 37,206,140,245, 69,255,198,228,198,197,197, 5,125,250,244, 97,103,101,101,137,102,205,154,245,145, 80, 40, 76, 1, 48,168, + 49, 90, 34,145, 40, 86, 44, 22,103,112, 56,156, 71,242, 34, 22,139, 99, 37, 18, 73, 6,135,195, 25, 80, 61, 93, 38,147,157,147, +203,229, 26,153, 76,118,165, 14, 35, 20, 43,151,203, 53, 82,169, 52,182,122, 58,135,195, 25, 32,149, 74, 51,101, 50, 89,205,244, +254, 50,153, 44,163,102,122, 93,112,185, 92,175,140,140, 12,117,102,102,166,154,207,231,187, 85, 79, 79, 79, 79, 87,103,100,100, + 60,146,238, 8, 28, 14,167,191, 68, 34,201, 16,139,197,177,181,165,215,220,167,186,168,118,236,250,219,147,238,104,193, 19, 25, + 25,121, 38, 39, 39,199,219,201,201,233,145,137,187,157, 21, 78,131,190,217,186,254,237,145, 67, 35, 95,115, 13, 26,213,174,145, +250,131,132, 66, 97,202,172, 89,179, 62,202,202,202, 18,117,239,222,157,205, 98, 57,244,127, 34, 98,228,200,145, 7, 52, 26, 77, +179, 14, 29, 58,176,173, 86, 43,110, 28,156, 15,113,252,155, 16,166,108, 66,115, 81, 30,231,254, 79, 75,189, 34,251,117, 62,128, +191,185, 49, 40,217, 19,196, 3, 69,247,161, 9,113,189,149, 85,225, 58,108,196, 83,156,171, 25, 6, 87,139,205,230, 12,176,251, +145,175,125, 4,141,210,228, 88,122,211,132,184,253,146,202,117, 13,127,122, 6,251,100, 42,199,213, 98,179,185,128,133,190,141, +209,172,126,249,179,217,236,183, 87,174, 92,201, 2, 48, 29, 0,255,191,100,104,194, 60,209,172,127,107,246,165, 80, 15,244,124, +140,178, 33,149,247,187,127, 83,133,182,124,125, 20, 47, 79,137, 70,155,192,110, 77,210, 49,209,244,237,239,146,147,143, 63,223, +186,117,212,156,246,237, 95,172,197,108, 81, 0,230, 44, 93,186,116,226,141, 27, 55, 92, 91,182,108, 57,229, 49,253,233, 95,189, +116,233,210,119,111,220,184,225,233,235,235,187,192, 65,205, 58,203, 37,165, 82, 57,104,203,150, 45,111, 15, 27, 54,236,181, 78, +157, 58,181,123, 28,154,255, 98,190,184,118,237,154,247,202,149, 43,223,123,249,229,151, 75, 1, 96,192,128, 1, 60, 0,221,155, + 92,222, 17,194, 39,132,132, 19, 66,134, 17, 66, 6, 16, 66,194, 42,223,119,169, 92,134, 17, 66, 34,106,188,118,169,220,182,106, +125,215, 58, 52,134,213,220,174,218, 54, 53, 63, 63,242,190, 22,163, 53, 12, 15,218,106, 13,123,100, 7, 14, 31, 62, 76,170,191, +214,100,188, 47, 62,158,209,163,153,254,214,161,157, 68,151,145, 76,138, 18,175,146,171,209,139,201,140, 46,174,250,231, 90,226, + 51,199,143, 23, 33,103,207,158, 37, 55,110,220, 32, 58,157,142,220,189,123,151,116,237,218,213, 32, 22,139,127, 1,224,235,136, +152, 76, 38,211,252,242,203, 47, 36, 50, 50,178, 68, 42,149,174,168,186,185,228,114,185,230,236,217,179, 36, 50, 50,178, 68, 38, +147,173, 6,192, 6,128,177, 99,199,106, 9, 33,196,213,213, 53,187, 54,189,145, 35, 71, 22, 17, 66,136, 66,161,168,170,106, 98, +203,100,178,213,211,166, 77,211, 93,190,124,153, 40,149,202,170,116,150, 92, 46, 95, 49,125,250,116, 93, 92, 92, 92,245,244,122, +113,118,118,206,176,217,108,228,208,161, 67, 68,173, 86,103, 87,187,153, 51,108, 54, 27, 57,112,224, 64,157,121,171, 47, 80, 32, +149, 74,151, 63,255,252,243,101,169,169,169,196,197,197, 69, 83, 45,125,197,164, 73,147,202,210,211,211,137, 74,165,178, 43,143, + 46, 46, 46,154,115,231,206,145, 49, 99,198,148, 86, 63,166, 46, 46, 46,154,243,231,207, 87,165, 47,183,167, 32,243,244,244,156, +162, 86,171,179,213,106,117,182,147,147,211, 34, 15, 15,143,220,188,188, 60, 66, 8, 33,173, 90,181,210, 86,143,100,169, 67, 70, +188,181,105,207,249,139,167, 19, 10,242,218, 15,124,109,185,162,253, 72,133, 3,199,192, 87, 44, 22,255,210,183,111, 95, 67, 70, + 70, 6, 41, 47, 47, 39,241,241,241,228,236,217,179,228,222,189,123, 4,128, 61, 51, 12,200,164, 82,105,150,209,104,164,141, 70, + 35,157,151,151,103,211,106,181,182,196, 21, 30,132,124,197,125,184, 20, 31, 24, 78,114, 79, 47,161,229, 82,113, 38, 0,217,223, +102,180,214, 7,123,145,205, 1,223,221,156,239,157,120,122,233, 96, 11, 73, 61, 73,118,190,232,106, 57,245, 86,179,251,100, 99, +224, 15,100,115, 80,243, 70,105,110, 12,218, 25,255,161,247,237,117, 11,222,176,164,165,165,145,217,147, 6, 91, 79,204,104,150, + 68, 54, 5,238,105,140,102, 53,158, 29, 61,122,180, 46, 61, 61,157, 4, 7, 7,151,179,217,236,151,255, 75, 38, 43,194,159,159, + 21,255,237,108,122,120,136,184,224, 49,153,173, 16,181, 90,157,191,109,219, 54, 34,147,201,180,141, 53, 91,227, 70,245, 35,134, +146, 95,200,168,168,176,122,239,145,167,159,126,154,132,135,135,147, 25, 51,102, 52,116, 47, 81,129,192,136,237,237,219, 31,160, +199,141,179,109,111,223,254, 64, 32, 48,162,210, 96, 81, 0,222, 91,182,108, 89,156,197, 98,137,251,250,235,175,227, 70,140, 24, + 17, 7, 96,118, 19,143,197,154,207, 62,251,140, 88, 44, 22,242,245,215, 95,147, 17, 35, 70, 16, 0,107,155, 82, 46, 85, 69,178, + 66, 67, 67,223,218,191,127,255,197,219,183,111,231, 69, 69, 69, 45,111,223,190,189,162,177,154,255, 68,164, 82,169, 95,187,118, +237,118, 4, 7, 7,167,119,232,208,193, 20, 20, 20, 84,225,239,239,159, 26, 18, 18,178, 77, 32, 16,248, 54, 82,182, 91,207,158, + 61,109,167, 78,157, 34,163, 71,143, 38,213, 76, 72,189,212,231, 69, 8, 33, 97,239,189,247,222,251, 0,200,123,239,189,247, 62, + 33,100, 88,165,159, 24, 86,253,125,205,215, 42,243, 84,245,185, 54,141,170,165, 54,205,218,126,163,198,239,160,142, 72,214,228, + 63,236,220,225,195,135,251, 30, 62,124,248, 84,205,157,123,170, 37,122,204,232,209,204, 96,200,203, 33, 9,139,223, 36,191,134, +123,145,179,253,220,201,157,183, 71,147,156,111, 87,147,215, 59, 42,245,227, 90, 34,220, 81,163, 21, 23, 23, 71,226,226,226,200, +149, 43, 87, 72, 74, 74, 10, 41, 41, 41, 33,223,127,255,189,205,197,197,197, 32, 16, 8,150, 2, 16,217, 35, 38,151,203, 53,132, + 16, 98, 52, 26,201,162, 69,139, 42, 42, 35, 85,110, 10,133, 66, 67, 8, 33,197,197,197,100,233,210,165, 21, 10,133, 34, 30,128, +167, 74,165,202, 72, 78, 78, 38,110,110,110,181,154, 25,165, 82,169,185,125,251,118,149,113,106,166, 84, 42, 19, 14, 30, 60,104, + 38,132,144,204,204, 76,226,236,236,172, 1,224,230,226,226,114,245,240,225,195,102, 66, 8,201,206,206,174, 74,183,203,104, 25, + 12, 6,114,226,196,137, 71,242, 80,149,126,244,232,209, 71, 12,152, 29,184, 41, 20,138,184,239,191,255,222,100,179,217, 72, 66, + 66, 66,149, 73,116,115,114,114,186,178,103,207, 30,147,205,102, 35,137,137,137,118,155,193, 22, 45, 90,104, 9, 33,196,106,181, +146, 77,155, 54, 25,171,142,105, 85,186,201,100, 34, 27, 54,108, 48,202,229,242, 56, 0,245, 70,223, 84, 42, 85,182,201,100, 34, +197,197,197,164,107,215,174,186,179,103,207,146,210,210, 82, 66, 8, 33, 45, 90,180,208, 2, 64, 64,223,151, 63,189,120, 87, 87, +250,210,187,235,119,251,134, 61,183,248,248,165,172,204, 45,251, 99,227, 84, 33, 35, 7,219, 19,212, 20, 8, 4, 75, 61, 60, 60, + 42,126,255,253,119,155,217,108, 38,233,233,233,228,202,149, 43, 15,175,177,235,215,175,219,101,180, 56, 28,206,252,139, 23, 47, +154,109, 54, 27,157,159,159,111,211,106,181, 54,173, 86,107,173,105,180,200, 87, 92,146,127,244, 85, 18, 19, 61,211,196,227,241, +230,255, 61,209, 44,176,201,230,128,145,100,115, 64,220,182,231, 85,249,101, 87,118, 17,242,211, 76,146,244,105, 75, 50,127,176, +172,140,222, 28, 16, 71, 54, 7,142, 35, 31,247,229, 56,164, 25, 29, 52,156,108, 14,136,251,236, 41,159,130,171,113,151,201,169, + 83,167,200,134,213,203,200,140,136,102,229,244,230,128, 56,178, 49,104,140, 35,154,213, 17, 8, 4,119,207,156, 57, 67, 78,159, + 62, 77, 22, 44, 88, 64,196, 98,113,250,227,136,234,145,141,254, 62,228, 75,255,190,100,107, 27, 15,242, 91,223,127, 92, 7,159, + 48, 79, 52, 27,232,207,207,204,191,186,159,144,194,123, 36,119, 69, 48, 25, 28,192,109,170,217, 10, 81,171,213,121,169,169,169, + 36, 55, 55,151,172, 90,181,138,200,229,242, 70,153,173,113,163,250, 17, 67,241,207,245, 26,173,145, 35, 71,146,207, 63,255,156, + 88, 44, 22,210,173, 91, 55,123,254,180,252,193,108, 5, 0, 35, 1,188,191,124,249,242,135, 38,107,253,250,245,113,215,175, 95, +143,243,246,246, 62,210,132, 99,177,118,249,242,229, 15, 77,214,250,245,235,201,245,235,215,137,143,143, 79, 70, 83,202,165,129, + 3, 7,126,154,146,146, 82, 58,119,238,220,221,125,250,244, 89,124,245,234,213,204,152,152,152,184,208,208,208,193,141,213,124, + 12, 81, 29, 78,101,100,135, 79, 8,225, 18, 66,170,204, 43, 7, 0,183, 42,160, 96, 15,207, 63,255,188,184, 71,143, 30,113, 19, + 38, 76,208,111,219,182,141,164,166,166,146,248,248,120,178,124,249,114,242,209, 71, 31,145,175,190,250,138,140, 25, 51,166,188, +107,215,174, 23,199,141, 27, 39,116, 32,155,193,190,190,190, 37, 7, 14, 28, 32, 59,119,238, 36, 60, 30, 47,198,222, 13,235,243, + 34,117,153,169,186, 12, 86,205,117,245, 24,177,122, 13,155, 29,191,247, 71, 83, 85, 51, 18, 82,237,253,111, 81, 81, 81,125,255, +240,240, 33,248,100,242,172, 79,133, 41,219, 86, 65,243,253, 23, 96, 23,107,192, 45, 43,128,241, 76, 12, 44,103, 14, 98, 98,247, +238, 34, 17, 69, 45,116,244,130,225,243,249,224,243,249,224,241,120,208,235,245,200,206,206, 70,175, 94,189, 88, 87,174, 92, 17, + 78,153, 50,101,166, 72, 36, 74, 7, 48,170,193,187,153,122, 16,145, 62,119,238, 28, 94,125,245, 85,193,142, 29, 59, 58,184,186, +186, 94,179,217,108,124, 0, 72, 76, 76,196,248,241,227, 5,187,118,237,106,235,233,233,121,197,108, 54,139, 5, 2, 1,216,108, +118,157,122,124, 62, 31, 22,139, 69,208,166, 77,155,248,107,215,174,133, 68, 69, 69,113,211,210,210,144,156,156, 12,139,197,194, +247,247,247,191,126,229,202,149, 14,195,134, 13,227,102,100,100, 32, 45, 45,237, 97, 62,236,201,175,201,100,130, 64, 32, 64,245, + 42, 45,138,162, 96, 52, 26,193,231,243,237,214,226,112, 56,253, 3, 3, 3,175, 95,187,118, 45,116,228,200,145,188,203,151, 47, + 35, 51, 51, 19, 54,155,141, 31, 20, 20,116,253,218,181,107, 29, 71,140, 24,193,139,143,143,135, 70,163,129,189, 85,104, 85,223, +187,118,237, 26, 38, 76,152,192, 63,118,236, 88, 71, 15, 15,143,120,171,213,202, 7,128,235,215,175, 99,252,248,241,252,227,199, +143,135, 54,111,222, 60,190,129,170, 68, 54, 0, 88, 44, 22, 76,153, 50, 69, 34,151,203,145,145,145, 1,154,166, 97,179,217, 0, + 0, 5, 69, 5,215,175, 93, 79, 72,156,248,236, 83,125, 13,102,163,241,252,165,216, 91,173, 90,248,120, 81, 20,105,209, 64, 86, + 71, 73, 36,146,244, 21, 43, 86,188,149,154,154, 42, 8, 12, 12,100, 37, 37, 37,161,172,172, 12, 60, 30,239,225, 53,102,239,126, +243,249,252,126,193,193,193,156,138,138, 10,208, 52, 13, 0,132,197,170,189,197,138,176,248, 12,130,220,172, 92,145, 72,212,239, +111,121,122,151, 6,187,128,198,192,180, 60,147, 64,224,228, 37,147,122,248, 3,233,167,209,210, 85, 0, 54,139, 45,188,156,172, +151, 0,100, 32,188,243, 93, 28,211,164, 7, 38,107, 77, 2,139,115, 91,169,167,151, 55, 10, 10, 10,208,188, 85, 32, 42,248,174, +252,115,247,202,165,160, 28,212,252, 63,189,219,180,105,227,238,231,231,135,252,252,124,132,134,134, 66,169, 84, 42, 1, 12,108, +244, 67,231,107, 31, 1, 74,209, 19, 96,173,128,141, 90, 0, 11,103, 9,238,229,133,146,205,161,220,127,146,201,146, 75,249, 23, +118,125,247,125, 51, 23,239, 32, 32,230, 37,184, 57, 9,176,245,181, 80,103, 87,133,224, 64, 35,205, 86,136,155,155,219,201,139, + 23, 47,170,132, 66, 33,174, 92,185,130,224,224, 96,172, 90,181,202, 85,169, 84,158,110, 92,100,139,128, 80,117,155,172, 62,125, +250, 96,250,244,233,216,177, 99, 7,156,157,157, 49, 97,194,132,134,204, 22, 73, 4, 14,125, 22, 31,255,245,142,251,247, 15, 63, +223,186,117,212, 4,127,255, 69, 83,159,121,230,229, 55,222,120, 3,203,150, 45,195,129, 3, 7,208,179,103, 79, 76,158, 60,217, +146,158,158,190,189,177, 85, 85, 43, 86,172,152, 49,115,230,204,154,154,230,180,180,180,207,154, 84, 46, 21, 20, 92,143,143,143, + 79,124,246,217,103,251, 86, 84, 84, 24, 47, 93,186,116,203,215,215,215, 11, 64,139,198,106, 54,193, 96, 81,132, 16, 33, 0,113, +229, 34, 1, 32,222,181,107,151, 98,228,200,145,242,202, 52, 81,229,210, 96,245,126,112,112,176,215,221,187,119,179,222,126,251, +237,208, 29, 59,118,136,196, 98, 49,138,139,139,241,229,151, 95,226,253,247,223, 7, 69, 81, 32,132,224,171,175,190, 18,191,248, +226,139, 97,247,239,223,207,242,241,241,177,167, 73,139, 64, 42,149,238, 89,180,104,145,156,166,105,204,153, 51, 39,223,108, 54, + 79,175, 92, 55,215,201,201,233, 2, 30, 24,238,250,168,213,139, 84,123, 86, 30,174,113,108,162,106,166,213, 92, 71, 8,137,170, + 79,195,193,115, 81,219,239,197,212,103,182,170, 63,129,250,213,234, 34,129,246,238,190, 1, 40,249,105, 15, 68, 28, 10, 34,118, +229,194,161,192, 74,186,142,230, 66, 46, 44,132,132, 52,214,104, 85, 45, 92, 46, 23,122,189, 30, 54,155, 13,239,191,255,190,224, +196,137, 19, 46, 44, 22,235,135,134,116,170, 27,166, 59,119,238, 32, 40, 40,136, 58,116,232,144,219,244,233,211, 69, 85,191, 83, + 82, 82, 2, 63, 63, 63,234,232,209,163,234, 15, 63,252, 80, 90,159,153,161, 40, 10, 60, 30, 15, 51,103,206, 20, 93,186,116,201, +217,211,211, 19, 73, 73, 73, 40, 44, 44,132, 84, 42,197,204,153, 51, 69, 23, 47, 94,116,245,244,244, 68,106,106, 42, 74, 74, 74, + 32,149, 74, 29, 54, 90, 60, 30,239,145,109, 40,138,130,217,108,118,200, 24, 40, 20,138,157,113,113,113,174, 10,133, 2,241,241, +241,176, 90,173, 80, 40, 20,152, 49, 99,134, 40, 46, 46,206,213,201,201, 9,137,137,137, 32,132, 64, 46,151, 59,148, 71, 0,160, +105, 26,137,137,137,104,209,162, 5, 78,159, 62,173,158, 58,117,170,176, 42,253,222,189,123,240,242,242,194,233,211,167,213, 18, +137,100,103, 93, 90, 52, 77, 35, 39, 39, 7, 55,110,220, 64, 82, 82, 18,242,242,242,144,159,159,143,178,178, 50, 88,173, 86, 0, +128,184,172, 52,102,215,238, 67,215, 68, 34,145, 56,216,191,141,247,245,132,155, 90,145, 72, 36,246,241,246,246, 7, 62,102,213, + 99, 8,127, 72, 75, 75,115,121,241,197, 23,121,185,185,185, 40, 42, 42, 2,135,195,249,195,181,197,231,219,215, 20,200,106,181, + 6, 9,133, 66,202,108, 54, 63,140,128,241,249,124,188,181, 83,143,224,249,120,100,121,102,181, 22,196,102,129,201,100, 10,250, +203,163, 89, 0, 5,202,212, 6, 20, 21,122, 33,169,220,185,119,212,179, 60, 36, 31, 3,104, 11,192,226,160, 95,123, 47,206,129, +235,229,110, 32,104, 15, 35, 2, 9,105,184,231, 23, 1, 40,192,236, 7, 80,157, 79,220,181,186,244, 28,253, 26, 47, 43, 43, 11, + 60, 30, 15, 2,129, 0,161,253,199,114,118, 93,179,184,131, 66, 7,152, 17, 96,143,230, 35, 97, 71,145,104,222, 71, 31,125, 36, +169,174,249,242,203, 47, 75, 20, 10,197, 71,141, 54, 89,229,226,238,176,146,153, 55,178,244, 45, 22,197,228, 6,221,215, 26, 2, + 64,200,219,128,165,227, 99, 48, 91,253, 4, 2, 65, 50,128, 94, 77, 50, 89, 50,254,249,239,190,251,190,153,115,243, 7, 38, 11, +214, 10,128, 43,130,187,171, 19,182,190, 21,238,236,234, 36,114,212,108,133,184,185,185,253,114,225,194, 5,149, 80, 40, 68, 92, + 92, 28,120, 60, 30,132, 66, 33,218,181,107,135,205,155, 55,187, 58, 59, 59, 59,108,182, 8, 72,173, 49,223, 81,163, 70,145, 62, +125,250, 96,218,180,105,216,190,125, 59, 76, 38, 19, 22, 45, 90,132,180,180, 52,187,100, 19,129, 67, 75,227,227,183, 45,185,113, +227,206,123, 33, 33,129,163, 36, 18,231,105, 19, 38, 40, 62,252,240,195,195, 7, 15, 30,252,122,216,176, 97,249,151, 46, 93,250, + 28,192, 30, 7, 15, 47, 5, 96,253,202,149, 43,167, 85, 25,183, 15, 63,252,240,171,131, 7, 15, 46, 25, 54,108, 88,206,165, 75, +151,222, 6,176,190, 41,229, 18, 77,211, 49, 63,252,240,195, 53,145, 72, 36, 14, 8, 8,240, 78, 72, 72,208,138, 68, 34,177,183, +183,183,127,223,190,125, 89,141,209,108, 12,106,181,122,192,133, 11, 23,130,241,160,211,152,160,202,104, 37, 36, 36, 56,149,150, +150, 58, 73,165, 82, 39, 15, 15, 15, 89,149,217, 26, 61,122,180, 19,135,195,169,247,186,213,233,116, 7,231,206,157,171, 24, 61, +122,116,213,103,156, 57,115, 6,219,183,111,135, 68, 34,121,228,187, 35, 70,140,192,171,175,190,170, 52,153, 76, 63,216,145,221, + 73, 83,166, 76, 9,112,115,115,195,188,121,243,140, 89, 89, 89, 3, 0,164, 1, 80, 68, 68, 68,124,154,144,144,208, 53, 44, 44, +108, 55,128, 78,245,221,123,181,121,145,234, 70,199,158,180,198,126,223, 94,179, 85, 35,169,206, 49,180, 30, 49, 90, 81, 81, 81, +167, 80, 71, 79, 42,115,161, 6, 2,216, 32, 98, 83, 16,179,171,153, 45,208,224,148,104, 65, 53,162,151, 74,109, 15, 67, 62,159, + 15, 54,155, 13,147,201, 4,123, 39,170,174, 50, 5,114,185, 28, 82,169, 20, 6,131, 1, 86,171, 21, 66,161,176,202,140, 64, 46, +151,131,203,229,130,203,229, 66, 40, 20,254, 33,154, 84, 51,154,195,227,241, 32,145, 72,144,147,147,131,180,180, 52,208, 52, 13, +169, 84, 10,137, 68, 2, 62,159,143,236,236,108,100,103,103,131, 16, 2,137, 68, 2,137, 68, 2, 71, 26, 92,219,108,182, 90, 31, +254, 22,139,197,161,136,150,213,106,197,173, 91,183,144,158,158, 14,161, 80,248,112, 95, 5, 2, 1,238,221,187,135,220,220, 92, +136,197, 98,200,229,114, 40, 20, 10,187,117,171,246, 69, 38,147, 65, 36, 18,161,168,168, 8,122,189,254,225, 49,149,203,229,144, + 72, 36, 40, 41, 41,129, 86,171,173,119,223,109, 54, 27,178,179,179,145,151,151,135,140,140, 12,228,231,231, 63, 44,128, 42,163, + 70, 77, 11,236,148,150,162,160,160,224, 97, 36,178,174,197, 30,104,154, 70, 89, 89, 25, 46, 92,184, 64,209, 52,141,226,226, 98, + 58, 47, 55,215,246,122, 54, 31, 7, 62,222, 72,190, 63,118,181, 98,215,145, 56,195,190, 95,110, 24,214,239,187,110, 16,118, 93, + 96,197,223,193,134, 16, 5, 44,220,200,124,157, 69,144,103,230, 41,220, 66, 34,128,228,163, 0,139, 3, 8,149,232,214,182, 37, +210,138,108,146,219, 26,147, 16, 20, 6, 97,189,191,210, 46, 77, 27,119, 96, 94,153, 69,144,106,118,149, 7,181,239, 4,141, 70, + 3,129, 64, 0,129, 64,128,206, 61, 35,144, 92, 96, 19,223,204, 50,136, 65, 16,105,151,230,255,105, 37,149, 74,187,247,234,213, +139,170,174, 57,116,232, 80, 80, 20,213, 14, 64,160, 67,133,220,218, 86,124,152,197,221,192, 33, 51,111,230,232, 61, 15, 36, 84, +248, 15, 31, 53,214,121,205,207,218,160, 91,185, 70, 95, 16,203, 44, 16,115,167, 38,152,173,190, 50,153,236,240,186,117,235,124, +133, 66,225, 81, 0,189, 27, 35, 34, 21,177, 55,205,155,246,108, 51,101,149,201,178,232, 1,142, 8,224,138, 0,142, 8,238,106, + 21, 22,190, 58,208, 89, 44,228,238,115,192,176,238, 90,191,126,189,107, 77,147, 85,181,132,134,134, 98,254,252,249,174,206,206, +206, 59,237,209, 91,177,124, 25, 41, 46, 41, 1, 8, 80, 90,170,195,138,229,203,138,170,214,141, 30, 61,154,244,238,221, 27,211, +166, 77,195,146, 37, 75,112,228,200, 17,116,235,214, 13,147, 39, 79, 70, 88, 88, 88, 67,210,145, 10,133, 98, 71, 68, 68,196,133, +108,153,236,213,156, 78,157,248,191, 40, 20, 37, 3, 74, 74, 20, 62, 9, 9,230, 0,224, 58,128, 13,153,153,153,131, 29, 48, 89, +207,200,229,242,184, 1, 3, 6,152,101, 50, 89,250,170, 85,171, 94,159, 62,125, 58,150, 45, 91,134,185,115,231,126, 9,224, 21, + 0, 31,100,102,102,122,214,103,178,254,172,114,233,207, 42,235,108, 54, 91,198,158, 61,123,194,204,102,179, 87,101,245,160,160, +184,184, 88, 94, 88, 88, 40, 51,155,205, 18,154,166, 37, 78, 78, 78, 82, 0,226,137, 19, 39,114,110,222,188, 25,100,181, 90,179, +234,211,204,205,205,125,110,206,156, 57,249,249,249,249, 0,128,118,237,218,161,184,184, 24,179,103,207,198,155,111, 62,232, 16, +220,177, 99, 71, 16, 66,160,209,104,176, 98,197, 10, 77,110,110,238, 11,118,100,183,117,155, 54,109,144,144,144,128, 91,183,110, +253, 12,128,198,131,118,172, 37, 87,175, 94,189,150,151,151,135,157, 59,119,242,154, 53,107,118, 16,117, 12,241, 82,159, 23,105, + 12, 20, 69,197, 52,102,187,170,200, 85,109, 17,177, 58,168, 63,162, 21, 21, 21, 69, 85,127,125, 36, 98, 68, 33, 62, 61,246, 52, +156, 67, 58, 61, 18,205, 18,179, 41,136,228, 10, 36,103,164,129, 7,234,198,227, 50, 90, 69, 69, 69,120,253,245,215, 13,207, 61, +247, 92, 1, 77,211, 99,237, 53, 5, 10,133, 2, 10,133, 2, 55,111,222, 36, 99,198,140,209,172, 90,181,202, 80,221,104,221,185, +115,135, 68, 70, 70,106, 63,250,232, 35, 93,125, 70,171, 42,162,181,116,233, 82, 67,191,126,253,242,110,220,184, 65,170,204,148, + 84, 42,197,138, 21, 43, 12,225,225,225,154,203,151, 47,147,170, 52, 71, 34, 90, 44, 22,235,161,209,170,190, 13,139,197, 2, 77, +211, 14, 25,173,242,242,242,231,134, 13, 27,166, 73, 76, 76, 36, 85,251,169, 80, 40,176,106,213, 42,195,192,129, 3, 53, 55,110, +220, 32, 85,105,114,185,220,110, 51, 88,245,251, 50,153, 12,114,185, 28, 55,111,222, 36,145,145,145,154,181,107,215, 86, 84, 79, +191,117,235, 22, 25, 49, 98,132,166,172,172,236,185,250,204, 75, 85,117,158,213,106, 69, 69, 69, 5,242,243,243,145,145,145,241, + 48,156,110,144,200, 7, 63,251,244,240, 14, 6,131, 65,127,243,206,221,244,118,109,131,213, 6,131, 65,159,150,158,126, 7,248, +152,174, 71,123,108, 72, 72, 72,193,235,175,191,110, 40, 42, 42,106,178,209,226,243,249,137, 28, 14,135,244,238,221,155,152, 76, + 38,146,145,145, 97,201, 47, 42,178, 6, 46, 94, 76,110,188,245, 22, 37,138,141, 21, 72,165, 82,170, 82,147,149,148,148, 68,139, + 68,162,196,191,220,104,177,104,119, 80,164,215,239,119,117, 78, 3,135,143,231, 83,185,151, 0,179, 14, 16, 40, 1,129, 18, 28, +137, 11,134,244,238,200,222,118,161,212, 29,132,238, 1,158,192,171, 65, 77, 46,113, 3,232,222, 63,221,169, 80,246, 26, 55,131, + 95, 88, 88, 8, 54,155,253,208, 20,137, 37, 18, 12, 24, 53,145,245,213, 37,163, 59, 64,122,130, 98,123, 57,112,175,191, 59,111, +222, 60, 94, 81, 81, 17, 88, 44,214,255, 53,197, 98, 76,157, 58, 85, 32,151,203,231,218, 93,248,237, 9,226,129, 43,232, 6,144, + 55,111,231, 86,120, 30,188,110, 8,152,181,116,171, 40,164, 99, 24,166,244, 83,139,150,198,104, 67,174,101, 24, 90, 2,182,183, + 96, 53,117,110,132,217,234, 45,147,201, 98, 98, 99, 99,197, 67,135, 14,197,138, 21, 43, 36, 34,145,232,104, 99, 10,254,114,157, +109,250, 39,107,191,209,196,127, 62, 8, 48,151, 63, 48, 88,213, 22,173,142,198,252,173, 39, 75, 44, 22,242,172,189,154, 6,131, + 97,210, 43,175,188, 82,176,111,223,190, 63,152, 44,161, 80,136,148,148, 20, 44, 90,180,168,176,176,176,176,193,135,226,170,149, + 43,226, 18,174,253,138,175,190,252, 4, 0,193,186, 85,175,225,252,239,223, 57,245,235,219,135,180,104,209,130,132,133,133,225, +245,215, 95,199,194,133, 11,113,251,246,109,168, 84, 42,188,246,218,107,232,219,183, 47, 86,174, 92, 89, 95, 33, 21, 57,125,250, +244, 69,153,153,153, 1, 63,253,244, 19, 39, 47, 47, 79,189,114,203,150,146,189, 37, 37,133, 75, 18, 18,110,127,208,182,109,155, +247,218,183,127,161,158,161, 31,106, 53, 89,211,166, 77,219,149,153,153, 25,250,243,207, 63,115,243,242,242,188,166, 77,155,134, +229,203,151, 99,238,220,185,155, 1, 76,129,125, 29, 94,236, 46,151,216,108,246,224,177, 99,199,118, 48, 24, 12,250,219,183,111, +167,183,109,219, 86,109, 48, 24,244,233,233,233,119, 78,157, 58, 69, 55, 70,179, 49, 20, 20, 20,220,223,185,115,231,157, 84, 3, + 53,104, 0, 0, 32, 0, 73, 68, 65, 84, 25, 51,102,132,102,102,102, 6, 1,112, 41, 43, 43,147,148,149,149, 9, 76, 38,147, 72, +169, 84, 42, 59,118,236,168,154, 60,121,178,244,234,213,171, 65,153,153,153,186,202, 40, 82,157,152,205,230,219, 69, 69, 69, 81, +131, 6, 13, 42, 46, 42, 42, 66,251,246,237, 49,124,248,112,184,187,187,195,211,211, 19, 35, 71,142,132,191,191, 63, 10, 10, 10, +240,236,179,207, 22,230,229,229, 13, 2,144,100, 71,118,239,231,230,230,162, 71,143, 30,248,228,147, 79,162,158,122,234,169, 27, +189,123,247, 46,109,219,182,173,222,203,203, 43,112,205,154, 53,104,214,172, 25,246,236,217,227, 33, 16, 8,118,214, 98,178,234, +244, 34, 0,242, 42, 13,143,169,198,107, 94, 3,235,236,221,182,214,247,118,124,175,166,217,170,190,252,161,234,176,246, 19, 2, +204,223,190,103, 91, 5,223,219, 15,138,128, 14, 16, 11,133, 16,241,249, 16, 41, 93, 96,164,105,108, 73,201,213,151, 19, 50,215, +209,139,167,230,131,144,162, 40,124,241,197, 23,214,238,221,187, 87,156, 60,121,114,157,193, 96,240,198,131, 81,101,237, 54, 5, +107,215,174,213,207,156, 57,243,154, 86,171,237, 32, 20, 10, 77, 85,233,235,214,173,211, 79,156, 56, 49, 33, 51, 51, 51, 84, 44, + 22,235,235,106,159, 85,221,104, 9, 4, 2,163, 86,171, 13,123,249,229,151, 19, 55,108,216, 80, 46, 22,139, 33,145, 72, 32, 16, + 8, 76, 90,173,182,195,235,175,191,126,109,249,242,229,122,145, 72, 4,137, 68,226, 80,181, 28, 33,228, 15,134,170,122,186,189, + 88,173,214,147, 90,173,182,195,204,153, 51,175,174, 89,179,166,188,202, 0, 85,207,227,202,149, 43,245, 82,169,212,161,136, 86, +213,247, 36, 18, 9, 86,175, 94,173,159, 49, 99,198, 53,173, 86,219, 65, 32, 16,152,170,165,151, 79,159, 62,253,170, 86,171,237, + 96,181, 90, 79,214,243,111,204, 86, 90, 90, 10, 14,135,131,132,132, 4, 35,143,199, 3,139,197,194,189,123,247, 30, 22, 62,206, +206,206,193, 29,218,181, 13,252,102,215,158, 83, 34,158, 64,208, 61,172,115, 80, 82,106, 90, 38, 33, 84,106, 3, 89,221,111, 48, + 24,188, 79,158, 60,185,174,123,247,238, 21, 95,124,241,133,181,174,200,150, 61, 24,141,198, 83, 87,174, 92,177, 8,133, 66, 42, + 39, 39,199,202,102,179, 97,179,217,136, 49, 44,204,216,110,205, 26,114,243,189,247, 40,185, 68,194,225,241,120, 16,139,197,212, +177, 99,199, 76,122,189,254,212, 95,111,180, 32, 6, 5,209, 93,173, 81, 38,100, 89, 41,220,217,255,192,100, 9,157, 0,161, 18, + 16, 42,209,172,153, 23, 46,165,232,101, 96,129, 15,155, 29, 99,136, 17, 34, 1, 5,113,130, 6, 50, 46, 95, 68,229,230,230, 62, + 52, 68, 85,139,175, 95, 16,174,164,233,164,160,136, 0,108, 56, 50, 4, 73,148,139,139, 11, 39, 39, 39,231, 15,154,193,193,193, +108,139,197, 98,255,208, 46,217, 54, 15,128,158,118, 39,183,194,227,199,107,229, 1,111, 45,249, 74, 36,178, 21, 3,177,107, 17, +210,202, 19,111,141,235,200,255,240, 96, 94,200,229, 84,125, 43,176,201, 20,208, 58, 87, 7,242,217, 75, 38,147, 29,189,124,249, +178, 88, 38,147, 33, 41, 41, 9, 97, 97, 97,136,142,142, 22,139,197,226, 35, 0, 28,106,143,119, 81,131, 52, 93,153,173,251,187, +123,210,115,227,115,172,143,152,172,188,114,130, 87, 62, 59, 88, 92, 84, 90, 49,246, 66, 70,221,247, 79, 45, 92, 45, 46, 46,142, +156, 59,119,110, 65, 94, 94,222, 35, 38, 43, 45, 45,173,234,161,216, 15, 64,131,127,126,127,251,245,120,232,226,133, 51,113, 57, +246, 6,134, 68,189,137, 43,241,247,241,193,156, 81,112,146,139,112,242,228, 73,140, 30, 61, 26,159,124,242, 9,238,221,187,135, +239,191,255,158,138,142,142,166, 46, 92,184, 64,125,246,217,103, 84, 3, 77, 26, 38, 44, 89,178, 4,151, 47, 95,198,208,161, 67, +113,250,244,105, 20, 22, 22,226,187,163, 71,239,238,188,123,247,131,170, 54, 91,117, 12,253, 80, 43,114,185,124,214,146, 37, 75, + 16, 27, 27,251, 80,179,160,160, 0, 75,150, 44,201, 4,240,154, 35, 38,203,145,114,169,125,251,246,129,187,118,237, 58, 37, 20, + 10, 5, 97, 97, 97, 65, 41, 41, 41,153, 0, 82, 27,161, 89,218,148,154,170,252,252,252,115,209,209,209, 23,250,247,239, 47,158, + 52,105,146,235,129, 3, 7, 92,244,122,189,167, 64, 32, 80,155, 76, 38,254,173, 91,183,216,123,247,238,117,191,121,243,102, 74, + 69, 69,197, 37,123,142,135, 86,171,189,116,251,246,237, 65,237,219,183,191,181,110,221,186, 76, 15, 15, 15,122,242,228,201,120, +229,149, 87,224,234,234,106, 91,189,122,117,122,239,222,189, 19,238,223,191, 31,161,215,235,175,219,153,215,175, 23, 47, 94,124, +118,215,174, 93, 24, 62,124, 56, 62,251,236, 51,124,247,221,119,248,245,215, 95, 69,191,255,254, 59, 63, 58, 58, 26, 60, 30, 15, +221,186,117, 67,100,100,228,128,202,234, 78,123,159, 75,151, 41,138,138,161, 40,234,231, 26,175,151,235, 91,231,192,182,117,189, +175,247,123, 53,178, 25, 93, 99,177,159, 9,173,240,241,212,182, 50,253,185,231,187,145,220,201,189,136,102,124, 16, 57,211,215, +153,188,220,154, 42,159,212,200,225, 29, 12, 6,195,195,101,223,190,125,196,221,221,189, 92, 38,147, 57, 60,188,131,187,187,187, +166,180,180,148,116,233,210,165,208,213,213,245,225, 80, 4, 30, 30, 30,154,242,242,114,210,173, 91,183, 66,181, 90,253,112,120, + 7, 47, 47,175, 12, 66, 8,241,241,241,201,174, 75,207,106,181, 18,119,119,247,170, 30,122, 92,103,103,231,141, 93,187,118, 45, +212,104, 52,196,195,195,227,225,208, 9,174,174,174, 43,194,194,194,106,166, 55,148,223,140,204,204, 76,146,153,153, 73,154, 55, +111,158, 93, 61, 61, 45, 45,141,164,165,165, 17, 47, 47, 47,135,135,119,112,117,117, 93, 94, 75, 94, 26,149, 71,111,111,111,141, +193, 96, 32, 61,122,244,120,228,152,122,123,123,107, 42, 42, 42,170,210,237, 26,222, 65, 36, 18, 77, 17, 10,133,217, 66,161, 48, + 91, 32, 16, 44,106,209,162,133,118,247,238,221,100,245,234,213, 85, 93,210,225, 26, 60,162,187, 95,143, 23, 62,112, 13, 30, 57, +171, 41,195, 59,200,100,178, 95,220,221,221,203,247,237,219,247,200,245,101, 48, 24,236, 30,222, 65, 36, 18,101,234,116, 58, 90, +163,209, 88,206,158, 61,171,143,141,141,213, 39, 36, 36,232, 83, 82, 82, 12, 5, 90,173, 89,163,209, 24, 74, 74, 74,140,215,174, + 93, 51,138,197,127,207,240, 14, 36,218,223,143,108, 12, 60,120,255, 19,223,155, 51,251,136, 43,174, 47,236, 64,200, 15,163, 9, + 57,242, 10, 33, 39,223, 37,151, 54, 79, 38, 61,124, 5,182,179,179,155,223, 33,155, 2,126,180,103, 72, 6, 18,221,206,143,108, + 12, 60,114,119,129,239,205, 73,189, 61, 43,182,108, 88, 77, 46, 94,188, 72, 18, 18, 18, 72, 82, 82, 18, 57,178,127, 55,233,209, + 74,252, 64,115, 99,224, 65, 7,135,121,232, 41, 16, 8,116,171, 86,173, 34, 23, 46, 92,120,168,121,240,224, 65, 34, 22,139,245, +128,125,189,150, 9, 64,145,141,193,163,172, 27, 2,126,255,112,160,180,172,224,240,187,132, 92,223, 70, 72,116, 8, 33, 95,119, + 37,100,247, 48, 66, 14,189, 64, 46,172, 30, 71,122,250,242, 44,100, 83,192,105,178, 57,216,238,198,246, 92, 46,183,116,223,190, +125, 36, 59, 59,155,156, 62,125,154,196,198,198,146,196,196, 68,146,158,158, 78, 98, 98, 98, 8,151,203,173, 64, 35,166, 45,235, +234, 6,159,136, 54,188,156,107, 75,123, 18,114,224, 89,146,183,115, 2,137,106, 43, 43,236,214,188, 73,227,209,117,116,113,113, +201,143,137,137, 33, 41, 41, 41,228,212,169, 83, 68,173, 86,231, 3,176,187,189,108,212,144,222,132,152,174,145,240, 62,109, 73, +251,246,109, 73,223,158,109, 72,214,253,181, 36,172, 83, 11,178,113,227, 70,162,209,104, 72,139, 22, 45,136,163, 25,139,136,136, +184, 72, 8,137, 27, 58,116,104, 28,128, 99, 17, 17, 17,113,201,201,201,113, 97, 97, 97, 23, 80,255,208, 15,117, 50, 96,192, 0, + 51, 33,132, 12, 29, 58,148, 0,200,142,136,136, 32,201,201,201, 36, 44, 44,204,212,152,131,103, 79,185, 20, 26, 26,218,189,127, +255,254, 31,132,134,134,206,178,103,120,135, 6, 52, 31,215, 32,212,108, 60, 24,252, 51, 24, 64,231,202, 37,168, 50,141,221, 4, +205, 23,184, 92,238, 22,103,103,231, 95,149, 74,229, 73, 54,155, 29, 13,224,121, 52,110,124, 51, 86,101,132,241,132,171,171,235, +189,246,237,219, 27, 6, 13, 26, 68,134, 12, 25, 66,166, 77,155, 70,104,154, 38,187,119,239, 38,159,124,242, 9,105,237,226, 98, + 93, 13,228,111, 2, 94, 4,195,131, 1, 75, 95,108, 69,157,122,174, 37,202,158,109, 9,221, 75,173, 41,123, 6, 44,141,168,203, +104,209, 52, 77,238,220,185, 67,194,195,195,203, 37, 18, 73, 22,236, 31,176,244, 17, 77,149, 74, 21,171, 86,171,255, 48,136,102, +181,244, 71, 6, 44, 85,171,213,231, 60, 60, 60, 52,174,174,174, 87,106,211, 84,169, 84,177, 30, 30, 30, 26,149, 74,245,200,224, +158,108, 54,123,168, 74,165,202,170,153,206,225,112,250,171,213,234,140,154,233,117,236, 59,220,221,221, 51,178,179,179, 73, 94, + 94, 30,241,246,246,206,174,105,192,114,115,115, 31, 49, 96,246,104, 54,148,151,122,242, 88,171,166, 29,199,180, 49,231,189, 10, +255,102,205,154,105, 87,174, 92, 73,164, 82,233, 35, 93,158, 3,250,188, 52,239,226, 93, 93,233, 43,115, 54,238,174,101,192, 82, +123, 7, 7, 29, 36,145, 72,178,194,195,195,203,239,220,185, 67,104,154, 38, 52, 77,215,101,180,106,211, 28,220,185,115,231,130, +252,252,124, 91, 89, 89,153, 53, 35, 35,195,152,156,156,108, 88,184,112,161, 57, 47, 47,175, 66,167,211,153,226,227,227,141, 30, + 30, 30,121, 0, 6, 59,122,142, 26, 73, 68,205,234, 51,178, 57,168, 39,217, 20, 20,147,248,145,207,173, 23,186, 74,140,113, 43, +135, 18,114,242, 93,114, 97,227, 43,164,187, 47,255,129, 33,218, 28,120,148,124,229,223,135,172,109,197,183, 75,115, 75,235,222, +100,115,224,209,155,243,125,110,141,238,228,106,218,181,109, 51,185,119,239, 30, 57,184,119, 39,233,214,178,210,100,109, 10, 58, + 65, 54, 6,133,219,163, 89,155,217,218,186,117, 43,185,119,239, 30,249,241,199, 31,237, 53, 89, 17,181, 25,173,247, 35,164,197, +175,116, 21, 26,159,237,200, 55,141, 12,225,153, 35,253,120,214, 30, 62, 28, 91, 7, 15, 22, 29,228, 10, 18, 25, 32, 50,146, 77, + 1,167,201,166,160, 65,246,230,147,207,231,167,163,218,152, 58, 53, 23,129, 64,144, 87,143,209,138,104,208,108,249, 11,114,126, +249,164, 63, 25,222, 94, 86, 96,167,201,106,232, 90,234,168, 82,169,242,191,254,250,107,226,230,230,150,103,167,201,122,168, 57, + 34, 42,146,164,221, 63, 66,126,220,189,132,132,247, 9, 34, 59,182,206, 36, 23, 79,127, 68,134, 13, 9, 39, 17, 17, 17, 36, 63, + 63,159,244,239,223,159, 56,154, 79,133, 66,177, 67,167,211,197, 29, 63,126, 60, 46, 34, 34, 34,110,199,142, 29,113,103,206,156, +137, 19,139,197, 59,170,130, 19, 53,205, 86,208, 31,203,255,136, 26, 17,173,184,178,178, 50,114,252,248,113, 18, 17, 17, 65,118, +236,216, 65,206,156, 57, 67,196, 98,113, 92, 99,239, 35,123,203,165,129, 3, 7,206, 75, 73, 73, 41,157, 63,127,254,238, 90, 6, + 44,181, 87,243,222, 99,202,231, 99, 41, 67,254, 6, 77,153, 72, 36,138,187,118,237, 26, 41, 42, 42, 34,109,221,220,200, 98, 54, +155,100,242,120, 36,155,199, 35, 27,129,194,127,129, 77,154, 92, 87,213,225,159, 77,173, 70,171,162,162,130,204,158, 61,219, 36, + 20, 10,245, 60, 30,207,209, 41,120,158,232,139, 80,165, 82,157,115,115,115,211,184,185,185, 61, 98,246,170,167,171, 84,170, 43, +255,242, 27,208,159,199,227,165,113,185,220, 71,167,224, 9, 30,209,189,117,207, 73,115,221, 66, 70, 12,105, 98, 62,121, 60, 30, +239,125,161, 80,168,159, 61,123,182, 73,167,211, 57, 98,180, 0, 96,160, 88, 44,206,218,190,125,187,225,238,221,187,150,194,194, + 66,235,197,139, 23, 45,177,177,177,166,143, 63,254,184, 76, 44, 22,103,161,238, 97, 9,254,146,227, 73,214,182,226, 87,153,173, +235,115,125, 18,135,183, 21,155,163,223,142, 36,221, 91,212, 48, 89,117,143,228, 94,187,102,165,217,186,250,161,119, 98,184,191, +212,186,100,238, 91,164, 91, 75,209,163, 38,203, 1,205,154,102, 75, 44, 22,151,125,244,209, 71,142, 68,178, 30, 53,132, 91, 2, +188,201,230,192, 29, 15, 76, 84, 3,203,198,128, 47,201, 23, 1,222,255,148,251,168,171, 27,124, 6,248, 11,110, 56, 16,201,178, + 39,159, 29,149, 74,229, 45, 7, 34, 89, 15, 53,191,248, 98, 29,153, 48,126, 32,185,127,107, 31,209, 21, 28, 33, 87,206,175, 34, + 99, 70,132,146,110,221,194,200,230,205,155,201,237,219,183, 73,151, 46, 93, 72, 35,242, 25, 57,117,234,212,184,228,228,228,184, +164,164,164,184, 51,103,206,196,141, 26, 53, 42, 14, 64,100,245,154,160, 42,179,101, 30, 51,198,216,145,197,122,171, 1,205,103, +166, 78,157, 74,146,147,147, 73, 82, 82, 18, 57,115,230, 12, 25, 53,106, 20,129, 99,211,247, 52,170, 92, 10, 13, 13,237, 30, 30, + 30, 62,183, 83,167, 78, 67, 30,151,230,127,208,104, 73, 70,143, 30, 77,219,108, 54, 50,100,200, 16,219, 26,160, 56,154,162, 52, +209, 20,165,217, 12,228,253,219, 35, 90,127,246,132,159, 17, 0,126,174,158, 32, 20, 10, 53, 21, 21, 21,174, 82,169,116,191, 78, +167,155,129, 7,221, 34,155,164,249,103,228,147,209,252, 87,104,122, 72,165,210,117, 58,157,110,148, 80, 40,204,171,168,168,112, +115, 64,211, 73, 32, 16,188, 37, 20, 10,195,245,122,189, 63, 0, 72, 36,146, 59, 70,163,241, 87,131,193,240, 57,128,226,191,123, +223,201,218, 86,124,240,249,157, 65,240, 94, 92,122,121,203, 37,199, 11,125,222,238,175, 76,239,209, 90,146, 2, 46,253, 25, 40, +227, 37,234,197, 52,163,195,154, 34, 42, 12, 54,238,123,151, 82,245, 45, 62,251,169,204,103, 86,184, 52,189, 71, 43,105, 58, 8, + 62,131, 64,127,222, 81,205,154,102, 75, 34,145,108, 47, 47, 47,127, 21,192,175,142,238, 59,217, 19,196, 67,185,165, 25, 44,236, +182, 32,245, 76,225, 67,136, 30, 44,118, 2,114,161,161, 62,190,101,102,238,163,218, 53, 55,108, 88, 79,126,254,233, 8,140,250, + 66,228,104, 75, 49,225,249,151,208,177, 99, 40, 84, 42, 21, 22, 47, 94, 12, 63, 63, 63,124,242,201, 39, 84, 35,242, 25, 41,149, + 74, 39, 4, 6, 6,182,186,121,243,102,146, 94,175,255, 22,192,137,154,207,159, 64, 32, 92,204,225,116, 48, 88,173,167,111, 1, +177, 13,104, 62, 35,149, 74,103, 5, 6, 6,134,220,188,121,243,134, 94,175, 95, 9,224, 59,166,172,123, 50, 52, 89, 44,214,231, + 62, 62, 62, 99, 82, 82, 82,222, 3,176, 11,255, 33,254,114,163,197,104, 50,154, 79,160,102,213,125, 66,254,105,249,252,191,217, +162,103,128, 66, 75, 16, 42, 19, 60,122,117, 3, 38,171, 97, 77, 17, 21, 6, 43,231, 77, 80,104, 14,130, 92, 16,214,231, 13,152, +172,191,214,100, 2, 20, 62,174,167,252,250, 24,132,170,251,124, 49,215,124, 45,204,155, 55,143, 28, 59,118, 12, 98,177, 24, 6, +131, 1,131, 6, 13,194,167,159,126, 74, 49,101, 8,163,249, 23,106,254, 43,225, 48,135,128,129,161, 65,200, 63, 53, 99,212, 27, + 73, 38,178, 39,232, 50,242,217,179,193, 66, 75,192,154,134,114,107, 46,245, 70,154,169,137,154, 23,145, 79,205, 4, 27,254,224, + 91,239, 67,103,202,165, 94,107,188,230,159,240, 15,145,224,227,127,238,121,121, 18,169,105,170, 98, 99, 99,153,131,194,192, 96, + 63,147,241,104, 79,195,135,159, 25,163,197,192,240,132, 67, 61,117,203, 12, 32,179,114,249,199,106, 50, 48, 48, 48,252, 7, 13, + 23, 40,212,221,160,205,145,144, 96, 99, 26,218,253,204,104, 54, 74,147, 13, 64, 1,192, 9, 15,198, 32,169,234,210,219,208, 48, + 27, 67, 0, 88,152,227,201,104, 50,154,140, 38,163,201,104,254,205,154, 13,105, 63,137, 85,146,181,245, 50,140,254, 43,126, 56, +130,209,124,172, 12,250,215,236, 59, 65, 7, 16,172,174, 92, 58, 48,231,157,209,100, 52, 25, 77, 70,243, 63,175,249,175,132,169, + 58,124,178, 16, 62,177, 57, 39,196, 3, 64,213, 32,151, 9,168,160, 2, 33,196, 76, 0, 64, 25,174, 16,130,187, 0,218, 86,174, +207,160, 40,135,123,163, 50, 48, 48, 48, 48, 48,252, 93,132, 2,184, 2,192, 3,192, 48, 0, 49,168, 28, 85,225,111, 53, 90, 34, +151, 54, 30,224,176,218, 83, 52, 9, 4, 0,194,162, 18, 97,165,227, 13, 5,119,155,252,144,149,122,250, 59, 19,240,247, 80, 48, + 61,165,203,190,211,228,193,208,218,250,203,199,184,169,100, 19,114, 11, 74,182,223,184,173, 59,224,200,182, 10,133,143, 66,232, +172, 28,103, 52, 91,218,242,121,188,116,115,113,105,116, 81, 81, 82, 89, 35,178,225, 92,223,202,143, 63, 38,212,225,156, 43, 20, + 79,108,102,185,200,121,148, 14, 58,162,203,145,210,190,197, 41,100,239,222,167,136,163,231,134, 98,161,159, 68, 38,235, 36, 16, +138,195,196, 50,101, 27,154, 0,133,154,172, 84,147,197,122,198,102,210,199, 17, 26,191, 57,112,174, 38, 2, 88, 2, 0,232,223, +255,103,180,133, 28,159, 87,101, 28,175,245,191,142,137, 39, 79,162,106,112,217,247, 1, 44,101,238, 91, 6, 6, 6, 6,134, 39, +204,104, 13,195,131, 42,195,134, 27,195,251, 4,247,186, 44, 20,138,124, 1,128, 38, 4, 52, 1,202, 75,139,227,114,147, 98, 7, + 1,128,170, 69,232,113,174, 80,222,137, 38, 15,214,219,104,192,106,174, 72, 41, 77,187,216,197,158, 28, 73, 92,253, 71,247,143, + 24, 48, 38, 42,106, 88, 64,187,182,237, 90, 3,192,245,132,235,247, 15, 31,142,185,125,242,103,106, 95,121,222,157, 31,155, 20, + 64,129,240,211,206,157, 59,246,138,141,189,242, 9,128,105, 77, 61,130, 46, 46,210, 25, 39,126,152,221,103,192,152, 21, 18,192, + 49,163, 37,116, 86,142, 27, 57,124,112,199,119,222,152,202,122,101,246, 98,223,203,103,127, 91, 38,245, 8, 41, 38,180,229, 68, +185,102,252,239,245, 77,156, 92,211, 63,214,101,176,190, 45, 60,198, 90,253,117,119,165,161,240,254,120, 66,219,198, 83, 20, 5, + 54, 95,188,215,181, 85,175,221, 78,253,222, 46, 2, 96,119,143, 49,185, 71,112,132,218,195,107,223,248,151,222, 18,138, 21,110, + 28,176,121, 0, 40,100,167,222,194,201,239,150, 40,223, 92,176, 53,244,108,124,154,245,151, 31,214, 87, 80, 60,238, 24,125,206, +205,134,235,211,211,210,156,224,227,243,224,253,151, 95,206,131,111,203,235,120,208,214, 12, 88,133,146,111,178,209, 22,120, 96, +180, 82, 83,161,100,238, 89, 6, 6, 6, 6,134, 39,136,152, 74,115, 21, 83,115, 69,157, 70, 75, 40, 20,249, 94,248,237,176,243, +143,103, 50, 0, 0, 17,161,238,248, 96,225,186,200, 29,107, 99,111, 3, 64,247,254, 81,254,159,188,255, 6,206,221,208,130, 16, +130,142,126, 46, 24, 50,242, 41,251,140,135, 91, 80,151,113,227,198, 62, 55,123,246,172, 17,247,238,221, 75,221,181,107,215,239, + 0,208,187, 79, 31,191,197,139, 23, 63,189, 66,233, 44,248,126,239, 15, 89, 21,154, 91,151, 27,179,183, 66,207, 86,205, 2,218, +180,156,240,253, 87,235, 88,253, 6,141,125, 54, 21,229, 75, 42,178,147,178,236,217, 86,165, 82,205,228,114,185, 10,224,193,108, +236, 85,152,205,196, 29, 0,172, 54, 90,166,244, 12, 40, 99,243,132, 54,129,128,119,179, 76,167,219, 94,154,117,107, 75,125,154, + 70,139, 37,228,205,215, 94,100, 93, 77, 42,128,111, 72,111,246,234, 37, 31,130,182, 89,148,111,189,191,112, 92,236,197,239, 81, +174,193, 41, 59,119,141, 91, 51,161, 89,179,110,236, 79,151, 72, 7, 82, 20, 94,240,233,254,210,168, 79,182,237,229,118,246,147, +195,104,161,113, 52,174,160,251,198,207, 63, 93,126,118,227,176, 67, 0, 54, 3,248, 5, 64,131,166,206,217,197,249,219,153,115, + 63,151,150,155,254,223,219,187,210,100,225,203,237,123,112, 45,131, 70, 96, 64, 32,199,125,230, 50,233,230,133,147,183,233, 31, +204,179, 85,155,221,109, 5,160, 39,144,232,140, 41, 11, 6,224,155,165,139,160, 86,151, 67, 38, 75, 7, 5, 55, 0,109, 42,191, +120,151,159,143, 12, 0,239,107,181,144,124, 50, 21,131,174, 2,115, 58, 0, 90, 0,103, 41,251,102,141,103, 96, 96, 96, 96, 96, +248,187,200,193,163,141,223,163, 27, 52, 90, 0, 32, 21,113,112, 59, 57, 23, 0,224, 36, 2,102, 76,153,132,130,252, 60,127,147, +149,198, 75,147,158,199,149,196, 28,220, 78,201, 3, 33, 4,254, 94,118, 79,194, 13, 54,232,206, 47,189,252, 82,223,227, 39, 78, + 92,154, 55,119,222, 55, 20,133,243, 0,176, 57,250,203,238,243, 63,154,255,234,243,147,158, 31,184,119,239,222, 27, 0, 26,101, +180, 56,148,108,221,242,165,139,248,153,249, 21, 21, 51,103,191, 71,207,122,123,230,106, 0, 99,237,114, 50, 92,174, 34, 51, 51, + 83,202, 98, 61, 58,151,230,103,139,222, 59, 61,112,204,138,187,169,233,197, 87,143, 31, 60,216, 37, 56, 56, 24,153, 89,185, 61, +151,173,217,212,225,232,113,209,139,101,165,134, 49,250,252, 91,181, 78,218, 44,224,114,111, 44, 88,182,177, 35,237,228,199,250, +224,213,161, 8,105,237,137, 44,109, 49,250, 12, 26,193,137,187,124, 57, 18,176,219,104,213, 28, 60,112,156,137,214,118, 88,188, +253,226,128, 81, 61, 60, 59,179, 88,108,232, 12, 22,228,149, 24, 97,163,129,222, 65, 10, 12,222,177,134, 83, 88,110, 25,189,240, +135,140,209,231,215, 70,105, 42, 74,178,167, 3,216, 87,255,207, 16,103, 47,181, 28,183, 51,202,106, 53, 89,229, 21, 86, 0, 0, +143,109, 3, 5,226, 82,143, 80, 79, 0, 95, 3,129,192, 79,211,159,131,155,219, 46, 55, 55,183,113,106, 55,247, 56,255,231, 94, +164,154,249, 6,201,116, 6, 51,110,222,184, 94, 22,220, 41,129,148, 21,106,223,170, 40, 47,218,123, 11, 72, 8, 4,118, 87,106, +188, 8,198,104, 49, 48, 48, 48, 48,252,179,169,179,215, 33, 7, 0, 14, 31, 62, 76,162,162,162,254, 48, 2,176,205, 70,112, 59, +229, 65, 19, 28, 54,155,141, 97,189,252,176,122,217, 2, 24, 76, 86, 92, 75, 46,193,143,231, 50, 96, 42, 47, 6, 33, 4,249, 33, +234,218,126,248,145, 42,165, 21, 75, 68,161,108, 1,119,252,217,139,146, 22,206, 74,165,242,238,141,111,202,231,191,173, 9,226, + 16,115,220,194,207,252,146,121,206,156, 30,123,246,236, 14, 30, 30, 21,197,151, 74,101,239, 18, 78, 7, 47,110, 57,153, 85, 82, + 18, 95, 82,151,102, 77, 68,234,192, 17, 35,134, 13,238,239,238,238, 70, 63,183,248, 98,226,186,233,161,222,109,252,218,244,188, +109, 49,140, 48,104,239, 30,172, 99,179,135,154, 52, 77,131,197, 98, 65,163,209,192,102,179,193,104, 52,194, 98,177, 32, 35, 35, + 85, 67, 19,226,101, 3,205,242,240,240, 2,135,195,135,111, 11, 31,108, 92,189, 68,188,227,251,131, 97,115,230,125,122, 64,159, +143,110,248,255,224,150, 15, 53, 43, 10,139,246, 30, 57,118,194,149,224,164,231, 7,175, 14,101,107,139,116, 56,121,249, 30,174, +220,204,112,244, 68,214, 28,194,161, 69, 86,218,189,210, 21, 43, 86,176, 63, 57,122, 47,163,255,144,177, 54,159,214,237, 91, 24, +109, 4, 0, 5, 1,143, 3, 30,135, 5, 31, 87, 33,246,191,215, 22, 23, 71,198,187, 69,134,186,126, 78, 8,217, 87,223,241, 52, + 26, 45,182, 94,129, 18,118,135, 86, 10,196,223, 47,194,165,163,231, 49,115,238,231,136, 77, 54,162, 76,167, 7,101, 51,130, 77, +140,200, 79, 75,130,213,102, 35, 13,157,247, 7,132, 22, 1,128, 64, 32,120,255,199, 67,199, 60,141,180, 16,185,197, 70,104,138, +140,240,235, 54, 70,146,150,149,135,175, 23, 60,253, 62,128,189,129, 64,153,125,154, 77,134,209,100, 52, 25, 77, 70,147,209,252, +135,104,214,229, 69,158, 16,234, 28,202,129, 85,223, 86,247, 51, 10,113, 59, 57, 23,157, 2,155,161,117, 11, 15, 92,186, 83,132, +111, 79,102, 96,235,241, 52,156,188,150, 7,154, 35, 67,110, 41,112, 55, 85,131,187,105,249, 13,142,159,205, 22,112,199,191,249, +102,201,236,118,193,165,221,126, 59, 58, 3,205, 92,239, 6,207,153, 83, 60,131, 45,224,142, 87, 54,151,237,122,111,246, 91, 19, +100, 98, 49,223,100, 52,161, 85, 75, 31,225, 27,211,103,188, 72, 41, 5,118,207,137, 36,107, 22,164, 20,136, 68, 91, 22,126,252, +174,224,243, 31,239,166,151,155, 80,190,239,188, 38,105,214,123,243, 11, 57, 92,225, 70, 89,179, 32,187,219,254, 88, 44, 22, 24, +141, 70,152, 76, 38,152,205,102,100,101,220, 26,241,203,143,239, 12,106,217,220,121,144, 64, 40, 4, 1, 80,106,176, 34, 57, 71, +143,240, 1, 3,217,157, 66, 67, 67,164, 30, 65, 47,215,166, 85, 82,146, 86, 66, 19,182,236,240,254,157,236,221, 63, 93,197, 55, +135, 47,227,192,175, 87,113,233,212, 81, 43,161, 45, 15,231,255,146,122,248,249, 75, 61,218,165, 73, 61,219,107, 30, 46,205,218, +214, 59, 60, 51,155,205, 34,225, 3, 34,126,158, 50,237,141,223,244,101, 5,218, 45,235, 22,100,229,101,167,222, 18,240, 40,171, + 88,192,134,174,194,138,109,191,100, 99,220,146,107,184,153,174, 3, 33,164,193, 9,188,105,224,237,241, 47,191, 99,179,152,205, + 8,240,150, 98,103,244, 82,140, 8,239,128,254,237,148,232,210, 90, 2, 49,199,136, 27,137,183,241,221,206,109, 86,154,102,205, +106,224, 70, 28, 92,185,196, 1,128, 78,167,123,103,206,187,179,242, 76, 86, 26,102, 11, 13,115,229,235, 47,223,125,150,103,171, +208,191, 83,185, 93, 92,181,237,152, 41, 30, 24, 24, 24, 24, 24,158,132,136, 86,213,226, 81,125, 69,157, 85,135, 21, 21,134,148, +177,227,159,135,135,218, 93, 58,178,223, 11,188,184,251,197,200,203, 73,195,189, 59, 9,208, 87, 88,192, 83,182, 4,132,238,104, +225,235,131,248,219, 7,204,107,151,199,232,104,171, 49,165, 46,189, 17, 35, 60,188,238, 37, 82,172,229,203,188, 47,220,185, 93, +212,105,231,220,175,241,220,115, 82,213,242,101,222, 23, 82,147, 36, 44,177,144,244,120,113,210,179, 20,139, 34,152, 51,103, 54, + 70, 70, 13,198, 75, 47, 78,164,182,111,223,214,173,216,206,189,164,193,253,226,253, 15, 23,240, 53,197, 86,211,165, 59, 58,163, + 88, 34, 18,157,189,171, 43, 15,241,245, 22, 13, 29,243, 66,118,204,158, 45,159, 3,152,100,143, 86,149,193,178, 88, 44, 48,155, +205, 0, 96, 3, 0, 22,235,193,107, 65,153, 9,218, 98, 35, 52,197, 70, 88,109, 52,198,140,159, 36,186, 28,123,109, 18,128, 58, +218,107,209,180,197,106,193,190,159,174, 32,235,242, 94,154, 98,177, 75,170, 53,134,135,212,195,207,223,221,221,251,116,212,152, +137,174,124,225,131,106,216,178,114, 35,182,111, 90, 86,111, 62, 89, 20, 69,104,155,181,216,106,177,148,183,106,217, 42, 43, 48, +184,131,240,204,111,199, 71,156,253,121,159,206,218,106,162,211,253,212, 28,176,185, 2,176,121, 66, 24,205,246,117, 60,212,220, +187,176, 30, 0,245,242,235,179, 87,191,245,206, 7,236,183,215,254, 14, 83,133, 30, 70, 67, 57, 74, 75,138, 32,226, 88,112,227, +220, 65, 43,177, 89,222, 42,207,185,186,190,110, 37, 42, 27, 64,118,245,148,194,194,194,147,231,126, 63,125,232,226,185,223, 95, +114,111,213,137,101,178,208,184,151,112,145,206,186, 27,123,200,104, 44, 61, 9, 0, 20, 80, 0,224, 56,115,223, 50, 48, 48, 48, + 48, 60,129, 17,173,201,213,211,234, 52, 90,105, 55,207,116, 1, 0,255,206,145, 5, 82, 33,199,153,195,162,160,201,188,143,237, + 43,102,130,166, 9,134,190,186, 28, 50, 95,119,136,120,108, 24,117, 5,186,194,251,167,234,107,171, 3,138,178, 12, 92,191, 57, +203,247,245,215, 90,201,119,238,212,113, 1, 96,231, 78, 29,247,181,169,205,229, 27, 54,167,248,118,237,213, 9,196,102, 67,212, +200,177, 24,255,204,120,164,230,234,241,195,233,116,148, 27, 76,118,245,150, 19,169, 2, 59,168, 92, 92, 7,191,249,194, 96, 9, +135, 77, 81,109,124, 20,236,140, 60,139,149,205,230,218, 14, 93, 46,201, 30, 51,230, 25,213,201, 35,187,251,219, 84,129, 29, 12, +249,137,215, 26,210, 51, 26,141,143, 84, 29, 58,171, 90, 30, 25, 56,118, 69,102, 78,110, 89, 76,110, 81, 69,215,114,139, 21,154, + 98, 35,180,197, 70, 20,151,155,225, 46, 83,194,106, 49,181,171, 75,143, 16,242,205,168,177,207, 79, 4,192,162, 88,214,175,117, + 57,137,119, 30,172,249,191,201, 26, 60,242, 57,215,211,113,247,113, 47,246,104, 17,161,173, 15, 70,113,167,232,204,250,143, 43, + 8,155, 2,205,227, 80, 22, 54,139, 69,155,205, 58,139, 90,237,122,242,212,201, 99,195, 43,172, 73, 96,243, 4, 15,191,107, 48, +253,143,189,183, 14,143,234, 90,191,199,215, 57,103, 92,226,201,196, 8, 18, 36,193, 29, 18,220, 73,113, 40, 20, 45, 80,138,183, +212,160,165, 45, 45, 46, 23,215,210, 98,165,184,187, 67,240,226,154, 0, 9,196, 61,153,137,140,219,177,223, 31,147, 64,128,144, + 76,160,247,247,189,247,115,179,158,103,158,201, 57,204,121,217,103,235,218,235,125,247,222,172,211, 53, 38,251,197,205,181, 0, +176,106,245,202,101,173,186, 14, 19, 93,190,159, 8, 51, 13,132, 55, 9,193,225, 61, 27,173, 60, 79, 79, 51,102, 62, 88, 91,142, + 74,232, 30, 20, 20,244,149, 80, 44,238, 36,147,187, 4,249,248, 87, 38,237, 12, 11, 59,205, 66,225, 21, 72, 74,148,158, 93, 57, + 82,116,141,177,219, 34,237, 70,245, 42, 0, 5, 21,237,182, 2, 21,168, 64, 5, 42,240, 95,166,106, 1,197,246,208,122,141,104, + 29, 63,126,156, 7,128,146,252,163,233,217,121,240, 82, 10,224, 19, 80, 13,195,191, 90,134,109, 43,190, 5,203,210,224,121,128, + 97,157,219,153,128,231,133,231, 38, 79,172, 86,187,106, 53,202,103,248, 48,185,121,199, 78,147,108,248, 48,185,185,126, 3, 47, +237,228,137,213, 18,245,150,202,173, 25,150,197,245,232, 28, 68, 37,106, 17,149,164,131, 82,230,252, 54, 95,148, 88, 52,113,241, +162,133, 34, 1, 69, 16,209,201, 6, 67, 90, 46, 99,160,132, 66,187, 92, 38,230,109,188,192,154,164,225,115, 59,247, 27,109, 62, +182,125,213, 24, 0, 95,188, 83, 21, 43, 92,105, 88,164,100, 21,125,243, 60,207, 19, 0,199, 17, 44,155,166,177,192, 96,167,145, +157,255,138,104, 17,204,187, 61,167, 74,255,154, 33,174, 46,202,211, 20, 69, 73,120, 30,160,237,204, 39,240,175,217,221,144,249, + 34,182, 56,201,186, 25,157,129,184, 7,231,179, 89,187,105,132, 41, 39,230,130,179,239, 78, 16,224, 41, 10, 28, 69, 18, 28, 65, +128, 19,146,188, 13, 60,207,189,153, 34, 83, 57,136, 86, 17,217, 18, 11,169, 25,103,119,175, 80,125,214,179, 14,246, 92,113,112, + 62,139, 94,173, 51,166,151,139,100,193,203,203,107,228,247,223,127, 63,179,207,199,195,160,181, 16,200,206,119,168,129, 54,154, +131, 72,225,141,174,147,183, 4,101,170,117, 65, 47,110, 31,107,173,121,176, 83, 75, 91,180, 43, 43,218,108, 5, 42, 80,129, 10, +252,111,161, 52, 46,242, 95,164,106,189,173,104,149,246, 66, 60, 15, 60, 79,214,160,106, 37, 31, 84,170, 90, 3,177, 79, 31,189, +250, 55, 0, 12,235,156, 59,234,232,209,204,180,101,203, 92,185,111,191,213,134, 47, 94, 92,249,198,196, 9, 65,110,245, 27,120, +105,191,255, 62, 37,124,249,114,183, 27,231,110, 10, 89,190,112,191,174,162,189,185,120,190, 60,123,108,146, 45, 26,213, 13,166, +102,239,124,158,114,225,177, 62, 71, 36, 18,209,126, 30, 82,194, 69, 41,166, 40, 82, 40,182,210,164, 53,164, 94, 19,234, 24, 73, + 52, 41,205, 74, 17,209,122,211,117,152,171,142,235,115,246,192,212,250, 29,250, 45,241, 76, 87,155,161,181, 81, 47, 93,135, 20, + 73,224,241,211,100,128, 18, 69,149,100,211,213,197,243,204,174, 29,219, 42, 47, 95, 60, 31,118,134,197,228,111,127,193,232,145, + 35,206,192,191,102,247,202,213, 66,239, 93, 61,246,167,188,251,132,245, 72,142,185,155,197, 88,117,187,203, 67,178, 94,146, 45, +128,103,121,142,204,203,215, 41,173, 12,164, 40,129,247, 89,237,220,123,213, 28,131,153,193,177, 91, 89, 56,126,104, 55,220, 92, + 20,239,101,195,205,205,173, 78,187,118,237, 65, 8,196,176,209, 86,216, 24, 14,182, 98, 49, 90,118,154, 3,205, 11, 33,247,111, +136,188, 39,135,235,192,162,173,232,113, 42, 80,129, 10, 84,224,127, 8,255,197,129,240,197,201,213,187, 21,173,210, 80,165,146, + 47,110, 69, 37,162, 65,237, 96,184,185,186,224, 89, 92, 26, 40, 82, 8,146, 0,104,198,121, 50,196,219,233, 61,203,151,187, 33, + 57, 81, 65,254,182, 62,177,218,228,137,213, 18,151, 47,119,187,193,219,233, 61, 0, 70,240, 60,224, 32, 91, 14,194,197,150,131, + 23,240, 28, 29,228,235, 41,167,238,198, 27,115, 73,146,178,122,185, 73, 57, 47, 55, 9,233,229, 34, 22,138,132, 20,199,240,164, +189,146,170,154,133,231, 56,103,206,213,123,205,117,200,178, 44, 8,130,100, 11,137,152, 34, 53,215, 12,173,133, 66,118,129, 21, +249,122, 59,106, 5, 42,112, 62,114,191,137,165,205, 59, 75,178, 69, 9, 69,110, 53,170, 85,194, 79,115,151,195,108,101,241, 60, +221, 0,145, 68,226,231,235, 87,239,225,136, 73,211, 37, 83, 54,196, 97, 76, 39, 47,124,123, 53, 46,221,148, 45,157, 94,158,146, +101, 89, 22,102,139, 77,148,173,201,247,208,233,141,174, 50,169,196,236,227,233,166, 41,233,183,150,114, 42, 90, 69,144, 75, 5, +232, 29,230, 7,139,125, 40,204, 86, 6,127, 95, 56,248, 62,102,130,125, 3, 42,193, 96, 43, 70,174, 10,201, 86,113,210, 37, 84, +250, 0, 32,130, 43,186,156, 10, 84,160, 2, 21,168,192,127, 17,222,185,234,208, 41,162,165,148, 75,193, 83, 82, 92,189, 23,135, +208,186, 13,177,245,232,109,212,108, 16,134, 76, 61, 3, 30,100,153,171, 13,139, 48,245, 71,243,125, 0,247,251,244,145, 87,234, +223, 63,176, 43,207, 11,207,173,255, 67,151, 6, 0,193,245, 29,102, 56,142, 7,207, 3, 60,231, 32, 92,206, 75, 58,130,228,196, + 76, 93,213,106,126, 10, 60, 73,179, 91, 21, 18, 17,233,161, 16, 83, 62,110, 98,145, 72, 32, 0,203, 19,214,204,204, 56, 43, 1, + 36, 57, 99,238, 77,215,161, 92,233,127,178,115,191, 37,234,164, 20,237,221, 90,121,166, 70, 90,187, 24, 60, 15,212, 10, 84, 32, +234,230, 9, 54, 59,253,197,115,115,118,204,239, 37,217,226, 56, 80,118,134,195,195,120, 45, 10,140, 52, 10, 12,118,180,238,216, + 91,212,186, 75, 31, 92,141,210,128, 99,104, 44,222,120, 66,207,242,244, 96,224, 41, 93,142,151, 38,111,221,143,174,164,206, 55, + 74,132, 2, 65, 65,237,154, 85, 18,196, 34, 33,163,211,233,196,175,255,138,130, 66, 38, 70,158,129, 6, 0,186,188,181, 71,107, +164,113,244,102, 22,142, 29,220, 5,153, 76, 6,254, 61,106,160, 72, 36,114, 23,138,164,176, 27, 29,238,194,162,143,253,141, 15, + 41,144, 0,164,192,189,162,205, 86,160, 2, 21,168, 64, 5,254,139, 80,252,140,195,158,197,201, 23,233,148,106,194,241,240,246, +242,132, 84,225,138,196,108, 59,244,132, 10,249, 38, 30, 44,235, 80,180, 74, 17,158, 74, 60,221,251,232,209,204,180, 35, 71, 52, +155,143, 30,205, 44, 22,232,253, 74,201,122,249,205,241, 78,219, 36,120,246,252,209, 83,151,180,125, 90,250,120,144, 20,101, 22, + 9, 73,171, 64, 68,217, 69, 2,146, 22, 9, 72,155,175,171,144,186,116,108,183,152, 39,112,169, 44,155, 22,139, 5, 93,186,116, + 65,143, 30, 61,208,183,111, 95, 12, 26, 52, 8, 33, 33,117, 84, 36, 69,216,120,130,227,124,196,122,212,240, 33, 32,176,164,226, +194,238,127,153,162,174, 31,126,200, 90, 45,189,241, 58,229,124,101,147,231,185, 60,173, 21, 22, 59,139,124,131, 29,249, 70, 59, + 24,159,112, 28,254, 59, 3,102, 27,139,228,123,251,205,234,172,180,175,172, 57, 47, 18,203, 40,138, 31, 94,191,228,211, 62,255, +108,164,218, 69, 74,190,104,219,170,185,218,219,203,147, 33,136, 87,202, 43, 65, 16,144,186,170,224,225,238,130,196,251,167,112, +118,113,103, 51,128,159,157,201,207,226,112,149, 11,208,167,165, 31,122, 15, 24,138, 6, 97,221,157, 33,214,111,217,148,203,229, +178, 34,245,170,248,182, 14,182, 98,170, 22, 91, 88,222,164, 64, 34,115,182,220, 63, 16, 21, 54, 43,108, 86,216,172,176, 89, 97, +243, 63,199,230,127, 51,138,206, 56, 44,250,118,110,103,248, 34, 2, 84,221, 95,129,154,129, 10, 88,236, 42, 88,108, 44,140, 22, + 22, 58,147, 29, 58, 19,141,196, 44, 19,162,142,126,120, 10, 29, 42,150, 99,235,115,222,177,223, 38, 88,142,119, 90, 61, 17,219, +109,115,151, 45, 94,240,201,238, 38,141,109, 83,122,250, 7, 61, 74,180,101, 16, 4,105, 38, 41, 1,237,233, 34, 16, 62,123,246, + 72,125,227,202,201,118, 82,134,253,212,129, 93, 93,197, 0, 0, 32, 0, 73, 68, 65, 84, 84,138, 29,134, 97,180,129,129,129,133, + 74,212, 43, 10, 89,167,134,172,239,245, 19, 63, 4,183,239,179,216,103,197,252,169, 38,146, 18,113,132, 64, 20,197,210,230, 93, +230,236,152,245, 40,133,126,144, 34,233,211, 91, 15,158,132,185,123, 6,225, 69,186, 17, 70, 11, 3, 59,195,193, 67, 41, 66,218, +227, 51,246,196,103,119,247, 26, 50, 30,109,125,143,108,219, 25,251, 52,170, 82, 68, 68,247,143,195,194,194,169, 95,127,253, 5, +161,161,161, 48,155,205, 32, 73, 18, 65, 85,107, 32, 49,246, 1,110,158,152,203,154,114,147,126, 7, 48, 7,128,186,188,255,137, + 70,103,195,169,187, 57, 56,113,104, 15, 40,161,248,125,138,151,148,201,100,210,146,200, 85,113,210,245,242,199, 66,177,180,112, + 18,192, 85,180,221, 10, 84,160, 2, 21,168,192,127, 9,198,189,241,189,193, 41,162,101,177, 88, 18,219,116,233, 13,142,227,193, +242, 0,199, 22, 42, 79,220, 43,245,137,165, 45,137, 31,154, 58,142, 99,111,175,221,176,185, 71,147, 22,237,169,186,149,149,208, +229,102,225,230,245,139, 12, 56,254,134, 51,207,231,230, 62, 55,200,124,107,126,252,201,192,254,251, 70,126, 54,161,160, 93,199, +142, 10,149,202,207,154,150,158,102,218,178,125, 7,125,230,228,145,118, 28,152, 33,185,185, 47, 12,165,217,209,106,181,171, 74, +186, 47, 17, 43, 91, 3, 8,166, 4,132,205,172,126, 94,174,136,112, 77,122,234,128, 5,115,103, 37, 13, 27,251,141,184,122, 96, + 13,228,104, 41, 36,166,101,225,217,149, 35,214,244,216, 59,135,116,105,247,199, 56,105, 42,179,132,123,105, 0, 86,220,188,121, +163, 94, 68, 68, 68,247, 78,157, 58,241,227,198,141, 3,207, 3, 23, 54, 76,228,243, 18,111,238,135, 67,197,138,127,207,114, 73, +190,114,227,129,231,160,118,205, 4, 94, 46, 99,176,121,207, 73, 26, 60,151, 92, 78, 51,190,149, 42, 87, 21, 56,220,133,142, 45, + 29,222,252,216,232, 87,241, 99, 34,165,175,192,132, 40,223,119,188,111, 5, 42, 80,129, 10, 84,160, 2,255,105,120,255, 24,173, +212,167,142,253,180,254,221,208,103,229,140,216,186,117,219,188,109,219,119,183,182,216,108,129, 60, 68,169, 44, 99,187,108, 96, +241,171,179, 54,204,217, 47,238,122,121,213,170,191,101,227,218,159,183,108,254,173, 61, 56,182, 54, 1, 36,241, 4, 46, 73,105, +118,100, 89, 36,171, 84,178,164,209,255,209,245,227,165,230,220, 92,195,182,242, 62,107,206,141,201, 34, 41,123,208, 31, 43,231, + 46, 33, 73,170, 27,203,114, 66,142,165, 95,176,118,203,191,204,234,152,163,112, 58,202, 13,121,165,252, 91, 52,128,232,200,200, +200,182,145,145,145, 45, 0,172,130,227, 12,197,187, 31, 82, 46,214, 92,125,231,105, 83,167, 93,248, 14, 68, 21,142,227,193,176, + 92,178,200,108,234, 92, 78, 51, 65,213,171,215,144,219,105,246,173, 0,248,226,129,240, 47,137,150, 91, 37, 57,128,160, 10,162, + 85,129, 10, 84,160, 2, 21,248, 47,193, 56,188,189,105,169,115,138,214,255, 95,200,207,143,215, 35, 31, 83, 62,212, 78,110,238, +115, 3,128,183, 86,238,153, 62,208,110,212,115,221, 1, 60,215, 29,120,223,231,141, 57, 9,106, 32, 97,228, 7, 38,195,153, 64, +246,171,133,159,127, 4, 26,205, 83, 35, 52,104,249,161,197,178,115,199,246,103,187,119,239, 17,242, 36, 37,228,120, 74,196,240, +132,144,225, 8, 33, 77,115,176,218,105,218,206, 48, 52, 88,198, 14,142,165,121,206, 78,195,177, 59,124, 5, 42, 80,129, 10, 84, +160, 2,255,205,132,235, 63,135,104, 85,224,255, 52,226,227, 94,196,134, 85,100, 67, 5, 42, 80,129, 10, 84,224,255, 56,201, 42, +254, 13,192, 17,123,254,174,149, 3,229, 57,204,247,125, 86, 31,156,175,176,249,193, 54,133, 0,196, 0,148, 0,202,114,105,118, + 71,225,121,141, 21,249, 89, 97,179,194,102,133,205, 10,155, 21, 54,255, 31,218, 44,203,246,121, 84,224,223, 74,192, 42,108, 86, +216,172,176, 89, 97,179,194,102,133,205, 10,155,255,123, 54,255,155, 49,174,132, 15,128, 10,215, 97, 5, 42, 80,129, 10, 84,224, +127, 16, 94, 94,181,148,192,203,184,222, 50, 33,247,174,227, 11, 0, 38,205,211,236,138,220,171, 64, 9, 40,126,206,225,107, 49, + 90,228,123, 26, 20,146, 2,241, 52,185,139,215, 83,133,155, 87,250,255,120,230, 18, 33, 85, 21, 95,118,109, 87,237,112,104,176, +172,111,121, 30,148,251,132,252,233, 87,163,101,138, 66, 21,242, 37,252,155,200, 62, 36, 17, 10, 85,176,143, 50,168,217,117,151, +192,122, 31,253, 27,222, 81, 82,183,110,221,240,186,117,235,134, 3,144,252, 19, 6,229,170,144,161,149,106,134, 93, 81, 85,111, +124, 81,225, 91,107,224, 63,157, 96,165,127, 77, 47,101, 80,211, 3,202,128,134,249, 74,255,134, 58,101,165,166,151, 93,188,235, + 84, 47,235,185,160, 62, 11,106,207,222, 21,181, 43,168,207,130,218, 37,253,187, 71,196,106,151,153,187,159,207,247,234,253, 47, +101, 69,191,242,126, 8,106, 61,212,221,191,253,119, 94,229,125, 46, 48, 36, 44,186,106,189,182, 57, 1,181, 90, 70, 57,251, 76, +165,208,240,251, 85,234,182,206,174, 20, 18,126,183, 34,231,157,131,212, 39, 56, 92,234, 81,249,132,196,163,242, 73,137,103,112, +199, 15,181,231,239,239, 47,171, 93,187,118, 68, 88, 88,216,248,206,157, 59,127,221,184,113,227,113, 85,170, 84,233,246,255,114, +162, 47, 87,133,252,104, 21, 18, 26,171,144,208,200, 85, 33, 63,150,221,191,134,206, 35, 72, 54,131, 32,217, 12,133, 42,116,222, +127, 74, 89, 73,124, 67,170,200, 85, 33,203, 93,252,234,222,150,169,106,245, 46,239,243, 30, 30, 30,221,124,124,124,250, 21,125, + 60, 60, 60,186, 85,180,128,247, 70,113, 21,235,131, 21, 45, 74, 40,145, 95, 27,246,217,228,250,139,102, 77,151,174,220,124, 24, + 43,231, 79,125, 98, 53, 22,212,253, 79,124,115,239,224, 22,119, 41,146,170, 84,252, 30,203,177,105,154,132,219,205,254, 9,251, +161, 85,101, 99,126,254,126,196,183, 67, 63,233, 82,165, 75,175,175,136,152, 4,243, 17,231, 41, 26, 26,237, 61,112, 40,232,202, +165,139,171, 55,111,222, 48, 71,205,132, 46, 23, 74, 4,107,117,169,209, 5,229, 73,131,171, 79,245, 96,129,194,251, 74,155,190, +147,253,238,157,223,177,149,181,113, 93, 77,154, 98,167,127,191, 63,124,106,212,168,209,156,162, 40,175, 47,191,252, 82, 4, 0, + 43, 86,172,168,201,178,108,110, 92, 92,220, 29,188,199,230,167, 14,130, 25, 58, 98,213,146,217,219, 62,250,168, 7, 50, 52, 70, + 44, 94,190,174,195,233,227,123, 7, 25,179,159,239,255, 39,202,196,221,189,154, 43, 68, 46,143,191,250,126,142, 42,162, 67,115, +202, 96, 97,112,250,202,131,182, 59,214,205,185, 13,212,105,161,215, 60,125,231,158, 98,156, 73, 59,195, 87,201, 71,112, 38, 45, + 0, 12,125,107,176, 87,210, 93,124,100,108,132,191, 68,240, 32, 23, 40,243,208, 71,247,170,173,207, 8, 37,146, 42, 36, 73,130, + 36, 0,146, 36, 64, 17,132,227,156, 80,187, 57, 57,253,217,213,238,255, 9,237,196,165,114,139, 44, 80, 2, 47,146,120,149, 62, +130, 44,252,230,121, 93,214,243,107, 94,255,192,127,227, 86,191,166,123,189,214, 53,141, 91, 46, 39,228, 41, 4,237,190, 62, 65, +240,228,111, 41, 87,151, 63,116,138, 0, 72,165, 30,199,142, 29,243,137,136,136,112, 83,213,235,123,217,153,103,196,148,161,238, +241,227, 71, 69, 17, 17,221,203, 81, 63, 67,186,130, 36,183, 19,128,144,227,248, 21, 20,199,239, 53,228,198,198, 1,229, 59,125, + 74,166, 10, 29, 67,130,119,186,159,225, 64,220, 53,231,196,108,126,223,204, 21, 72, 92, 59, 11, 69,162,175,131, 67, 26, 52, 73, + 79,122,113,215,104,208, 47,103,172,218,203,229, 54, 68, 51,211,206, 95,189,247,145, 64, 40, 36, 34, 58,183,164,172,192,197, 15, + 41,116, 95, 95,223,126,107,214,172,169, 30, 30, 30, 14, 0, 96, 24,198,117,223,190,125,126,115,231,206, 85,196,198,198, 30,124, + 79,179,129, 62, 62, 62,149,197, 98,113, 32, 0,216,108,182,116,181, 90,157, 2,160,204,137,191,194,183,186, 55,120,204,185,122, +229,138, 0, 0,218,182,109, 55,175,114,155, 47, 60, 40,145,210, 92, 98,118,216,244,138,130,184,139,223,220,188,117,131, 0,128, +176,150,225,211,229,222,117,214,254,191, 84,182,164,170,208,150, 36,240,109, 88,219, 46, 3, 6, 15, 25, 65,214,171, 85, 25,221, +186,118,250,193, 12, 28, 43, 87,157, 17, 8,100,183,111,223,174, 65,146, 36,197, 48,140, 37, 44, 44, 44,229, 67,210, 21, 16, 18, +254, 55, 1, 50,200,206,216, 54,170,227,239,206,195,219,155, 78, 83,110, 65, 77,126, 6, 37, 24,203,113, 92,170, 62,229,110,171, +255,131,138,214,219,249, 92, 94, 75,164, 64,252,245,208,209,147,234,127,243,221, 79,210,175, 86, 70,226,196,186,233,154,255, 84, +146, 5, 0, 20, 73, 85, 58,115,246,140, 74, 46,166, 0, 0, 6, 11,131,143, 34, 34,202, 30, 17,170,182,184, 68, 18, 68,104,209, +129, 54, 44, 99,151, 10,132, 98, 11,225, 32, 72, 32, 0,120, 7, 84,141,244,101,174,201,135,126,210,165,202,246,221,231,210, 82, +210,114,203,221,169, 17,148, 8, 97,237,186,161, 75,215,238,110,183,111,253, 61,103,195,239,235,127,100,236,244,122,142,230,150, + 91,242, 94,100,148,217,153,251,213,106, 42, 86,122,159, 30, 48,126,174,151,133,244,196,175,243, 87,121, 95, 57,181,243,114,122, +106, 35, 46, 57, 57,213,194, 19,196,147,252,188,204,175,141, 89,113, 49,206,102,153, 82,169,172,174, 84, 42, 27, 53,108,216, 80, + 58,117,234, 84, 97,135, 14, 29, 94, 81,246,113,227, 68,151, 46, 93,242, 95,186,116,105,143, 71,143, 30, 89, 12, 6,195, 67,131, +193, 16,143,114, 4,218,251,249,249,124,241,113,255,222,232, 52, 96, 50, 88,142,192,184, 73,223,224,204,169,131, 19, 0,252, 35, + 68,139,150,187,206, 29, 59,126,170, 79, 88,243,198,212,156,157, 49,144,137, 5,232,222, 44,148, 24,253,229, 12,247,205,171,231, +108,130, 6,237, 75, 82,178, 56,147,118, 70,125,111,219,144, 62,225,193, 56,186,203, 54, 4,157,191, 7, 41,119,155,151,122,244, +167,103, 0, 80, 61,226, 75, 23, 9,171, 94, 19,224, 78,169, 36,172,122, 77,245,136, 47,207,199,159, 94,163, 47, 45, 45, 66,137, +164,202,174,157, 59,107,121,184,136, 32, 32, 9, 80, 20, 1, 1, 69,194, 98, 99, 49,232,147, 33,255, 88, 53,151,169,106,245, 32, +129,209,142, 1, 27,127,154,115,158,159, 44, 79,153, 16,148,200,235,248,209, 67, 2,149,155, 4, 20, 69,128, 34, 1,138, 36,144, +148,109,198,152, 49,163,221, 62,148,176,127,212, 90,213,124,218,224,208,238, 97,245, 61, 27,238,185, 65,184,133,125, 52,216, 75, + 99,145,143,218,125,228,226, 16,190,237, 55,183,120,158, 91,146,118,109,213,217,210,140, 88,173,214,236,238, 17, 31,185, 18, 2, +133,252,252,225,173,237, 4, 36, 1,154,229,193,176, 60,216,194,179, 81,137,194, 25, 12, 73, 18,224, 57, 30, 99,199,142, 65,247, +136,143, 76, 28,195,165, 57,223,201,145,219, 79,159,191,238, 99,165, 57, 44, 93,179,121,142, 81,171,158,147,240,204, 43,201,160, +213,124, 99,206,121,238,244, 57, 24, 36,248,102,169,241, 81,227,119, 30,191,137,250,117,235,128,229, 28,233, 12,173,164,192,206, + 19, 55, 81, 59,180,182, 35,221, 28,143,144, 32, 37,154, 55,107, 14, 0,239, 69,180, 4, 18,151, 95,219,247, 28, 49,187,215,160, +207,160,242,241, 1,201,211,189,206,159,216,217,235,207,223,150, 76, 99, 44,186,165,229, 50,198,179, 47,199, 5,158,227, 62, 88, +117, 10, 8, 8,240,105,222,252,213,118,140, 12,195,160, 90,181,106, 72, 79, 79, 15,125,159,121,154,191,191,127,207,153, 51,103, +170,122,244,232, 33,244,243,243, 3, 0,100,101,101, 5,158, 62,125,186,201,204,153, 51,115, 50, 51, 51, 79,160,148, 29,125, 88, +154, 20,145, 2, 80, 82,169,220,241,142, 32,200,169, 95,124,218,208,215, 63,192, 90,210,239,213,234, 44,241,247,147, 47, 18, 2, +129,168,240,247, 32,121,158, 35, 74, 81,137,186, 8,133,194, 18, 61, 20,118,202, 53,140, 23,186,125, 78, 82,164,163,178, 50,180, + 58, 63,229,126,157,114, 40,113,245,132, 98,209,250,143, 7,127,214,106,224,128,190,240,247,113,195,249,107,143, 48,225,139,111, +105,198, 78, 47,127,175,206,131,162, 4, 57, 57, 57, 73, 30, 30, 30,126, 31, 62,222, 18,193,231,206,156, 82,157,191, 16, 57,125, +217,202,213, 19,237, 54,134,230,120,254,229, 57,198, 50,153, 68,216,181,215, 39,174,170, 26, 97,210,213, 51, 63, 23,254, 31, 84, +180, 54,252, 35, 68, 75, 44,115,249,228,151,239,191,148,206,221,113, 19, 39,214, 77,208,152,116, 26,159,151, 51, 5, 87,247,251, + 70, 93, 65,147,247, 73,161,210, 39, 36,156,160, 4,227, 9,138, 82, 16, 36, 33,230, 88, 46,149,177,217,230,153,115,159,127,240, +166,149, 28,199,227,192,223, 57,229, 35, 64, 60,106,110,223,115, 72,229,235, 46,129,197,206, 98,240,208, 17,216,182,109,155,139, +143,155, 24, 22, 27,131, 37,203,150,233, 13, 73, 39, 84, 73,169,249,233, 93,122,127,123, 54, 62, 49, 39, 42, 37,211,178,183,188, +105,179,218, 89,232, 76, 12, 76, 86, 18,181,234, 53,199,146,229,181,165, 41,201, 9,223,110,253,115,211,148, 39, 79,168,109, 28, + 69,206,182,100, 62, 77, 45,177,209,249,213,239,238,234,225,181,171,255,248,249,238,207,115, 4,224, 97, 71,156,171, 20,159,140, +154,226, 90,221, 79, 6,133,148,114, 79, 72, 78,247,159, 58,109,218,181,120,150,111,161, 83,199, 39,148,149,158,170, 85,171, 14, +232,213,171,151,252,187,239,190, 19, 6, 5, 5,225,207,157,251,170,180,237, 62,168,119, 70,102,118, 16,207,243,240, 85,169, 82, +199,142, 30,116,236,228,201,147,201,169,169,169,194,197,139, 23,183, 60,116,232, 80,221,172,172, 44,167,103,166, 44,207,195, 98, +101,193, 22, 14,144,106,173,181,220,252, 52, 48, 48, 80,146,158,158,110, 45,166, 50, 16,175,132, 66,162,123,231,246, 45, 5,127, +156, 74,132,193,194, 66, 33, 21, 34, 49,219,132,102,141, 27, 16, 27, 89,166, 81, 73, 6,199,124,210,115,134,175,146,143,232, 19, + 30, 12,149,135, 28, 91,214,206,199,209, 27, 9, 17,217, 6, 2,107,120,106,188,191, 68,208, 85,193,101,174,233,208,172,134, 95, +167,166, 85,112,167, 89, 13,191, 43,247, 98, 98,101,131,150,125,153,110, 16,158,207, 63, 61, 69, 95,114,199, 67,194,211, 69,132, +205,103,146, 33,151, 10,160,144, 10,160,144, 56,190, 73,146,248,176, 89,173,127,157, 32,138, 99,199, 80,148, 96,204,144, 79, 6, + 5, 12, 27, 50,136, 7, 69, 98,223,129, 99,125,119,236,216,158, 73,219,109,155, 88,146,218,252,174,250,243, 90,134,146,128,202, + 77,140,105,155,162,224, 42, 19,194, 69, 46,132,171, 92,136, 78, 13,125, 64,145,239,157, 68,143, 9,125,171,247,152,208,191,106, +199,208,202,202, 90, 15,227,180, 79,198,204,187,187,242, 82, 65,199,175,215,174,168,235,101, 40,176, 9,126,157, 58, 86,144,150, +145,209,113,223,177,203,157, 88,219,103, 49,140,221,248,147,250,209,190, 18, 85,225,180,152, 27, 77, 2,195, 6, 74,237, 6,250, +241,195,152,180, 26,249, 86, 9,162,147,116, 80, 72, 5, 80, 22,229,173, 84, 0,133, 84, 8,165, 84,128,140,180, 68,228, 25,169, +107,233, 94,100, 71, 92,190,193,148, 39,225, 22, 59,139, 7, 9, 6, 84, 13,109, 12,127,255, 0,216,122, 12,175,122, 43,242,192, +145,219,151, 15, 47, 52,101, 61,251,201, 89, 59, 59,143,223,196,244,111,198,223, 35,128,251,133,131,116,147, 95, 23,173,107, 58, +103,250,228,215,238, 77,157,189,186,233,251, 43, 89, 46, 51, 58,245,159, 52,187,109,215,254,208,231,101,227,239,179,123,209,189, +215,199, 24,254,217, 87,112,119,247, 94,178,124,222,247, 15, 25,171, 46,242,173, 62,215,175,118,155, 6,245,235,236, 8, 12, 8, + 8,226, 56,199, 41, 31, 60, 15, 24,244, 90,124,255,245, 88,112, 60,143, 70, 77, 90,116,146,182,237,202,243,133,167,129,104,114, + 53,198,152,103, 79,186, 88,114, 98,110, 57,157,151, 22, 11,173, 86,171,241,224,193, 3,196,198,198, 34, 58, 58, 26,185,185,185, +112,115,115, 51, 24,141,198,114,137,247, 13, 27, 54, 28, 22, 25, 25, 41,245,240,240,120,121,211,102,179,193,197,197, 5,195,134, + 13, 19,118,235,214, 45,176,103,207,158, 35,163,162,162,118, 2,208,149,152,158,188, 23, 25, 46,190,161,191,183,239,208,126, 34, + 0,200, 92,253, 19,214,252,121, 44,186,212, 9,173, 91, 64,149, 86,173, 90,215, 0,207,131, 0,191,202,148, 27,155, 85,138, 74, +164,184,121,243,102,117,138,162, 4,175,198, 32, 14,191,109,217, 83,251,220,213,199, 3, 22, 45, 89, 42,117, 85, 72,160,214,218, +240,249,240,254, 78,143,193, 50,223,208, 30,173, 90,181, 59, 50,103,246, 47, 2,165, 66,129,179,183,226,241,229,215,211, 44,153, + 73, 81, 75,121, 78,184,206,164,142,205,249,192,161,146,199, 63,128, 90,149,148,112,233,211, 93, 58,225,211, 62, 82, 27,205,162, +192, 72,195,106,103,193,114, 60,180, 70, 26, 79, 82,244,240,118, 45,255, 81,110, 60,207, 55, 7,224, 3, 64, 77, 16,196,157,226, +215, 69, 19,186, 34,110,252,198,181,166,112,124,240, 2, 96,131, 99,165,254,203,234, 83,120,253,174,251, 69,207, 63, 1, 80,167, +208, 38, 11,224, 54, 65, 16,249,239, 32, 91,111,169, 92,130,227,199,143,243,189,122,245,122,217,227,191,121,253, 38, 36, 34, 97, +128,194,205, 7, 60,255, 20,197, 15, 48, 86,249, 5,230, 46, 93,190,210,243,139, 73,227,147,117, 5,121, 85, 10,111,159,119,102, +176, 16, 16,212,242,246,173,195,186, 77,156, 52, 9,161,213, 43,137, 88,150,229,163, 98, 19,232,173,155,183,140,186,114, 67,188, + 82,151, 22, 53,163,152, 4, 89,174,101,159, 44,199,166,189,169, 96,177, 28,251,230,236,246, 45,155, 4, 1,184, 43,197,248,253, + 84, 34,120, 30, 32,192,195, 77, 33,196,238, 75,105, 72,184,119, 80,215,171,145,206, 56,108,209,172, 78, 29,123, 76,137,124, 18, +103,217,155,147, 99, 57, 3, 32,171, 52,155, 37,119,232, 28,172,118, 22, 52,195, 96,255,177, 99,136,232,212, 18,173, 90,181, 68, +187,182,173, 4,119,239, 61,250,108,210,196,177, 65,120,181,186,227,165, 77,169,111,205,230, 74, 55,239,189, 3, 38, 46,118,121, +156,198, 64, 64, 1,193,126, 50,120,186,136, 96, 99, 8, 36,169,237,133, 45,199, 29, 95, 78,157,237, 57,253,219,137, 39,117,106, +113,125,224,169,189,180,119, 55,153, 76,226, 17, 35, 70, 8,105,154,182, 15,251,252,171,110, 89, 89,234,190,191,173,250,151, 68, +165,242,133,201,194,224, 94,244,139, 58,115,230,204, 14, 62,118,250,210,225, 89,211, 38, 28,137,136,136,112,219,179,103, 15, 87, + 86,126,190, 54, 67,204,214,172,221,178, 99,255,182, 21, 75, 23, 32, 38, 57, 31,155,255, 88, 7,158,101,126, 47, 35,171,138,219, +228, 71,140, 24, 33, 59,124,248,112,165,180,180, 52,157,201,100, 82,191,166, 71,144,132, 32, 59,207, 4,111, 23, 49, 68, 2, 18, +190, 30, 82,168,220, 36, 16, 82, 0, 73, 16,108, 73, 54, 55,239, 61, 49,143, 51,105,113,116,151,109,200,150,181,243,241,217, 23, + 63, 35, 74, 35, 62, 77,202,221,230, 77, 30, 50, 96,186,143,140,141, 8,112, 39, 85,157,154, 86,133, 66, 42,194,143, 83, 70,160, +197,189, 36, 85,122, 1,247,179,218, 76, 53,158,125,250,229, 97,221,231, 95, 23, 71, 28, 10,150,139, 92,136,211, 59,150,228, 24, +181,106,109,145, 75,206,102,181, 36, 59, 89,141,207,151, 48,179,157,222,184, 65,189,249, 19,199,141, 33, 91,135,183,224, 73, 82, + 8,141,222, 70,240, 60,240,245,151, 19, 48,121,194, 88,191,212,140,156, 95,215,173,251,125, 70,228, 57,126,174, 81,253,108, 86, +105, 54, 73,194,161, 2, 41,165, 2, 40,101, 14,226,162,148, 10, 96,177,177, 32, 8, 80,238,149,155,104, 9,135,146,155,145,151, +252,206, 25,248,107, 54, 61, 43,215,187,112, 46,193,165,118,254,222,252, 27,137, 25,209,243,238, 61,202,190, 13, 32, 47,168,157, +251, 72, 59,195,195, 96, 97,144,152,109, 2, 99,231,137,207, 62,170,130,106, 3,137,208, 5, 91,238,111, 59,245, 8,174,197, 58, +253,215,108,166,223,220,111,241,170,223,127,240,138,213,127,220, 89, 58,255,103, 74,163,181,129,227,121, 72,197, 20,100, 98, 65, +225,135,130,217,168,197,186,245, 27,179, 24, 16, 3,112,249, 50, 83,158,250, 9,142, 31,222,191, 71,187,221, 4, 32, 38, 72, 81, + 90, 64,149,170, 85, 58,247, 30, 37,237,220,103, 4, 88,198, 54,253,222, 85,254,162, 41, 39,230,130, 51, 54,235,215,173, 3, 2, +184,111,204,137,157, 0, 0, 10, 85,200,239,181, 67,107, 55,125,243, 94,205,154,161, 77,157, 41,247,151, 74,169,212,229, 11, 15, + 79,159,159, 67,235, 53, 86,101,231, 91, 9, 23,175, 74, 72,124,254, 0,187,214,255,186,157,179,216,102, 95, 56,177,119,254,202, +205,135, 62,233, 28,209, 31, 91,126,251,215,143,185,153, 47,137,214,249, 98,106,213,240,173,155, 54, 4, 9,197, 18,208, 12, 7, +154,229, 29,223, 12,139,188,188,124,208, 12, 7,169,220, 5, 12, 71,128,102, 57,208, 12, 7,171,141, 81, 76, 24,209,115,146, 5, +184, 85, 82, 58, 3,107,183, 63, 35,146, 72,170,240,112,156, 93,203,243, 60, 18,179,204,164,191,191,255, 78, 0,144, 72, 36,144, + 72, 36,224, 56, 14,247, 98,212, 95,120,135,134, 76, 68, 33,193, 99,237,182,228,130,164,235,221,223,245,238,126,126,126,189,223, + 36, 89, 22,139, 5, 6,131, 1, 87,111,220,113,219,180,109,127, 68, 98,114, 90,117,142,119,179,186,168,170,119,215,231,196,247, +126, 87,126,234,179, 99, 38,185,134,141, 37,191,155, 60,178,230,234,173,199,111,191, 56, 51,175,212, 56,173,106,157,127,176,125, + 55,254,227,102,139, 86,109,126,158,127,253,247,111,202, 42, 35,129, 64, 32, 84,171,213, 47,219,247,154,141,187,154,221,143, 73, +239,183,114,197, 74,233,189,120, 61, 30, 39,102, 96,100,151,202,142, 25,142, 19,229,174,240,173,238, 29, 92,163,198,206,117,171, + 22, 9,158,103, 88,176,246,224,109, 68, 30,249,253,106, 86,206,173, 8,100,103,154,223,167, 15,249, 7,136,214, 59,109, 94,124, +164,129,193,194,192,106, 99, 64,115, 60,116, 38, 26, 57, 5, 54,232, 76,118, 24,204, 12, 70,118,173, 92,226,115,101,240, 17, 31, +130, 32,142,243, 60,223,139,231,249, 46, 0,196, 69,215,142, 49,155, 56, 94, 72,200, 94,187,158, 62,125,250, 79, 11, 23, 46,140, + 46,250,109,209,253,162,223,150,118,191,216,243, 94, 63,254,248, 99,253, 69,139, 22, 45, 8, 15, 15,223,253,247,223,127, 39, 0, +200,119,214,125, 40, 40,254, 50,199,143, 31, 47, 43,163,171,219,105,187,196, 85, 38, 68,112,181,202, 24,253,211, 22,239,191, 22, +141,201,145,138, 5,212,169, 83,167, 60,115,109, 74,144, 36,229,244, 20, 69,233, 83,171,149, 72, 36, 62,177,108,217, 50, 12,233, +221, 86,150,162,161, 13,143, 82,204,217, 70, 27, 24,149, 79,136,120,222,130, 69,202, 69,139,151, 76, 62,126,148, 43, 48,100, 63, + 89, 82,178,139,175,217, 93,138, 40, 22,131, 69, 16,224, 57, 54, 45, 63,233, 78, 51, 0,248,144, 88, 44,131,133, 6, 85, 24, 91, + 67, 16,128,201,194,128,162,136,156,130,152,189, 79,134,205,157,215,105,251,238,115, 25, 60,233,174, 55, 26, 19,229,112,156, 57, + 88,110, 88,108, 44,172, 52,139,232,135,247,208, 46,172, 46, 90, 53,171, 13,147,133,133,201,202,160, 90,141, 80, 0,240, 46,177, +224, 40, 50,129,103,105, 11,207,179, 46,189,154,251, 64,229, 46,134,191,135, 4, 18,177, 0, 52, 3,152,109, 28, 44, 54, 22, 73, + 57,102,232,205, 50, 52,104, 63, 40,216,203,255,174, 53, 43, 73,118, 56, 47,229,238,128, 82,201, 41,203, 98,235,206,253, 53, 51, + 50,178,251,158, 60,188, 67,162,214,209,120,148,100, 68, 78,129, 21,160,124, 48,115,193, 90,201, 15,223,140,235,183,117,215,129, +228,206,109, 91, 38,151,247,157, 77,234,152,237,123,247,237,255,189, 87,175,126,178,232, 91, 39,241,252,193,133,249,198,156,114, +197,103,145,141, 26, 53, 98,198,141, 27,167, 95,176, 96, 65,208,209,163, 71,171,169,213,234, 7, 0,104,119,119,247,218, 33, 53, +171, 60, 60,123,250, 84, 96,207,126,131,132,105, 26, 51,220,228, 34, 84, 81,201,113,227,234, 25, 90, 44, 22,150, 24,111, 82,232, + 30, 28,138,206,223,227,232,141,132,136,232, 92,233,165,177, 99, 70, 38,159,189, 18,147,187,102,219,217,127, 5, 42,233, 7, 82, + 78,189,230,110,179, 26,126,211,191, 28,129,133,171,183,227,242,189,152, 28, 35,233, 63, 63,211,202,156,123,183,148, 14, 8, 40, + 2, 46, 50, 33,140, 58,181, 54,238,254,233,144,127, 72,166, 30,121,246,240,118, 50, 79, 79, 35, 85, 99, 33, 50,242,244, 96, 57, + 30,238,114, 17, 24,142, 71, 65,158,134,216,177,125, 27,238,220,185, 65,130, 34, 63, 7, 48,171,212, 12, 37, 28,174, 66,165, 84, +232, 80,132,100,142,111,154,229, 16, 90,179, 6, 54,172, 89,238,234,173,242, 69,155,118,206,199, 70,187,120, 85,105,180,251,207, + 53,184,244,247,253, 14,151, 87,174,109,174, 12,240, 89, 77, 16,236, 82,240,176, 88,237, 44,180, 5,249, 16,219, 82,209, 34, 80, + 13, 79, 57,139, 36,157, 63,162,178,158, 43,203,234,240,115,163, 14, 61, 32,248,126, 51,246, 31,139, 92,216,189,107, 7, 68, 37, +233, 32, 19, 11, 32, 21, 83,144,138, 41, 8, 9, 22,203,215,255, 78,231,107,245,189,114,163,143,104,222,163,126,158, 47,156,253, + 58,200, 29,107,240,217,190,122,198, 95, 99,191, 95,220, 61,162,255, 40, 34,234,206,197,159, 76,192, 5,231, 38,122,188, 83,247, + 56,206,249, 49, 78,234,226,189,106,202, 15,243,166,116,235, 53, 8, 20, 37, 0, 77,211, 56,176,103, 59,254, 92, 59,243,153,205, +144, 59, 10, 0,103,203,161,198,237,221,190,126,208,247,191, 46, 39,234, 55,106,209,242, 98,230,219,199,209,114, 20,241,199,167, + 99,198, 15,246,245,245,117,121,165,104,241, 8, 9,173,139, 30,125, 62,198,153, 35,135,240, 36,250, 17, 56,222, 65,152, 56,142, + 71, 65,126,110, 22, 67,219,182,190,211,227, 33,149, 86,217,242,231,182, 90, 36, 73,188, 60, 64,254,155, 73,163,109, 19,190,254, +169, 77,143,110,237,163,197, 20,116, 73, 41,153,238, 55,238, 63,109,192, 9,149, 65, 99,166, 46, 23, 89,172, 44,180, 38, 26, 39, + 55,191,155,235, 72, 61, 42,135, 87,109,218, 99,204,132, 95, 54, 72, 36, 20,105,175, 23, 18,148,208, 62,172, 94,106,229, 0,111, +253,156, 69,107, 91, 92,187,117,191,199, 39,195,198, 72, 71,214,110, 74, 4,120,201, 92, 70, 15,235,223,144,101,236,159,154,242, + 82,223,185,191,160, 80,238, 81, 80,185, 90, 77,211, 43,197, 40,228, 32,193, 35,248, 53,230, 65, 32,193,156, 29, 59, 0, 0,252, + 3, 42, 91,132, 18, 87,125, 57, 20, 24, 30, 0, 86,111,220,213,236, 97,108,198,216, 21, 43, 86,202,239,197,235,241, 32, 94, 11, +137,136,132,157,230, 64, 56, 41,106,115, 60, 53,254,231, 31,167,187,230, 27, 89, 92,122,164, 70,244,221,139,188,205, 96, 25, 38, +103, 92, 7, 64,229,242, 41,128, 26, 0,226, 8,130,255,195,152,237,119, 4,184,204,148,183,222,115,156, 99,190,236,234, 83, 61, +152, 21, 72,122, 8,197,138,112,130,224,235, 17, 60, 60, 0, 62, 61,175,112, 76,117,150,169, 25,179, 99,177,120,193,175, 88,181, +233, 16, 50,114, 45,112, 99, 83,113,100,243, 60,124,183,112, 39,204,214,119, 71, 53,148,197, 71, 74, 34, 70,111, 18,174,162,191, +139,126,183,112,225,194, 94,111,148, 77,175,119,148,217, 91,191, 43,122,126,209,162, 69, 11,138,253,187,201, 89,146,245,146,104, + 21,189, 84, 25,100, 43,196,199,191,202,223, 71, 14, 31,244,200, 55,216, 33, 21, 81,168, 92,173, 38,102,173, 57,226,243, 81, 51, +111,104,236,110,216,181, 97,105,158,197,164,223,227, 84,103,161, 10,109, 41, 83, 42, 78, 30, 60,112, 8,213, 43,171, 68, 59,174, +230, 37,222, 79, 48,191,148,122,117,234,100,113, 53, 87,147, 96, 64,255,254,242, 11,145, 23,191, 54, 0, 37, 18, 45,138,160, 42, +109,220,118, 64,229, 34, 19,130, 32, 0,189,153,193,216, 79, 63,254,240, 97,140,231,168, 49,163, 70,130, 40, 36, 89,186,220, 44, +252,244,195, 36,139,130,126,254, 36, 37, 41, 37,189, 75,239,239, 46,232, 12,132,101,240,136, 73,119,158,196, 46,204, 55,153,222, +239,144, 31,171,141,133,213,206, 33, 62, 62, 14,223,140,236, 10, 33, 69,130,162, 56, 71,176, 52,243,238,202,104,200,136,205,131, +159,104,224,246,101, 95,108, 12,240, 85,121, 41, 21, 50, 94, 41,151, 16,245,106,215, 18,133,133,181, 18, 87, 11,109, 40,186,250, +212,140, 20,181, 25, 9, 25, 90, 72,124, 27, 11,134,116,250, 8,219, 87, 78,237,144,151,114,151,196,219, 65,138,175,225,220,165, +155,189, 55,173, 95, 33,201, 46,176,227, 89,138, 1, 89,249, 22,100,230, 91,145,149,103,129, 82, 38, 68,187, 62,227, 36, 39,142, +252,209,187,115,219,150,171,223,231,189, 19, 18, 18, 79, 36,165,103, 14,106,216,164, 5,182,255,245,103, 91,119,247,106,174, 5, + 5,137, 58,103, 75,103,222,188,121,226, 69,139, 22, 9,214,172, 89,163, 11, 11, 11,243,251,241,199, 31,187,231,228,228,220,174, + 90,181,106,232,153,131, 91, 35, 27,183,235,219, 28,156,221,167,109,251,142, 34, 9, 39,192,217,227,199,237,123,247,236,200, 53, +155,245, 19, 74, 37, 28,114,183,121,217, 6, 2, 62,129,129,209, 74, 49,219, 85, 64, 22,196,230,159,158,178, 45, 31, 56, 88, 61, +226,203,243, 23,239,198,196, 54,187,151,164,138,188,247, 34, 39,207,100, 15,137, 63,253, 93,169, 29, 47, 69, 16, 16, 82, 36, 92, +100, 2,144,133,189,170, 50,160,225, 11, 16,132, 79,145,114, 74,128, 40,252, 6, 8, 2, 25,249, 41, 15,156,136,217, 32,120,142, + 7, 98,210,140, 48, 88, 28,210,124, 37,111, 57,212,217,105,248,109,245, 86,220,191,123, 7,221, 62,234,131,117, 27,119, 96,236, +167,131, 44,101,205,126, 72,178, 80,209, 42,166,102, 41,101, 2, 0, 4, 10,140, 52, 14, 92, 75, 69,141, 96,210,233,129, 1, 0, + 92,148,114,104,245,102,144, 34, 23,196,221, 59, 41, 63,117,241,214,143, 51,230,174,152,150,159,249, 40,229,197,227,171, 8,245, +214, 34, 56,208,142,232, 44, 87,220,205,173,134,208,154,213, 65,138,238, 56,101, 91, 19,221, 96,241, 17,242, 64,175,102,141,235, +134, 87, 81,185,195,108, 99, 11, 85, 45, 10,127,110,217,134,164,196,180, 49,185, 79,142,220,255, 39, 24,173, 49, 39, 65, 45, 81, +213,156,252,248,214,133,132,254,195, 38,195, 63,176,114,163,130,148, 7, 78,135, 45, 56,115,143,117,146,104,137,228,238, 63,126, +243,243,191,166,116,235, 57, 16, 55,175, 94,192,131,232, 56,180,108,217, 28, 31,245, 27, 2,189, 46,175,246,190,109, 43,187, 50, + 38,253, 25,129,132,153,210,162, 85, 39,130, 99, 89, 60,127, 22, 21, 87,146, 45,115,102,204,131, 27,153, 49,174,175,185,167,188, +107, 55, 82,186,121, 62,176,218, 89,164,167,167,225,250,223,151,154,152, 51, 99, 30,148, 39,191, 36, 34, 10,103,239,231,192, 94, +120,134,105,187,246, 93,109, 34,210,218,118,254,138, 45, 97,153, 25,153,164,194,213,155,243, 12,172, 35,242,151,216,173, 15,227, +181, 34, 59,205,161,122,128,162, 84,155, 62, 1, 53, 23, 76,157,250, 77, 29, 74, 36,131,222,104,181,101,102,164,251,109,216,117, +209,240,244,217,227,192, 74, 42, 55,215,127,173,252, 67,164,179, 16,200,209, 90,145,167,215, 17,195,198,127, 31,176,105,237,194, +225,165, 17,173, 18,194, 69,130, 79,156,189, 90,219,195, 69, 68, 24, 44, 12,151,171,179,179,195,250,125,216,162,203, 66,146, 53, +110,197,242,149,242,251,241,122, 60,140,215, 66, 42,162, 32, 22,145,176,209, 28,156,108, 78,164,159,202,111, 66,171,102, 13,112, +230,129, 6, 20, 69,194,172,207, 55, 9,144, 27,219,172, 67, 55,121,211, 22, 97,232,216,161, 61, 94,196,198, 84, 62,126,244, 64, +231, 27,215, 47,103, 49,246,144, 47,140,234,216, 67,229, 18, 22, 76, 38,138, 22,251,141,246, 15,172,218,122,192,144,209,110, 85, + 42, 7, 18, 42,111, 47, 48,188, 0,227, 62,253,216,233,150,239, 32,230,192,162,185, 63,194,106,181,193,199, 93, 12,158, 7,182, +172,158, 5,155,205,134, 0, 47, 9,180,198,119,159, 38, 87, 22, 31,121,151, 10, 85,174,216,147, 98,100,172,180,251, 4, 65, 28, +159, 62,125,250, 79, 0,248,233,211,167,255, 84,116,189,112,225, 66, 51,128,140, 50, 92,135, 27, 94, 35, 90, 69, 47,247,238,214, + 45, 10,245,246,242,191,113,246,204,105,183,195, 15, 57,220, 60,116, 23, 61, 91,250, 67, 36, 32, 33,119, 11,192,195, 68, 45, 78, + 28, 92, 95,112,100,247, 31,233, 86,171,117, 73,217,190,230,154,205,148,114,197,153,191,182,239,225,188,189,188,200,223,206,170, +227,115,245,204, 75,151, 86,236,173,163,220,221, 51, 27,252,121, 16,167,165, 82,105, 77,155,205,230, 81, 86,193,110, 57,155, 92, + 24,196, 75,252, 19,125, 43, 8,138, 98,183,239,216, 14,111, 87, 49,172, 52,135,233,211,190, 50,143,236,166, 44, 24,246,201,144, + 78, 29,123, 76,137, 20, 42,106, 93,104,213,164, 22,223,184,113,227, 2,138,162,156, 10,165, 80,169, 84,179, 72,146, 28, 42, 22, +139, 93,108, 54,155,222,198, 89,228, 70,139, 13, 22, 59, 96, 50, 89, 32, 20, 57,200,162,144, 34, 96,182,216, 96, 50,219, 74,111, + 24, 89, 81,215, 0,132,232,138,105, 74, 23,158, 86, 23,239,220,119,228,171,129,159, 12,158, 17,216,168,159, 50, 49, 83, 11, 17, + 97, 71,243, 58,254,184,120,250, 16,159,150, 20,251, 77, 89, 36, 11, 0,114,212,121, 65, 62, 62,190,184,159, 96, 64,122,174, 25, + 89,133, 36, 43, 51,223, 10,189, 89,143,134, 85, 2, 80,160,213, 6,189,119,254, 2,135,206,156, 57, 51,168, 71,223,193,152, 50, +109,118,155,205,235,151, 62, 82,136,133,159, 25,179,159, 95,114,134,104, 69, 69, 69,229,253,240,195, 15, 53, 54,110,220, 72, 14, + 31, 62,220,220,160, 65, 3,233,136, 17, 35,218,108,219,182, 77, 42,151, 75,205, 15,175, 30,157,241,249,151,211,251,110, 88, 53, +175, 81,126,126, 62,193,208,244, 41,123,126,254,116, 67, 25,100, 46,245,232, 79,207,102,198,219, 71,117,109,235,115,212, 83, 78, +214,147,240,182, 33,168, 51,107, 15,158,206,178,199,159, 94,163,151, 13, 90,246,101, 70, 1,247,179,133, 84,205, 47,139,100, 1, + 0, 73, 17,176, 49, 44, 92,100, 66,144, 36, 89, 68,226,253,255,220,115, 74,238,227, 38,134,144, 34, 33,160, 8,232, 76, 52, 52, + 58, 59, 38,143,118,118,135, 16,158, 99, 88, 30,102, 27, 3, 83,225,236, 80,175,211,224,199,105,223,226,163,222,253,241,249,132, +111,145,111, 6,238, 38,232, 97,167,233, 50, 27, 5, 73,144, 48, 89, 25,124,214,173, 10,242, 12,118, 24,205, 12,108, 12, 7,185, + 88, 0,161,128,132, 66, 42,128,171, 92, 8,240,188,168,168, 51, 17, 10,133, 22,154,166,183,151, 50,163, 71,181, 32, 95,152,105, + 18, 45, 6, 47, 69,151,240, 16, 68, 95, 59, 32,184,124,243,113,240,215,211,126,198, 87, 99,123, 99,255,179, 26,240, 84, 85,129, + 82, 33, 3,205,147, 0,120, 39, 3,246,102,113,164,189,255,208,223, 55,110,137,153,243,235,116,105,129,145,128, 68, 68, 33,242, +194,121,220,184,117,119,149,230,201,145,237,248, 7, 33,228, 73, 95, 87, 87, 87, 72,197, 20,108,118,171,205,249,208, 5, 30, 60, +208, 68,161, 10,249,189,112,198,223,132,229, 80,194,189,178,137,150, 64,234, 58,253,139,105,115, 22,116,235, 57, 16,103,143,239, +199,190,253,123,216,240,136, 49,212,142, 63,215,163, 77,151, 62,104,211,109, 48, 78, 29,218,246,173,145, 35,234,142,155, 50, 99, +110,187, 78, 61,112,246,196,126,100,103,165, 45,115, 54,189,148,144,152,210,169,107,111, 88,108, 44,218,118,238,133,211,199, 14, +125,137,194, 69, 22,206, 15, 98,111,244,207, 32,153,111,191,153, 34,204, 41,176, 9,213, 58, 27,210,212, 38, 36,102,155,112,100, +247,102,222,249,254,194,214,188, 93,195, 74,194,113,139, 35, 83,131, 42,249, 91,133, 86,179, 44, 54, 46,190,246,231,163, 71, 10, +131,107,214, 38,115,180, 86,168,181, 86,104,180, 86, 24, 44, 12,106, 86,170, 69,210, 12, 17, 94,222,114,246,118, 19, 11,215, 29, + 75,128,171, 66,136, 86,181,223,127,161, 45,199,113,175, 72,214, 10, 7,201,122,148,160,133, 68, 68, 65, 34, 34, 33, 17, 81, 96, + 88,222,169,137,139, 76, 21,210, 99,242, 23,147, 2,108, 12,144,171,181, 65, 64, 17, 80,121,123, 40,154, 55, 26,138, 45, 75,191, + 4, 0,140,253,225, 55,124,254,217, 8,212,169,215, 0, 5,249,249,126, 67, 7,246, 88, 1,224,144,179,105, 61,121,246, 82,229, +179, 87,238,255, 48,121,234, 76,229, 39,189, 59, 82, 15,226,181,200,204,179, 34, 46, 86,189,197,216,208, 0, 0, 32, 0, 73, 68, + 65, 84, 95, 46,229, 13, 0, 24,150, 3, 15, 30, 91,247, 28,135, 76, 44,128, 90,107, 7,207,243,152,183,102, 47, 92,100, 66,100, +230, 59,220,253,165,161, 84, 62, 82,138, 34, 85, 14,181,177, 23, 28,177, 92, 62,206, 42, 90, 11, 23, 46,140, 94,184,112, 97,137, + 10, 89, 49,146,245,126,135, 74,139, 68,138,218,174, 94,222, 55,207,158, 62,233,114,232, 33,139,139, 15,115, 49,176,109, 37, 24, +242, 82,176,100,218, 39,121, 4,120, 27, 73, 81, 5, 86,179,233,160,217,108,156, 15,192, 94,106,165,241, 11,105,162,144, 42,207, +175,219,240, 23,227,173, 82, 97,251,213,188,180,124, 35, 67,191,114, 91,209,196,221, 51, 27,130, 25,142,142,176,100,191,184, 83, +214, 76,156,227, 33, 90,184,254, 8, 0, 30, 28,199,129,231, 56, 8,165, 74,133,119,245,176,236,194,142, 78, 42, 32, 9, 75,241, + 30,128,231,152, 52, 77, 66,233, 50, 40, 1,192, 77, 46,196,158,203,233, 0,144, 77,233,239, 61, 29,246,137,195, 93,104,177, 73, +117,245,106,212,224,155, 55,111, 94, 32,147, 57,181,253, 21,229,235,235,123,123,198,140, 25,181, 63,255,252,115,137, 88, 44, 6, +195, 48,158,127,108,216,192,109,152, 63, 22, 3,190, 92, 7,145, 88, 2,179,197, 14,161, 80,128,124,173, 1, 5, 58, 19,244, 38, +186,252, 53, 40, 62,222,166, 6, 22, 31, 62, 36,238,223, 93,217,176,133,152, 20,161,105,168, 63, 46,158, 57,204,223, 60,189,101, +172, 57, 39,246, 47, 39, 43, 34, 12, 22, 26, 25,185, 22,164,231, 90,144,149,111, 65, 86,158, 21, 89,249, 22, 16, 4, 1,139,141, +249,160,129,203,152, 19,179,111,251, 95,155,250, 88,237, 24,210,174, 91,127,124, 59,115, 93,149,237,191, 47, 58,159,192,147,173, +157, 12,180,101,163,163,163,147, 70,143, 30,221,104,215,174, 93, 84,253,250,245,205, 79,159, 62,149, 23,146, 72,187, 82, 41,151, +109, 94,187,240, 76,139, 22, 45,118,167,199, 62,139, 44,244,167,151,217,177, 87,105, 63, 74, 34,179,223, 31, 87, 89,209,170,123, +117, 63, 57, 42, 43,244,221,107, 43, 31, 46,201,237,244,213, 2,117,228,170,156, 76, 43,115, 78,109,166, 26,167, 27,132, 78,197, +224,209, 86, 75,242,128,129, 67, 64, 17, 36,236, 22, 83,114, 81,229, 82,185,137, 49,107,199, 51, 40,165, 66,184,200, 4, 80,202, +132,104, 83,215, 19,229,232,207,120,154,229, 96,178,178, 48, 91, 25, 88,108, 12,188,131, 60,176,113,251, 62,164,228,152,113,228, +142, 6, 49,201,122,212,170,164, 0,207,151,221, 77,114, 44,109,236,253,241,112, 23,138, 36, 64,145, 4, 89,183,118, 8,242, 12, +118,136, 4, 36, 68, 82, 25, 20, 18, 1, 92,101, 66,136, 68, 66,228,228,228,192,106,181,162,114,229,202,210,210,169, 32, 15, 23, +165, 12,181,130, 3, 96,167, 25,156,188,242, 4,243,191, 25,128,174,237,154,129, 16, 42,241,204,218, 4, 46,158, 46,224, 72, 18, +118,134,131,205,206, 2, 32, 45,239,178, 23, 20, 20,212, 73,161, 80, 40, 76, 38,147, 62, 37, 37,229, 82, 86,204,161, 20,150,234, + 59,238,244,217,200,237,189, 62,234,138,251,143,162,177,255,208,209,171, 26, 47,237,212,162,103,234,213,171, 23,230,237,237,173, +204,205,205,213, 69, 69, 69,221,126,223,121, 1, 79,146, 95,135,183,233, 0, 67, 65, 14,178, 83, 19,157,158, 69,215,169,226,130, + 95, 22,174,107, 26, 26, 18,218,148,229, 29,196,171,110,101, 23,124, 55,115,117,211, 26,181, 66,154, 22, 45, 8,169, 83,185,244, +109,217, 4,114,151,110,159,126,254,237,194, 62, 3, 71, 33,242,236, 81, 44,159, 63,109,187,194,205,167,142,167,135, 91,227,250, + 97,221,112,245,252, 81, 72, 93,252,224,225,229,215,102,248,103, 95,116, 25, 56,124, 60,110, 92, 61,143, 85,139,126,218,198, 90, +245, 59,157, 73,171, 66, 21,236,211,168, 73,139, 97, 46,158,190, 40,208,234,225,226,161, 66,157,134,205,135, 61,121,104,253,193, +152,147,160,126,111,210,193,243,176,218,121,228, 27,236, 72, 85,155,145,148,229, 32, 90, 28, 87,142,152, 32,150, 35,148, 82,129, +192,147,126, 81,249,241,249, 72,190, 74,144, 47,177,120,238, 52,202, 14, 41,212, 5, 14,146,165,214,217,160,214,218, 96,176,208, +240, 84, 8,192,177, 92,185,103,221,249, 6, 59, 92,228, 66,184,201, 69, 78,171,140, 37, 97,253,159,123, 66, 31,198,102,244, 91, +190,124,165,252, 65, 66, 49,146, 37,116,168, 89, 18, 17, 5,150,227, 0, 39, 90,188, 80, 32,156,210,183, 71, 23,164,106,204,142, + 85,203, 36,129, 90, 13, 90,192, 91,198,161,243,224,233, 0,128,222, 61, 28,161,109, 9,153, 70, 28,187,169, 6, 94, 15,236, 46, +189, 47, 54,155,169, 13, 59, 78,124,189,111,239,110, 55, 11, 43,192, 31,167,146, 96,178, 50,144,138, 40, 72, 68, 20,100, 34,234, +181,120,236,178,137,150, 35,230, 46, 69, 67,195,100,177, 64,103,166,193, 3,184,253,194, 0,179,141,129,214, 72, 35,172,182,199, +135, 9, 33, 4,113,130,231,249,158,111, 18,162, 55,201, 82, 49, 69,170, 36, 27,119,138,219, 40,250,253,187,136, 92,241,152, 45, + 0,229, 90,193, 37,120,147, 57, 22,191, 22, 41, 60,234,184,185,184,221, 60,125,234,184,242,208, 67, 14,151, 30, 57, 72, 22,109, +214, 96,217, 15, 67,211,116, 5,154,142, 0,226,157,253,207,228,222,117, 26, 74,197,146,200,127,173,252,195,174,242, 13,228, 14, +222, 44,200,209,154,216,215,216, 4,107,181,146, 60,199,139, 44,217, 47,156,242, 33,144, 36, 97,159,249,101,127,112, 60,143, 89, + 43,247, 97,193,212,193, 80,202,134,203, 9,130,144, 27, 45, 12,190,153,189, 9,203,126, 25,227, 34,151, 8, 64, 16,142,152,168, + 79,135,244,119,174, 2, 90, 24,196,221,218,101,208, 39, 28,127, 90,220, 93,216,178,205, 71,119, 91,182,108, 89,224,225,225, 1, +153, 76,246, 74,169,120, 7,124,125,125,127,153, 57,115,102,232,132, 9, 19, 94,110,246, 41, 16, 8, 48,121,210, 36,146,101,121, +156, 58,181, 5, 62, 85,155,224,232,185,155,136,232,212, 28, 6,147, 5,121, 5,122,112,160,222,187, 34,234, 11, 52,145, 89, 73, +143, 91,180,238,216, 27,151,206, 28,230,111,158,218, 60,182, 60,123,244,120,120,122,164,222,123, 28, 87,135, 32, 60, 29,138, 86, + 33,201,178,209, 28,170,248,202,145,154, 20, 7,119, 55,183, 84,103,237,201,124, 66,251, 18, 36, 63,129, 0,191,197,152,253,124, + 31, 0,222,152,249,116,232,190,157, 27, 30, 69, 71, 61,152,223,107,216, 20, 65,183,129,147,168,223, 23,126,241, 19, 0,103, 55, +222,179,199,196,196, 60, 25, 51,102, 76,171, 27, 55,110,176, 0, 76, 4, 65,208, 20, 69,201,109, 54,155,168, 99,199,142,218,103, +207,158, 93, 70,201, 65,139,175,161,205,232,125,222,132, 68,255,145,152,179, 15,173,226,162,239,218,177,109, 56,194,235, 5, 33, +181,109, 56, 0, 76, 73, 54, 40, 67, 45, 53, 54,237,161, 25,217,201,223,255, 60,182, 96,236,224, 46,223,108, 23,204, 90,158,121, +124, 86,169,129,168,169, 79, 47,119, 47,137,198, 11, 40, 18, 46, 50, 33,148, 50, 1, 92,100, 66,184, 72,133,160, 25,190, 60, 51, + 71,158,102, 56,135,162,101, 99, 96, 48, 51,136,124,144,141, 44,173, 13, 5,122, 59,204,118, 22, 60,120,199,108,212,137,222, 92, +253,226,186,123,209, 72,234, 94,185,137,118,195,154,165,174, 7,174,165,189, 92,209,231, 38, 23,195, 69,238, 88,141,125,229,202, + 21,120,121,149, 61,219,231, 56, 14,251, 79,223,198,242,173,145, 56,189,229,123, 72, 69, 20, 26,246,157,141, 81,253, 90,130,227, + 57,196,197, 68,103,215,170,219,200,151, 36,101, 32, 9, 2, 86,154, 3,192,191, 51, 63,109, 54,155, 87, 74, 74,138,174,102,205, +154,126, 1, 1, 1, 3, 41,138,226,161,127, 96, 61,188, 59,207,116,225,248, 78,185,209,108,101,229,140,118, 75,205, 76,115, 79, +212,172, 9,130, 32,120, 87, 87, 87, 81,100,100,164,161, 65,131, 6, 62,239,217,148, 72,153, 42,100,213,231, 19,191, 30, 88,163, +122,117,236,219,185, 5, 60, 79, 28,112,246,225, 29,199,110, 96,238,143,175,175, 48,252,110,230,234,166,203,102, 79,121,237,222, +196, 31,151,151,186,234, 80, 38, 81, 78, 29, 48,116, 28,238,222,254, 27, 75,102,127,183,219,106,200, 27, 69, 51,244,160,188,204, +132,221,193,117, 91,130,183,235,113,118,239, 82, 12, 30, 49, 86,210,173,215, 64,220,184,122, 30, 11,126,154,184,195, 84,144, 51, + 26, 78, 6, 57,115,188,112, 66,199,238,253,132,102,171, 29,171, 23,255,138,241, 83,231, 35,172, 83,111, 97,212,131,155, 19, 0, +204,113, 58, 28,194,206,162, 99, 3,111, 7,121,166, 57, 28, 77,160, 4, 37,213, 64, 1, 69,144,141,171,187,195,108, 99,160, 43, + 99, 82, 41, 16, 9,179, 10,180,186,170,107, 23,124, 77, 25, 45, 12,212, 90, 27,114,180, 86,104, 10, 94, 17, 44,141,214, 10,181, +214, 6,161,128, 64,108,124, 50, 72,161,160,220,241,121,249, 6, 26, 45, 66, 60, 28,109,244, 61,189, 35,180,192,181,229,233,203, + 15, 7, 44, 95,190, 66,250, 48, 81,143, 71, 9,186, 66, 37,139,130, 68, 72, 66, 92,248, 55,203, 57, 98, 35, 75,131,171, 79,245, +224,145,159, 14,239,236,170,148, 33,227,121, 14, 4,148, 99,139, 24, 55, 85, 16,220, 36, 22,124, 49,113, 28,188,189,220,145,162, +177, 98,213,161, 88, 60,122,242, 2,156,185,124,175,189,250,143,221, 17,159, 79,254,206,157, 20,138,177,237, 76,162, 35,157, 20, +139,103, 55,143, 89, 50,226, 30, 27, 13,186, 92, 30, 60,235,100, 12, 50,193, 51,172,163,186, 45,152, 53, 29,187,183,254,134, 51, +247,114, 94,214,192,107, 7,150,225,235, 31,231, 65,163,179,161,164,122, 89, 26, 31, 1,160, 46,166, 68,189,117, 93,140, 28,149, +116, 77, 20, 94,219,222, 97,195,246, 6,185,178,189,113,223,246,134,189,146,246,254,219, 80,166,235,240, 45, 82,228,238, 83, 95, + 46, 85,252,125,234,212, 49,197,225, 71,252, 75,146,101, 55,105,248,249, 83,122,167,233, 10,212,221,202, 69,178,124,106,213,151, +200, 37,151,103,204, 91,101,245, 13,172,202,156,124,160,203,213, 91, 88,230,237, 24, 4, 5,171,112,243,177, 8,196,146,229, 66, +179,237, 87,141,230,169,177, 44,229,137,227,121, 28,191,149, 5,158,119, 76,145,246, 94, 73, 71,225,204, 28, 44,231,112,171,156, +123,144, 3, 65, 97, 28,138,179,242,247,250, 63,126,211,245,108,160, 53, 14, 91, 48,235,165,187, 48,172,145, 67,201,114,117,117, +133,187,187, 59,148, 74, 37,202,114, 29, 18, 4,241,233,231,159,127,254,214,236, 63, 39, 39, 7, 93, 58,119,196,154,223, 54,162, + 81,231,145, 56,119,253, 12,236, 52,135,134,117,171,163,106,128, 7, 82,179,245,239,213,208, 21,190,161,147, 91,116,236,247, 83, +155, 78,189, 17,121,250, 32,127,243,244,159,227,202,187, 17, 98,207, 46,173,142,205,157, 59, 43,120,198,252,181, 18, 23,169, 0, + 79, 13, 54,144, 4,129, 42,190,114,120, 41, 72, 92, 58,188,205, 50,184,119, 43,167, 55,199, 11, 10, 10,220,190,108,205, 6,197, +178, 69,179, 59,222,189, 71, 68, 26, 50, 98,243, 0,192,148, 29,179,248, 25,240,164,210,223,103, 79, 54,106,223, 31,190, 1,213, +187, 38,100, 63,115,154,108, 0, 48,197,199,199, 39,204,152, 49, 35,116,209,162, 69, 60, 69, 81, 28, 0,201,202,149, 43, 77,207, +159, 63,127, 0,199,210, 92,148, 53,216,116,238, 90,239, 27,165,152, 13,243,148,147,245,170,251,201, 17, 94,207,225, 21, 29,220, +179, 13,130, 42, 87, 70,124,150,169,113,158,137, 19, 26,108, 84,245,117,127, 60,186, 83,205,155, 26,203,152,109, 79, 0, 28, 41, +111,249, 16,120, 21, 32, 95,164,102,185,200,132,224, 28,117,165, 92, 68,203,106,103, 97,182,178, 48,219, 24, 24,109, 44, 76, 54, + 22, 28,239,104, 19, 4, 65,192,206,112,112,106,218,252, 70,221,119,245,244, 70,245,106, 4, 92,229,142,180,185, 22,110,247, 64, + 0,240,242,242,130, 74,165,114, 74, 21,181,217, 29, 77,220, 70,115, 47,221,250, 54, 59, 3,158,231, 17, 27, 27,243,125, 82, 66, + 66,223,154,181,106,182,171,219,176,145,167, 92, 66, 2,192, 59,137,150,201,100, 98, 93, 92, 92, 84,158,158,158,100,122,122,250, + 75,242, 92,179,113, 71,230,208,193, 3, 24, 48,160,191,225,233,237,135, 47,151,184,155,205,102,162,117,235,214,174, 65, 65, 65, +164,213,106,213,149,183,152, 20, 62, 33,253, 60,188, 60,231,127, 58,122,124, 72,199, 46, 17,184,120,225, 44,142, 28,220,245,151, + 73, 29,123,214, 89, 35,161,161,181,223, 90,117, 88,163, 86,200, 91,171, 14,171, 6,215, 42,149,104,213,109,216,188, 37, 79, 8, +112,230,248, 94,222, 66,218, 39, 2,224, 88,139,126,239,158,245,191,204, 25, 58,225,199, 26, 61,250, 12,197,167, 35, 70, 65, 32, +160,112,233,220, 49, 44,155,253,237, 9,131, 54,103,164, 51, 97, 2, 14,233,173,142, 40, 80, 22,244, 85,229, 26,245,113,239,230, + 85,196,197, 70, 69, 63,188,115,163, 94,205, 6, 97,240, 9,168,242, 85,178, 55,181, 8, 79,159,218,203, 50, 99,179, 88,146, 71, +141, 28,129,226,171, 14,195,155,132,122, 17,111, 54, 0, 0, 38,125,142,125,243,210,111,158, 23,173, 58,228,236,182,228,119,217, +213,230,171,247, 95,186,126,107,106,223,158, 17,164, 70,103,115, 40, 88, 90, 91,225,199, 10, 77,209,223, 58, 43,106, 5, 40, 17, + 19,125,143,179,104, 53, 7,202,217, 46, 45,163, 6,117,127, 82, 84,119, 57,142, 7, 1, 88,202,237,150, 18,186,142, 91,188,100, +185,244, 97,130, 1,143, 18,117, 14, 87,161,144,114, 16, 44, 33,249,146,116, 57, 86,179,151,161, 14, 17,212,130,207, 70, 14,129, + 70,103, 7,199, 1, 2,138, 44,252,136,144,162, 39,144,170, 55, 65,147,175, 70, 66, 82, 50, 10,178,226, 64,146, 36,188, 3, 66, +156,222, 73,154,229,197,254, 38, 27,223, 96, 96,207,118,130,131,127,103, 66, 46, 17,192,170,207,198,169, 61, 75,213, 86,131,110, +190,217,100, 56,232,204,126,142,175, 66, 16, 8,181,206, 96,241,149, 8, 41,236,219,186, 22,131, 70, 77,124,173,247,253,254,231, +185, 0, 73, 32, 47, 95, 15,130, 32,212,229,235,151,136, 59,165, 93,191,167, 50,246,193, 54, 74, 32, 91,111, 79, 20,222, 61, 27, +229, 79,157, 61,125, 76,113, 45, 73,130,219, 49,153,133, 36, 75,205,205,251,178,103,154, 94,155,215, 29, 64,108,249,230,133,100, +247,193,159, 77,141,174, 30, 82,215,122, 49,202,144, 88, 96,164,223, 25,231, 16, 62,112, 70,244,221, 19,107,122,104,233,248, 73, + 10,255,186, 44,199, 48,139,205,234,216,217,239,112, 29,138,103,175,218,247,210,109,248,195,162,109,142,191, 89, 22, 44,207,129, +231,128, 47,126, 89, 15,134, 99,193,177, 44, 56,150, 7,205,242,242,178,146,171, 10,168,122, 48,255,217,222,218,195,230,188,237, + 46,116,119,119,135,151,151, 23,188,188,188,224,234,234, 90, 38,209, 18, 10,133, 74,129,224,245,172, 78, 78, 78, 70, 82, 82, 18, + 92, 93, 93,193,115, 52,108, 52, 80, 63,172, 27, 30,199, 69,225,252,181, 7,224, 57, 22, 10,101,249, 79,121, 81,248,134, 78,106, +222,161,239,218, 78,125,198,224,220,193, 63,248, 59, 87,142,141, 55,231,196,110,114, 90,161,103, 89,130,166,105,244,236,214, 33, +249,126,244,139,211, 63, 79,157, 16,209,170,215,120, 73,120,104, 32, 44, 54, 22,105, 73,113,184,116,248, 79, 75, 72,176,255,153, +206,109, 91, 38,211, 52, 13,150,101,203, 28,200, 45, 54,187,134, 18,202, 20, 67,134, 12, 19,222,185,125,251,128,194,167,214, 62, +150, 32, 31, 18, 60,215,144,224,249, 1, 13, 27,214,129,157,230, 96, 50,233,242,203,251,206,122,189, 62, 97,203,150, 45,193, 35, + 71,142,148,215,173, 91, 87, 24, 23, 23,135,101,203,150,229,234,245,250, 4,103,109,156,189, 18,179, 82, 64,228, 63, 47, 82,180, + 82,218,132, 99, 72,175, 54,216,125,226, 26, 46, 93,189,129,100,131,242,129,129, 17, 28, 78, 77,206,176,214,243,212, 29,232, 19, + 94,149,218,183, 53,255, 64,116,135,233,159,240,188,228,172,230,242, 44,163,243,141, 27,208,155,105,184,202, 29,251, 61, 21, 41, + 91, 20, 65, 56,205,136, 8, 32,225,234,141,123,245,155,213,170,139,251, 9, 90,228, 20, 88, 97,182, 50,224, 56, 30, 28,120,120, +185,136, 33, 21,145, 72, 73, 74, 0,199,219, 19,203, 57, 84,168,219,183,107, 47, 0, 8, 16, 4, 47, 16, 10, 4,224,225,216, 95, + 81, 38,147, 25, 84, 42,149, 83,138,150,157, 97, 48, 32,162, 37,194,154, 55, 68,223,241,142, 61, 51, 47,252, 53, 29, 30, 74, 33, +118,111,223,132,212, 43, 43,183, 7,135, 79, 56, 27,245, 56,250,227,232,251,127, 15,251,168,169,172,177,159, 32, 67,244, 46,153, +212,104, 52, 30, 0, 32, 22,137, 68, 17,237,218,181,243, 60,112,224, 64,129,183,183, 55, 39, 22,137,212,125,122,247,226,132, 34, + 81, 94,209,111,175, 95,191, 46, 28, 63,126,188, 75,126,126,126, 74,118,118,246, 13, 0,116,233, 19,193,208, 46, 32,177, 11, 4, + 33, 85,202,228,201,213,170, 85, 15,104, 30,214,210,173,223,128, 65,144,136, 37, 56,119,246, 52, 86,175, 88,180,215,144,249,244, +179,242,228,228, 63,181,234, 48, 45, 37, 49,193,100,182, 54,168,223,172, 3,113,245,236,225, 41,118,120,175,160, 36,246,165, 93, + 6, 76,172,145,144, 97,192,234,133,223,195,195, 77,129,196,184,103,230,231, 79, 31,175,167, 45,186,239,157, 38, 89, 0,228,185, +236,199,225, 35, 34, 60,172,118, 22, 87, 34, 79, 88, 56,134,139,184,113,249,100, 92,165,144,230,210,250,205, 59,123,104,142,108, + 26, 96, 2,118,151,101, 39,253,217,219, 10, 46,111, 43, 72,188, 16,121,222,205,183, 74, 61,138, 0, 1,187,213, 2,117,252, 29, +198,148,253, 76,167, 75,143,114,106, 21,110,110, 42,126,249,113,230,191, 38, 53,111,214, 76,193, 67,250,154,130, 85, 68,176, 52, + 58, 27,188, 93,196, 48,235,212,120,126,231,180,197,164,166, 74,221,239,140,177, 25,229,154,156,108,241,171,112,134,216,176,210, +126,175,201,201, 22, 51, 54,163,188,236,161,142,130,171, 66,140,199,137,233, 47, 3,223, 37, 66, 71,108,150, 88, 72,189,140,211, + 42,234, 11,202, 64, 7,145,212, 29,233,185, 22, 16,224,193,177, 12, 24,218, 6,189, 78,135,244,140, 44,100,103,101, 67,175, 47, +128, 92,233,129,250,141, 91,192, 69, 33,197,195, 75,123,193,243,188, 83,251, 26,210,132, 48,180,121, 88, 91, 73, 84,146, 35, 22, + 75, 42,228,113,108,215,162, 92,131, 46,167,173, 33,243,249,243,242,246,197, 12,203,158,127,244,228,121,189, 74,254,213,136, 7, +113, 90,108,223,184, 6,182, 66,101,147,166, 89, 68,165, 24,145,153,103, 66, 74,252, 83,158, 99,217,243,248, 31,129,224,221, 2, + 32, 4, 13,235,215, 65,183,225,253,240,219,111,235, 17,159,144,196,205,159,210, 35,197,160, 47,248,168, 28, 36,171, 11, 10,247, +218, 48,101,199, 44, 54,123, 52, 79, 59,122, 63,143, 52,219,248, 82, 3,124,164, 62, 85,208,246,179,101,103,204,250, 60, 49,107, + 53, 9,142,109,255,108, 87, 73, 54, 29, 12, 26,182,249,223, 13,134, 82, 38, 0, 65, 16, 40,114, 23,174,155, 59, 14,114,137,195, +183,108,182, 50, 24,254,205,114,108, 95,254, 45,120, 0, 67, 7, 93, 51,189, 43,157,112,156, 93,248,133, 63,110, 87, 74, 78,202, + 73,239,210,251,187, 11, 22,187,196,218,171,255,200,187,205,154, 53, 43,144,201,100,144,201,100,112,117,117,133,135,135, 7,220, +221,221,203,124,119,154,166, 13, 54,155,205, 75, 44, 22,131,227, 56, 36, 38, 38, 34, 49, 49, 17, 90,173, 22,106,181, 26, 70,131, +142,185,125, 97,159,160,126,120, 15, 4, 84,111,128, 42,181, 26, 65, 72, 17, 16, 8, 72, 92, 58,186,241, 93,233, 44,153,100,181, +239,179,174,115,223,207,113,238,224, 6,254,206,149, 99, 19,204, 57,177, 27,157, 45,163, 66,119,207,195, 1, 3, 6, 52, 24, 63, +126,188,104,230,212,241,103, 78,156,189, 20,187,239,248,134,222,249,249, 5, 65, 60,207,195,221,205, 45,117,112,239, 86,199, 58, +182,110,158,124,225,194, 5,110,215,174, 93, 86,130, 32, 30,151,102,211,209, 73,229,252,117,225,124,228,172,182,237, 59, 96,211, +214, 93,237,163,159, 60,109, 31, 23,247, 28, 65, 85,170,163, 90,112, 45,152, 8, 15, 68, 94,190, 10, 67, 65,206, 95,206,164,243, + 13, 85,139,200,207,207,255,123,240,224,193,221,174, 93,187, 70, 14, 30, 60,216,164,209,104,174, 23, 83,177,248,178,108,222,248, +189,191, 26,192, 95, 85,218,143,218,155,110, 47,248, 10,192,162,202, 85, 42,227,210,213, 27,184,113,237,214,122,141,188,242,236, +207,134,143, 30, 87,181, 15,245,121,159,240,170,148,202, 67,142,157, 27,150, 81, 71,111, 36, 45, 79,202,101, 55, 45,186, 60,107, +174, 51,101,244,114,224,208,219,209,186,142, 39,104,150, 7,199, 59, 58, 92, 23,169,240, 93, 29,239, 91, 54, 5, 54,201,103, 19, +198,143,143,171,223,176,241,215,195, 71, 79, 16, 53,174, 30,132,219, 47, 10, 0,130,128,167,159, 2,153,153,153,184,178,127, 3, +147,159,254,108, 61, 69,113,115,202,145,159,200, 79,126, 80,179,216,229, 56,141, 70,131, 75,151, 46,161,136, 96,249,248,248,188, +139,104,189,102, 51, 55, 59,227,250,220, 37,127,180, 30,251,105,127,244,234, 80, 15,151,239,196,193, 86,184, 95, 83,209, 82,242, +132, 27,191,139,191, 26, 92,221, 54,105, 64,136,206, 76,139,147,126, 73,212, 94,129,227, 12, 86,238, 29,233,180,229,229,229, 29, +141,137,137,105,211,168, 81,163,170, 39, 79,158,204,139,190,117,102, 74,241, 68,124,247,221,119,202,223,126,251, 77,206,243,252, +117,155,205, 22,239,212,187,147,216,121,239,238, 93, 47, 59,205,225,234,173,135,117, 58,183,110, 12,142, 7,238,220,185,131, 77, +155, 55, 89, 30, 63,122,176,212,152,237, 55,167, 20,242, 82, 98,126,178, 31,182,234,240,165,205,204,244,164,165,231, 78,236,223, +222,188,125,111, 12,251, 98,206,156, 75, 39,118,205,106,218,182, 23, 89,167,121, 55,220,187, 17,137,243, 39, 79,255,203,110,200, +155,133,178, 99, 71, 74, 76,167, 68, 38,255,178,110,211,246, 72, 73, 78, 66,226,243,168,191, 44,121, 47, 50,146,227,168,191, 50, +210,146, 39, 4,215,107,141,107,103,118, 79, 41,133,104,149, 90,231,131,124,100, 27, 78, 30, 63, 58, 36, 45,237,119, 63,163,217, + 34,225,121,222, 34, 17, 11,178,148,164,126,143,206,233,116, 62,181,171, 51,170, 14, 24, 52,124,194,137,213,171, 87, 8,125,221, +229,200,202,183, 64,103,182, 67,111,178,131, 36, 8,212, 12, 80,192,164,207,195,229,253, 75,104,155, 33,127, 48, 16,103,127,151, + 77,133, 42,116, 94,254,139,200, 47,190,155,120, 17, 98,183,160,128,106,157,126, 44, 85,173,211,167, 63,232,253,221,196, 99,161, + 60,207,119, 86,168, 66,245,198,156,152, 25,239,122,119,130,112,180,239, 97, 29,131, 96,103, 28,251,143, 49, 28,192,114, 92,161, +202, 7,240, 47,253,249, 68, 25,239, 78,112,123, 78, 92, 71, 70,118, 1,204, 54, 26, 86, 27, 3, 59,205,130,164, 40,184,123,184, +163, 86,181, 38,112,115,119, 69,118, 86, 6,110, 92, 56,138,216, 71,151,175, 19, 60,102,155,213,207, 47, 56, 83, 70, 34,153,123, +168,127,128, 31,153,169,179, 65, 38,166,240,224,242, 73, 59,109,179, 46,117,146,100,189,101,179, 32, 55,111,249,215, 83,167, 13, +253,115,203, 86,191, 6,193,174, 72,211,152,145,166,182, 64,111,161, 11,137, 24, 7,171, 65,131, 71,145, 91,179, 88,139,126, 57, +254, 71,240, 78,162,197,216, 45,250, 3,167,111,123, 77,159,181,132,122, 17, 23, 79,207,251,170,103,154,217,160,235, 81,110, 37, +171, 24,254,156, 28,188,251,223,241, 18,111,185, 11,121, 14, 28,207,227,216,173,172,151,238, 66,174, 48,242,242,126, 92,233,199, + 8, 22, 63,187,176, 67,143, 41,231, 30,197,232,119,152,205,217,110,207, 94, 44,205, 7, 0,138,162, 94,126,138, 98,179, 44, 22, +139,173, 12, 23,202,182,141, 27, 55,254, 48, 97,194, 4, 73,106,106, 42,226,226,226, 80, 80, 80, 0,169, 84,138,211,167, 79,211, +224,152,165,143,174, 29, 74,140,185,119,246,215,208,102,221, 42, 53, 8,239, 1,185, 92, 1, 1,239,124, 48,166, 92, 21, 50,164, + 89,251, 62,107, 59,247, 27,139,243,135, 54,242,119, 46, 31,157,104, 86,199,110, 40,111, 94, 22, 20, 20, 68, 3,120,190,116,233, +210,198,155, 54,109, 10,158, 58,117,106,252,182,181,179, 86, 3, 64,110,110, 46, 0,224,254,253,251,252,196,137, 19,173, 22,139, + 37, 33, 63, 63,255, 30,202, 88, 0, 1, 0,102,181,124,193,166,117,139,234,167,166,103,246,175, 94,191, 5,124,130, 91,192,175, +102, 75,228,235,237,184,253, 34, 3,241, 79, 47,224,233,213,253, 39, 77, 74,102, 22,202,185,191,113,163, 70,141,130, 72,146,172, +102, 48, 24,252,234,214,173,219, 72,161, 80,220,111,212,168, 81, 19,129, 64,144,118,247,238,221,164,242,216, 74,190,188,213, 90, +165,253,168, 85,201,122,151,142,241, 89,166, 38,201,122,151,251, 38,137,219,183,234,200, 85,214, 63,169,192,229,188, 93, 19,189, +111,171,238,192,206, 13,203,168,225,227,190, 99,163,180, 30, 95, 9,100,226,115,229,147,171,201,204, 73, 35,251,190,218,222,161, + 80,201, 42,252,219, 41,153, 94,171,125,164, 5,240,195,163, 39,194,181, 81, 95,141,159,219,176,121,235, 17,237, 62, 26, 76, 50, + 34, 37,206, 28,250,157, 79,120, 20,185, 79,192,179, 63,155,157, 56, 13,160, 76,119,144,205,230, 12,201,122, 59,141,169,138, 14, +251,118,109, 30,117,224,208,193,133,253,250,244,245, 90,247,203, 39, 88,242,199, 97, 40,100, 18,240, 28,135, 79, 58, 6, 13,252, +245,243,218,189,131,124,165,129, 7, 46,166, 93,249, 98, 69,212, 15, 38,147, 61,214, 9, 37,134,215,104, 52, 87,149, 74,165,186, + 77,155, 54, 97, 18,137,132,208,104, 52, 2,149, 74,197,184,185,185,217,210,210,210, 76, 86,171,245, 0,128,114,109, 59,110,167, + 57, 36,102, 91,112,228,224, 1, 60,188,117, 1, 79,159,198,232,159, 62,121,186,134, 16,240, 43,140,217,207,243,128,114, 79,240, +193,149,184,234,144, 47,247,170, 67,214,170,223,185,109,253,188, 78, 38,139,117, 84,163, 86, 61, 81,181, 78,107,210, 78,179,120, +124,231, 34, 46,238, 95,177,196,110,200,155,254, 33,101, 28, 80, 41,184, 22, 79,137,241,247,165, 19,224, 57,110, 61, 0,240, 28, +183,254,254,181,147, 19, 90,246,248, 28,158,170,170,141, 10, 82,238, 19,120,143,221,195, 69, 2,210,120,234,192,159,135, 18, 19, + 19,241,236,217, 51,188,120,241, 2,121,121,121,216,185, 51,177, 92,229, 99,202, 79, 58, 23,251,132,236,254,241, 39,195,142, 13, + 28,242,169, 52,184, 86, 3, 50,180,146, 7,188,148, 2,196,188, 72, 66,236,221, 71, 92,204,237,147, 22,187, 46,167,159, 57, 63, +233,157,196, 79,238, 93,199, 23, 96,167, 23,157, 93, 24, 30,222, 58,116,218,252,133, 97, 94, 62,170, 18,251,241, 92,117,142,248, +251, 47,142,134,222,184,249,183, 83,103, 29,114, 44,155, 59,110,212, 96,142,114, 28, 20,138,151, 58,117, 97,238, 57, 38, 83,142, +251, 60,199,148,169,224,143,238,223, 22, 12,199,193,104,182, 67,103,180, 66,171,183, 32, 51, 39, 23, 15, 31, 61,194,229, 99, 71, + 17, 23,243, 48,129,182,217,206,146, 36,177,223,156, 29,123,185,124,158, 38, 65,176,151,167, 39, 18,242, 12,144,138, 5, 72,138, +189,107, 53,234,180, 59,222,183, 30,153,115,159,103,230, 80, 68,183,193,131,135,156,238,212,189,143, 91,243, 86, 93,228,222,174, +238, 16, 9,120, 60, 79,204,192,189,235,167,141,241, 15,175,232,104,155, 33,226,159, 56,245,229, 63, 28,101,175, 58,180, 91,141, +189,135,246,109,127,144,162, 4, 98,142, 99,172,118,155,245,227, 15, 33, 89,255, 46,240, 60,155, 54,106,104,255,215,230, 6, 12, +199,203,134, 14, 58, 99, 46, 62, 87,160, 89, 94, 62,116,208,117,147,163, 3,121,119, 96,159,191,191,103,207,162,179, 11,147,147, +115,239,228,229, 89, 47, 2, 72,179, 88, 44,239,157,198,236,236,236,185,243,231,207,239,101, 50,153,106,119,232,208, 65,226,234, +234,138,220,220, 92,156, 61,123,150, 62,126,252,248,147,156,156,156, 95,129, 28,198,140, 38,127, 61,178, 28, 26, 25,115,247,236, +175,181,155,117,175,212,160, 85, 15,231, 59, 51,137,108,108,167, 62, 99,136,243,135, 55,242,183, 47, 29,158,100, 86, 63,255,227, + 3,178,213,110,177, 88,110, 89, 44,150,168,159,127,254,185,185,175,175,175,239,175,191,254, 42,213,233,116,194,117,235,214, 89, + 52, 26, 77,150, 78,167,187,129, 82,226,105,222,198,125, 90,155,142, 1,167, 14,108,236,200, 31,216,216,213,221, 59,176,155,155, + 79,165, 26, 5,234,244, 4,173, 58,227, 44,128,243,133, 27, 69,150, 11,141, 27, 55,174, 78, 16,196, 96, 0,245, 21, 10, 69, 77, +165, 82, 41,225,121,190, 54, 65, 16,209, 28,199, 61,170, 91,183,238,241, 39, 79,158,148,107, 51,217,228,203, 91,173, 65,161,173, +119,229,153, 56,145,141, 20,237, 74,190,188,213, 10, 0, 57,231,166,153, 0, 28,121,210,225,135, 1, 71,111, 36,173,142,206,119, +155,162,190,180,240,104,121,211,172, 77,123, 88,243,159,170,255,150,204, 39,105, 0, 70, 61,186,139,101,143,239,223,152, 73,240, + 16,178, 96,230,153,115, 94,220,253, 39,236, 11,133, 66, 75, 96, 96, 96,137,171, 11, 37, 18,137,197,106, 45, 77, 64,185,204, 24, + 50,177, 9,104,191,245,224,222,173,163, 14, 31, 61,178,176, 93,231,126, 94,210, 74,149, 80, 77, 69, 96,235,244,166, 83, 46,220, + 87,223,238, 51,237,202,111,241, 25,150, 71, 40,103, 60,140,193, 96,136, 5,144,111, 48, 24,250,242, 60,159, 74, 16, 68, 80,126, +126,254, 3,154,166, 31,151,155, 16,112, 24, 22, 30,222, 98, 39, 65, 16, 2,158,225, 22,223, 16, 82,187, 44,153, 79,211,240,129, +199,146, 52,168,230,138,111,126, 93,213,180, 70,205,144,166, 69,103, 29,214,171,234,130,241, 63, 44,107, 90, 53,184, 86,211, 87, +231, 31,150, 25, 38,192,211,166,252,207, 14,110, 94,124,229,254,205,139, 63,121,251, 87,173,154,149, 22,255, 52,245,197,131,185, +172, 69,119,240, 67,203, 57,241, 69,244,138, 77, 75,127,152,154,153,158,176,201,164,126, 30, 5, 0, 38,245,243,168,167,247,240, +139, 38, 43,109,106,110, 78,252,210,247,205, 11,163,209,152,177, 99,199, 14,247,214,173, 91,147,190,190,190, 80,171,213,184,120, +241, 34,199,113, 92,122,185,109,229, 37, 92, 52,230, 17,158,127,253,177,118,177, 72,225,210,131, 97,152, 0,158, 7, 4, 2, 65, +166,205,164, 59,173, 39, 21,211,144,159,100, 41,125,204,224, 8, 0,100,209,217,133, 28,199, 17,139, 87,111, 77, 18, 74, 93, 74, +220, 12,145,182,232,229, 28,199, 57,125,214, 97, 65,202,189, 26,255, 84,251, 38,120,126,118,163,102, 97, 63,209,180,221, 82,216, + 62, 44, 0, 44, 60,143, 92,146, 36, 46, 83, 28,125, 70,247, 1,147, 41,130,128, 43, 79, 8,224, 34, 19,128, 0, 1,131, 54,143, + 47, 79, 76, 86,137,132, 56, 39, 54,218,148,211,190,202, 41,219,222,145,145,231, 78, 14, 98, 89,182, 90,161,102,144,104, 53, 27, +247, 25, 50, 61,254, 2,238, 50,248,191,143, 19, 69,100,139,248, 55,255, 71, 78,185, 81,254,147,108,134, 6,203,250, 86, 10,244, + 29,153,152,148,115, 59, 62,213,244, 23, 94, 63, 86,231, 67,210, 73,249,250,250,254, 66, 16,196, 8,177, 88,172,180,217,108, 70, +158,231,183,101,103,103,207,197, 91,135,255, 54, 17,202, 84,230,145, 98,169,124,134,221, 98,252,219,148, 19, 59,172,172,119,151, +251,132,116,147, 42, 20, 63, 88,204,198,109,166,236,216,173,255,112,126,186, 73, 36,146, 38, 74,165, 82,168,209,104,110, 1,208, +254, 39,149,123,163, 70,141, 42,147, 36, 89,141,227, 56, 95, 0,110,112,172, 10,209, 8, 4,130,244, 66, 69,139, 47,175,205, 54, +163,247,121,119,238, 90,239,155,179, 87, 98, 86, 22,186, 21, 95, 34,112,224,114,233,136, 30, 29,255, 63,246,238, 59,172,169,235, +255, 3,248, 59, 11, 18, 72, 32,236, 61, 84,134,184,192,162,181, 78,220,171,226,182,110,173,187, 86,127, 90,173,117, 87,176, 85, +235,168,117,213,182,246,107,213, 58,234,174, 85,220,180,206,186,131, 34, 56, 0, 65, 4,100,143,144, 1, 36, 33,201,249,253,193, + 40,181, 76, 71, 91,237,231,245, 60,121, 88, 55,239,220,155,220, 27, 62, 57,247,220,115, 62,254,241,240, 47,149, 93,117,248,218, +237,243,127, 95,102, 71,190,196, 57,251,125,174,169,116, 89, 87,191,162,130,236,212,167, 83, 47,221,205,186, 14, 64,249, 34,235, +105, 98, 98, 50, 74,167,211,153,153,152,152, 20,234,116,186,221,255,150,109, 55,115,240,155,192, 5,171,245,204, 20, 70,112,110, + 61,115,209,202,155,178, 47,241,252,253,253, 59,152,152,152,120, 24, 12, 6,115,173, 86, 91, 80, 88, 88,248, 56, 49, 49,241, 10, +170,158,248,252,149,174,167,216,193,119,157,137,137,112, 38, 0,232,116,154, 13,234,204,216, 89,213,221,177,154,229, 95,235,215, +200,174,126,203, 88, 62, 79, 96,143,210,129,185,141,122,125, 86, 70,194, 77,223,127,112, 61,201,115,190,184,148, 73,153,148, 73, +153,207,226,210,243, 73,153,255,100,166,200,185,177,187,200,185,113,173, 7, 93,174, 98,121,122, 62, 73,153,201,149,220, 0,212, + 98,192, 82, 66, 8,121, 5,140,244, 20,144,127, 82, 81,218,253,228, 87,185, 60,249,207,169,178, 79, 52,167,154,170,180, 46, 77, +130,207, 83,217,134, 83, 38,101, 82, 38,101, 82, 38,101, 82,230,127, 46,179,166,236,215,241,148,228,228,103,126, 62, 14,224,111, +233,240, 79,205,170,148, 73,153,148, 73,153,148, 73,153,148,249, 95, 83, 94,120,113,233,185, 32,132, 16, 66, 8,121, 53,168,143, + 22, 33,132, 16, 66,200,139,169,236,212, 33, 21, 90,132, 16, 66, 8, 33, 47, 65,149,157,225,233,212, 33, 33,132, 16, 66,200,139, + 41,107,209,114,198, 51,195, 59, 80,161, 69, 8, 33,132, 16,242,114,164,161,178,214,173,176,176, 48, 86,217,247,132, 16, 66, 8, + 33,127,135,215,188, 22,169,216,146, 53,185,244,103, 0, 21, 90,180,168,192, 34,132, 16, 66,200,191,165,216,122,205,148,181,100, +149,221,210,254, 82,104, 5, 7, 7,115,168,216, 34,132, 16, 66,200, 63,229, 77,172, 69,184,207,110, 32,189,204,132, 16, 66, 8, +249, 39,139,173, 55,105,123,104,120, 7, 66, 8, 33,132,144, 23,227, 12,160, 79,133,159,255,182, 41,120, 8, 33,132, 16, 66,222, +116,147,171,250,153, 90,180, 8, 33,132, 16, 66, 94,126,177, 69, 8, 33,132, 16, 66, 94,103, 52,179, 57,101, 82, 38,101, 82, 38, +101, 82, 38,101,190,233,202,198,209, 2,170, 26, 71,139, 16, 66, 8, 33,132, 60,151, 62, 40, 25, 63,107,114,233,215, 62, 84,104, + 17, 66, 8, 33,132,188, 92,127,153,126,135, 10, 45, 66, 8, 33,132,144,151, 91, 96,125, 79,133, 22, 33,132, 16, 66,200, 43, 70, +133, 22, 33,132, 16, 66,200, 43,194, 65,213, 87, 14,132,215, 33,231,121,174, 62, 8,167, 76,202,164, 76,202,164, 76,202,164,204, +255, 92,102, 77,217,225,120,253,148,141, 12,127, 28,127,116,132,255,254,239,120, 96,186,244,149, 50, 41,147, 50, 41,147, 50, 41, +147, 50,223,116,147,159,249, 90,142, 78, 29, 18, 66, 8, 33,132,188,220, 98,139,166,224, 33,132, 16, 66, 8,121, 73,170, 60, 77, + 72, 45, 90,132, 16, 66, 8, 33, 47,166,202, 73,165,169,208, 34,132, 16, 66, 8,121, 53, 5, 23, 21, 90,132, 16, 66, 8, 33, 47, +177,200,154, 92,233, 95,195,194,194, 24, 61, 71,132, 16, 66, 8,249,167,188,177,181, 72,217,134, 81,177, 69, 8, 33,132, 16,170, + 69,234,204, 25,127, 92,109, 56,185,244,103, 0,116,213, 33, 33,132, 16, 66,200,139,234,131, 63, 95,121, 56,185,236,103, 42,180, + 8, 33,132, 16, 66, 94,220,228,106,255, 74,167, 13, 9, 33,132, 16,242, 79,122, 19,107, 17, 14,189,172,132, 16, 66, 8, 33, 47, +164,178,214,172,239,233,105, 33,132, 16, 66, 8,121,181, 5, 23, 33,132, 16, 66, 8,121, 21, 69,214,171, 30,176,148,102, 54,167, + 76,202,164, 76,202,164, 76,202,164,204,255, 74,145, 85,113,136, 7, 0,116,213, 33, 33,132, 16, 66,200,139,162, 73,165, 9, 33, +132, 16, 66, 94, 17,154, 84,154, 16, 66, 8, 33,228,111, 46,184,168,208, 34,132, 16, 66, 8,121,137, 69,214,159,138, 45,234,163, + 69, 8, 33,132, 16,242, 98,170,236,163,197, 65,213, 87, 14,132,215,225, 1,158,231,234,131,112,202,164, 76,202,164, 76,202,164, + 76,202,252,207,101,214,148, 29,142,215,223,100,252, 77, 3,150,210,165,175,148, 73,153,148, 73,153,148, 73,153,148,249, 95, 67, +195, 59, 16, 66, 8, 33,132,188,236,194,234, 89, 84,104, 17, 66, 8, 33,132,188, 24, 26, 71,139, 16, 66, 8, 33,228, 21,113, 70, + 73,171, 86,217,215, 64, 42,180, 8, 33,132, 16, 66, 94,142, 62, 40,105,213, 42,251, 74,133, 22, 33,132, 16, 66,200, 75, 84,233, + 56, 90, 28, 0, 8, 11, 11, 99,165, 63,119, 10, 14, 14,190, 64,207, 21, 33,132, 16, 66,254, 78,111,106, 45, 82,222,162, 21, 28, + 28,204, 98,130,209,125, 0, 0, 32, 0, 73, 68, 65, 84, 1,112,158, 94,106, 66, 8, 33,132,252, 19,222,196, 90,132,251, 76, 37, +217,137, 94,102, 66, 8, 33,132,252, 19,222,196, 90,132,255, 76, 21, 73, 8, 33,132, 16,242,143,120,141,107, 17,103,148,116,132, + 63, 94,250, 21, 40, 29,242,129,198,209, 34,132, 16, 66, 8,121, 49,101, 87, 27,254,101,234, 29,106,197, 34,132, 16, 66, 8,121, + 49,149,141, 12,255, 61, 61, 45,132, 16, 66, 8, 33,175, 16,181,104, 17, 66, 8, 33,132,188,184,138,173, 90,127, 91,107, 22,205, +108, 78,153,148, 73,153,148, 73,153,148, 73,153,255,165, 34,235, 79, 63,211,200,240,132, 16, 66, 8, 33,175, 8, 93,117, 72, 8, + 33,132, 16,242, 98,202,174, 56,172,248, 51, 21, 90,132, 16, 66, 8, 33, 47,177,216,250, 11, 58,117, 72, 8, 33,132, 16,242, 98, + 38, 87,245, 7, 42,180, 8, 33,132, 16, 66, 94, 81,193,197, 65,213, 87, 14,132,215, 33,248,121,174, 62, 8,167, 76,202,164, 76, +202,164, 76,202,164,204,255, 92,102, 77,217,225,120,253,252, 99, 3,150,210,165,175,148, 73,153,148, 73,153,148, 73,153,148,249, +159, 69,167, 14, 9, 33,132, 16, 66,254, 5,133,150, 61,159,207, 95,104,102,102,246,141,153,153,217, 22, 62,159,255, 37, 0,235, +186, 62,160, 88, 44,158,225,228,228,244,192,201,201, 41,197,195,195,227,132,133,133,249, 71, 94, 66, 4, 1, 16,188,164,237,241, + 3,240,145,153,153,217,125,145, 72,148, 8, 96, 23,128,143, 0,216,189, 72,240,231, 46, 24, 28, 53,179,255,145,207, 93, 48,248, +153, 63,245,113,116,116,188, 4,160,199,203,122, 81,134,155,163,219, 16, 49,146,134,136,145, 52,220,252,249, 63, 53, 88, 88, 88, +140,118,118,118,190,106,107,107,251,212,217,217,249,119,145, 72, 52,164,142, 17, 14,142,142,142,107,220,221,221, 99, 92, 92, 92, +214,163,100,118,242,127,173, 14, 66,116,104, 45, 68, 86, 27, 83, 40,219,153,226,155, 54,166,232,222, 29, 48,127,206,184,246, 0, + 14, 90, 90, 90,222,230,243,249, 97, 0, 6,149,238, 95,131,248,124,126,152,165,165,229,109, 0, 7, 75,151,123,158,253,116, 13, +128,167, 0, 86,148,254,252,127,238,238,238,202,128,128,128,196,128,128,128,237, 62, 62, 62, 99,106, 27,102,110,110,222,221,221, +221,253,144,135,135, 71, 98,155, 54,109,114, 93, 93, 93, 31,186,185,185,237, 16, 10,133,157,232, 45,142, 16, 66,254,253,250, 2, +248, 2,192,166,200,200, 72, 25, 99, 76,198, 24,147, 69, 70, 70,202, 0,124, 3, 96, 37,170,110, 66,252,211,239,109,109,109,151, + 46, 91,182,172, 40, 45, 45,141,101,101,101,177,152,152, 24,182,110,241, 60, 99, 79, 27, 62,243,178,183, 46,112,118,118,126,228, +233,230,182,183,169,132, 59, 15,128,119,109, 50, 43,176, 54, 51, 51,187,190,120,241, 98,213,165, 75,151, 84, 90,173, 86,101, 52, + 26, 85,169,169,169,170,240,240,112, 85,187,118,237, 84, 0,102, 1,224,213, 33,179,220,103, 46,184,192,126,248,148,125,230,130, + 11, 21,127,223,168, 81,163,123, 70,163,145, 13, 30, 60, 88, 3,192,181, 46,153,207,114, 5, 68, 77, 45, 97, 53, 68,130, 12,253, +142,207, 25,219, 60,135, 13, 17, 35,233,121, 50, 29, 28, 28,126,153, 49, 99,134,226,233,211,167, 76,163,209,176,164,164, 36, 54, +101,202,148,124, 7, 7,135,221,181,220,118, 91,127,127,255,140,171, 87,175, 26,229,114, 57, 59,127,254,188,177, 89,179,102, 25, +181, 44,182,186, 61,179, 46,223,187,184,184,156,168,203,205,193,193, 97,107, 93, 95,163,119,132, 72,210,201,206, 49,118,243, 12, + 59, 58,184, 13, 91,215,210,141, 13,178, 49,149,183, 55,197,255,117,172,124, 40,147,170, 50,223,235,216,177,163,250,238,221,187, +134,156,156, 28,118,239,222, 61,227,164, 73,147,138, 0, 68, 79,154, 52,169,232,222,189,123,198,156,156, 28,118,247,238, 93, 67, +199,142, 29,213, 0, 38,214, 97, 61,185, 0,182,133,134,134, 50,198, 24, 91,182,108, 25, 11, 8, 8, 96, 93,186,116, 97, 42,149, +138, 49,198, 18, 25, 99,219,245,122,253,251,181,201,148, 74,165,163,103,204,152,161, 42, 40, 40, 96,101,140, 70, 35,147,203,229, +108,211,166, 77,106, 39, 39,167, 19, 85,124,200,160, 83, 30,148, 73,153,148,249,111,203,124,157, 57,163,164,159, 86,217,173,214, + 13, 19, 35,230,205,155, 87, 86, 84,157,108,223,190,253,141,247,223,127, 95,246,254,251,239,203,218,183,111,127, 30,192,233, 91, +183,110,201,230,206,157, 43, 3, 48,162,134, 23,194,186,109,219,182,242,244,244,116,230,235,235,203,234,213,171,199,210,211,211, + 25, 99,140,221,124,175, 5,251,181, 49, 88,242,197,147,236,204,207, 7,217, 36,103, 62,235,224, 44, 45,118,118,114,202,177,179, +179, 91,142, 63,207,201, 88,217,139, 59,176,113,227,198,202,232,232,104, 85,108,108,172,106,233,210,165,170, 46, 93,186,168,252, +253,253, 85,131, 6, 13, 82,109,220,184, 81,165,211,233, 84, 91,183,110, 85, 89, 90, 90, 70, 87, 82,108, 61,119,161,197,231,243, + 55, 68, 70, 70,178, 71,143, 30,177,210, 86,138,170, 50,165, 86, 86, 86,189,172,173,173,103, 89, 89, 89,245, 2, 32, 5, 0, 95, + 64,210, 92, 10,143,255,107,238,213, 40,108, 68, 55,239, 77,221,222,110, 49,196,130, 43, 47,254,122, 14, 99,131, 61,158,171,208, +146, 74,165,163, 63,250,232, 35,165, 70,163, 97, 5, 5, 5, 76,165, 82,177,130,130, 2,166, 84, 42,217,136, 17, 35, 20, 34,145, +104, 96, 77,153,118,118,118,159, 95,188,120, 81,159,158,158,206, 46, 94,188,200, 78,156, 56,193, 54,111,222,108,116,112,112,248, +170,174, 7,160,147,147,211,217, 51,103,206,200, 34, 34, 34,100,215,175, 95,151, 21, 23, 23,203,116, 58,157, 76,167,211,201,194, +194,194,100,135, 15, 31,150,237,219,183, 79,166,213,106,101, 90,173, 86,166,209,104,100, 13, 26, 52, 56, 85,215,215,168,149, 16, +201,218, 75, 71, 25,251,106, 26,203, 95, 53,149,201,103,191,203, 50,167, 4,177,111,222,118, 99, 65,102, 56,134,191,206,237, 89, +105,166, 64, 32,184,144,152,152,104, 92,176, 96,129,182, 73,147, 38,249,227,199,143, 47,210,104, 52,140, 49,198, 52, 26, 13, 27, + 63,126,124, 81,147, 38, 77,242, 23, 44, 88,160,125,252,248,177,145,207,231,135,215, 97, 61, 87,150, 21, 89, 23, 46, 92, 96, 21, +169, 84, 42,214,165, 75,151,196,128,128,128,237,245,235,215, 31, 89, 83,166, 68, 34,233, 63,127,254,124, 21,171, 68,113,113, 49, + 83, 42,149,236,241,227,199,198,122,245,234,165, 2,176,165, 55,115,202,164, 76,202,164, 66,235,149,153, 92,195,207,149, 63,137, +115,231,206,149, 49,198,100,139, 22, 45,146,149,182,108,153, 0,144,148,222,248, 0,134,207,159, 63, 95,198, 24,147,205,155, 55, +175,108,153,170, 94,136,190, 7, 14, 28,208,173, 95,191,158, 57, 58, 58, 50, 39, 39, 39,182, 97,195, 6,102, 52, 26, 89,122,216, +110,246,107, 99,176,251, 11,199, 50,198, 24,139, 89, 62,157,253,218, 24, 44,254,219,207,216,168, 81,163, 10,204,205,205, 71, 84, +243,226,218,180,104,209, 66, 89, 88, 88,168,218,177, 99,135,202,220,220,252, 38,128, 38, 40, 57, 21,201, 41, 93,215, 49, 77,154, + 52, 81, 68, 69, 69,169,126,250,233, 39, 21,128,165,181,220, 97,188, 1,116, 22,139,197,131,230,187, 10, 98,217, 15,159,178,249, +142,184, 11,160, 25, 0,251,210,101, 92,230,205,155,199, 24, 99,204,221,221,253, 98, 21,153, 82,127,127,255,121,177,177,177, 33, +197,197,197, 33, 17, 17, 17, 33, 13, 27, 54, 92,208,175,129,115,155, 35, 35,186, 7,230,127, 54, 53,144,173,157,237,255,101,239, + 86,221,246, 14,235, 52, 98, 92,125,187, 75,227, 29, 68, 5, 67,165, 60,229, 51,167, 14,107,181, 99,187,186,186, 94, 79, 74, 74, + 42, 47,174,148, 74, 37,123,250,244, 41, 75, 72, 72, 96,151, 46, 93, 98,206,206,206,191,214,148,233,228,228,116, 47, 41, 41,137, +125,187,110, 29, 27,220,172, 17, 11,178,178, 96, 29,173, 45, 88, 75,137, 72,221, 24,104, 89,215, 66,235,246,237,219, 50, 0, 50, + 0,178,156,156, 28, 89, 78, 78,142, 44, 47, 47,175,252,119, 0,100,249,249,249,178,252,252,124,153, 86,171,149,121,121,121,213, +185,208,106, 39, 66,187,119, 68,200,109, 35, 68, 97, 95, 87,187,212,169, 13,236, 12,215, 70,180, 97,121,211,186,176,245,129,174, +172,189, 41,254,175,150,153,125, 77, 77, 77,207, 3,152, 83, 90,148,143,237,213,171, 87, 1, 99,140,245,234,213,171, 0,192,216, +210,223,127, 84, 90,100,245,170,229,122,114,125,124,124,212,101, 45, 89, 0,174,248,248,248,168, 3, 2, 2, 88, 64, 64, 0,115, +119,119, 87,150,102,215,234, 13,205,219,219, 59,166,176,176,176,188, 0,148,203,229, 44, 53, 53,149,197,199,199,179,232,232,104, +118,243,230, 77,150,152,152,200,246,239,223,111,176,178,178, 58, 78,111,230,148, 73,153,148, 73,133,214, 43, 45,180,158,189,253, + 89, 88, 88, 24,123,230, 87,171,110,221,186, 37,155, 63,127,190,172,134,202,108,242,162, 69,139,202, 90,189,190,168,230,159,255, +214,152,152, 24, 54,118,236, 88,230,231,231,199,252,252,252,216,251,239,191,207,242,243,243,153, 42, 46,138,253,218, 24,236,230, +208,150,140, 49,198,148,247, 35,216,175,141,193,100,163,218,178, 59,119,238, 48, 55, 55,183, 51,213, 60,254,177,223,127,255, 61, +107,247,238,221,233, 40,233,143, 37, 0,208, 26,192, 6, 51, 51,179,109, 40, 57, 93, 88, 15,128,181,175,175,111,110, 65, 65,129, +106,240,224,193, 42, 0, 30,213,100,118,244,243,243,123,180,117,235, 86,150,153,153,201,114,115,115,217,234,118, 13, 25,251,225, + 83,182,172,101, 61,227,183,223,126,171,153, 51,103,142,218,198,198, 38, 12,128,203,224,193,131,245,140, 49, 22, 20, 20,148, 81, + 89,152,149,149, 85,175,216,216,216,144,162,162,162, 16,185, 92, 30,146,155,155, 27,114,244,200,145,144,158,205, 26,142,205,255, +108,106,224,145, 17,221, 3,123,187, 90, 15,250,170,199,219, 31, 60, 93, 48,113,240,162,182, 77,238, 23,173,156,121,238,189, 6, +142,107,158,231,213,182,183,183, 79,211,104, 52, 12,192, 95,110,143, 30, 61, 98,182,182,182, 73, 53,101,216,216,216, 44,250,104, +248, 48,195,192,122,174,236,209,250,197,172,248,236, 79,172,248,196, 14, 22,183,106, 54,235,231,100,167,104,109,194,157, 95,219, +245,113,114,114, 58,123,253,250,245, 63, 21, 90,121,121,121,149, 22, 90, 10,133, 66,166,213,106,101, 62, 62, 62,167, 94,116,175, +111,109, 10,175,142,102,188,155, 17, 99, 59,176,172,169, 93, 88, 47,169, 32,241, 5,226,134, 3, 56, 15, 96, 84, 29,239,199, 5, +176,178,172,160, 90,181,106, 21, 99,140, 49, 31, 31, 31, 53, 94,236, 98, 20,105,163, 70,141, 18, 38, 78,156,168,111,220,184,113, +102,187,118,237,228, 55,110,220, 96, 23, 46, 92, 96, 39, 78,156, 96, 7, 15, 30,100, 81, 81, 81,236,233,211,167, 44, 38, 38,134, +245,233,211, 71, 14,160, 35,189, 23, 18, 66,254,205, 42,169, 69, 94,123,220,178, 13, 11, 14, 14,230, 84,216, 64, 41, 0, 81,203, +150, 45,179, 86,174, 92,185, 22, 37, 99, 65,112,252,121,120,175,139, 25,255, 78, 23, 51,254, 29,127, 30,222, 43,109, 49,250,126, +249,242,229,159, 7, 4, 4,164, 1, 48, 3,224, 84,217, 3, 49,198, 58,216,218,218, 34, 41, 41, 9, 82,169, 20, 82,169, 20, 73, + 73, 73, 96,140, 65,207,128, 98, 6,104,116, 58, 20, 22, 22,162,200,200, 80,104, 4, 20, 42, 21,156,156,156,160,211,233,188,170, + 88,255,230, 67,135, 14,245,242,247,247,207,154, 59,119,110, 42, 74,250,202,108,155, 48, 97,194,217, 43, 87,174,248,171, 84,170, +220,232,232,232,162,102,205,154,245, 2,224, 20, 27, 27, 59,122,211,166, 77, 24, 59,118, 44,170,249,167,211,172, 79,159, 62, 39, +162,162,162,188, 70,141, 26,133,243,231,207, 99,245,234,213,200,206,206,102, 0,160,209,104,152,193, 96,208,181,109,219, 86,183, +126,253,250, 86, 65, 65, 65,215, 27, 52,104,192, 3,128,132,132,132,184,202, 2, 57, 28, 78, 67, 79, 79, 79,104, 52, 26,100,101, +101, 33, 42, 42, 10, 22, 82, 41, 34, 83,179, 29, 59,125,245,109,206,194, 35,103, 5,195, 91,249,219,204,234,222, 78,179,226,204, +121,223, 38, 46,142,142, 90, 93,177, 83, 76, 90, 70,234,243,188,168, 38, 38, 38, 73,217,217,217,208,106,181, 40, 44, 44,132, 66, +161, 64, 78, 78, 14,178,179,179,145,154,154, 10, 19, 19,147, 71, 53,101, 88,230,230, 94, 76,248,253, 2,103,255,119,171,224,165, +207, 5,255,208, 6,240,127,249, 6,222,218, 44,108, 89, 60,197, 66,107,107, 31,106,105, 97,145,103,101,101,245, 61, 0,159,154, +242, 2, 3, 3,145,147,147,131,156,156, 28,216,218,218,194,218,218, 26,214,214,214,144,203,229,200,207,207,135, 66,161,128,175, +175, 47,154, 55,111,142,157, 59,119,190,148,157,251,154, 22,241,122, 24,166,158,125,152, 10, 19,177, 24, 13,172, 37,158,111, 75, + 96, 83,205, 93,186, 8, 4,130, 3, 54, 54, 54,103, 0, 76, 3, 32, 6, 48,205,198,198,230,140, 64, 32, 24, 0, 96, 25,128,221, +117, 92,141, 21,161,161,161,243, 98, 99, 99,205,239,220,185,131,185,115,231, 98,233,210,165,136,139,139,251, 26,128,177,116,153, + 15,109,109,109,195,184, 92,238,255, 0,188, 11,160,151,179,179,115,215, 26,114, 7,204,153, 51,167,168, 69,139, 22, 49,247,239, +223, 31,240,251,239,191,183,156, 61,123,118,254,147, 39, 79, 16, 19, 19, 3,103,103,103,184,187,187, 67,165, 82, 33, 47, 47, 15, + 3, 6, 12,144, 90, 90, 90,142,160,183,113, 66,200,191,185,200,122,166, 22,121,221, 90,180, 42,253,185,210, 79,212,230,230,230, +161, 50,153,172, 77, 64, 64, 0, 31,192,126, 0,240,231, 97,200,128,182,111,109, 59,242,253,170,128,195,235, 23, 7,244, 12,240, +221,230,207, 67,217, 85,108, 97, 45, 91,182,180,150,201,100,109,133, 66,225,255, 85,177, 18, 12, 0,172,173,173, 33,149, 74, 97, +101,101, 5,107,107,107, 24,141, 70,168, 10,138,160, 54, 0,202, 34, 45,242,243,243,161, 44,253, 89,165,209, 65,173, 86,151,223, +183, 18,157, 38, 78,156,152,181,105,211,166,204,180,180,180, 85, 0,154,141, 29, 59,182,255,198,141, 27,241,219,111,191, 21,189, +235,231,109,187,188,195, 91,159, 55, 73,139, 11,241, 19, 96, 18,128,139, 23, 47, 94, 68,219,182,109,193,225,112,134, 85, 22,104, +102,102,246,205,222,189,123,205,162,163,163,225,237,237, 29, 61,108,216,176,247, 86,173, 90,229, 37, 86,229, 94, 6, 0,125, 78, +122,244,244,233,211, 63, 93,190,124,121, 86, 86, 86,150,174,160,160,192,161, 95,191,126, 72, 74, 74,194,211,167, 79,175, 84, 81, +100,198, 68, 68, 68,176,252,252,124,196,199,199, 35, 34, 34,194,236,211, 79, 63,109,101,224,114,251,167,192, 98,220,216,118, 45, + 91,141,106,253, 22,118, 95,189, 99,114,233, 97,130, 85,203,122,174,214,183,147,211,234, 23,115,240,232,121, 94,109,165, 82,185, +225,243,207, 63, 87,169, 84, 42,164,164,164,224,238,221,187,184,127,255, 62, 18, 19, 19,177,122,245,106, 85,110,110,238,198,154, + 50, 92, 68,252,143,215,204,158,192,225,223,187, 2,220,185, 0, 20, 40,129, 66, 21, 52, 15,100,216,254, 32, 29,155, 15,253,108, +250, 36, 41,201,106,223,190,125, 19, 61, 60, 60,100, 0,124,171,203, 99,172,228, 37,228,114,185,207, 22,161,224,114,185, 74, 0, +233, 98,177, 56,217,194,194, 34,153,203,229,166, 51,198,212, 47,229,147,132, 30, 58,240,120,128,169, 25,184,130,106,167,246,124, +111,216,176, 97,123,147,147,147,123,198,199,199,183,217,184,113,227,231, 34,145, 40,114,227,198,141,159,199,199,199,183, 73, 78, + 78,238, 57,108,216,176,189, 0,198,212,229,241,125,124,124,166,135,132,132, 96,245,234,213,104,222,188, 57,124,125,125, 11, 66, + 67, 67, 55, 0, 88, 12,224,255,124,124,124, 46, 79,159, 62,125,124,102,102,166, 83, 74, 74, 74,243,175,191,254,122,202,134, 13, + 27,222, 78, 77, 77, 21,213, 16,221,190, 71,143, 30, 56,121,242, 36, 0,164, 1,136,207,201,201,209,167,166,166,162, 81,163, 70, +104,213,170, 21, 84, 42, 21, 84, 42, 21,228,114, 57, 60, 61, 61, 97, 52, 26,219,208, 91, 57, 33,132,252,173, 5, 87,229,133,150, + 72, 36,178, 14, 12, 12, 68,131, 6, 13,172, 81,122,181,150,173, 41,127,193,172,137,195,205, 37,178, 83,224, 68,252,138, 97, 29, +154,154,219,154,242, 23,148,222,133,239,233,233, 41, 12, 12, 12,132, 88, 44,118,173,226,193,207,167,167,167, 35, 48, 48, 16, 86, + 86, 86,144, 74,165, 8, 12, 12,132, 78,167, 67,190, 82, 9,181, 1, 40, 40, 54, 34, 63, 63, 31,185, 89, 25, 40, 48, 0,122, 11, + 91, 36, 38, 38,130,199,227, 37, 84,145,233,236,237,237,157, 21, 25, 25,153, 5,224, 34,128, 15,150, 46, 93,138,249,243,231, 99, +201,146, 37,123,205,211, 30,247,216,123,242, 23,219, 61,161, 31,218,251,154,114,134, 3,208, 37, 39, 39,195,202,202, 10, 98,177, +184,210,194, 32, 40, 40,168,133, 88, 44,198,142, 29, 59, 88, 74, 74, 74, 59,148, 92,194,159,192,225,148, 20,123,102, 92,228, 3, +216, 32,147,201,222,249,244,211, 79, 31,118,235,214, 77,208,186,117,107, 44, 91,182, 12, 0,194, 42,203,148,203,229,215,198,140, + 25,163, 61,119,238, 28, 30, 60,120, 32, 62,114,228,200,144,101,203,150, 53,125,242,228,137,240,216,137, 83,189,119, 37, 43,134, +172, 58,115, 73,180,252,244,249,107,118,150,226, 38,245,237,108, 16,241,228,169,137,129,135, 27, 53,189,162,239, 8,120, 19, 59, +137,248, 17, 29,132,220,180, 78, 34,190,236,109, 1,111,130, 82,169,220,119,244,232,209,211,179,103,207, 86,101,102,102,194,194, +194, 2, 57, 57, 57, 88,177, 98,133, 42, 34, 34,226,144, 86,171, 61, 86, 83,174,193,200, 90,184,215,243, 0, 30, 69,150,255, 78, +103,100,184,161, 53, 65,240, 7, 51,225,215,168, 17,180, 90, 45,154, 53,107,198, 89,186,116,169, 88, 42,149,126, 82, 99,209,195, +253,203,238,166,231,112, 56,233,140,177,167, 42,149, 42,197,204,204,236,137,137,137,201,147,220,220,220, 20,198, 88,198,203,168, +179, 24, 23, 31,183,109,230, 3, 8,205,240, 36, 71,149,122, 83,133,220,202, 22,180,176,176,152,176,121,243,102,209, 15, 63,252, + 80, 60,125,250,116,205,148, 41, 83, 4,133,133,133, 14, 83,166, 76, 17, 76,159, 62, 93,243,195, 15, 63, 20,111,222,188, 89, 36, +145, 72, 6, 61,207,138, 20, 23, 23, 35, 50, 50,114, 85, 92, 92,156, 24, 37,195,141,204, 12, 13, 13, 29, 27, 27, 27, 43,218,180, +105, 19, 14, 30, 60,136,131, 7, 15,162,127,255,254,152, 49, 99, 6, 66, 66, 66,170,139, 51, 15, 8, 8, 8,180,181,181,197,133, + 11, 23, 82, 1, 60, 1,208, 66, 34,145, 88,244,239,223, 31, 61,123,246, 68, 81, 81, 17,116, 58, 93,121,161,197,227,241, 96,101, +101,101, 75,239,129,132, 16,242,202,139,172, 63, 21, 91,124, 0, 40,107,170, 11, 14, 14,230, 84,247,143,209,144,151, 9,185,186, + 0,137,249, 5, 72,202, 51,254,233,111, 70,163,177,218, 71, 79, 77, 77, 61,118,245,234,213, 9,129,129,129,252,212,212,146, 51, + 98,129,129,129, 40, 40, 40, 64,234,157,235, 80, 27, 1,177,183, 63,212,106, 53,242,238,223,134, 36,160, 13,108,251,140,194, 87, +155, 54,105,114,114,114,190,171, 44,211,212,212, 84,224,230,230,150,149,144,144,160, 7,144, 43,149, 74,123,120,120,120,224,252, +249,243, 0,176,155, 1,107, 16,113, 14,184,112, 24,172,164, 73, 69,226,233,233,137,204,204, 76,168, 84,170,243,149,101, 94,189, +122, 53,182,184,184,184, 89,191,126,253, 56, 63,254,248,227,126,133, 66,177, 4,192, 93,141, 17,188, 59,201, 25, 80, 27, 32, 2, +208,221,218,218,250,163,144,144,144,174,211,167, 79,199,209,163, 71,113,230,204, 25, 29, 74,250,130, 93,173, 36, 54, 63, 62, 62, +126,203,156, 57,115, 90,115,185,220, 15,206,158, 61,171,247,245,245, 85,232,116, 58, 67, 67, 63, 63,238,146,165,159,153, 76,251, + 96,178, 85, 78, 1,238,245,108,232,220,150,195, 1,238, 61,205,124, 18,167, 66, 78,117,207,105,144, 41, 47,108, 64,187,128,160, + 9,195,250, 74,196,222, 77,160,142,186,238,180,229,192,137,175,204, 34, 98,131, 47,100,102,246, 63,122,244,232,144,243,231,207, + 79,211,106,181, 13,132, 66,225, 35,185, 92,190, 94,165, 82,213, 88,100,241,120,188, 62, 26,103, 55,107,121,110, 46, 68,165, 45, + 81,138, 98, 35,178, 53,122, 60,176,242,197, 8, 55,247,242,211,160,233,233,233,112,114,114,226, 24, 12,134,190,213,101,158, 57, +115, 6,193,193,193,101,133, 39, 56, 28, 14, 56, 28, 78,182,159,159, 95,134, 80, 40,204, 49, 49, 49, 81,172, 89,179,166,168,168, +168, 8,124, 62, 95,100, 48, 24,120, 47,178,183,183, 50,135,131,144,113,190,153,210,175,115,183,230, 77, 26,177,139, 55,239,112, +242, 10,138,182, 87,211, 10,248,181,143,143, 15, 63, 55, 55,247, 24,128, 7,197,197,197,123,246,239,223, 47, 26, 61,122,116,209, +129, 3, 7, 70, 2,240, 90,187,118,237, 16,149, 74, 85,167, 41, 21,226,226,226,190, 94,190,124,249,188, 69,139, 22, 97,231,206, +157,211,227,226,226,230,151,182,116,245, 15, 9, 9,193,154, 53,107,176,115,231, 78,227,131, 7, 15, 78, 24,141,198,184,217,179, +103, 7, 56, 58, 58,102,167,165,165,197, 85, 19,219,178, 87,175, 94,154,203,151, 47,155, 42,149,202, 75, 0, 62,154, 58,117,234, +196,119,222,121, 71, 49,108,216, 48, 73,110,110,174,220,220,220,220,116,235,214,173,214,124, 62, 31,106,181, 26, 28, 14, 7, 74, +165, 82, 75,239,131,132,144,127,171,170,106,145,215, 68,149,255, 27,248,149,109, 96, 65, 65, 65, 70, 82, 82, 82,163,167, 79,159, +234, 1,232, 1, 32, 71,171,255, 98,249,214,195, 63, 12,106,237, 35, 78, 43, 46,198,145,155,209, 5, 57, 90,125, 89,231,119,253, +211,167, 79,149, 79,158, 60,177, 40, 44, 44, 84, 85,241, 88, 87,190,249,230,155,194,115,231,206, 89,196,199,199,195, 96, 48,160, + 69,139, 22,136,137,137, 65,222,131, 72,136, 27,181,128,184, 99, 48,162,101, 55, 17,113, 38, 28,143, 85, 90,253,195,197,203,243, + 85,106,117,136, 78,167, 59, 82, 89,160, 64, 32,200, 5,192, 24, 99, 6, 0, 80, 40, 20,119, 85, 42, 85, 7, 71, 71, 71,220,187, +119, 79,172, 54, 96,198,144, 5, 95,109,100,140, 25, 76, 74,174,230,154, 53,108,216, 48,220,186,117, 11, 0,110, 85,150,169, 80, + 40,166, 79,154, 52,233,220,142, 29, 59,248,241,241,241, 61,127,248,225,135,158, 15, 31, 62,100,156,220, 36,195,229, 2, 1,188, +198,206,120,251, 91, 79,191, 51,193,193,193,112,118,118,198,214,173, 91,177,126,253,250,226, 15, 63,252, 48,118,253,250,245,111, +103,102,102,238,169, 98,251,243,229,114,249, 41, 91, 91,219,105, 77,155, 54, 85,170,213,106,228,228,228, 32, 53, 53, 21, 54,182, +182, 92, 61,184,109,237,173,172,246, 28, 75, 87,138,249,167,174,225,122, 74, 90,181,173, 89,173, 5,188, 49,131,130,222, 10,250, +191, 69, 11, 36,184,124, 4,156, 73, 33, 96, 63,124,142,153,239, 15,177, 40,210,236,233,168,190,147, 56, 90,166, 80,236, 82, 40, + 20, 7,235,184,179,244,106,219,182,237,222,229,203,151,155, 45, 92,189, 28,107, 27,185, 66,159,147,131, 44,141, 1,217, 26, 61, + 20,121, 15,112,239, 94, 52,108,109,237,240,248,241, 99, 20, 21, 21,225,254,253,251,140,199,227, 29,171,169, 69,167, 76,133,211, +133,114,161, 80,152, 35, 16, 8, 50,248,124,126,110,124,124,188,186,168,168, 8, 92, 46, 87,108, 48, 24,204,106,177,174,110,118, +118,118,179, 81, 50,152,232, 81,101,118,246,134, 64, 1,172,192, 71, 39, 79, 59,219,222,139,167,140,182,243,112,113,144,199,199, + 62, 42,254,238,244,239,217, 69,154,170, 47,214, 0, 16,150,155,155, 91,222, 34,121,224,192,129,153, 7, 14, 28,152, 8, 96, 27, + 74,230,221, 10,151,203,229,223, 62,199,193,183,248,208,161, 67,243, 22, 45, 90, 4, 51, 51,179,242,193, 83,205,204,204, 68, 0, +240,211, 79, 63,225,222,189,123,239,160,180,191,150,209,104,220,155,150,150, 86, 83,166,151,191,191,127,252,225,195,135, 77, 1, +184, 76,157, 58,181,205,198,141, 27,241,254,251,239,103, 69, 71, 71,183, 6,144, 0,192,235,131, 15, 62,184,177,115,231, 78,107, +163,209,136,188,188, 60,104,181,218, 4,122, 43, 39,132, 80,177,245, 74, 4, 2,136, 64,201,248, 89,125, 0, 28, 71, 73,183,142, + 42,185,151, 86,103,167, 1,244, 43,251,255, 88, 69,103,120,160,228,138,172, 83, 0,254, 7,192,177,170, 80, 91, 91,219, 79,198, +142, 29, 91,156,146,146,194,210,211,211,217,193,131, 7,217,172, 9, 99, 13,221,189, 93,140,222, 46,142,106,123,123,251, 24,103, + 59,155,237,111,153, 99, 22, 0,183, 90,108,216,216,135, 15, 31, 78, 30, 59,118,236,132,210,199,157,176,119,239, 94,213,217,179, +103, 85, 60, 30, 47, 12, 37, 67, 59,148, 21,148, 99,250,246,237,171,210,104, 52, 42, 63, 63,191, 92,148,116,220,175,202,144, 78, +157, 58,229,157, 60,121,146, 25, 12,134,191,140, 81,148,149,149,197,206,156, 57,195,218,181,107, 39, 7, 48,186,107,215,174,231, +127,255,253,247,243,237,219,183, 63, 84,211, 10,219,217,217, 45,184,115,231,206,173,196,196, 68,217,241,227,199,101,123,246,236, +145,125,240,193, 7,119, 3, 2, 2, 10, 99, 99, 99,141,122,189,158,221,185,125,155,249, 53,108,168, 6,224, 89, 85, 78, 23, 51, +254, 13,197,214,207, 89,209,178,247, 89,209, 0,119, 6,128, 41,191,250,132,101, 76,239,198, 98,166,245,102,157, 69,188,171,207, +179,167,216,216,216,156,190,117,235, 22, 83, 42,149, 44, 42, 42,138,141, 9,238,201,174, 78,236,198, 78,245,244, 97, 59, 59,214, +103, 95,245, 8, 96, 61, 59,118, 96,223,124,243, 13, 59,124,248, 48, 91,176, 96,129,209,206,206, 78,137,106,250,104, 57, 57, 57, +157,221,191,127,191, 12,128,140,199,227,201, 20, 10,133, 76,169, 84, 30, 75, 78, 78,222,236,231,231, 55,175,105,211,166, 35, 27, + 53,106,212,165,115,125,207,121, 93, 45,132, 49,221, 44, 69,143, 26, 74,204,191,194, 95,199,189, 42, 39, 5, 60,189,189,188,148, + 23, 46, 92, 48,106, 52, 26,118,233,210, 37, 99,227,134,190, 69,107,135,246, 58,244,120,235,202, 67, 69, 39,127, 60, 93,240,203, +247,191, 31, 24, 23, 28,217,201,156,251, 99, 27,113,249,112, 28,207,107, 56,128, 35,248,227,170,195,177, 0,126, 65,245, 87, 33, +114, 1,108, 91,182,108, 89,197, 43, 13, 1,128, 27, 16, 16, 32, 99,140,201, 2, 2, 2,100,117, 93, 17,115,115,243,217, 71,143, + 30, 13,245,240,240, 88, 61,108,216,176,173,114,185,252,248,200,145, 35, 35, 81,114, 49, 8, 7, 37,179, 35,244,117,115,115,203, +138,136,136, 96,231,207,159,103,131, 7, 15, 86,154,152,152,140,162,183,113, 66, 8,121, 37, 38, 87,241,181, 90,203, 35, 35, 35, +203,198,208,154, 90, 93,248,252,249,243,101,183,110,221,146,161,100,148,248,106,241,249,252,159, 63,252,240, 67,230,232,232,168, +114,112,112,248, 89,192,227, 77,116, 55, 67, 32,158,239, 82,247, 14,187,118,237,234,255,245,215, 95,247, 1,240, 14, 0,129,171, +171,107,106,122,122,186,234,247,223,127, 87,181,107,215, 78,101,103,103,151,233,239,239,175, 90,187,118,173,170,184,184, 88, 53, +123,246,108, 21,254, 58,222, 87,101, 68, 0,166,153,154,154,254,220,184,113,227,200,197,253,186, 20,175,158, 49,145,141,245,177, + 87, 1,248, 26,192,135, 0,172, 0, 8,134, 12, 25,242,235,253,251,247, 79,251,251,251,111,169, 69,174, 75,211,166, 77,127,219, +187,119,239,173,195,135, 15,203, 62,249,228,147, 91,182,182,182, 41,177,177,177,198,162,162, 34,150,151,151,199,228,114, 57, 59, +126,252,184,193,198,198,102, 83,149, 27, 46,228,165,177, 51,187, 43, 29,194, 33,121,209, 40,214,206,148,251,244,121,246, 20,177, + 88,156,155,147,147,195,210,211,211, 89,124,124, 60, 59,116,232, 16,235,213,182, 21,219,247,193, 32,182,123, 66,127,182,166, 87, + 43,246,142,133, 72,237,100, 33,185,101, 97, 97,145, 89,155,171, 14,157,156,156,206,106, 52,154,242,225, 27,220,220,220,100,126, +126,126,135,253,253,253,191, 58,122,244,232,204,117,235,214,245,239, 92,223,115,222,138,158,109, 11, 11,194, 15, 48,229,254,175, +217,252, 22,190, 69,165,197,124,165, 92,109,109,118, 93, 56,127,222, 88, 86,252,234,245,122,118,228,231,159,217,208,222,221, 35, +243, 79,253,244,191, 75, 33,211,247,206,110,225,123,164,157, 8,195,171, 43,216,202, 63,138, 72, 96, 27,100,201,221,252,174,135, + 77, 90, 7, 41,247,235,214, 22,127,154, 94,106,168,175,175,111, 60, 99, 44,173, 81,163, 70,241, 0,118, 55,106,212,168,226,207, +227,170,136, 45, 31,156, 52, 52, 52,148,149, 30, 31, 92, 0, 75,150, 47, 95, 46, 99,140,201,124,124,124, 46, 3, 64,115, 49,236, + 58, 74,185,255,235,231,229,152,211, 81,202,253, 95,115,113,229, 83, 70,121,154,160, 97, 7,123,243, 75,253,125,156,149,157, 92, +165, 23,119,111,255, 97,245,187,239,190,187, 21,192, 38, 0,159,219,218,218, 94, 26, 62,124,248,189,157, 59,119,222, 91,187,118, +173, 46, 54, 54,150,141, 31, 63, 94, 45, 20, 10, 63,167,247, 65, 66, 8,121,101,202, 70,134,119,174, 75,161,213,119,222,188,121, + 50,198, 88,217, 88, 90,163, 43, 89,166,223,162, 69,139,100,140,177,178,209,225,159, 29,192,172,178, 1,205, 66, 55,111,222,204, +132, 66,225,255,158,115, 99, 42,102, 58, 13, 24, 48,160,181, 66,161,120,219,209,209,241,237,210,150, 43,119, 59, 59,187,248, 61, +123,246,168, 10, 11, 11, 85,140, 49,149, 94,175, 87,221,186,117, 75,213,169, 83, 39, 85,133, 79,253, 53,173,231,159, 44,116,194, +229,155,139, 39,176,133, 78,184,252,204,159, 70,109,219,182,237,100, 66, 66,194, 49, 75, 75,203,185,181,204,116,183,183,183, 95, + 98, 99, 99,115,218,206,206,110,161,141,141, 77,154, 78,167, 99,121,121,121, 44, 38, 38,134,157, 63,127,158, 93,189,122,149,217, +216,216,164, 84,181,158, 93,205,248,215,242, 86, 79, 99,198,109,203,153,118,227, 2, 6,128,201,215,205,103,217,223, 44,101, 55, + 39,245,100,157, 68,188, 43,207,241,124,194,202,202,234,251,159,127,254,217, 24, 23, 23,199,194,194,194,216,241,227,199,217,140, + 25, 51, 88, 67, 23,103, 77,107, 83,110, 70, 7, 33,255,244,243, 12, 88,170,209,104,100, 10,133, 66,166, 82,169,100,141, 27, 55, +150,181,106,213,234,112,235,214,173,191, 58,112,224,192,204, 21, 43, 86,244,239,106, 33,140, 41, 8, 63,192,216, 39,189, 25,155, +214,158, 61,154,216,137,117, 49,227,223,169, 50,211,209, 49,165,108,180,118,181, 90,205, 46, 94,188,200,126,251,237, 55,230,100, +103,167, 8, 50,227, 77,110, 39, 68,199,118,150,176,170,237,122,118,150,114,183, 95,251,230, 11, 67,225,201,157,236,167,177,189, +245,157,172,184,155, 43, 44,183,143, 49,150, 54,120,240,224,199,140,177,180, 67,135, 14, 37, 51,198,210, 6, 13, 26,244,152, 49, +150, 6, 96,111,101,153,207, 12, 78,186,173,180,200,154, 22, 26, 26, 42, 99,140,201, 66, 67, 67,101, 64,201, 32,170, 29,165,220, + 29,215,183,172, 49,106,142,239, 96, 7,198,247, 49,116,148,114,119, 84,186,158, 86,252, 99, 17,219,214, 49,237,233,221,236,231, + 25, 35, 13,237,157, 44, 47,248,250,250,174,153, 57,115,230,225,171, 87,175,222, 53, 24, 12,247,226,227,227,239,109,218,180,233, + 94,155, 54,109, 46,219,218,218, 70,154,154,154,126, 88,211,107,244,146, 80, 38,101, 82, 38,101,146,103, 27,152,170,249,219,177, + 85,171, 86,137, 25, 99,179,135, 12, 25,130,149, 43, 87, 14,109,218,180,233,112, 87, 87, 87,123, 0, 72, 77, 77, 45,136,138,138, + 82, 12, 25, 50, 4, 75,150, 44,193,234,213,171,191, 66, 73, 95,150,191, 83,250,145, 35, 71,220,166, 79,159,158,185, 98,197, 10, +227,248,241,227, 27, 1,136,202,206,206,110, 56,114,228,200,105,124, 62,127,136,167,167,167,127, 90, 90, 90, 86, 97, 97,225,110, + 0, 91, 80,195, 57,211,170, 8,185, 48,180,172,231,140,211, 92, 24, 42,252,186,247,146, 37, 75,134, 13, 26, 52, 72,183,110,221, + 58,189, 66,161, 56, 90,203,184,228,172,172,172,207,202,126,176,177,177,113,186,115,231,206,135, 14, 14, 14,220,248,248,120,104, + 52, 26,196,197,197, 25, 81,114,106,170, 82, 42, 61,219,240,237,161,179,126,179, 71, 5, 91, 22, 60,184, 13, 19, 30, 15,197, 2, + 83,164, 95, 59,141,109, 23, 31, 40,212, 58,108,124,158,237,148,203,229, 95,206,152, 49, 99,228,220,185,115, 69,158,158,158,156, + 43, 87,174, 96,255,254,253,154,204,204,204, 94, 0, 46,252, 49,244, 83,221, 24,141, 70,152,154,154, 2, 0,230,207,159, 15, 46, +151, 43,200,204,204, 52,229,112, 56, 66, 14,135, 99,206,225,112,120,197, 9,247, 96, 84,228, 33, 35, 79,142,228, 12,121,181,121, + 6,163,113,255,245,235,215,103,189,245,214, 91,220,155, 55,111, 34, 43, 43, 11,113,113,113,204,192,216,222,139,133,134,146, 78, +137,154,218,175,159,185,141,237,128,230,214, 66,174,233,246, 37, 8,210,114,121,223, 25, 49, 24, 37, 99,105, 1,192, 54, 14,135, + 99, 2, 32,167,113,227,198,157,239,223,191,111,214,184,113,227,194, 7, 15, 30,156,228,112, 56,174, 0,118, 84,150,105,102,102, +150, 13, 32,251,208,161, 67, 0, 48, 9, 37, 79, 94,139,144,144,144,180,139, 23, 47, 34, 52, 52, 52, 3,192,102, 0,144, 88,219, +246,243,151,154,112, 76,127, 12, 69, 27, 13,184, 27,141,172,210, 86, 87,137,131, 99,151,166, 98, 46, 4, 63,124,138,183,157,252, +184,166,122, 93,179,165, 75,151, 94, 84,169, 84,154,125,251,246,105,199,141, 27,199,139,141,141,189, 1,224, 18,128, 67, 40,237, + 99, 73, 8, 33,228,149,122,182, 5,171,198, 62, 90,207, 86,173, 43, 1,124,251,240,225,195,242, 73,165, 31, 62,124, 40, 3,240, + 29, 74, 70,131,239, 91,135,138,119,113,105,139,214,150,231,220,152,103, 51, 69,129,129,129,102,247,239,223, 55, 65,229,147, 56, +114,158, 35,243, 47, 42,155,235,208,215,215,119,125,113,113,241,225,239,190,251,238, 0,143,199, 27,249, 2,213,190,167,143,143, + 79,222,158, 61,123,140, 97, 97, 97,108,241,226,197, 6,103,103,231, 60,252,181,143,214,159, 50,131, 76,121, 7,231, 52,114, 85, +220, 26,221,158, 61,154,217,143, 93, 26,213,137, 77,118,149, 40,130, 68,188,253, 47,248,169,196, 71, 42,149,110, 51, 51, 51, 83, + 88, 90, 90,158, 5,208,246, 69, 94, 35, 91, 91,219,157, 78, 78, 78,103, 43,222, 28, 29, 29, 15,219,219,219,127,109,103,103,183, +216,202,202,106,138,151,200,116,221,204,134, 46, 69,145, 3, 26,179,240,118,246,108,148,157,233,179,167, 14,159, 93, 79,103, 47, + 47,175,156, 93,187,118, 25,143, 29, 59,198, 22, 44, 88, 96,172, 87,175,158, 2,213,244,107,171,182, 69,203,138,183,255,224,160, +214,198,140, 62,174,108,101, 35, 11, 99,103,107, 94, 85, 87, 40,142, 42, 45,128,199,214,148,233,237,237,253, 29, 99,108,251,178, +101,203,182,227,143,185, 64,187, 47, 93,186, 52,132, 49, 22,178,116,233,210, 16, 0, 61, 1, 32, 72,202,221,181,187,127, 75, 67, +234,187, 46,236,139, 70, 18, 67,144,148,187,171,210,150, 76, 27,254,145, 95, 38,246, 49,166, 77,108,199,150,248,136, 13,173,109, +132,191,154,154,154,206, 68, 73,139,115, 43, 0,166,244,169,153, 50, 41,147, 50,169, 69,235, 95, 87,120,213,138,147,141,141,205, +182, 6, 13, 26, 28,240,244,244, 60, 32,145, 72,190, 66, 73,167,249,186,190, 16, 94,203,151, 47, 87, 72,165,210,230, 47,241,197, +117, 0,224,138,191, 78,156,251,210,118,152,207,156, 49, 61,118,238,208, 59,159, 57, 99,122,133, 95,183,106,212,168,209, 23, 40, + 25,205,251, 69,119, 66, 79, 27, 27,155, 77, 54, 54, 54, 41,165,125,179, 60,107,147,217,146,199, 27,217, 89,196,187,210,214,148, +155,222, 89,196,255,253,109, 30,111,196,107,122, 0, 86,119,177, 69, 85,153,110,118,118,118,235,108,108,108, 82,237,236,236, 54, +213,177,200,250, 83,102,115, 51, 56,119,177,226, 29,105,107,193, 81,119,145,242, 14,181, 52,175,250,162,142, 58,108,123, 96,104, +104,232,251,140,177,247, 93, 92, 92,134, 84, 40,252,253,151, 44, 89, 18,204, 24, 11, 46, 27, 1,190,149, 57, 28, 58, 89,241,246, +180,179,228,200, 59, 89,241,246,180, 50,135, 67, 85,235,217,217,138,183,191,157, 37, 71, 30,100,201,221,227, 33, 68, 61,122, 51, +167, 76,202,164, 76, 42,180,222,140, 66,139,118, 24,202,164, 76,202,164, 76,202,164, 76,202,164, 66,171,242,194,170,226,173,252, + 12, 27,159,158, 27, 66, 8, 33,132,144, 23, 82,229,128,165,156,106,170,210,186,116,108,127,158,202, 54,156, 50, 41,147, 50, 41, +147, 50, 41,147, 50,255,115,153, 53,101,255,221, 23,214, 19,174,245,180, 0, 0, 32, 0, 73, 68, 65, 84,189,214,168, 89,149, 50, + 41,147, 50, 41,147, 50, 41,147, 50,255,179,184,244, 20, 16, 66, 8, 33,132,188,144,192,210,175,207, 14, 92, 90,121, 31, 45,126, +171,101, 25,122,189,222, 1, 0,248,124,126,102,241,141,197,206,213,165, 11,128,174,250,146,233,119,192, 7, 38,233,129,179,149, +100,158,213,235,245,214,165,153,121,197, 55, 22,247,172, 54,179,213,178,211, 21,151,215,223, 88,220,253,217,101, 24,192, 19,180, + 90,150,250,204,186,186,212,246, 89,225,224, 79, 99, 98,189,178,245,124, 93, 50,255,203, 4,239, 44,203, 40, 46, 46,217,143, 4, + 2,126,166,238,122,245,251,145,201, 59,203, 82, 43, 46, 95,124,125,177, 99,117,153,230,102,194, 28,111, 87,251,175,170,203,140, + 79,205,158,173, 46, 40,178,173, 46,179,174,199,166,187,179,115, 87, 67,233,177,201, 3, 38,165,164,165,157,253,151,237, 75, 45, + 1, 44, 6, 96, 89,225,119,145, 0, 62,162,189,146, 16,242,154, 21, 90, 17, 40,153,231,240,251,210, 98,235,251, 42, 11, 45,189, + 94,239, 32,251, 57, 4,106, 13,208,117,204, 50, 7,175, 1, 91,254, 50, 81,178,190, 40,207, 84, 30,189,207,159, 87,172,176,182, +231,235, 44, 83, 83, 83, 57, 0,192,225,112,254, 7,192,163,146, 76,107,217,207, 33, 40,208, 2, 65,195,151, 90,123, 0,150, 89, + 38, 38, 31,155,137,197,157, 11, 11, 11,155, 2,128,153,153, 89,116,161, 90,125,206, 94,167, 91,251,236,242, 85,109, 89,197,117, +237, 50,122,153, 67,163, 1, 91,102, 24,140, 70,211,167, 55,191, 11, 42,202,142,229, 11,244,154,205, 11,129,147, 33,149, 20, 85, + 85,228,253,241,184,239, 45,176, 21, 0, 93, 76, 69,162,230, 86,214,214, 29,140,140, 53, 54, 26,141, 28,131, 94,127, 79,145,159, +127,201,168,215,223,209,107,213,182,178,163, 95, 24,171, 91,207,103,183,229, 61,128,255, 51, 48, 68, 44,145,116,230, 9, 4,109, + 1,192, 80, 92,124, 69,173, 82,157, 27, 8, 28,172,205,182,215,246,249,121,222,229,255,107,138,139,245, 14, 9,167, 67,160, 41, + 6, 2, 7,127,225, 16, 48,242,199, 61, 0,160,205,188,227,168,138, 61,250, 14, 0,136,189,131,175, 11,157, 2, 51, 0,128,255, + 36,205, 33, 38,108, 17, 52,197, 64,227,224,165, 14, 53,101,142, 91,178,223,118,238,228, 65, 66, 0, 56,115,232,235,134,191, 29, +254,182, 55, 0,116, 25, 52,245,100,143,193,211, 99, 0, 96,245,247,135,109,247,126, 49,180,218,204,218, 29,155,249, 38,249,177, + 97, 62, 90, 69,154,149,187,152,239, 20, 27, 27,203, 5, 0, 23, 23,151, 90, 29,155,110,128, 52, 13,152,198,229,241, 58,120,251, +248, 4, 2, 96,241,143, 30, 69, 24,244,250,203,206,192,230,151,188, 47,205, 96,236,207,131,179,114, 56, 28,218, 33, 9, 33,175, +155,227,165,197,213,241,191,124,152,173,234, 30,106, 13,112, 33, 14,232,216, 58, 0,147, 71,190, 43,169,248,183,131, 91,150,122, +196,222,252,165,209, 15, 63,174,229, 6, 4, 4, 32, 33, 33,161, 86,107, 81,160, 5,206,199, 2,144,223,183,200, 19,139, 31,173, + 91,179,198,178,123,247,238,124, 23, 23, 23,112, 56, 28,164,167,167,183, 14, 15, 15,111, 57,107,214,172, 15, 32,191,159, 87,160, +133,242,124,108,205,185,101,235,218,180, 97, 61, 44,158, 62, 84, 10, 0, 11,199,108,110,121,243, 97,134,205,163, 71,143,186,206, +155, 55, 47,135,119,238,220,183,118,192,246, 12, 32,185, 54,235,185,243,216,117,145, 52,237, 39,175, 81,211,167, 31,242,241,241, +145,120,122,122,114, 44, 44, 44,192,227,241,144,151,151,231, 17, 21, 21,213,251,198,141, 27,234,240, 11,255, 51,189,117,163, 95, +124,166,232,157,162, 90,109,123, 97,170,232,140,133, 69,244,232,129, 3,221,134, 14, 29, 42,242,246,246, 6, 0, 60,122,244,200, +247,224,193,131,195, 15, 29, 58,180, 4,133,169,250, 2, 45,138,106,218,246,242, 76, 0, 34,160,173,149,131,195, 40,158, 64,208, + 84,175,215,187,150,182, 54, 60, 53, 20, 23, 71,203, 51, 51,119, 63,187, 60,249, 43, 77, 49,112, 63, 13,232,214, 33, 16,163, 7, +117, 19, 3,192,188, 97,203, 91, 63,121, 28,103,162,213,106,209,208,175,113,187,207,191,248,234, 52,184, 92,236, 58, 28, 94,190, +124,109, 50, 35,239, 39, 32,228,243,117, 72,189,123,176,181, 33, 63,174,179, 82,145,207, 3, 0, 75,169,116,208,193,125, 63,157, +115,241, 31,114, 45, 46, 91, 87,171,204,234,142,205, 83,251, 54, 57,167, 68,157,107,242,205,153,109, 2, 15, 15, 15,220,189,123, +183,110,199,102,254, 67, 11,163,179,243,189,181,159,124,226, 20, 20, 20, 4,137, 68, 2, 62,159, 15,189, 94,223,237,242,229,203, +221, 66, 66, 66,166, 34,255,161,186,182,199,102, 45,172,229,112, 56,157,199, 77,158,225,252,110,255, 33, 24,212,171, 29,237,136, +132,144,215, 77, 89,235, 85,197, 43, 15,191,175,182,208,226,243,249,153,221,199,174,112,232,240, 78, 51,220,188, 19,147,159,152, +148,166, 42,251, 91,110,244,193,134,253,219,185, 54,185,120,241, 2, 52, 26, 13,174, 92,185,130, 59,119,238,224,241,227,199,152, + 50,101,138,166,244,212, 97,101,153,121, 65,195,151, 90, 35, 63, 86,226,107,250,176,126,248,131, 7,188,162,162, 34, 92,188,120, + 17,121,121,121, 48, 53, 53,133,155,155, 27,122,244,232,193,127,240,224,129, 77,215,238,189,164, 65,189, 70, 36, 64,234,171,226, +243,249,121, 85,205, 35,194,231,243, 51,187,142, 89,230,208,196,183, 30, 30, 37,166,230, 47,254,226, 7,149,209,200,248,241,143, +159,232, 46, 92,184,128,192,192, 64,156, 61,123,214, 54, 55, 55,247,211,205,155, 55, 47, 22,172,250,102, 67,177, 54,103, 14,170, +206,203, 11, 26,190,212,218, 54,243,128,231,111,167,142,152, 68, 71, 71,155,124,247,221,119,200,201,201,129,169,169, 41,172,172, +172,224,228,228,132,134, 13, 27,114, 22, 46, 92, 40, 9, 14,142,198,255, 77, 26,226,169,243,154,248,176,170,245, 44,223,118,213, + 19,115, 59,197, 25,239,195,199,143,115,219,183,111,255,167,143,237, 13, 26, 52, 64,207,158, 61, 69,163, 70,141,242, 30, 58,124, +164, 49,168,207,184, 71,144,120, 22,212,152,169, 78, 54,179, 45,184,234,210,109,248,240,163, 75,151, 46,181,114,114,114,130, 88, + 44, 6, 0,228,231,231,187, 37, 38, 38,182, 94,178,100,201,224,235,145,251,248, 65,193,201,169, 16,187, 23, 86,247,124,254, 87, + 9, 4,252,204,178, 86, 36, 11,177, 89, 94,114, 74,134, 26, 0,180, 90, 45,180, 90, 45, 52, 26, 13, 62,156, 58,133, 55,105,112, + 43, 31,207, 14, 51,110, 63,126,154,145,219, 56,252,154, 77,217,125,139,107,200,228, 23, 60,150,203,147,126,157, 20,242,201, 39, + 78,142,142,127,156, 17,220,181,115, 39, 47, 55, 55,183, 91, 72, 72, 72, 19,102,222, 73,222, 56,120,169, 85,117,153,213, 29,155, +242,152,227,245, 63,159,222,179,249,150, 47,194, 96, 48, 24,112,245,234, 85, 92,188,120, 17, 95,125,245, 21, 59,121,242,100,190, +165, 88, 60, 9,213, 30,155, 15, 45,218, 59,167,123,173, 90,117,136, 35, 20, 10,241,203, 47,191,224,193,131, 7,224,114,185, 8, + 8, 8,192,232,209,163,209,173, 91, 55,167,201,147,167,176,160, 94,195,226, 33,245, 83,190,224,190,196, 5, 48, 99, 65,200, 42, +231, 49, 19,167, 97,245,231, 11,169,208, 34,132,188,206,173, 89, 85, 14,241,128,176,176, 48, 86,122,235, 8, 0, 12,224, 54, 24, +176,101,239,129, 91,198,227, 13, 6,108,217,203, 0, 46, 3,184,150, 64,189,183,222,122,171, 88, 46,151,179, 27, 55,110,176, 15, + 63,252, 80,189, 97,195,134,115,199,143, 31, 63,168,215,233,182,186, 56, 59,127,201,170,232, 96,207, 0,174, 39, 32, 53, 55, 55, +207, 74, 74, 74, 98, 39, 78,156, 96,161,161,161,108,247,238,221,236,228,201,147, 44, 60, 60,156,157, 60,121,146,237,221,187,151, + 69, 70, 70,178,152,152, 24, 38, 22,139,179, 60, 1,105, 53,153, 60, 6,240, 26, 14,248,110,206,161,155,197, 75,253, 6,108,153, +197, 0,158, 53,208,232,173,183,222, 50, 28, 60,120,144,237,218,181,139,253,248,227,143, 44, 50, 50,146,101,103,103, 51,190, 80, +156, 85,118,191,170,214,147, 1, 92, 87, 87,215, 44,185, 92,206,220,221,221,153,169,169, 41,115,116,116,100, 13, 27, 54,100,173, + 91,183,102,189,123,247,102, 35, 71,142,100,159,126,250, 41,147,203,229, 76, 36, 18,101,148,221,175,170,204, 64,192, 76, 44, 22, + 39,201,100, 50, 86,149,194,194, 66,150,157,157,205, 78,159, 62,205,196, 98,113, 82, 32, 96, 86, 93,166, 25,208,194,223,223, 63, + 43, 59, 59,155,233,116, 58,150,148,148,196,162,162,162,216,131, 7, 15, 88, 82, 82, 18, 43, 44, 44, 44,207,142,137,137, 97, 94, + 94, 94, 89,102, 64, 11, 70, 23, 65, 84,185, 47, 61,123,243,112,116,236,237,228,228, 84,120,232,208, 33,246,244,233, 83,182, 99, +199, 14,198, 5,150, 63,187, 92,117,153,166, 64,143,246,237,219, 27,174, 94,189,202,110,223,190,205,230,207,159,207,122,246,236, +201,122,245,234,197, 66, 66, 66, 88, 74, 74, 10, 75, 73, 73, 97,189,123,247, 54,152, 2, 61,106,218, 63, 43, 59, 54,165,128, 71, +112,112,112,161, 78,167, 99,241,241,241,172,105,211,166, 41, 60, 96,148, 24,104,210, 17, 16,214,180,127,186, 2,214,206,206,206, +105, 87,175, 94,101,135, 15, 31,102,158,158,158, 89, 60, 96,156, 37,208,192, 18,104,192, 3,198, 53,104,208, 32,235,234,213,171, + 44, 39, 39,135,121,120,120,164,185, 2,214, 47,176, 47,113, 1,108, 91, 16,178,138, 61, 76, 81,179, 5, 33,171, 24,128, 36,198, + 24, 67, 37,125, 60, 9, 33,111,190,103,107,145, 55, 69,249,155,100,112,112, 48, 7,192,249,234, 22, 46,228,241, 86,172, 94,189, +154, 95, 84, 84,132, 31,126,248, 65,249,222,224,193, 7, 58,118,232, 16, 95,223,211, 83,206,225,114,107,156,109, 56, 75, 40,156, +185,122,245,106, 43,173, 86,139, 91,183,110,161,101,203,150,112,114,114,130, 68, 34,129, 68, 34,129,131,131, 3,252,252,252,144, +153,153, 9, 11, 11, 11,204,157, 59, 87,154, 37, 20,206,172, 41,215,104,100,124, 0, 48, 24,141,166, 38,192,100,175,183,223,190, +181,100,201, 18,174,173,173, 45,108,108,108, 32,145, 72,240,224,193, 3,104,181, 90,152,155,153,215,106,144, 86, 46,151,203,149, + 72, 36,248,237,183,223, 48, 99,198, 12,180,109,219, 22, 86, 86, 86,176,176,176, 64,211,166, 77,209,163, 71, 15, 76,154, 52, 9, +241,241,241,224,212,162, 83,201, 61, 62,127,218,164, 73,147, 28, 2, 3, 3, 43,253,123, 81, 81, 17,228,114, 57,178,178,178,224, +230,230,134, 33, 67,134, 56,220,227,243,167, 85,149,103, 11, 56,185,249,250, 30,189,113,227,134,157, 88, 44,198,174, 93,187,112, +228,200, 17,156, 58,117, 10, 39, 78,156, 64, 88, 88, 24,126,249,229, 23,100,101,101, 1, 0,124,125,125,177,127,255,126, 59,137, +131, 67,152, 45,224, 68,135,116,237, 60,201,200, 56,211, 52, 61,221,110,212,200,145,151, 84, 42, 21, 70,141, 26,133, 21, 43, 87, + 46, 20, 0,179,106,115,127, 63, 64,106,227,236,188,125,213,170, 85,220,244,244,116, 12, 28, 56, 48,123,237,202,149, 19, 34, 78, +159,246,150,157, 58,229,189, 98,233,210, 9, 29, 59,118,204, 78, 73, 73,193,206,157, 59,185,142, 30, 30,219,253, 0,105, 93,215, + 83, 9,204, 88,191,126,189,168,168,168, 8,221,187,119,143, 55, 70, 71,251,233,129,159, 84,192,131,243,128,174,166,251,167, 1, +211,230,206,157,235, 36, 20, 10,241,241,199, 31,103, 23, 60,121,210, 76, 15,252,152, 15, 36,230, 3,137,122,224, 71,101, 66, 66, +179, 49, 99,198,100, 11,133, 66,172, 91,183,206, 41,237,143, 73,183,107,171, 37,128,163, 0, 46, 0, 72, 29, 55,121,198,184,192, + 86,109,176,115,235,102,124,177,116,222,118, 0,239,113, 56,156,221, 0,230,208,158, 71,200,127, 83,109,106,145,127,169, 42,167, +220,225, 87,172, 36, 1,116,170, 46,197,218,214,182,101,179,102,205,112,241,226, 69,248,251,251,223,176,178,178,210,155, 8,133, + 16, 8, 4, 96,198, 26,235, 44,152,137,197, 93,187,117,235,198,191,118,237, 26,188,188,188, 96,102,102, 6,129, 64,240,167,155, +137,137, 9,156,157,157,161, 80, 40,208,181,107, 87,193,198,141, 27,187, 66,163,249,188,198,127,136,177, 81,146,172,107,171, 70, +254,111,199,246, 6, 65, 65, 65,200,207, 87,192,104, 52,194,220,220, 28, 90,173, 22,124, 62,191,228, 20, 80, 49, 83,212,230, 25, + 51, 24, 12, 6, 30,143, 7, 47, 47, 47,172, 88,177, 2, 69, 69, 69, 48, 49, 49, 1, 0, 40, 20, 10,200,229,114, 68, 69, 69, 33, + 49, 49, 17,165,159,194,171,101, 33,149,190, 59,116,232,208, 74, 39,252,213,104, 52,200,207,207, 71,126,126, 62,228,114, 57,138, +138,138,208,166, 77, 27,211,227, 97, 97,239, 34, 39,103,109,165,247, 17,137, 6,239,220,185,211,193,212,212, 20,133,133,133, 80, + 42,149, 72, 78, 78,198,147, 39, 79,138, 50, 51, 51,245, 22, 22, 22, 92, 79, 79, 79,174, 80, 40, 20, 14, 24, 48,128,163, 80, 40, +192,225,112, 16, 28, 28,108,187,103,215,174,161,208,106,191,162, 67,186,118,206, 0,154, 22, 90,109,223,119, 90,181,250,237,198, +205,155,129, 51,103,206, 68,100,100,228, 42,243,125,251, 46, 20, 0,119,170,187,111, 60, 48,237,203, 10, 5, 12,123,242,196, 95, + 7,100, 85, 88, 36,209, 51, 33,225,212,152, 49, 99,238, 70, 70, 70,218,173, 91,183,206,233,189,129, 3,167, 1, 88, 94,151,117, +180,144, 74,223,118,118,118,198,201,147, 39,145,244,248,241, 60, 61, 80, 88,167, 79, 92, 60, 94,251,160,160, 32,252,242,203, 47, + 72,121,242,100,158,254,207,235, 88,242, 65, 9,200,226,199,199,207,219,190,125,251,182,241,227,199,131,199,231,183,135,190, 78, + 39, 14,255,210,241,125,252,148,153,216,254,253,198,237, 0, 38, 2, 48, 2,184, 65,123, 28, 33,255,237, 86,173,154,106,145,215, +168,216,250,190,206, 45, 90, 14, 14, 14,174, 18,137, 4,169,169,169,104,220,168, 81,166, 80, 40,132,169, 64, 0,145,169,105,173, +214,160,160,160,192,223,197,197, 5,249,249,249,176,179,179,131,137,137, 73,249,205,212,212,180,252,123, 11, 11, 11,112,185, 92, +120,120,120,160,160,160,192,191,198,220,140, 40,135,125, 27,167,126,120,245,194,201, 6, 3, 7, 14,130,181,181, 13,220,221,221, +224,224,224, 0, 51, 51, 51,184,187,187,195,219,219,155,173, 93,187, 22,230, 14, 1,181,122, 35,175, 88, 60,241,249,124, 24, 12, + 6,100,100,100,224,225,195,135,136,140,140,196,213,171, 87,113,251,246,109, 40,149, 74,212,162,206, 66, 65, 97, 97,115, 62,159, + 95,105,145, 37,151,203, 33,151,203,203, 11,173,172,172, 44, 36, 38, 38, 66,165, 86,191, 85, 77,209, 59,168, 89,179,102, 60, 0, + 48, 51, 51,195, 91,111,189,133, 45, 91,182,232,143, 29, 57, 50,172,201,213,171, 54,238,167, 79, 91,253,239,187,239,134, 13, 25, + 50,196,112,237,218, 53, 40, 20, 10,220,191,127, 31,246,246,246,124, 83,145,104, 40, 29,206,117, 35, 3,212,118, 74,101,175,182, +109,219, 38,228,231,231, 99,205,154, 53, 92,129,133,197,247, 75,171, 56,197, 87,142,199,107, 23, 20, 20,132,163, 71,143, 34,245, +201,147,249, 79, 42, 41, 96,158, 0, 89, 73,241,241,243,183,111,223,142, 30, 61,122,128,195,231,215,185,163, 82,235,214,173,155, + 25,141, 70,220,189,123, 23, 86,192,245,186,222,223,219,199, 39,176,172,229, 87, 12, 92,170,106, 57, 49,112, 41, 34, 34, 2,102, +102,102,104,220,164, 73,139, 58, 62,204, 90, 14,135,147, 54,126,202, 76, 28, 62,245, 59, 0, 96,251,247, 27, 51, 42, 20, 89,132, + 16,106,209,122, 93, 91,180,202, 10,171,138, 55,252,169,208,170,101,241, 1, 0, 16, 8, 4, 48, 21, 10, 97,106,106, 90, 82, 32, + 9,133,181,206,224,112, 56, 16,137, 68,229,133, 85,197, 2,171,226,247,230,230,230,181, 42, 96, 0, 32, 47,238, 84,135,137, 19, +198,155, 10,133, 66,104,181, 26, 48,198, 32, 20,138, 96,101,101, 5, 47, 47, 47, 40, 20, 10,180,109,215, 81,147, 44, 55, 9,179, +109, 60, 32,242,121,158, 61,189, 94, 15,181, 90,141,188,188, 60,228,230,230, 66,161, 80,160,176,176,176,214,151,162, 27,141, 70, + 94,114,114, 50,126,250,233, 39,228,228,228, 0, 40,233,104, 93, 86, 92,149,125, 77, 72, 72,192,174, 93,187,240,248,241,227, 58, +189, 62, 29, 58,116, 64, 88, 88, 24,175, 83,215,174, 91,207,122,122,166,158,245,244, 76,237,212,181,235,214,163, 71,143,242, 92, + 93, 93,145,152,152,136, 91,183,110, 33, 47, 47, 15,140, 49,186,126,254, 57, 60, 2,242, 10,114,115,199, 47, 92,184,144, 73, 36, + 18,172,249,242,203,230,203,129, 17,181, 45, 96,164,213, 20, 48,210, 23, 43, 96,192, 24,131,209,104,132,193, 96,120,174,109,227, +112, 56, 28,129, 64, 80,215,161, 21,234,178,112,121,199,247,185,159,174,192,137, 95, 14,150,253, 62,150,138, 44, 66,200, 27,160, +202,142,240,252, 10, 21,100,249,215,170,100,100,100, 60, 85,171,213, 13, 60, 61, 61,145,146,146,226,224,225,225,241,196, 84, 32, +128,137,169, 41, 56,220,154,107, 2,115,115,243,187,169,169,169,237, 92, 93, 93,161,215,235,203,139,170,103, 79, 29,150,181,210, +220,190,125, 27,230,230,230,119, 81, 84,237,200, 9, 48,104,243,234,181,104,209,162,188,101,200,202,202, 10, 86, 86, 82, 8,133, + 34, 44, 90,180,200,184,110,237,218,205, 30, 93,150,230,191, 63,107, 33, 91,184,124,235, 75,125,102,107,251,143,201,220,220,252, +174,187,187,123, 27,169, 84,138,195,135, 15, 35, 49, 49, 17,121,121,121, 40, 40, 40,128, 70,163, 65, 65, 65, 1,180, 90, 45, 68, + 34, 17,154, 52,105, 2, 75, 75, 75,132,135,135,223,133, 70, 83,121,113,153,147,115,248,238,221,187,109, 90,181,106, 85,222,162, +210,185,115,103, 78,231,206,157,237,202, 91,209, 10, 10,144,157,157,141, 27, 55,110, 32, 60, 60, 28, 28, 14, 7,177,177,177, 6, + 77, 97,225, 94, 58, 38,158, 79, 17,112,133,183,125,251,182, 15, 62,248, 96, 66,187,118,237, 96, 0,122, 3,216,245, 15, 22, 48, + 0,128,171, 87,175, 70, 25, 12,134,118, 13, 27, 54,132, 28,120, 7,192, 47,117, 42, 34,227,226, 34,244,122,125,215,230,205,155, +227,240,129, 3, 29, 0, 36, 86,182,156, 26,232, 16, 24, 24,136,194,194, 66,220,191,119, 79, 86,135, 34,107,235,130,144, 85,227, +198, 76,156,134,157, 91, 55, 99,251,247, 27,147,183,109,217,224,142, 90,244, 31, 35,132,252,167, 90,179,106,172, 69,254,165, 38, + 87, 85,124,241,235,146,146,159,151, 39,139,136,136,104,208,162, 69, 11,108,221,186,181, 85,219, 54,109,158,154,152,154,234, 77, + 77, 76,192,173,197, 63,146, 66,181,250,215, 95,127,253,245,157, 1, 3, 6,240,175, 93,187, 6, 39, 39,167,242, 66,171,236, 43, +159,207, 7, 99, 12,230,230,230,248,249,231,159,117,133,106,245,175, 53,182, 22, 25,140, 6,110,105,161,199, 24,131, 92, 46,135, +137,137, 9,190,250,106, 29, 54,173, 93, 59,210, 0, 28,244, 21,219,127, 2, 64,244,143,253,131, 46, 40,248,237,196,137, 19, 45, +151, 44, 89, 34,112,115,115,131, 92, 46, 71, 94, 94, 30,114,114,114,160, 80, 40,160, 80, 40,144,151,151, 7,185, 92, 14,145, 72, +132,200,200,200,226,162,130,130,223,170,202, 19, 22, 21, 29, 26, 59,118,236,220,136,136, 8,103, 62,159,143,226,226, 98, 24,141, + 70, 24,141, 70,232,116, 58,196,197,197, 33, 58, 58, 26, 15, 30, 60, 64,110,110, 46, 4, 2, 1,120, 60, 30,110,223,190,157, 39, + 46, 46, 62,160,165, 99,250,185, 9,128,195,151, 47, 95,158, 48,122,244,104,184,184,185,117, 68, 74, 74,173, 10,152, 35,213, 20, + 48,249,207, 87,192,252, 81, 0, 41,149, 55, 19, 18, 18,218,117,234,212, 9,206,110,110,171,154,164,164,156,189, 87,135,126, 90, + 6,189,254,210,229,203,151,187,142, 25, 51, 6, 91,183,110, 93,101,159,144,112, 42,235,153,211,156,246,128,125,125,111,239, 85, +227,198,141,195,153, 51,103, 96,208,235, 47, 85, 19, 89,113,196,247,122,227, 38,207,112,127,166,227,251, 22, 14,135, 51, 29,192, + 26,218,163, 8, 33,111,114,139, 86,157, 78, 29,154, 25, 12, 11,230,204,153, 83,204,229,114, 49,104,208, 32,139, 95,142, 30, 29, +114,251,206, 29,175,204,204, 76, 43,131,193, 80, 99,150,189, 70,179, 97,206,156, 57,114,173, 86, 11, 63, 63, 63,228,230,230,194, + 96, 48,128,207,231,131,207,231,131,195,225,128,203,229, 66, 34,145, 32, 34, 34, 2,219,182,109, 83,216,107, 52, 27,106,252, 39, + 97, 48,220,221,181,107, 23,120, 60, 30, 19,137, 68,224,112, 56,224,243,249, 88,183,110, 93,230, 38,224, 48, 0,240,184, 92, 45, + 0,112,185,156,218,246,222,173,241,188,165,169,169, 41,140, 37, 23, 1,212,184,172,181, 70,179,126,245,234,213,202,251,247,239, + 67,173, 86,151,183,190,169, 84,170,242,206,245,114,185, 28, 28, 14, 7,106,181, 26, 71,143, 30, 85, 90,107, 52,235,171,202,203, + 1,210, 83, 98, 99,251,181,106,213, 42, 39, 33, 33, 1,249,249,249,184,123,247, 46,194,195,195,177,127,255,126,156, 57,115, 6, +113,113,113,208,235,245,112,117,117, 5, 99, 12, 71,142, 28,201,215, 43,149,189,115,128,116, 58, 38,170, 86,207,201,169,171,163, +131, 67,146,189,157, 93, 74, 61, 39,167,174,207,254, 93, 10,196,196,196,196, 64,175,215,195,203,203,203,166,186,126, 90, 76,175, +191,124,249,242,101,140, 25, 51, 6,238, 13, 26,172,244, 4,236,159, 93,198, 19,176,247,244,246, 94, 89, 86,192, 48,189,254,114, + 93,215,217, 2,216,248,201, 39,159, 20,154,152,152, 96,223,190,125, 94,197, 62, 62, 15,248,192, 8, 9,208,168, 19, 96, 82,211, +253,157,129,205,159,126,250,105, 58,135,195,193,238,221,187,237,164,222,222, 81,124, 96,172, 20,168, 39, 5,234,241,129,177, 82, +111,239,168,125,251,246,217,233,245,122,204,154, 53, 43,221, 25,216, 92, 77,228, 12,198, 88, 95,198, 88, 16, 99,204,125,219,150, + 13, 56,241,203,193,178, 34,107, 34, 74, 58,189,143, 6, 16, 69,123, 28, 33,228, 77, 86,105, 51, 20,191,213,178, 12,128, 57,116, +108, 29,128,155,119, 30,230,219, 89, 91,158, 46,251, 91,110,244,193,134, 93,252, 45, 3,190,249,230, 27, 8, 4, 2, 36, 39, 39, +227,222,189,123,176,180,180,196,200,145, 35, 53,133, 74,101,191, 10,115, 29,118, 3, 16, 94,154, 89, 50,159, 90,126,172,196,155, + 31,217,224,212,137, 48,158, 84, 42,133, 74,165, 2,151,203,133, 72, 36,130,185,185, 57,204,204,204,112,235,214, 45,244,233,219, +223,144,101, 30,244,199,128,165,127,204,167, 86,158, 89, 54,214,208, 59,128,121, 4,240,177,131,139,203,156,197,139, 23,155,245, +236,217, 19, 38, 38, 38,112,171,231,155,238,213,107,205, 70, 46,151,163, 79,201, 81, 44,242,174,231, 34,189, 23,155, 8,128,147, + 89,124, 99,177, 75,133,185, 14,255,178,158, 30,218, 11, 94, 63,255,184,214,242,173,183, 74,250,163,203,229,114,100,100,100, 32, + 51, 51, 19,114,185, 28,106,181, 26, 0, 16, 22, 22,134, 19, 23, 31, 40, 10,221,134,196, 87,181,158,127,108,251, 67, 11, 23,221, +245,250,123,118,253,200,179,183,183, 71, 70, 70, 6,178,178,178, 32,151,203, 81, 88, 88, 8,131,193,128,220,220, 92,252,176,253, + 71, 67,142, 36,232,113,249,128,144,213,101,170,147,205,108, 84,191,187, 6, 54,241,100, 19, 38, 76,176,176,180,180,132,209,104, + 68, 94, 94, 30,146,146,146,144,144,144,128,139, 23, 47,170, 51,229, 90,168,237,186,167,148, 15, 88, 90, 73,230, 75,244,218,101, + 86, 28,183,202,197,217, 57,245,201,147, 39, 14, 6,131, 1,174,174,174,122,121,110,238, 74, 83,224,140, 5,144, 6,128,101, 3, +139,215,111,220, 56,190,127,255,254,120,251,237,183,147,211, 51, 50,234, 87,182, 47, 49,128,231, 7, 72, 11,220,220,162,111,220, +184,225,148,148,148,132, 49, 99,198,100, 63,121,244,104,126, 89,127,173,124,160,131,167,183,247,202,125,251,246,217, 53,104,208, + 0,254,254,254,233,162,164,164,166, 15,129,252, 42,246,207, 42,143, 77,121,204,241,250, 83, 7, 54,123,251,195, 15, 63,132, 94, +175,199,197,139, 23,113,253,250,117, 60,121,242, 4,191,255,254,187,220, 82, 44, 30, 86, 97,174,195, 74,247,207,222,190,106,175, +221,187,119,113, 76, 76, 76,176,125,251,118, 68, 68, 68, 0, 0, 2, 3, 3, 49,110,220, 56,232,245,122,140, 26, 53,154, 29,127, +104, 22, 95,221,254, 9,160, 25,128, 47, 81, 82,228,189,205, 24, 19,113, 56,156, 84, 0,238,168, 91,159, 44,218, 63, 41,147, 50, +255, 59,153,111,164, 26,231, 58, 92,246, 45,164,127,158,230, 99, 82,234,193, 45, 75,249,237, 59, 4, 53, 90, 26, 26,194,109,213, +170, 21,220,221,221, 17, 24, 24,136,164,164, 36,161,149,149, 85, 77,243,169,169,130,122,141, 72, 8, 8, 8,176,154, 63,127,190, +180, 71,143, 30, 2,119,119,119, 48,198, 16, 17, 17,129,195,135, 15,235,182,110,221,170, 40,112,236, 43,151,157,251, 73, 85,155, +249,212,174, 3, 5, 0, 62,115, 75, 77,253,126,218,212,169, 33,111,181,104, 49, 33, 52, 52,148, 43, 49, 55, 19,172, 88, 52, 81, + 4, 0,203,190,222, 47,237, 63,100, 36,214,251, 0, 29, 71, 84, 62,143, 92,197,245, 76, 74,153,244,228,221,129, 93,125, 62,158, + 62,222, 48,116,232, 80,177,165,165, 37,220,221,221, 97,109,109,141,248,248,120,164,164,164,176, 99,199,142,169,174,222,142, 17, + 28, 57,115,243,137, 72,234, 92,155,121, 9,149, 65, 61,223,123,252,238,187,239, 90,143, 29, 59,214,162,101,203,150, 2,161, 80, + 8,161, 80,136,140,140, 12,196,197,197,233,142, 29, 59,166, 42,112,232,157, 39, 59,183, 79, 89,203,185, 14, 11,131,134, 47,141, +187,116, 54,116, 86,244,221,187,163,141, 64,115,157, 78,231,106, 48, 24, 56, 92, 46, 55,205,104, 52,222,213, 41,149,219, 52,129, +161,235,104,174,195,218, 49, 24, 12, 38, 6,131, 1,114,185, 28,103,207,158,229, 63,122,244,104,241,157, 59,119, 22,167,166,166, +162,184,184, 24,131, 7, 15, 70, 96, 96, 32,206,157, 59,135,172,140,140, 99,213,101, 61, 4,242,133, 41, 41,227, 38, 77,154,116, +114,215,174, 93,220, 59,119,238,216,109,223,190,253,135,202, 10,152,209,163, 71, 27, 51,146,146,198,105,128,252,106,246,207,234, +142,205,236, 83,251, 54,221, 25, 48,104, 72,147,208, 37,139, 5,109,219,182,133,157,157, 29, 58,116,232, 0,157, 78,103,213,184, +113,227,154,142, 77,101, 80,175, 97,241,205,155, 55, 23,175, 91,183,206,105,252,248,241,152, 62,125, 58, 0,160,176,176, 16,103, +206,156,193,172, 89,179,210,147,248,239,168,107,218, 63, 75, 91,170,202, 10,176, 11, 0,130, 0,196,131, 58,190, 19, 66,222, 76, +101,147, 74, 59,163,100, 98,233,227, 40,249,112, 94,243, 92,135,151,174, 71,161,226, 52, 31, 37,156,239,233, 61,198, 62,154, 50, +103,165, 63,175, 88, 97, 45,224, 20, 89,198,198,196,112,106,154,243,176,124, 62, 53,169,175,202, 54, 97,111,171, 21,203,150,205, + 92,191,126,125,215,178, 33, 28,204,205,205,239, 22,170,213,191,218,107, 52, 27, 10,164,190,191,214,117,110,190, 20, 32, 3,192, + 84,107,153,108, 99,112,255,193,171, 69, 54, 94,130,133,203,183, 22,241,184, 92,109, 92,106, 22,214,251, 0,226, 90, 92, 32, 89, +160, 5,162,229,206,250, 12,219, 33, 15, 63,253,228,147,143,151,125,246, 89, 43,137, 68,210, 81,167,215,251, 26,141, 70,192,104, +140, 45, 80,171, 47, 48,157,238,134, 38,112,201, 90,145,212,153,213,122, 94, 66,171,198, 74,155,199, 7, 91,237,216,182,109,198, +129, 3, 7,254,178,237,182, 26,205,198, 2,171,198,225,181,217,246,138,203, 20, 1, 87,144,153,121,165,186,166, 75,154,235,176, +150,159, 62,140,198,201,214,214,214, 59,187,118,237, 42,234,214,173, 27,250,244,233,131,182,109,219,194,104, 52,130, 49, 6,165, + 82,137,253,251,247, 99,245,234,213,177,245,129,207,106,202,211, 0,191, 10, 79,156,232,221,188,121,243,237,213, 21, 48,165, 69, + 86,141,125, 18,171, 63, 54,133,177,122,105,191,196,225,211, 86,248,104, 21,105, 86,182,230,122,167,232,168,187,220,218, 31,155, +126, 74, 67,196,254,119, 6, 15, 28, 56,141,199,231,119, 40,189, 2,146,221,191,119, 79, 86, 54,169, 52, 2,199,157,173,227,190, + 84, 54,118, 29,117,124, 39,132,188,233,133, 86, 31,148,244,215, 42,159,146,167,202,185, 14,203, 90,125,248,124,126,102,252,145, + 41, 35,171, 75, 23, 0, 93, 75, 91,178, 80,227, 92,135,165,223, 39, 2, 74,104, 52,159,255,105, 48,210, 10, 87, 23, 10,158, 89, +190, 46,195, 34,230, 1, 15,161,215, 4, 35,243, 30,112,116,106, 73, 94,171,101,243, 42,110, 83,149,255,100,255,244,184, 38,185, + 69,192, 37,168, 84,151,160, 82, 85,218,105, 87,192, 55,201,173,105, 61,159,221,246, 36, 64,241,162,219,254,108,102,141,197,195, + 11, 60,159,255, 53, 79,179,179,143, 0,144,184,133,133, 57,158, 10, 11, 27,250,241,236,217,131,157, 93, 92,188,237,236,236,172, + 45, 44, 44,184,215,174, 93, 75,208, 23, 21,109,124, 11,216, 81,218,154, 90, 35, 13,240,171, 95, 82, 82,211,247, 6, 14,156,198, +225,243,219, 87, 44, 96,152, 94,255,187, 23,176,185,186,150,172,231, 61, 54,221,133,206, 93, 75, 91,178,192, 3, 38,213,102,223, + 72, 41, 89,143,229,208,235,151, 35, 50,178,146,125,190,206,251,210, 50, 14,135,163, 4,117,124, 39,132,188,185,202,230, 59, 60, +254,119, 63,112, 55,202,164,204, 55, 40,147,135,146,171,232,232,249,164, 76,202,164, 76,202, 36,181,194,167,167,128,144, 90, 51, +224,143,211, 96,132, 16, 66, 72,153,178,190, 89, 21,125, 15,148,116,221,169,170, 42,173,203,213, 4,207, 83,217,134, 83, 38,101, + 82, 38,101, 82, 38,101, 82,230,127, 46,179,166,236,215,241,106,198,178, 62, 89,229,125,179,254, 46,212,172, 74,153,148, 73,153, +148, 73,153,148, 73,153,111, 58,231,210, 34,171,226, 13, 64, 29, 7, 44, 37,132,144, 55, 85,104, 40,184,140,129,195, 88, 40,151, +177, 3, 60,198,134,240, 24,195, 11, 77, 5, 50,100, 72,229,131,217,254,223, 72,107, 11,122,198, 9,121,163,164,161,138, 73,165, +169,143,214, 63,203,195,201,201,105, 11, 0, 78,122,122,250,100, 0, 73,244,148,252,251,216,216,216,116,213,235,245, 80, 40, 20, +191,190,137,219,215,196, 27, 3, 25, 23,141,203,127,193,144,116, 63, 14, 59, 43, 91,182,177, 15,198,128,243,199, 88, 92, 28, 35, +238,223,123,132,159,235,240,112,220,222,221,220, 55, 3,192,201,240,228,105,120, 53,227,106, 53,180,183,183, 63,205,231,243,249, + 6,131, 97,106,102,102,102, 88,213,133,208, 16, 30, 0, 8,216,185, 5,242,116,135,249, 31,125,192, 17, 20,104,182,201, 53,133, +234,124,158,128,247, 88, 40,112,186, 60,101, 60,247,100,158,170,205,189,202,238,127,240,224,193, 42,103,241,110,234,131,222, 92, + 67,147,190,129,205, 18,226,191,220,208,106,125, 71, 47, 59, 65, 66,242,109,201,170,239,242,183,152, 90,121,246, 29, 51,148, 19, +198, 55,231,140,222,182, 45, 71, 69, 71, 89,237,173, 0,108,116,128,191, 64, 40,116, 55,232,245,142, 28,128,241,248,252,140, 98, +141, 38,217, 4,136, 92, 0,200,223,244, 76, 19,161,208,205,160,215, 59, 2,192,191,113, 61,201,159, 85, 89,104, 73, 36,146, 91, + 92, 46,215,173,226,100,184,101,243, 9,150,253,174,226,223, 56, 28, 14, 12, 6, 67, 74, 94, 94, 94,203, 58, 60,190, 37,128,161, + 0,202, 46, 81,223, 3, 96, 63,158,191,195,177,165,137,137,201, 28,177, 88,220,165,176,176,176, 41, 0,152,153,153, 69,171,213, +234,223,116, 58,221,151,207,153,203, 7,240,158, 68, 34,233,204,229,114, 59, 51,198, 56,140,177,115, 42,149,234, 55, 0, 7, 0, + 60,207, 72, 9,102, 14, 14, 14,203,109,108,108, 70, 44, 88,176, 32,199,214,214,214,111,214,172, 89, 55,115,115,115,127,202,206, +206, 94,132, 58,204, 81,247,138,121, 59, 57, 57,237, 17, 8, 4,188,228,228,228,206, 0,224,238,238,126, 78,171,213, 26, 50, 51, + 51, 71, 2,120, 84,199, 60, 49,128,214, 18,137,164,165, 68, 34, 9, 50, 24, 12,141, 75,231,103,188,175, 82,169, 46,234,116,186, + 91, 0,174, 1, 80,255,139,142, 17, 11, 62,159,191,171,116, 95,247, 5,160,124,211,222, 4, 24, 23,141,239, 69, 63,240, 43, 47, +188,154, 54,170,122, 97, 14, 60, 42, 89,182,214,133, 86,151,142,206,125,251,245,235,206, 5, 0,109,241,201,190,191, 93, 72,251, +229, 37,111, 78,195, 65,131, 6, 93,217,181,107,151,181, 70,163,193,228,201,147,247,132,135,135,111, 86, 40, 20, 11,170,125,227, +144, 88,207, 90,179,238,140, 57,135,195, 5, 0, 7,163,209,224,240,244,233, 35,223,123, 81, 87,122, 69, 71, 95, 93, 81,248,224, +183,107, 70,142, 96,138, 14, 29, 30,212,102, 37, 26,123, 33,184,239,224,129,125, 62,251, 44, 20, 35,134,141,168, 23, 29, 93,100, +230,106, 25,111,154, 91, 40,246,177,181,119,232,247,217,178,131,156,203,151,142,244,219,181,125,233,111,227,199,219,118,161, 98, +171, 86, 56,203,248,252,214, 82, 31,159,160, 97, 71,142, 64,226,238,206,231, 11,133, 92, 0,208,107, 52,238,170,228,100,231,125, +253,250,189, 19, 26, 19,115, 62, 20,184, 78,153,255, 72, 38,169, 75,161,197,229,114,221,158, 62,125,234, 32, 22,139, 75,222,140, + 25,131,193, 96,128,193, 96, 40,159,188,152, 49, 86,254, 85,175,215,163, 81,163, 70,181,250, 68, 11,160, 11,128,247, 59,117,234, + 52,228,203, 47,191, 20,248,251,251,151, 77, 25,210, 97,225,194,133, 95, 71, 68, 68, 28, 2,176, 3, 37,131, 55,214,246, 19,111, + 79,177, 88,188,123,205,154, 53,150,221,187,119,231,187,184,184,128,195,225, 32, 61, 61,189,117,120,120,120,203, 89,179,102, 77, + 85,171,213,163, 0,156,174,195,243,211,204,194,194,226,224,192,129, 3,221, 58,118,236, 40,106,210,164, 9, 12, 6, 3,110,223, +190, 61,254,214,173, 91,195, 15, 29, 58, 20,162, 84, 42,135,160,246,243,181,113, 36, 18,201, 88, 75, 75,203,229, 75,150, 44,177, + 25, 53,106,148,105, 84, 84, 84,158,151,151, 23,231,242,229,203,246,251,247,239,159,186,114,229,202,247, 20, 10,197, 34,149, 74, +245, 35,106, 49,135,162,133,133,197, 45, 46,151,235, 86,155, 66, 24, 64, 93,138,225,183,234,215,175,191,255,210,165, 75,245, 19, + 19, 19, 13, 3, 6, 12,216, 9, 0,191,253,246,155,127,113,113, 49,167, 71,143, 30, 39, 83, 82, 82,134, 2,184, 93,203,109, 15, +176,177,177,249,101,196,136, 17, 54,222,222,222,230,245,235,215,231,136,197, 98,240,120, 60,228,231,231,187, 68, 69, 69,117,187, +126,253,122, 97,120,120,120,174, 70,163,233, 7, 32,178, 14,175, 83, 91, 7, 7,135,209, 2,129,160,153, 94,175,119, 5, 0, 62, +159,255,180,184,184, 56, 42, 51, 51,115, 23,128, 43,207,123,128, 56, 58, 58,110, 90,190,124,185, 93,102,102, 38, 91,185,114,229, + 38,165, 82, 57,246, 77,125, 51,216,243,211, 1,220,186,121, 29, 40,153, 54,135, 83,201,254,199, 1, 96,242,209, 71,179,209,242, +237,119, 48,114,196,123, 53,102,190,219,213,109,141,192,212,196,182,168,168,232, 74,126,129,230,128,216, 92, 52,116,196,240,224, + 88, 0, 56,121,234,252,208, 86,173,172,207, 73,205,133,239,137, 68,162,182,197, 90, 93,206,137, 95, 83, 62,169, 75, 81,229,234, +234,122,218,218,218,218, 60, 55, 55, 55, 61, 43, 43,235,219,190,125,251, 46,219,177, 99,135,117, 66, 66, 2,146,147,147, 49,115, +230, 76, 73, 74, 74,202,180,200,200,200,171, 90,173,182,202,150, 45,165, 50,119,195,194,249,253,151, 72,165,118, 60,177,185, 37, + 44,164, 54,240,242,110,142,214,109,251,162,119,159, 9,136,139,141,104,189, 99,251,103, 17, 79,159,134,127, 33,177,105,176, 76, + 46,175, 95,229,251, 82,147,134,232,216,111, 96, 73,145,181,100,201,255,179,119,221, 97, 81, 92,237,247,204,246, 70,135,165,131, + 5,169, 2, 54,140,177,197,134, 21,236, 37, 38, 26, 77,212, 88, 98, 98,141,209,104,108, 41, 26, 99, 18, 53, 49,177, 36,177, 97, + 98,195, 18,172,168, 8,246, 40, 88,232, 32,210,100, 23,118, 41, 91,216,222,230,247,135, 44, 31, 18, 96, 23,163,223, 47,201,183, +231,121,246,217,221,217,153,179,247,206,189, 51,247,204,123,223,251,190,107,145,155,157, 45, 47, 42,164,188,127,250, 4,141, 59, +124, 80, 40,203,160, 45, 47,186,118,245, 68,187, 62,125,199, 0, 64,212,129, 61,235, 46,191,255,166,243,160,239, 14,214,200,109, + 67, 82,243,247,206,245,116,250,180,161,223,126,235,222,117,238, 92, 70,109, 97,161,174, 96,199, 14,101, 69, 74,138,145,198, 98, +145,126,195,134, 17,252, 1, 3,216,115,179,178, 24,215, 55,110,124,141,190,110, 93,192, 74,157, 46,206,198,249, 95,229,252, 95, +135,217, 9,190,225,234,195, 93, 45, 10, 45,130, 32,192,227,241,112,232,208, 33,208,233,116,208,104, 52,181,187, 27,129, 0, 0, + 32, 0, 73, 68, 65, 84,208,233,244,102, 63,251,251,251, 91, 83,144,113,158,158,158,223,111,223,190,221, 99,232,208,161, 96,179, +217,245, 63, 80,169, 84, 12, 30, 60, 24,209,209,209,116,129, 64, 48,249,208,161, 67,147,191,248,226,139, 10,137, 68, 50, 31,117, +137,161, 91,192,128,144,144,144,248, 11, 23, 46,112,212,106, 53, 82, 82, 82, 80, 83, 83, 3, 38,147, 9, 95, 95, 95, 12, 25, 50, +132,150,157,157,237, 50,120,240,224,248,220,220,220, 88, 0, 73, 86,148, 53,202,221,221, 61,249,200,145, 35,236,206,157, 59, 19, +249,249,249,232,218,181, 43, 0, 64, 42,149, 98,204,152, 49,236, 41, 83,166,116,152, 60,121,242, 45,145, 72,212, 15,192, 93, 11, +124,221, 60, 61, 61,247,141, 29, 59,214,251,139, 47,190,112,176,183,183, 71, 81, 81,145,208,211,211, 51,200,124,190, 39, 79,158, +204, 28, 57,114,164,215,166, 77,155,182, 30, 61,122,244, 67,145, 72, 52, 13, 64,106,139,170,181, 78, 16,115,185, 92, 84, 84, 84, +224,224,193,131,120,239,189,247, 64,165, 82, 33, 18,137,112,248,240, 97,188,255,254,251,102, 65, 99,149, 24,230,114,185,209,129, +129,129, 63, 95,190,124,217,215,201,201, 9,222,222,222,148, 79, 62,249, 36, 34, 32, 32,128,211,182,109, 91,170, 80, 40, 68,124, +124,124,192,212,169, 83, 79,150,148,148,188,163,209,104, 44, 78,169,121,120,120,252,114,250,244,105,255,140,140, 12,236,216,177, + 3,213,213,213, 96, 50,153,112,114,114,130,167,167, 39,130,130,130,136,229,203,151,115, 71,142, 28,201,157, 63,127,254, 47, 90, +173,182,139, 21,109,212,217,221,221,125,231,128, 1, 3, 2,214,173, 91,231,228,233,233, 9,243,131,129, 84, 42,245, 45, 42, 42, +122,117,245,234,213, 19,238,222,189,251, 88, 36, 18,205, 6,112,191,149, 23, 78,151,142, 29, 59,198,142, 25, 51,134, 42, 20, 10, +113,224,192,129, 88,185, 92,222,165, 21,226,242, 31,133,187,119,110,227,221,121, 11,106,189,253,252, 24, 23,206,255, 60,238,232, +241,224, 59, 78,156,167, 9,169, 37, 42,232, 38,140,205,237, 62,100,232, 12,198,136,152, 49,181,187,126,216,106,103,141,208,162, + 51, 25,174, 7,227,190, 41,185,122,237,110, 68,226,197,219,195,198,141, 26, 69, 50, 24, 78, 1, 0,240,225,162,133,244,248, 83, +167,246, 12,142,238, 33,232,219, 39,170,228,205, 41,139,253, 91, 81,220,224,224,224,224, 43,105,105,105, 30, 44, 22, 11,213,213, +213,174,187,118,237,250,166, 79,159, 62,148,130,130, 2,100,103,103,163,176,176, 16, 82,169, 20,131, 7, 15,182, 75, 77, 77,253, + 17, 64,179, 66, 75, 71, 25,248,185,119, 91,253, 54, 87, 14,175,157,206, 40,115, 39,245,194,142,137,167, 19, 59,253,118, 64,213, +213,195, 43, 52,104,250,219,107,176,254,179, 99,244, 95, 15,126,185,250,210,197,223, 0, 74,187,230, 51, 2,144,232,245,241,202, + 21,144,201, 53,152,242,198, 44, 76,125, 99,150, 43, 9,173, 23,105, 84,243,180,170, 26, 39,123, 70, 86,194,246,159,190, 25, 11, +192,183,129,216,186,100, 19, 91,205, 99, 61,141,214, 35,246,251,239,249, 17, 51,103,178,238,175, 91,167,168, 76, 73, 81, 5,142, + 24, 81,211,117,206, 28, 13, 0,200, 11, 11, 25,185,107,214,112,249,175,189,198,233,185,116,169,179, 81,171,245, 92,191,126,253, + 43,171,159, 38, 47,111, 21,167,255,164, 73,198,213,123,246,116, 79, 89,188,184, 63,161,215, 83,135,245,236,121,111,227,129, 3, +101,127,133,243, 69,150, 83,144,156,172,169, 14, 8, 64,215, 49, 99,170,252,221,221, 53, 47,178,238,127,165,156, 54,212,195,236, +171,245,110,195, 39, 84, 36, 36, 36,244, 3,112, 5,192,186,216,216,216,181, 0,224,232,232, 88, 33,145, 72,220,227,227,227, 45, +138, 44, 58,157, 14, 47, 47, 47, 4, 5, 5,137, 68, 34,145, 71, 11, 5, 40, 53,153, 76,190, 36, 73,214, 91, 95,154,131, 70,163, + 65, 94, 94, 30, 58,117,234,244, 4, 79, 19,209, 54,107,212,225,114,185, 5,217,217,217,110,153,153,153,184,123,247, 46, 2, 2, + 2,224,236,236, 12, 58,157, 14,189, 94, 15,153, 76,134,144,144, 16,176, 88, 44,116,235,214,173, 82,161, 80, 4, 88,152, 2, 98, +241,120,188,188,228,228,100,191,174, 93,187,226,143, 63,254,128,159,159, 31, 60, 61, 61, 1, 0,133,133,133,184,118,237, 26, 70, +140, 24,129,180,180, 52,140, 31, 63,190, 84,161, 80, 4, 1,208, 52, 71,232,226,226, 34,188,124,249,242,147,200,200, 72,181, 66, +161,160, 84, 84, 84,208, 83, 82, 82, 12,114,185,220, 78, 42,149,210, 37, 18, 9, 93, 38,147,209, 20, 10, 5,157, 66,161, 48, 84, + 42, 21,253,210,165, 75, 84,157, 78,215, 98,128, 76,115, 59,157, 58,117, 10,145,145,145,136,143,143,199,146, 37, 75,112,253,250, +117,248,249,249,225,200,145, 35, 88,186,116, 41,114,114,114,224,230,230,134,142, 29, 59, 90,106, 35,116,232,208, 33,255,225,195, +135, 29, 24, 12,134, 57,175,163, 57, 95, 30,196, 98, 49, 30, 61,122,132,178,178, 50, 4, 6, 6,226,141, 55,222,120, 84, 86, 86, + 22,104,169,231,249,248,248,136, 51, 50, 50,220, 58,117,234,132,138,138, 10, 56, 57, 57,193,209,209, 17, 78, 78, 78,245,159, 3, + 2, 2,176,120,241, 98,120,122,122,138,212,106,181,135, 37, 17, 20, 25, 25,121,254,210,165, 75,110, 14, 14, 14, 40, 47, 47,135, + 76, 38, 3,141, 70, 3,151,203,133,155,155, 91,189,144,207,203,203, 67, 76, 76, 76,101, 65, 65,193,208, 86,136, 36,138,135,135, + 71,246,131, 7, 15,130, 72,146, 68, 73, 73, 9,114,114,114, 48,111,222,188, 60,181, 90, 29,138,127, 81,206,190, 6,126, 87,140, +105,111,191,203, 24, 59,186,151, 54, 43, 35,129, 96,153,114,208, 37,194, 65, 10, 0,247,210,101,142, 26, 74, 8,194,194, 99,201, +227, 39,111, 48,247,237,221, 69,135, 9, 30, 32,144,147,149,135, 79,155,227, 30, 50,192,107,230,194,133,239, 68,244,239,211,143, + 34, 87, 40,220,127,252,241,219,110, 5, 5, 89,238, 0, 16, 16, 16, 38,154, 59,119, 81,170, 61,143, 39,186,114, 45,217,180,101, +203, 47,233, 23,146,132, 63, 89, 81,228,128,160,160,160,155,167, 78,157,114,115,119,119,135,163,163, 35, 20, 10, 5,116, 58, 29, + 50, 51, 51,213,135, 14, 29,210, 59, 56, 56,216,151,151,151, 67, 34,145,128, 32, 8,156, 58,117,170, 4, 64,155,198, 68,102, 31, + 45, 0,152, 55, 60,140,222,113, 96,144, 51,131,101,224,112,232,185, 94, 32,140, 44,130,180,243, 56,123,254, 94,167,179,137,127, +188, 57,118,220, 18,126,223,126, 99,177,122,213, 4,189, 64, 80,210, 85,135,190,217, 77,249,104,133, 6, 98,224,152,241, 99, 39, +174, 95,191, 22,107, 87,175, 67,194,169, 19, 82, 59, 30, 69,227,224, 68,119,124,237,213,222,234,197,239,141, 46,173,173, 21,248, +173,223,116,232,141,152,209,139,125,251,244, 29,131,107, 87, 79,224,192,158,117,119, 9, 14,105,155, 70,108,132,181,128,179, 83, + 64,192,236, 15,242,242, 24,247,215,174,173, 53, 8, 4, 53, 81,139, 22, 85, 54,181,239,147,196, 68, 30,211,219,219,193,121,212, + 40,151,173,109,218,144,122,145,104,103, 83, 62, 70, 77,113, 94,180,179,115,250,237,236,217, 65, 36,157,222,111,217, 71, 31,113, + 98, 99, 99, 33,147,201,112,236,216, 49,236,220,177, 67,227,229,229,245,208, 59, 61, 61, 45, 66, 38, 91,101, 45,103,212,162, 69, +149, 70,163,145,152,184,116,233,224,140,194,194,129,229, 34, 81, 91, 0,240,114,113, 41,141, 10, 8,184,251, 75, 66, 66,206,119, +237,218,153,172, 45,231,238,115,231, 60,142, 22, 21,205,116,113,113,225, 84,136, 68, 52, 22,147, 89,245,106,199,142, 71,126, 88, +185,242,138,225,193, 3, 6,219,215,215,193, 49, 54,182,213,117,143, 90,180,168,178, 90, 46,167,125,240,217,103,189,139, 43, 42, +218,214,106, 52,129, 18,185,220,211,168,215, 83, 28,184,220,170,246, 33, 33, 34, 85, 74,138,176,189, 82,185,224, 39, 64,244,178, +218,186, 41, 45,242, 15, 66,227, 56, 90,127,202,117,120, 37, 54, 54,246, 79,171,107, 72,146,180,202,154, 69,167,211,159,153,166, +106, 1, 12,130, 32,144,154,154, 10, 87, 87, 87,120,122,122,130,197,122, 54,249,160, 88, 44,198,245,235,215,145,149,149,133,206, +157, 59,155,167, 49,154, 87, 68, 44,214,194, 77,155, 54, 57,105,181, 90,220,189,123, 23, 81, 81, 81, 96,177, 88, 96, 48, 24,207, +136, 64,145, 72,132,240,240,112, 44, 91,182,204,241,139, 47,190, 88,168,209,104,154,125, 34,165,209,104,243,103,205,154,229,110, +182, 96,149,150,150,162, 91,183,110,245,191,243,249,124,220,187,119, 15, 81, 81, 81,240,245,245,197,132, 9, 19,220, 15, 28, 56, + 48,223, 96, 48,108,110,142,147,201,100, 82, 34, 35, 35,187, 3, 0,143,199, 3,133, 66,201,117,112,112,224,123,120,120,240, 28, + 28, 28,254, 84,199, 61,123,246, 72, 40, 20,138,222,162, 26,160, 80, 80, 94, 94,142,136,136, 8, 72,165, 79, 51,184, 40, 20, 10, + 4, 6, 6, 66, 38,147,213,139, 86,111,111,111,168, 84, 45,187,126,117,234,212,105,109,104,104,232, 16, 30,143,199,162,211,233, +184,127,255, 62,186,118,237,138, 67,135, 14,193,223,223, 31, 92, 46, 23,121,121,121,136,140,140, 68,114,114, 50,248,124, 62,194, +195,195, 89,238,238,238, 87,171,171,171,147,138,139,139,215,182, 80, 78,138,157,157, 29,146,147,147,241,203, 47,191,160,176,176, + 16, 2,129, 0,246,246,246,232,210,165, 11, 58,118,236,136, 94,189,122, 33, 47, 47, 15,132,229,206,228, 25, 20, 20,148,240,199, + 31,127,184,145, 36,137, 3, 7, 14,160,182,182, 22, 90,173, 22, 20, 10, 5,108, 54, 27,206,206,206, 24, 56,112, 32,248,124, 62, +130,130,130,112,248,240, 97,183,225,195,135,159, 17,137, 68, 93, 0,148, 91, 58,175,206,206,206, 11,214,172, 89,227,231,238,238, +142,162,162, 34, 72,165, 82,120,120,120,160,127,255,254, 62, 23, 47, 94, 92,160,215,235,191,253,183, 12,100, 13, 28,223,137, 11, +231,127, 30, 23,212,190, 38,178,115, 8,215, 47, 62,193,195,239, 80,130, 40, 28, 0, 34,194, 60, 50,198,197,114, 75,239,103, 36, +148, 94, 56,127,226,110, 86, 46,226, 97,197,212,182, 84,169, 57,146,120,241,246,176,174,157,187,153, 54,125,185, 52,230,189,121, + 51, 89,238, 30, 51, 80, 81,114, 2, 23, 47,167,250, 47, 93, 50,139,191,249,235,221,103, 19, 47,222,166, 72,149,154, 85,214,153, +178,252,191,219,251, 67, 47, 55,121,229, 81,228,103, 51,193,177,143, 64, 64, 64, 48,100, 50, 25,216,108, 54,251,141, 55,222, 48, +174, 88,177, 66,233,224,224,192, 37, 8, 2, 73, 73, 73, 34, 0, 67, 45,241,170,221,157, 73,163, 78,111, 32,153, 84, 19, 73,216, +171, 8, 99, 53, 51, 61,243, 49,134, 68, 15,168,232,211, 35,226,139, 21,235,191,254, 56, 40,184, 43,255,157,153,235,232,159,173, +125,115, 7, 8,244,109,138, 39, 59, 31,151,137, 35,199, 57, 0, 98,214,127,186, 22, 5, 5,121,206,239, 78,151,172,163,177, 56, +222,161,109,122,219,239,248, 37,105, 88, 96, 96,187,182,139,231, 79, 56,253,205,247,223,196, 52,180,108,237,221,179,230, 36,128, + 65,214,156,219,255, 33,116,154,154,144,128,218,146, 18,125,245,213,171,234, 65,223,127, 95,233, 55,116,232,183, 90,157,206,205, +124,171,160, 16, 4, 8,179,235,132,201, 68,208,150, 45,163,144, 52, 26,244,206,206,211, 81, 83, 19,108,137,115,137, 80, 56,238, +205,153, 51, 99, 78,158, 59,135,118,237,218,213,143,103, 78, 78, 78, 88,186,116, 41, 22, 45, 90,196,186,119,239,222, 43, 71,143, + 30,125,101,243, 87, 95,121, 0, 24,103, 77, 57, 47,220,186,229, 60,103,253,250,149,157,163,162,252,247, 31, 60,200,234,208,161, + 3, 0,224,209,163, 71, 65, 95,110,220,216, 38, 34, 50,178,226,139,133, 11,247,102,172, 88, 17, 14,224,106, 75,156,229, 41, 41, +218,163, 69, 69, 51, 47, 39, 37, 57, 69, 68, 68, 0, 0,114,114,114,220,183,110,221, 58, 43,124,194,132, 41,235,231,206, 93, 21, +171, 86, 75, 28,196, 98, 86,236,119,223,209,126,155, 56,209, 34,167,185,156, 0,208,255,157,119, 22,246, 29, 48,160,227,184,153, + 51, 93,252,253,253, 9, 59, 59, 59,232,116, 58, 8, 4, 2,231,140,140,140, 14, 9,114,185,236,248,173, 91, 7, 96, 52, 14,126, +137,109,221,164, 22,249,135, 89,178,254,172, 41,234,222,251, 39, 36, 36,144, 0,250,199,198,198, 38,155, 7,112,163,209,104,149, +200,162,209,104, 32, 8,194, 90,177, 5,146, 36, 81, 89, 89,137,202,202,202,250,169, 35,145, 72,132,203,151, 47, 35, 47, 47, 15, +116, 58, 29, 12, 6, 3, 58,157,229, 28,180, 60, 30, 47, 58, 58, 58,154,118,235,214, 45, 4, 4, 4,128,195,225,212,151,203,252, + 98, 48, 24,240,242,242,130, 76, 38,195,160, 65,131,232,219,182,109,139,110, 73,104, 57, 58, 58,142,152, 52,105, 18,211,252,189, +182,182, 22, 84, 42,181, 94,180,212,214,214,162,186,186, 26, 18,137, 4,106,181, 26, 61,123,246,100, 38, 36, 36,140,168,170,170, +218,108, 77,253,149, 74,101,173, 72, 36,114,234,219,183,175,243,222,189,123,115,122,246,236, 25,242, 76, 79,187,114, 69,173, 86, +171,233, 20, 10,197,170, 60,122,113,113,113,245,231,190,172,172, 12, 59,118,236,168,255, 45, 47, 47, 15,219,182,109, 3, 73,146, + 32, 73,178,197, 54, 10, 13, 13, 29,126,224,192,129,168,253,251,247,215, 80,169, 84,228,228,228,224,224,193,131, 32, 73, 18,124, + 62, 31, 74,165, 18, 21, 21, 21, 72, 74, 74,130,193, 96,128,157,157, 29,124,124,124,216,243,231,207,239,179,110,221, 58,122, 75, + 66,203,104, 52, 26,169, 84, 42,218,180,105,131,213,171, 87, 67,173, 86,131,193,120,170, 47,101, 50, 25, 36, 18, 9,210,210,210, + 80, 84, 84, 4,146, 36, 91, 28,100,216,108,246,132,253,251,247,187, 51,153, 76,168, 84, 42,200,229,114,148,150,150,162,184,184, + 88, 45, 18,137, 12,246,246,246,148, 54,109,218, 80, 88, 44, 22,107,204,152, 49,132, 89,112,198,198,198,186, 30, 56,112,224,117, +173, 86,107, 73, 36,241, 61, 61, 61, 63,158, 53,107, 22,187, 97,159, 45, 47, 47,199,184,113,227,184, 55,110,220, 88, 33,147,201, + 14, 2, 16,255,203, 6, 52,242,232,241,224, 59,119, 47,230, 68,198, 39,120,248, 21, 63, 49,246, 94,250,225,215, 52, 0,216,181, +115, 67,239,248,132,178,235,161,237, 42, 74,143, 30, 15,190,227,236,156,101, 73, 8, 80, 6,246,243, 26,201,227,178, 39,141, 27, + 53,138,252,241,199,111,187,189, 55,111, 38,171, 77,240,210,167, 22, 78,186, 59, 6, 25, 62, 37,148,170, 71,236, 31,127,252,182, +219,184, 81,227,211, 10, 11,139,118, 14,236,199, 58,124, 57, 89,248,123, 75, 22, 67,119, 87,182, 15,151,165,128, 79, 64, 71,132, +132,241,112,239,126, 14,142, 29,185,137,176,240, 87,161,209,104, 96, 48, 24,120, 35, 71,142, 84, 30, 58,116, 72,157,155,155, 43, + 87,169, 84,253, 0,228, 90,170,252,147, 39,153,166, 16,207, 87,117, 12, 14,203, 32,151, 50,148,203, 87, 29,157,216,173,199,144, + 40,103, 47, 31, 58,159,103,250,125,248,224, 87, 14,254,242,211,234, 69,171,214, 28, 68,247, 87,134,244,204,202,185,218, 17,192, +195, 38,197,107, 1, 18, 40,199,142, 27, 10,242,243, 99,138,139,138,158, 4,123,120,106, 31, 73, 72,253,130,229,187, 7,247,237, + 55,161, 83,135,176,215,152, 89,153,201,196,234,101,175,255,186,126,211, 55,111,152,197,214,165,196, 95,251, 77,159,126,147,185, +119,111,243,214,241,255, 53, 48, 88, 44, 95,187, 54,109,104,133,123,247,170, 2, 70,142,172, 1, 0,173, 78,231, 86, 88, 84,228, +200,229,114, 65,146, 36,244,122,253, 51, 62,196,102,191,225,136,144, 16, 15,107, 56, 11, 63,249,164,211,178,101,203, 80, 94, 94, + 14,131,193, 0, 58,157,222,248,158, 13,133, 66,129,233,211,167,227,187,175,190,122,213, 26, 78,163,209, 72,204, 89,191,126,229, + 71, 43, 87,118,152, 61,123, 54,165,225,189,215,197,197, 5, 71,143, 29, 99,110,223,190,221,247,227,239,190,155,254, 38,139, 85, + 0,141,166, 69,206,202,192, 64,184, 84, 84,112,204, 34, 11, 0, 66, 66, 66,176, 99,199, 14,214,140, 25, 51,152, 35, 71,142,252, +250, 94,231,206, 91,191,237,211, 39,223, 53, 56,216,129,201, 98,249, 90,226, 52,159, 79, 0,144,171,213, 17,223,110,221,234,124, +251,246,109, 84, 84, 84,160,188,252,233,243, 40, 65, 16,232,222,189, 59, 49,117,234, 84,199,246,126,126,175,192,104,124,153,205, +253, 39, 45,242, 15,194,187, 77,108,251,143,143, 86, 93,133,136,186, 10, 18, 13, 6,199,103, 4,139, 37,161,245, 60,144, 72, 36, +144, 72, 36,248,233,167,159,192, 96, 48,234, 7, 95, 0,208,106,181,214,136,150, 72,111,111,111, 72,165, 82, 4, 7, 7, 63, 99, +201, 98, 48, 24,160,209,104, 96, 48, 24, 96,177, 88,208,104, 52,240,247,247,135, 82,169,140,108,137, 83,165, 82,117,113,113,113, +169, 31, 96, 53,117,157, 85,163,209,212,151, 87,171,213,162,166,166, 6,181,181,181,144,203,229, 80, 40, 20, 93,173,169,175,201, +100, 66,122,122,250,163,144,144,144, 46, 84, 42, 21,118,118,118, 60,133, 66, 81,239, 91, 84, 93, 93,141,125,251,246, 41,222,122, +235, 45,183, 83,167, 78, 89, 20, 90, 4, 65,224,253,247,223, 7,139,197,130, 82,169,196,143, 63,254,136, 15, 62,248, 0, 12, 6, + 3,114,185, 28, 59,118,236,192,226,197,139, 65,163,209,160,213,106,177,117,235,214,102,185, 50, 51, 51, 11,111,221,186,213,181, + 91,183,110,206,199,143, 31, 23, 15, 30, 60,152, 63,116,232, 80,112, 56, 28,168, 84, 42,232,245,122,188,250,234,171, 8, 13, 13, +133, 72, 36,194,217,179,103, 43,131,130,130,220,110,223,190,109, 42, 47, 47, 47,182, 32,174,201, 6, 22, 67, 24,141, 70, 84, 84, + 84, 64, 34,145, 64, 44, 22, 67, 32, 16,224,201,147, 39,160,209,104,176,160,179,224,234,234, 58, 62, 34, 34,130, 10, 0, 28, 14, + 7, 93,186,116,193,202,149, 43, 13, 42,149,106, 18,128,179,117,187, 13,223,189,123,247,241,107,215,174,209,188,189,189,145,157, +157, 13, 62,159, 79, 99,179,217, 22,133,150,167,167,231,158,223,127,255,221,197, 44,174,205,231, 89,169,124,218, 28,227,198,141, +115,217,191,127,255, 30,131,193, 48,226,223, 54,168, 57,113,192,232, 18,225, 32, 61,148, 32, 10, 95,250,225,215,180,208,136,167, + 15,175,239,206, 6,109,243, 87, 75,194,167,140,118, 56,237,196,145, 49, 44,241, 12,143,246,219, 62,106,212, 96,202, 27,147, 99, +243, 24, 12,167,128,157,187,214,185,187,123,204,104, 32,195, 28,224,234,230,128,128, 54, 76,226,232,233, 44,247,229, 43, 62,213, +196,237,255,166,224,215,223, 18,134, 49,233,137, 67,206, 94, 44,157,219, 28,119,238, 35,201, 41,165,134, 29, 38,171,122, 64,184, +120,244, 70,151,206, 33,112,231,215, 96,247,158, 67,104,215,190, 59, 52, 26, 13, 28, 28, 28,184, 70,163, 81, 71,165, 82,227,172, + 17, 89, 0,112,233,146,196, 20, 30, 46,209, 82,229, 38,195,123, 31,108, 30, 59,120,248,168,142, 3, 7, 70,155, 46, 36, 94,208, +245,238,170, 19, 14, 31,218,165,226, 92,226,246, 60,161,224,113, 80,120,100, 31,100,102, 36, 13, 35, 73,164, 19, 68,211,214,167, +140,124,156, 83,155, 50,147, 14, 29,122,215,164, 50,165,113, 62,251,252,225,240,152,152,105, 17,175,245,125,205,148,120,241,178, +150,137,202, 44,135, 62,189,202,222,155, 57,252,248,207,113, 91,135,156, 59,187, 39, 80, 42, 43, 78,176,137,172, 70, 15,105, 6, +131, 7,141,197,162,136,147,146, 12,145, 51,102,104,204,215, 35,151,203,197,201,147, 39,193,100, 50,235, 95, 12, 6,163,254,179, +135,135, 7,136,186,101,164,214,112, 2,128, 80, 40, 68,121,121, 57, 28, 29, 29,193,231,243, 81, 94, 94,142, 27, 55,110, 32, 55, + 55, 23,116, 58, 29,195,134, 13, 3,165, 25,223,230,198,156, 19,151, 46, 29, 28, 22, 25,233,223, 88,100, 1,128, 78,167, 67,117, +117, 53, 70,143, 30, 77, 57,123,246,172,231,185,146,146, 81, 0,226, 90,226,236, 26, 19, 83, 85,113,244,104,147,255,221,173, 91, + 55,226,250,245,235,172, 97, 67,135, 46, 90,242,249,231,219,191,219,191,191,212,104, 48,120,182,166,238, 20, 10,133, 66, 16, 4, +252,252,252, 80, 93, 93,141,218,218,167, 51,216,118,118,118,112,118,118,134, 94,175,135,137, 36,233, 47,179,173,155,211, 34,255, + 16,236,106, 32,184,118,253,201,162, 85, 87, 41, 0,232,223,112, 96, 49,153, 76, 86,137, 44, 58,157,110,209,231,202, 26, 43, 87, + 99, 88, 35,180,204,101,101,179,217,245, 23, 90, 67,129,101, 46, 39,133, 66, 1,149, 74,181, 56,136,215,137, 33,170, 92, 46,199, +177, 99,199,208,175, 95,191,250,105, 41,169, 84, 10,137, 68, 2,169, 84, 10,181, 90,141,194,194, 66, 92,186,116, 9,129,129,129, +128,149,193, 95, 11, 10, 10,238,182,107,215, 46,202, 60,136, 15, 24, 48,192,119,239,222,189,130, 17, 35, 70,120,147, 36,137, 85, +171, 86, 85,190,250,234,171,110, 13, 7,121, 75,160, 82,169,184,113,227, 6, 2, 3, 3, 65,146, 36, 24, 12, 6,114,114,114,224, +238,238, 14,147,201, 4, 26,141, 6,177, 88, 12,123,251,150, 99, 36,166,167,167,191,253,206, 59,239, 8, 28, 29, 29, 59, 85, 85, + 85, 9, 89, 44, 86,223,148,148, 20, 63,157, 78, 7, 7, 7, 7, 56, 56, 56,224,204,153, 51,112,114,114,194,194,133, 11, 75, 84, + 42,213, 13, 30,143,231,161, 82,169, 30,148,151,151,175,106, 77,123, 27, 12, 6, 40, 20, 10,212,212,212,160,186,186, 26, 50,153, + 12,106,181,218, 98, 25,155, 66,223,190,125,145,144,144, 64,221,176, 97,195,207, 5, 5, 5, 0,128,128,128, 0, 44, 92,184,144, +234,227,227,131,194,194, 66,220,189,123, 23, 58,157, 14, 36, 73,182,120,241,210,104,180, 1,111,189,245, 86, 31,127,127,127, 66, +167,211,193,100, 50, 65,163,209,192,252,185,164,164, 4, 97, 97, 97,148, 54,109,218,244, 44, 40, 40, 24, 0,235, 22, 86,216, 0, +160,162,228, 4,124,232,238, 0,197, 1,164,234, 4,170, 42,159, 47,138,139, 72, 36,250,124,217, 39,215,103,124,183, 73,231,241, + 68, 8,132, 68,140, 65, 80,199, 65,120,123,170, 1, 27,190, 58, 6,255, 54, 33, 40, 46, 46,198,128, 1, 3, 24, 2,129,224,157, +218,218,218,165,214,114, 39, 38,222, 50, 94, 56,115,118,194,196,215,167, 69, 69, 71,143, 48,156, 63,127, 6,233, 15,206,103,188, +243,250,120, 17,105,170, 37, 92,156, 56,105, 57,217,119,130, 58,117,233, 15,173,193,216, 23, 88,187, 9, 88, 75, 54,127,189, 67, +123,250,180, 23,229,244,137, 61, 83,223,152, 50,189,243,160, 65, 67,244,231, 19,127,199,221,155,137,247,191,222, 52, 43,121,195, +214,195, 3, 6, 15, 27, 31,206,247,184,113, 38, 34, 88, 51,211,207,213,241,209,238,189,213,182,206,210,212,181,201,102,155, 80, +119, 95,164, 16, 4, 72,146,124, 70,100, 53, 22, 90, 20, 10,197,162, 1,160, 33,103,195,177,200,252, 64,189,115,231, 78,176, 88, + 44, 48,153, 76,208,233,116,139,238, 23, 13, 57, 51, 10, 11, 7,238,139,139, 99, 53, 37,178,170,170,170, 80, 85, 85,133,218,218, + 90, 76,158, 60,153,177,238,206,157,110,168,115,253,104,142,211,223,203, 75,195,227,112, 42, 50, 51, 51,189, 59,118,236,248, 76, +121,101, 50, 25, 56, 28, 14,226, 14, 30,100,196,198,196,204, 27,116,230,204,215,176, 16,255,170,169,186, 19, 4, 1,119,119,119, + 56, 59, 59,131, 32, 8, 24, 12, 6,148,151,151, 35, 35, 35, 3,119,238,220, 1,149, 32, 12, 47,179,141,155,210, 34,255, 64,171, +214,174, 38,167, 14,155,155, 19,109,141,208,162, 82,169,207,109,213,106, 14,214, 76, 29,114,185,220,135, 2,129,160,183,143,143, + 15, 12, 6, 67,189,208,106, 60,117,104,182,126,220,187,119, 15, 92, 46,247,161, 90,173,110,145,147, 36,201,158,175,188,242, 10, +226,227,227,145,148,148,132,199,143, 31, 67,169, 84, 66,163,209, 64,165, 82, 33, 35, 35, 3, 38,147, 9, 17, 17, 17,224,241,120, +224,114,185, 15, 53,154,150, 31, 68, 21, 10,133,144, 78,167,135,112, 56,156,250,109, 94, 94, 94,168,170,170, 50,233,245,122,236, +219,183, 79,230,233,233,201,227,112, 56, 86, 11, 87,130, 32, 32, 18,137,224,235,235, 91,239,163, 37,151,203,225,238,238,110, 22, + 22,208,104, 52,176,183,183,183, 56,117, 8, 64,157,159,159,191,164,193,247,238, 19, 39, 78,252,245,208,161, 67,237, 47, 94,188, +136,219,183,111,131,207,231,227,139, 47,190,120, 92, 84, 84,244, 6,128, 59, 34,209,139,245,139,180,166, 15, 85, 85, 85, 29,123, +248,240, 97,207, 87, 94,121,165,254, 46, 49, 96,192, 0, 98,192,128, 1,110, 13, 77,253, 98,177, 24,127,252,241, 7, 46, 94,188, + 8,130, 32,144,151,151,103, 84,169, 84,191,182, 52, 75,225,227,227,179,119,229,202,149,118, 6,131,161,190,111,115, 56, 28,176, +217,108, 48, 24, 12, 80,169, 84, 20, 21, 21, 97,244,232,209,142,223,127,255,253, 30,141, 70,211, 1,128, 14,255, 18, 72, 84,208, +221, 75,151, 57, 70,132,121,100,236,218,185,161,247,187,179, 97,158, 58, 52, 68,132,185,103,220, 75,175,112,140,114,183, 92,223, +179, 23, 75,223,211,234,207,142, 60,123,238,202,164, 15, 23, 45,164, 7, 4,132,137, 46, 94, 78,245, 31,100,248,148,112,117,115, + 64, 85,165, 12, 69, 37, 21, 40, 40,214,146, 1, 1, 97,162,187,127, 60,100,125,245,237,150, 32,133, 82,109,158, 58,108,177,159, + 94,189,241,120,204,215,219, 88,201,211,222,233,206,228,112,188, 81, 93,249, 16,254,254,124,140,142,237,132, 95,246,223,128,163, +163, 11, 60, 60, 60, 64,161, 80,120,214,214,189,178,178,146, 56,246,219,213, 25,111, 77,159,245,234,208, 33, 49,134,115,231, 79, +211,146, 46,156,186,177,103,215,199,199, 73,170,130, 75,144,114, 78,219,118,158, 15, 30,229,223,123, 99, 96,244,100,112, 24,246, +129, 64,104,147, 29,182,126,129, 1,137,146,248, 67,107,217,111, 77,127,183,215,208,161,163, 12,231,207,159,192,249, 51,251,111, +173, 89,211,246,204,227,178,131,140,155,119,158,176,199, 76,152, 91,147,112, 54, 75, 59,126,100,187, 92,111, 94, 23, 21,240,216, +166,170, 26, 62, 72,210,104, 21, 6,141,198,207,119,232, 80,170,178,184,152,110,231,225, 97, 0, 0,189, 94,111, 81,104,161,153, + 41,232,198,156,214,150, 69,169, 84,194,212, 76,236,196,198,156,229, 34, 81,219,186,135,240,122,232,245,250,122,145, 85, 85, 85, + 5,137, 68, 2, 30,143, 7,177, 70,227, 97, 13,231,144, 30, 61,246,173, 91,187,118,233,209, 99,199, 24, 13, 69,150,249, 69,167, +211,241,229,166, 77,140, 15, 62,252,112,238, 60, 26,109, 1, 12, 6,171,207,167,249,161,157, 74,165,130, 70,163,161,184,184, 24, + 37, 37, 37, 40, 46, 46, 70,113,113, 49, 56, 28, 14,200,151,188, 8,232, 31,236,159,101, 22, 89, 13,223,235,173, 92, 45,134,119, +104,141, 51,188,181,194,192,216,138,249, 93,107,132,150, 66,161,184,120,233,210,165, 30, 99,198,140,161,221,186,117, 11,158,158, +158,245, 66,203,252,110,158,142,226,114,185, 56,126,252,184, 78,161, 80, 92,180,112, 49, 93, 58,115,230, 76,212,234,213,171,233, +111,191,253, 54, 50, 51, 51, 49,123,246,108, 72, 36, 18,200,100, 50, 84, 85, 85, 65,169, 84,162, 71,143, 30, 96,179,217,120,240, +224,129, 94,169, 84, 94,178, 96,177, 35, 69, 34, 81, 45,159,207,247,106,252,219,132, 9, 19, 60,126,248,225, 7,101,118,118,182, +190,119,239,222, 14,214, 10, 14, 51,126,251,237,183,122, 75, 93,110,110, 46,126,248,225,135,122,159,172,212,212, 84,108,222,188, +185, 62,246, 89, 43,113,167,178,178,210,160,215,235, 17, 24, 24, 8, 31, 31, 31,168,213,106,108,217,178,197, 0,224,206,255, 87, +111, 86,171,213, 71,167, 77,155,246, 81, 90, 90,154, 23,141, 70,123,106,210,174,171,159, 78,167, 67,126,126, 62, 50, 50, 50,144, +157,157,141,234,234,234,250, 7,129,123,247,238,213,232,245,250,195,205,241,242,249,252, 85,191,252,242,139, 39,151,203,125,166, + 63,155,173,161,102, 43,169, 88, 44,134,147,147, 19, 6, 13, 26,228,126,233,210,165, 85, 26,141,102,245,191,100, 76, 35, 38,140, +205,237,254,193,123, 99, 48, 46,150, 91, 26,159, 80,118,125,243, 87, 75,234,156,225,221, 51,198,197,250,148,222,207,113,194,132, +177, 39,186, 3,120,130,150, 29,182, 77,151,147,133, 39, 95,121,197, 57, 41,254,212,169, 61, 43,150, 45, 74, 93,186,100, 22, 95, +169,122,196, 14,104,195, 36, 0,160,160, 88, 75, 62,200, 52,169, 55,127,189, 40,117,195,166,239, 41, 21, 85,146,217,127,252,209, +124,120,131,134,226,133, 66, 1, 59, 32,180,159, 32, 40,184, 79,187, 91, 55,226, 96,199, 85, 33, 36,180, 59,134, 14,233,137,164, + 43,247, 80, 46, 86, 67, 40, 20, 66,163,209,180, 24, 46, 33,251,193,241,169, 36, 65,250, 19, 36, 81, 66, 80, 72,246,212,105, 51, +251,198,196,140, 34, 19, 18, 78, 25, 78, 28,143,187,118,248,192,182,163, 20, 6,157,166,210, 58,106, 9, 66, 45, 5, 37, 61,179, + 86,241,244,129,134,206, 98, 52,111,126,173, 11,236,218, 49, 60,212,115,234,180,217,142, 35,134,143, 38,207,156, 57, 97, 58,124, +104, 95,210,225,159, 34,227, 76, 20, 25, 67, 88,170,100, 73,101,122, 41, 73, 48,157,106,101, 38,101, 69, 65, 7,181,119,204, 4, + 29,112,212,166,174, 26,142, 3, 26,205,147,218,210, 82, 47,151,126,253, 88,249,107,215,114, 61,122,244, 80, 19,117, 62,196, 45, + 9, 45, 42,149, 10, 80, 40, 38,107, 56,173, 45,139, 74,165,130, 9,208, 63, 15,167,193, 96,120, 70,100,153,133,150,249,122,177, +134,115,215,154, 53,183,252,135, 14,173,190,114,229,138, 71,255,254,253, 9,185, 92, 14,185, 92,254,140,216,242,246,246, 38, 58, + 70, 68,112,127, 75, 74, 10,176,246,124, 90, 83,119, 10,133,242,210,133,214, 63, 28,205, 38,146,110, 49, 5,143,217,162,101,141, +208,178,210,162,165,215,235,245,112,119,119, 71,101,101,101,179, 3, 63,133, 66, 1,135,195, 49,207, 17,183,184,242, 78,163,209, +108, 89,186,116,233,252,225,195,135,187,133,132,132, 64, 44, 22,195,195,195, 3,108, 54,187,222,119,204,204,151,154,154,138, 95, +126,249, 69,166,209,104,182, 88,224,252,118,211,166, 77,239,141, 27, 55,206,197,211,211, 19,206,206,206,120,240,224, 1,156,157, +157, 33,147,201,144,147,147, 3,123,123,251,122,191,157, 83,167, 78,201, 53, 26,205,183, 22,196, 27,153,146,146,162,179,183,183, +127, 32, 22,139,169,213,213,213,180,154,154, 26,154, 76, 38,163, 75,165, 82,250,185,115,231,220, 28, 29, 29,149,151, 47, 95, 22, +251,251,251, 83, 31, 63,126, 76,213,235,245, 22,213, 43, 65, 16, 88,176, 96, 1, 24, 12, 6, 52, 26, 13,182,108,217,130,165, 75, +151,214,251,100,109,218,180, 9, 43, 87,174,172, 23,206,187,119,239,110, 85,207, 33, 73, 18, 58,157, 14,122,189, 30,122,189,222, + 42,241,251, 87, 96,165, 96, 47,207,203,203,139,125,229,149, 87, 46, 28, 57,114,196,181, 46, 38, 25, 42, 42, 42, 80, 81, 81, 1, +177, 88,140,218,218, 90, 24, 12, 6,248,248,248,160,162,162, 2, 39, 78,156,144,202,229,242,161,104, 97,197, 33,149, 74,157,214, +183,111, 95, 90,227, 50,152,159,242,204,226,157,197, 98, 65, 32, 16, 96,192,128, 1,204, 43, 87,174, 76, 3,240,143, 22, 90, 13, +195, 59, 12, 25, 58,131, 17, 22,222, 75,123, 63, 35,161, 52,180, 93, 69,233,148,209, 14,167, 1,224, 94,122,133,227,253, 28, 39, +132,133,199,146, 67,134, 58, 71, 85,148,239,138, 4,160,107, 41, 93, 15, 0, 56,114, 89, 19, 7, 71,247, 16,216,243,120,148,205, + 95,239, 62,251,227,143,223,118, 59,122,250, 63,225, 29, 54,127,253, 52,188,195,224,232, 30,166,236,172,236,137, 0,126,178, 86, +188,196,198,142, 76,251,101,239, 47,200,206,184,236,253,209,130, 78,204,234, 10, 61, 56,118,126,136,234,226,129, 93,123, 31,226, +254,253,251,229, 90,173,118, 64,139,253,155, 32,253, 51, 50,211,131, 35,195, 59,122, 78,157,246,174, 67,108,236,104, 36, 36,156, +196,129,125, 63,165,140,159, 60,238,231,178, 26, 25,213,157,206,101,112, 73, 19,147,202,112,164, 49, 88, 28,145, 86,251,116, 13, + 4,157,206,118, 0, 38,182, 56,240,204,121,119,138,227,192,232,209, 56,125,230, 36, 14,236,219,149,252, 73,248,132,159,218,117, + 13, 35,122,116,251,106,110,187,246,237,218, 40,106, 43,100, 20,130,169, 83,171, 77,246, 95,237, 43,250,166, 96,229,180, 2, 0, + 95,195,182,234,176, 33, 30, 28, 24, 49,226,149, 15, 30, 61, 98,240,251,244,225, 8,146,146,184,117,153, 72, 90, 20, 90, 52, 26, + 13,100,243, 83, 93,207,112, 18,251,247, 83, 0,180,184, 8,139,193, 96, 64,169, 84, 66,223,188, 5,251, 25, 78,175,243,231, 75, + 31, 61,122, 20,228,226,226,242,140,200,170,174,174,174,255,172, 86,171,161, 84, 42,193,225,112, 50, 84, 77,207,136, 60,195, 89, +145,146,162,222,184, 96,193,234, 55, 38, 79,222,118,241,210, 37,182,171,171, 43,164, 82,233, 51, 66, 75,171,213, 98,224,160, 65, +140, 77,105,105, 83, 33,147,173,177,230,124,122, 12, 24, 96,209, 31,152, 74,165,194,244,146,167, 14,255, 5,120,183, 41,225, 69, +177, 52,133, 99,237,170,195,102, 6,200,198,217,189, 87, 70, 69, 69,169,115,115,115,225,239,239, 95, 47, 86, 26,254,167,131,131, + 3,156,156,156,144,154,154,138,207, 63,255, 92, 5, 96,165, 5, 78,185, 82,169,124,125,240,224,193, 42, 26,141,134,208,208,208, +250,248, 89, 38,147, 9, 76, 38, 19, 60, 30, 15,105,105,105, 24, 57,114,164, 82,169, 84,190,142, 63,199,208,106,204, 41, 85, 42, +149,111, 14, 25, 50, 68,153,153,153,137,190,125,251,226,254,253,251,168,173,173, 69,109,109, 45, 10, 11, 11,209,177, 99, 71, 40, +149, 74,252,240,195, 15, 42,165, 82,249, 38, 0,105, 75,156,114,185,124,228,210,165, 75,169,191,254,250,107, 59, 31, 31,159,240, +238,221,187,135, 12, 26, 52,168,195,216,177, 99,219,140, 24, 49,194, 43, 40, 40, 72, 61,116,232, 80,254,240,225,195,249, 74,165, +146,126,253,250,117,161, 94,175, 31,110,161,156,245,226, 36, 55, 55,183,126,170,144, 70,163,161,178,178,178, 62,114,191,249,166, +212,140, 16,142,182, 36,182,205, 2,203, 44,184,172,240,115,107,138,211,226, 65, 76, 38,211,108,241, 36,173,224,188,151,149,149, + 53,184, 95,191,126,247,102,204,152, 33, 47, 47, 47,135,189,189, 61, 2, 2, 2, 16, 28, 28, 12, 55, 55, 55,232,116, 58, 28, 63, +126, 92,113,226,196,137,135, 82,169,116, 0,254, 28, 67, 43,186,209,121, 44,108,234, 38,107,182,102,153,133, 22,155,205,134,143, +143,143,249,220, 22,182,230,124, 62, 39, 94, 46,103,157,128, 25, 52,112,104,251, 17, 49, 99, 28,143,159,188,193,220,182,253,196, +195,168,104,236,118,109, 43, 59,229,218, 86,118, 42, 42, 26,187,183,109, 63,241,240,248,201, 27,204, 17, 49, 99, 28, 7, 13, 28, +218, 62, 51, 35, 59,164, 97,222,195,166,202,201,102,179,123,245,237, 19, 85,115,229, 90,178,105,195,166,239, 41, 3, 7,140, 79, +251,233,231,227,199,127,250,249,248,241,129, 3,198,167,109,216,244, 61,229,202,181,100, 83,223, 62, 81, 53,108, 54,187,151, 53, +117,159,243,238, 20,199,152, 17,163,145,144,112,220,112,244,183, 31, 54, 29, 58,150,215,111,230,252,148,138,220,220,251,164,232, +201,121,208, 41,197,200,202,202,146,214,137,172, 92,107, 56,103,207,154,210, 80,100, 93,117,245,236,187, 59, 43, 11,198,196,196, +223,245,151, 46,165,169,174,222, 19, 73,239,102, 86, 86, 11,196,213,143,101,178, 42,173,201,100,132,209,104,164,174, 91, 87,239, +176,219,100, 27,245,238,221, 31,151, 47, 30,196,190,189, 59,165, 38, 19,212, 19,143, 30, 53, 78,156,184,150,108,211,182,109,155, +184,223, 14, 18,177,163,198, 56,146,128,105,228,184,209, 78,191, 30,250,149,104, 31,216,190,109, 64, 64,125, 72,155,127, 94, 95, +122, 9,156,107,129, 26, 89,113,113,114,234,247,223,107, 60, 94,127,221,133,233,225,225, 0,163,145, 48,223,223,155,123,209,104, +180,198, 22,152,102, 57,125,220,220,202, 78,157, 58,133,224,224, 96,248,248,248,160,161,143,172, 57, 32,183,171,171, 43,142, 29, + 59, 6,242,217,224,212,205,114,118,109,215, 46,245,203,141, 27,181, 38,147, 9, 53, 53, 53,127,178,102,213,212,212,192,100, 50, +225,204,233,211, 90,217,211, 76, 32, 86,213,125, 0,149, 90,251,198,107,175,109,136,137,137,209, 61,122,244, 8, 38,147, 9, 13, + 45, 91, 34,145, 8,118,118,118, 80,107, 52,126, 0,184,214,112,138,206,157,227,193,194,125,189, 9,139,214,203,104,247,127,186, +200,106,152, 80,250, 93,171, 44, 90, 6,131, 1,126,126,126,207,164,116,161, 80, 40,207,188, 90,185,226,112,127,102,102,230,249, +161, 67,135,174,126,245,213, 87,231,172, 94,189,154, 26, 18, 18, 2,169, 84, 10,103,103,103,184,187,187, 35, 39, 39, 7,167, 78, +157, 50, 86, 86, 86,238,116,181, 93, 44, 0, 0, 32, 0, 73, 68, 65, 84, 0,176, 30,214, 45,161, 79,202,203,203,139,237,212,169, +211,161,229,203,151, 59, 14, 25, 50,132,238,231,231, 7,146, 36,145,150,150,134,248,248,120,221, 79, 63,253, 36,171, 19, 89,214, + 58, 47, 95, 16, 8, 4,227,135, 15, 31, 30, 55,109,218, 52,123,163,209, 72, 47, 44, 44,132, 70,163,129, 94,175, 71, 73, 73,137, + 46, 33, 33,161, 86,169, 84, 78, 1,112,193, 10,190, 84,137, 68,210, 49, 49, 49,113,218,245,235,215, 63,159, 49, 99,134,235,160, + 65,131, 24, 6,131, 1,215,174, 93, 19,119,237,218,213, 93, 36, 18,233,142, 29, 59, 86,165, 86,171, 87, 26,141, 70,171, 82,240, + 16, 4, 1,153, 76, 6, 55, 55, 55,104, 52, 26,152, 76, 38,104,181, 90,216,217,217,213,167, 77, 34, 73, 18,173,113,174,111,212, + 7,168, 58,157, 14,147, 39, 79,134,201,100,194,150, 45, 91, 96, 48, 24, 90, 77,230,232,232,120,247,222,189,123,177, 93,186,116, +169, 23, 47,230, 62,196, 98,177,224,230,230, 6, 87, 87, 87, 36, 36, 36,128, 78,167,223,181,228,239, 86,135,251,149,149,149, 93, + 19, 19, 19,123, 61,124,248,240, 45, 0, 93,116, 58,157,143,209,104, 36, 40, 20,138,144, 36,201, 7, 50,153,236,103, 88,153,130, + 71, 36, 18,125, 62,125,250,244,174, 7, 15, 30,180,163,209,254,115,105,208,104, 52,176, 88, 44,152,131, 99,146, 36, 9,173, 86, +139, 85,171, 86,201, 20, 10,197,231,255,150,187, 68, 84,247, 30,216,245,195, 86,187, 75,151,207,139,179,242, 16,223, 68, 8,135, + 39, 21,229,187, 34, 5,165,165,118, 81,221,123, 88,197,169,215,234,170,222,156,178,216,191, 46, 5,207,170,194,194,162,157,113, +251,191, 41, 0,128,175,190,221, 18, 84, 81, 37,153,157,157,149, 61,113,231,206,223,122,233,181,186, 42,107, 56,255, 35, 94,226, +164, 32,161, 6,112, 59,237, 97, 69,187,145,175,159, 91, 25,216,222, 97,148,168, 74, 85, 86, 91,171,124, 31, 64,129,181,117,239, +211,187, 31, 46, 95,248, 21, 7,246,197,201, 72, 19, 85,237,230,230, 70, 2, 64, 86,150, 27,153,149, 37, 33,255,227, 87,236,164, +160,147,247,215, 47,126,127,208, 98,169,172,250,219, 45, 63,180, 60,149,210,169,243,171,232,212,249, 85,204,127,255, 99,199,142, +225,161,254, 0,112,244, 40,140,225,129,153,191,175,254,100,237,168,245,235,215, 66, 38,215,192,156,174, 39, 39, 61,243,116, 65, + 1,180,182, 49,235, 89,172, 54, 24,110, 99,241,226, 32,101,117, 53,191,207, 71, 31,185,209, 62,252,144,210,146, 51,124,195,235, +215, 26,206, 59, 15, 30,156,158, 61,115,102,217,154,213,171,135,238,216,185,147, 19, 25, 25,137,242,242,114,132,134,134,194,199, +199, 7,137,137,137, 56,118,248,176, 66, 34,151,175, 4,240,163, 53,156,251,207,156,201, 9, 9, 15,175,220,185,115,167,119, 76, + 76, 12,161, 80, 40, 32,149, 74, 33,149, 74,161,209,104, 80, 23, 16,154,204,205,203,203,210,235,245, 59,172,173,187, 81, 44,102, +175,239,209,227, 9,195,100,250,114,252,184,113, 75,215,127,250, 41,171,125,251,246,132, 70,163,169,183,106,233,116, 58,216,217, +217,233,180, 90,173, 43, 0,165, 53,156,172,159,126, 50,136,197, 98,240,249,252,250,112, 77, 13,227, 18,202,229,114,144, 36,105, + 11,166,251, 28,104, 86, 33, 57, 59, 59,223,165,209,104,190, 13,173, 91, 77,229,206,107,184, 77,175,215, 63,169,172,172,140,106, +164,120,155,243,135, 10, 0,240,197,192,129, 3,199, 47, 89,178,132,184,114,229, 10, 78,156, 56, 65, 22, 20, 20, 28,173,179, 98, + 21,180,240,164,211, 28,167, 61,139,197, 90,200,227,241,162,205, 33, 28,184, 92,238, 67,133, 66,113,177,110,186, 80,254, 28,156, + 14, 44, 22,107, 1,143,199, 27, 92,151,126, 5,246,246,246,247, 20, 10, 69,162, 70,163,217,138,230, 19, 85,183,196,201,113,116, +116,252,220,205,205,237,205, 15, 63,252,208, 53, 37, 37, 69,120,249,242,101,134, 68, 34, 57,168,213,106, 91, 74, 42,253, 39, 78, + 23, 23,151,187, 84, 42,213,247, 37,181, 17, 58,117,234,148, 48,114,228,200,152, 41, 83,166, 64,175,215,227,199, 31,127, 68, 98, + 98,226,233,252,252,252, 88, 11, 79,163,141, 57,221,124,125,125,175,204,153, 51,167,205,228,201,147,185,206,206,206,160,209,104, + 80, 40, 20,200,207,207, 71, 90, 90, 26,121,242,228,201,218,212,212,212, 39, 74,165,178, 63,128,202, 86,156,207,191,242,212,252, + 12, 39,141, 70,235,231,231,231,247,219,154, 53,107,236, 7, 15, 30,204,113,117,117, 5,149, 74,133, 94,175,135, 80, 40, 68,122, +122, 58,206,159, 63,175, 56,122,244,168,162,170,170,106, 50,128,228,255,143,114,190, 72,206,176, 32,124,210, 40, 81,116,179,209, +222, 45,236,107,177,156, 3,251,121,141,158, 56,126,248, 48, 0, 56,114,236,236, 57, 43,146, 74, 55, 91, 78, 75,101,181,134, 51, + 52,144,178, 38, 35, 51,253,153,128,150,225, 29, 35,114,195, 34,199,125,102, 13, 81,131,200,240,207,212,189,193,116,108, 67,155, +238, 51,211,172, 97, 1,136, 29, 61,113,108,204,199, 43, 87,224,139,207, 55,224,228,145,227,167,179, 10,158, 73, 19,244,143,235, + 75, 47,153,147,248,140, 70,123,149,235,229,245,218, 22,147,105,197,253,244,116,187,134, 15,108,102,203,115,195,135, 74,111,111, +111,145, 80, 40,244,176,134, 51,246,187,239,116, 74, 30,143,181,226,203, 47,251,213,170,213,253,214,175, 95, 79,187,115,231, 14, +126,248,254,123,131,250,201,147, 56, 49,176,160,153,217,144,102, 57,219, 44, 88,192, 94,246,195, 15,111, 7, 4, 6,186,191,245, +214, 91,116, 58,157, 14,133, 66,129,210,210, 82, 92, 56,127, 94,155,153,149,149, 41,147,201, 70, 1, 16, 88,203, 25,251,221,119, + 58,167,128, 0,112,249,124,242, 82, 82,146,227,236,133, 11,231,180,109,215,206,113,232,176, 97,116, 7, 7, 7,212,212,212,160, +176,176, 16,199,143, 31, 23,213,214,214,122, 3, 48, 90,195, 25,119,253,122,167, 51,201,201, 19, 62,251,236, 51,102, 68, 68, 4, + 28, 29, 29, 33,151,203,145,158,158,142,228,228,100,205,142, 29, 59,164, 82,169,116,142,209,104, 60,245, 18,219,253,223, 96,213, + 50, 99,151, 69,161,245, 95,188, 0,163, 0,124, 82,247,249, 83, 88,206, 25,248,111,186,249,248,187,184,184,236, 82,171,213,164, + 74,165,154, 13,160,228,111, 88, 78, 90, 84, 84,212, 15, 34,145,168, 23, 73,146,112,116,116,188,145,145,145, 49, 15,205,172,188, +177,192, 73, 5,208,203,206,206,174,135,189,189,125, 63,141, 70, 19, 86, 55,253,150,165, 80, 40,146,117, 58,221,237, 58,235,147, +241,255,185,238, 84, 0,131,189,189,189,103,154, 76,166, 64,130, 32,156,140, 70, 35,244,122,189,196,100, 50,229, 75,165,210,159, + 0, 36,254, 13,202,249, 66, 56, 59,118,192, 88,146,130,176,230, 4,193, 51, 66,171,145,128, 32, 76,200,202,124,132,227,173, 40, + 39,101,120,180,223,118,224,233,202, 68, 88,118,174,253,143,208,178, 66,188,180, 90,100,118,160, 78, 39, 9,242, 25, 78,130, 36, + 74, 66, 59,141, 61,240, 87,132,150,181,232, 24,140,126, 32,209,203, 68,226,118,118, 62, 46,255,139,239,117, 47,140,243, 11,192, +229,123,103,231, 27, 20, 26,205, 19, 0,165,206,250, 98, 50, 17,132,145, 36, 8, 67,195,233,173, 70, 15,150, 45,114,234,128, 72, + 58,139,229,103, 52, 24, 60,202, 1,187, 51, 70, 99, 55, 53, 73,214,250, 2,159,220, 3,114,158,167,156, 58, 32,146,202, 98,249, +159, 33,201,209, 98, 30,175,147, 72,165,226, 3, 32,237,120,188, 44,153, 66,177, 79,173, 86,111,199,159,103, 46, 44,114, 50, 88, + 44, 95,163,193,224, 1, 0, 20, 26, 77,116, 72,163,241,123,226,224,240,150, 90,163,105, 99,103,103,167,215,106,181, 50,181, 90, + 61,197, 96, 48, 92,106, 77,221,243, 13,134,142,215, 41,148,190, 58, 30,207, 85, 71, 16, 60,173,193,160,211,234,116,165,106,181, +250, 33,128,111, 0, 60,122,201,237,110,195,115, 94, 44, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56, 95, 62, 39, 23,128, +127,221,195,226, 63,177,238,255, 38, 88,231,163,101,131, 13, 54,216, 96,131, 13, 54,252, 99,160, 68, 19, 62, 89, 54,252,255,130, +104, 65,149,182,198, 36,248, 60,202,246,162,141,211,198,105,227,180,113,218, 56,109,156, 54,206,255, 57, 78, 75,220,255,196, 41, +201,102,115, 29,190,108,216,204,191, 54, 78, 27,167,141,211,198,105,227,180,113,218, 56,255,103, 65,177,157,130,102,225, 81,247, +122,209,251,218,240,239,238, 11,255, 13,248,212,189, 90,179,191,151,173, 25,109,176,193, 6, 27,254, 55,132,150,181,131,214, 95, + 25,220,254,234,192,184,129, 32, 32, 32, 8, 8, 0,108,120,129,251, 90,130,183,155,155,219, 7, 29, 59,118,140,243,240,240,152, + 15,192,189,149,199, 7,113,185,220,173, 60, 30,239, 10,143,199,187,194,229,114,183, 2, 8,122, 65,237, 70, 0,152,205, 98,177, +146,188,188,188,202,152, 76,102, 18,128, 57,120,254,149,171, 33,120, 26, 39,237, 83, 0,157, 90,115,160,123,248,232,195,252,240, +209, 15,248,225,163,211, 93, 35, 70, 6,241,195, 71,167,243,195, 71, 63,112, 15, 31,125,248, 37,244,215, 23,217,190, 47,170, 60, + 37, 4,129, 18, 43,203,243, 13, 1,148, 18, 4,158,252, 77,202,111,131, 13, 54,216, 96, 67,179, 42,192,219,123,188,151,151,215, + 69, 47, 47,175, 68,111,111,239,241, 86, 28, 18,221,196, 32, 97, 36, 8, 24, 45,220,244, 91,218,207,146,185,178,225,177,155,173, +172, 90, 67, 78, 15,130,128,145,172, 3, 65,192,228,238,238,190,205,203,203,107, 67,227,151,187,187,251, 54,130,128,169,193,190, +198, 6, 2,175,181,102, 85,143,169, 83,167, 30,169,169,169, 73,208,106,181, 9,121,121,121, 9,253,251,247, 63,212,200, 18,209, + 44, 39,155,205,126,227,149, 30,189, 82,147,175,221,206,203,205, 47, 18,100,230, 60, 46,250,253,220,165, 59, 17,145,157,254, 96, +179,217,111,180,162,141, 8, 0,179,105, 52, 90,146,157,157,221, 19, 26,141,150, 4, 96, 46,149, 74, 61,181,113,227,198,162,140, +140,140,138,235,215,175, 75,146,147,147,203,102,204,152,145, 79, 16,196,239, 77, 8,246,104, 43, 44, 48,171,139,139,139,207, 9, +133,194,243, 28, 14,231,115, 43,246,175,231,228,135,143,126, 32,146,234, 72,145, 84, 71,242,195, 71,147, 13, 62, 63,104,229, 57, +183,212, 70,127,234, 11, 44, 22,203,223,130,160,127,153, 38,250, 63,149, 7,128,103,221,111, 81, 0,190,171,123,153,151,179,123, +178, 89,172, 23,213, 63, 95,196,249,180,113,218, 56,109,156, 54,206,127, 43,186,214,189,123,225,169,191, 86,253,216,221,218, 85, +135,239,229,229,229,217, 1, 64,112,112,240, 60, 0,199, 90, 35, 36, 8, 2,203, 76, 38,146, 2, 0, 20, 10,241,209,128, 1, 3, +187,114, 56,156,103,162, 32,171, 84, 42,102, 82,210,229, 65, 38, 19, 73,212,237,183,140, 36,177, 21, 64,133,181,255,161,213,106, + 40,116, 58, 19, 20, 10,177, 56, 34, 34,178,109,101,101,101, 10,133, 66,137, 43, 43, 43,171,105,181, 25,135, 32,176,123,247,238, + 96, 47, 47,175, 63, 69,107, 22, 10,133,204,209,163, 71,181,138,111, 58,192,210,176, 88, 61, 24, 4,225,101, 52, 24,156, 0,128, + 70,163,213,220, 97, 50,163,190,248,236, 51, 46, 65, 16,166,170,170, 42,168, 84, 42, 44, 90,180,136,147,153,153, 57,166,178,178, +114,187, 5,218,224, 78,157,187, 46, 58,127,254, 92,152,172,186, 70,189,251,219,157,169, 42, 26, 67,217,174, 99, 40,227,135, 93, +251,156,223,125,123,202,251,217,217, 25,247,208,116, 58,146,134,160, 0, 56,190,112,225,194,240,216,216, 88,166, 92, 46,103,171, + 84,170,182,113,113,113,171,162,162,162,236,186,116,233,194,252,237,183,223, 8,169, 84, 10,146, 36,185,161,161,161,228,164, 73, +147,212,135, 14, 29,154, 15, 96, 91, 11,194,119,217,211,115, 73,217, 18, 18, 18,178, 6, 0,242,242,242, 24, 13,206, 49, 61, 44, + 44,140, 7, 0, 57, 57, 57,235, 72,210,180, 16, 0, 72, 18,155, 0,172,104,194,180,150, 23,222,103, 34, 64, 32, 48,227,218, 17, +118,120,223,137,106,144,200, 39,128,188,186, 7,130,245, 64,131,184, 80,207, 34, 75, 32, 16, 60, 87,110,194,152,152, 88,130, 32, +136,163,169,169,169,199, 68, 34, 81, 59,147,201, 56,171,165,114, 54,215, 86,124, 62,255,188,209,104,212, 84, 87, 87,215, 7,202, +228,119, 26,219,203,213,158, 55, 72, 92, 35, 79,169,202, 60,153,108,101,223, 36, 92, 93, 93,167, 87, 86, 86,110, 0, 48, 51, 43, + 43,171, 43, 0,132,133,133, 49, 0,220,117,112,112,232,173,211,106, 9,219,253,207, 6, 27,108,176,225,191, 34,180,210, 0,196, +224, 63, 41,120,118, 61,143,208, 98, 2, 64, 74, 74, 10, 0,176,158,163, 32, 68, 67, 1,179, 96,193, 2,120,121,121, 53, 22, 47, +184,114, 37,233,175, 84,246,153,255,248,244,211, 79,237, 36, 18, 73,244,207, 63,255,252, 26, 73,146,155, 5, 2,193, 45, 11,199, + 87,144, 36, 54, 81, 40,196, 71, 4, 65,128,197, 98,231,206,153, 51, 39,173,238,183,182,191,255,254, 59,119,228,200,145, 74, 0, + 69, 0,192, 98,177,125,168, 84, 74, 48, 73,146,230, 1,183, 89, 65, 56, 1, 8, 48, 48,153, 3,103,127,247,157,161,219,200,145, + 52, 30,159, 79, 0, 64, 81,118,182,235,166,175,190,234, 93, 83, 80,192, 84,185,186, 86, 85, 41, 20,170,220,220, 92,176, 88, 44, +130, 74,165,118,179, 84, 97, 30,143,247,193,103, 95,124,201,147, 85, 75, 84,106,153, 92, 75, 53,232, 53,246, 28,174,177,162, 92, + 84,101,199,225, 41, 63,250,100, 45,243,189, 89,211, 62, 80, 40, 20,243, 44, 80,205, 95,188,120,113,216, 43,175,188,226,115,248, +240, 97, 66, 42,149,130, 70,163,217,117,233,210, 5, 81, 81, 81,198,203,151, 47, 19,237,218,181, 67, 68, 68, 4,174, 93,187,134, + 27, 55,110, 16, 93,187,118,229,198,199,199, 79,213,235,245,219, 44,137,107, 42,149,178, 40, 52, 52,180, 11,143,199,211, 6, 7, + 7, 99,214,172, 89, 32, 73, 18,209,209,209, 17,118,118,118,199, 20, 10, 5, 51, 39, 39,251, 53, 75, 34, 91,148,113,114,146,217, +178, 5, 32, 18, 36,242,197, 25, 39, 27, 78, 63,134,229,228,228,188, 90, 83, 83,131,167,237, 66,214, 39, 48,127,237,181,215, 90, +211,151, 42, 72, 18,155, 70,142,140,253, 8, 32,136,232,232,104,201,252,249,243, 41,217,217,217,111,142, 29, 59, 38, 34, 47, 47, + 31,173,124, 24, 8, 30, 50,100,200,181, 51,103,206,184, 6, 7, 7,139,171,171,171,235,127,240,116,117, 26,154, 28,191,229,131, +207,183,198,133,238, 39, 9,137, 56,235,196, 67, 11,125,147,152, 62,253,237, 10, 59, 59,187,113, 71,143, 30,205, 17, 10,133, 52, + 6,163, 94,187, 82,221,221,221,249,193,193,193,115, 93, 92, 92, 68, 84, 10,197,157, 4, 73, 90,234,159, 54,216, 96,131, 13, 54, + 60, 55, 78,215,137,171,211,141,127,160, 1, 64, 66, 66, 66,125,100,218,216,216,216,102,159,128, 73,146,172,184,127,255,190,159, + 82,169, 4, 73,146,214,220,176, 27, 46,209,172, 32, 8,202, 15, 20, 10, 49,143, 32, 8, 68, 68, 68, 62,222,178,101, 75, 83, 57, +189,180, 17, 17,145,143,169, 84, 74,123,146, 36, 65, 16,148, 31, 73,210, 84,209, 12,103,147, 3, 17,147,201, 90, 6, 0,158,158, + 94, 5,103,207,158,213, 78,152, 48, 1, 95,125,245, 21, 99,249,242,229, 75,105, 52,218,252,146,146,146,242, 22,202, 9, 0, 43, +248,124,119,238,238,221,187,131,231,204,153,147, 38, 20, 10, 87, 0,128,151,151,215, 6, 0, 29, 1, 20, 53,216,134, 29, 59, 14, +149,205,154, 53, 43, 87, 36, 18,173,104,142,115, 28,208,193, 47, 52,116,224,250,148, 20,146,162,209, 16,149, 87,175,202,196, 21, + 21,250, 71, 98, 49,119,239,221,187,177,171, 54,108,160,251,249,251,227,202,169, 83,110,149, 74,165, 88,170,209,168, 43, 42, 42, + 72,131,193,112,195,138,186,135,187,243,221,185, 59,191,249,241,142, 61,157,106,114,247,245, 33,232, 46, 46, 52, 10,215,129, 73, +165, 81, 52,237,219, 6, 49, 1,132, 91,106, 35, 6,131, 49,117,200,144, 33,220, 67,135, 14, 17, 17, 17, 17,112,114,114,194,213, +171, 87,113,239,222, 61,212,212,212, 80,244,122, 61,186,119,239,142, 47,191,252, 18,254,254,254,144, 72, 36, 40, 41, 41,113, 99, + 50,153,124,189, 94,223,220,249,124,166, 63, 45, 91,182, 12, 94, 94, 94, 48, 24, 12,168,174,174,134,193, 96,128,157,157, 29, 0, +224,201,147, 39, 56,117,234,164, 53,125,201, 34, 72,146, 68,207,158, 61,229, 4, 65,100, 53,182,104,181,134,211,199,199,231, 55, +177,184,114,248,192,129, 3, 81, 83, 83,163, 95,187,118, 45, 58,117,234,132,224,224, 96,139,229,244,246,246,158,109, 48, 24, 86, + 3,128, 78,167,219,203,102,179,223, 57,112,224,128,107,195, 20, 33,102, 75, 86,133,168,170,230,198,157,140,156,197,179, 39,244, + 79,185,149, 94,170,163,143, 46,145, 62, 56, 41,109,162,156, 43, 24, 12,230,207,109,218,180,249,102,193,130, 5, 94, 46, 46, 46, +208,104, 52,171,202,203,203, 49,119,238, 92, 0,192,136, 17, 35, 58,209,233,244,179, 51,102,204, 64,187,118,237,202,170,171,171, + 75, 82, 83, 83,103, 41,149,202,244,231, 61,159, 86,194,198,105,227,180,113,218, 56,159, 27,214,106,145,191, 41,132,120, 54,156, +195,174,103,132, 86,108,108, 44,145,144,144, 64, 90, 81,177, 42, 95, 95, 95, 63, 14,135, 3, 0, 85,173, 45,133,201,100,154,239, +234,234, 42, 90,177, 98, 69,159,224,224, 96,237,252,249,243,211,139,138,138, 86, 54,220,167,109,219,182,159,127,255,253,247,200, +205,205, 45,218,176, 97,195,181,170,170,170,214,230, 49, 91, 78,146,216, 82,103, 29,171, 60,117,234, 84,167,148,148,148,121,223, +126,251, 45,255,189,247,222, 99,124,240,193, 7, 83, 0,124,101,137,132, 74,165, 42,155,154, 46,108, 10, 94, 94, 94, 90, 42,149, +218,108,144,184, 88,128,195,102, 50, 7,172, 79, 73, 33,181, 69, 69,202, 95,190,254,218,126,231, 31,127,172,209,147,164,135,187, +187, 59,250,246,238, 93,203,166, 82, 43, 69,229,229, 38,247, 14, 29,168,133,103,207,186,169,152, 76,193,161, 67,135,164, 85, 85, + 85, 39, 44,154,240, 8, 66,102, 34, 73,173,157,175,191,126,194,152,193, 17,119,110,223,203,182,119,119,163,116,237, 18,209, 41, + 59,183, 40, 21, 38,147,142, 32, 8,153, 37, 30, 71, 71,199,224,170,170, 42,200,100, 50,240,249,124,108,217,178, 5,158,158,158, + 80, 42,149,200,200,200, 32,125,125,125,137,148,148, 20,248,250,250, 66, 44, 22, 67,171,213, 66, 46,151,139, 52, 26, 77,115,185, + 25, 43, 40, 20,234, 30, 10,133,120,155, 32, 8,180,111, 31, 80,188,125,251,118,173,201,100, 66, 88, 88, 24,198,142, 29,139,248, +248,120,100,100,100,152, 45, 79,218, 54,109,218, 22, 83, 40, 68,155, 58,173,244,220, 22, 24,115,106, 31,129, 64, 48,238, 57, 47, + 26,138,183,183,247,148,192,192,192,121,111,188,241,134,158,201,100, 66,161, 80,152,207,133,126,248,240, 17,146,145, 35, 99, 29, + 79,159, 62,221,108, 57,117, 58,221,234,178,178, 50, 47,149, 74,133, 97,195,134,125,176,121,243,102, 30,147,201, 4, 0, 24,141, +198,103, 44, 89,159,125,187,255,252,194,213,219,147,206,255,246,165,247,103,203,223,233, 63,101,254,231, 73, 0,206, 53, 85, 48, +173, 86, 91, 32,149, 74,103, 46, 94,188, 56,110,199,142, 29,206, 43, 87,174,132,201,100, 2, 73,146, 48, 24, 12,245,137,196, 77, + 38, 19,142, 31, 63,142, 71,143, 30,125,222, 72,100,217, 96,131, 13, 54,252,237,208, 10, 45,242,119,132, 23,158, 78, 27,162,177, +216,250,175, 71,134,167, 82,169, 59, 47, 92,184,208,229,181,215, 94,163, 13, 26, 52, 40,226,220,185,115, 17,101,101,101,233,117, +214,131,136, 65,131, 6, 69,184,187,187, 99,235,214,173, 74, 42,149,186,243, 57,255,166,126,208, 43, 47, 47, 79, 3,176, 57, 62, + 62,126,211,236,217,179,225,233,233,217, 81, 40, 20,254, 87,235,236,192, 98,117,157,177,101,139,129,174,215, 83,190,219,188,217, +225,235,164,164, 77,135,143, 28,161,245,236,217,147, 32, 73, 18, 15, 31, 60,224,124,185,109, 27,119,242,152, 49, 69, 57, 5, 5, +134,147,231,207,235, 43,202,202,170,203,196,226,213, 0,170, 45,241,235,245,250,155,121,121,121,222,125,251,245,244, 73,254, 35, +253,222,132, 49, 35, 6,210,105, 20, 34,191,232,201, 93, 47, 79, 55,199, 43, 73, 23, 85,122,189,254,166, 37, 30,133, 66, 81,104, + 48, 24, 92, 72,146,228, 95,185,114, 5,124, 62, 31, 53, 53, 53,208,235,245,208,106,181, 90,165, 82,201,174,170,170,130, 90,173, +134, 70,163,129,131,131, 3, 30, 62,124, 88, 97, 48, 24, 46, 55,199,105, 52, 26,103,176, 88,172, 79,233,116, 58,147,193, 96, 8, +238,222,189, 11,153, 76,214,214,201,201,233, 43,131,193, 0,129, 64,128,148,148,148, 15, 29, 28, 28,138, 0,128,205,102,131,201, +100,185,106, 52, 26, 3,128,178,231, 61,231, 36, 73, 62,119,123,121,122,122,250,115, 56,156,245, 31,125,180, 44,172,115,231, 46, + 16,139,197, 48,153, 76,224,241,120, 80, 42,149,112,112,112, 64,175, 94,189, 10,215,175, 95, 47, 36, 73,188,219,130, 24,164,214, +181, 15,102,207,158,205,115,112,112, 64,105,105, 41, 66, 67, 67,235,133,150, 80, 92,245,240,250,157,244,236,197,115, 38,246, 59, +120, 42, 41,235,252,149,187, 89, 99,134,245,238, 76, 16,100,219,150,202, 40, 18,137,196, 52, 26,109,254,236,217,179, 63, 13, 14, + 14,110, 79,146, 36,130,130,130, 48,100,200, 16,156, 61,123, 22,185,185,185, 80, 40, 20,198, 91,183,110,253, 42, 20, 10,127,183, +221,194,109,176,193, 6, 27, 94, 42,254,228,155,245,140, 69,235,191, 9,145, 72, 36,206,206,206, 62,151,154,154, 26, 59,105,210, + 36, 92,185,114,101, 58,128,197, 0,192, 98,177,166, 79,154, 52, 9,169,169,169,200,206,206, 62, 39, 18,137,196, 47,226, 63,153, + 76,166, 90,171,125,106,156, 98,179,217,236, 86, 30,222,182,110,202, 16, 0,218,182,176,173,121,211, 8,141,230, 21, 57,108, 24, +173,230,222, 61,217,238,219,183, 63,141,139,139,163,245,233,211,135,208,235,116, 48,154, 76, 8, 8, 8, 32, 6, 69, 71,243,246, +196,197,185, 24, 21,138,148,207, 62,250,232,234,174, 25, 51,106,243,234,252,192, 44, 65,163,209,108,155, 55,119,102,116,210,149, +171, 62, 29, 67, 59,184,156,187,144,148,230,234,234,200, 13, 14, 12,228, 85,213, 84, 27, 87, 46,255,144,166,209,104,190,179,196, +163, 82,169,142, 95,188,120,113,140,159,159, 31, 63, 61, 61, 29, 90,173, 22, 70,163, 17,131, 6, 13, 2, 73,146, 44, 0, 38, 26, +141,134,236,236,108,232,116, 58, 81, 94, 94,158, 32, 63, 63,159, 5, 96,163,133,242, 21,107, 52, 26,100,101, 61,157,181,243,245, +245, 29, 28, 19, 19, 3,131,193,128, 97,195,134,225,228,201,147,131,179,178,178,190,110,168,249,254,106,155,215, 89,200,194,188, +189,189,227,235, 54, 89,229, 4,239,227,227, 19, 17, 16, 16,176, 99,227,198,141, 12, 95, 95, 95,144, 36, 9,103,103, 39, 40,149, + 74, 84, 86, 86,161, 99,199,142,240,243,243,195,198,141, 27, 1,224,215,150, 44,110, 38,147, 9, 66,161, 16,133,133,133, 40, 40, + 40,128,159,159, 31, 8,130,128, 92, 46,135,193,240, 52, 39, 55, 87, 46, 59,253,253,158,223, 7, 28,217,177, 58,188, 71,100,144, +255,237,180, 76,209,212,113,131,185, 65,237,252,131,197,233,107, 41,192,218,102,147, 46, 11, 4,130,124,129, 64, 48, 73, 36, 18, + 49, 36, 18, 73,212,224,193,131,183, 70, 71, 71, 35, 45, 45, 13, 87,175, 94,157,204, 98,177, 68, 58,157,206,224,233,233,249, 46, + 65, 16, 14, 58,157,238, 96, 85, 85,149,208,118, 63,180,193, 6, 27,108,120,225, 48,251,104,161,193,123,235, 44, 90, 97, 97, 97, +188,162,162,162,183,218,182,109,203, 4, 0, 14,135,211, 49, 32, 32, 96,105, 65, 65,129,188,181,165, 81, 42,149,135,227,226,226, +134,124,243,205, 55,140, 17, 35, 70,116,136,143,143,127, 5, 0, 70,140, 24,209,193,222,222, 30,113,113,113, 58,165, 82,249,194, + 98, 34,233,245,250,215,186,119,239,142,234,234,106, 20, 21, 21,181,106, 10,229,247,223,127,231,226,169, 95, 86,139,219, 90,130, + 65,171,117,118,242,241,161,148, 37, 37,233,170,101, 50,175,215,250,245, 35,244, 58, 29, 40, 20, 10,170,170,170, 80, 82, 82, 2, + 71, 39, 39, 34, 59, 47,207,238,167,101,203,126,111,219,185, 51,211,168,213,186,182,162,152,138, 74, 81,197,219,239,207,127,239, +248,193,131,191,242, 37, 50,217, 35, 14,135,171, 97,177, 24,158, 11,222,127,223, 88, 93, 93, 61, 13, 64,173, 21, 60, 27, 15, 30, + 60, 56,108,216,176, 97, 15,252,253,253,221,197, 98,177,167, 68, 34, 49, 86, 87, 87, 83,241,212,215,138, 0,128,164,164, 36,200, +100, 50,131,209,104, 76,193,211, 88, 88, 90,107, 11,218,166, 77, 27,199,168,168,168,254,124, 62, 31, 82,169, 20,174,174,174,232, +210,165, 75,127, 42,149,250,115,113,113,177,244, 69,246,250,196,196, 68,123,146, 36, 95, 37, 73, 18,195,134, 13,179,234, 24,163, +209,248, 78, 76, 76, 12,131, 32, 8,168, 84, 74,176,217, 28,240,120,118,176,183,119, 64,112,112, 8, 4, 2, 1,134, 14, 29,170, +125,244,232,209, 15, 66,161,240,176, 5, 46, 8, 4, 2,136,197, 98,148,148,148,160,178,178, 18, 0, 80, 89, 89, 89,239,156,255, + 34, 32,149, 74, 71,247,234,213,107,201,220,185,115, 97, 48, 24, 48,122,244,104,148,150,150,126, 93, 88, 88,120,200,219,219,123, +202, 59,239,188,195,119,117,117,197,146, 37, 75, 56, 0,214,217,238,135, 54,216, 96,131, 13, 47, 28,141,125,180,254,108,209,106, +105, 78,212,211,211,179, 47, 65, 16,171, 84, 42, 21,211, 60, 37, 67, 16, 4,147,207,231,159, 84,169, 84, 27,132, 66, 97,171,156, +226, 36, 18,137,236,241,227,199, 39,111,222,188, 57,113,220,184,113, 72, 76, 76,156, 6, 0,227,198,141,195,205,155, 55,241,248, +241,227,147, 18,137, 68,246, 34,106,238,227,227, 51,188, 95,191,126,227,186,119,239,142,132,132, 4, 24,141,198, 27,173, 57,190, +225, 10, 67, 52,177,234,208,188,205, 42, 50, 42, 21, 4, 65,212, 91, 51, 42,197, 98,228,230,228,160,186,166, 6, 26,181, 26, 10, +165,210, 24,220,174,157, 74,170,213,210, 9,160,181,115, 95,197,169,119,110,149, 40, 21, 10,119, 87,103, 23, 21,151,203,130, 68, + 38,101,220,189,115,171, 22,192, 35, 43, 57,180, 36, 73,246, 59,123,246,236,106, 42,149, 58,201,206,206, 14,243,230,205,163,246, +239,223, 31, 12, 6, 3, 26,141, 6, 18,137, 4,113,113,113, 98,163,209,216,190,238, 24, 59, 46,151,187,143, 74,165, 62,145,203, +229,171, 44,254,129, 86, 59, 34, 54, 54,150,166,213,106,241,217,103,159, 97,205,154, 53, 24, 54,108, 24,237,206,157, 59, 35, 0, + 28,124, 81, 61,222,100, 50, 97,240,224,193, 13,157,225,179,172, 57,142, 78,167, 71, 4, 6, 6, 66, 44, 22, 67, 44, 22,131,207, +231,195,219,219, 27,158,158,158,248,250,235,175,201,173, 91,183,158,211,233,116, 63, 84, 86, 86, 86, 88, 83,134,130,130,130,122, +203,160, 90,173,134, 66,161, 64,105,105,105,253,212,161,138,231, 48,108,254,219, 35, 59, 43, 84, 42,229,237,135,121, 37,171, 62, +152,210, 83,161, 82, 41,243, 10, 75,114,129,109, 38, 43,250,247,187,211,166, 77,123,119,226,196,137,168,173,173,197,205,155, 55, +209,187,119,111,108,218,180,201, 43, 37, 37,101,113,247,238,221, 65,167,211,113,229,202, 21, 24, 12,134, 82,219,189,208, 6, 27, +108,248, 59,227, 31,234,159,213, 34, 90,180,104,249,249,249, 57, 25,141,198, 15, 99, 98, 98, 6,143, 25, 51, 6, 67,135, 14,125, +230,247,131, 7, 15,218, 31, 59,118,108,195,182,109,219,134,233,116,186,141,173,153,234, 51,153, 76,199, 15, 30, 60, 56,162,103, +207,158,220, 1, 3, 6, 4, 0, 0,139,197,210, 30, 60,120, 80,105, 50,153,142, 63, 71, 93,204,129, 24, 43, 0,192,219,219,187, + 19,141, 70, 27, 55,124,248,240, 78,111,191,253, 54, 50, 50, 50, 16, 23, 23,151, 31, 28, 28,124,173,162,162, 85,254,213, 69, 22, + 86, 29,110,176,100,221,162, 50,153, 85,146,242,114, 39, 59,127,127,186,179,189,189, 48, 33, 33,193, 47, 58, 58,154, 40, 45, 45, + 69, 77, 77, 13,212,106, 53,238,220,185, 99,162, 1,197, 52,103,103,162,248,230, 77,130,202,100, 86,225,217,149,124, 22,225,231, +229, 28,244,201,242, 57,109,213, 26,117,184, 84, 42, 53,208,232,116,186,175,167, 83,105,206,163, 86,205,196,105,184, 92,110, 20, + 0,154,201,100, 82,186,184,184,112, 47, 92,184, 0, 38,147, 9,130, 32, 16, 25, 25, 9, 54,155,205, 32, 73,178, 4, 0,236,237, +237,153, 59,119,238,116,156, 50,101,202, 85, 75,196, 93,187,118,165,179, 88,172, 81,193,193,193,184,121,243, 38,210,211,211,139, +111,222,188,217,166,107,215,174,240,247,247, 31,229,229,229,117, 36, 45, 45, 77,255, 34, 58,246,211, 21,171,173,119,134, 55, 26, +141, 38,130, 32, 64,161, 80, 96, 50,153, 32, 22,139,209,190,125,123,108,223,190, 29, 91,182,108,249, 76, 40, 20,158,106, 5,151, + 81, 38,147,129,199,227, 33, 61, 61, 93, 19, 19, 19,195,162, 80, 40,200,207,207,175, 23, 90,238,110, 46, 29,123,119,143, 8,253, +236,219,253,231,121, 44, 22,107,104,255,168,176,204,188,226, 39, 36, 73, 88,156, 54, 14, 11, 11, 99,180,111,223,126,218,196,137, + 19, 81, 80, 80,128, 13, 27, 54, 84, 10,133,194,164,243,231,207,143,159, 59,119, 46,181,119,239,222,168,170,170,194,158, 61,123, + 12,119,239,222,253,165,188,188,124,191,237, 54,110,131, 13, 54,216,240, 55, 17, 90,126,126,126, 19, 25, 12,198,146,215, 95,127, +157, 26, 18, 18,130,138,138, 10, 56, 56, 56,232, 9,130,160, 3,128,147,147,147,158,195,225, 96,206,156, 57,232,220,185,115,223, +101,203,150,245,166,209,104,219, 5, 2,193, 62,107,254, 88, 36, 18, 41, 41, 20,202,209,121,243,230,109,188,119, 47,173, 61, 0, +252,241,199, 31,143, 5, 2,193,114,145, 72,164,108,101, 61,204, 65, 49, 9, 22,139,125, 59, 40, 40,168, 48, 42, 42,202, 97,204, +152, 49,224,243,249, 72, 77, 77,197,151, 95,126,153,167,213,106, 87, 39, 39, 39, 27,254,219, 39,217,160,209,148,223, 61,113,194, +190,255,155,111, 58, 44,136,137,217,252,222,188,121,223,124,242,201, 39,180,144,144, 16, 66,169, 84,226,246,237,219,228,177, 99, +199,244,123, 62,253,116, 11,120, 60,250,205, 99,199,152, 90,173,182,184,149,150,187,126,125, 94,235, 27,178,249,155,109, 80,171, +106,113,251,198,105,212,212,136,177,115, 87,124,136,143, 15,217,175,172,172, 44,217, 90, 46,130, 32,130, 19, 19, 19,221, 73,146, + 4,147,201,196,250,245,235,225,237,237, 13, 7, 7, 7,200,229,114, 44, 94,188,216,113,225,194,133,142, 0,144,145,145, 81, 31, +158,193, 18, 4, 2, 65,175, 57,115,230,216, 27, 12, 6,156, 59,119, 78, 75, 16,196,170,139, 23, 47,254, 28, 25, 25,201,236,219, +183,175,253,254,253,251,123, 3,184,242,162,132,214,115, 30,151,127,225,194,133,238,147, 38, 77, 34,233,116, 58, 33,145, 72,224, +228,228,132,237,219,183, 43,132, 66,225,233, 86,114,173, 95,190,124,249,234,186,207,123, 87,173, 90, 53,115,227,198,141,252,242, +242,242,122,171,166,168,178,250,114,175,152,247,141, 85, 18,169,246,151,111,151, 77,224,176, 89,204, 85, 27,127,185,162,167,226, +150,197,126,101, 48, 48,185, 92, 46,147, 36, 73, 28, 61,122, 20,197,197,197,239, 84, 85, 85,149, 27,141,198,248, 15, 63,252,112, +105, 72, 72, 72,187,156,156,156, 98,185, 92,190, 73, 36, 18, 21,218,110,119, 54,216, 96,131, 13, 47, 13,102, 39,120,243,234,195, +211,120, 58,157,216,188,208, 50, 26,141,115,206,159, 63, 79, 53,153, 76,216,181,107, 23,238,222,189, 75,114,185,220, 85, 92, 46, +247,123, 14,135, 99, 84,169, 84,179,103,205,154, 53,101,205,154, 53,148,190,125,251,226,230,205,155,148,246,237,219, 79, 3,208, + 80,104, 69,163,133, 88, 27, 82,169,244, 78, 69, 69,121,251, 6, 1, 42,219,179, 88,236, 59, 22, 42,211,152,179,113, 80,204, 30, +235,215,175, 87,120,121,121,105,211,211,211,177, 99,199, 14,211,221,187,119,147,152, 76,230, 78,161, 80,168,177,146,243, 69,160, +158,147,105, 48,164, 30, 88,186, 52,172,219,232,209,166,153, 75,150,212, 50, 56,156, 15, 54,111,219,182, 76, 34,151,123,131, 32, + 72, 87, 71,199,226, 93,235,215,111, 24, 54,106, 84,109, 70,114, 50,251, 94, 98, 34,157,175,215,223,111, 77, 57,203,202,202,146, +175, 92,185,138,189,187,191,129, 78,167,129,176,236,169, 78,171,172,146,194,130,200,250, 19,167,193, 96,144,142, 31, 63,158, 1, +128, 51,117,234, 84,166, 72, 36, 66,135, 14, 29, 0, 0, 50,153, 12,167, 79,159, 70,104,104, 40, 0,224,225,195,135,245,159, 45, +149,147,199,227,141,234,221,187, 55,138,139,139,145,145,145,113, 73, 40, 20, 86, 1,184, 84, 90, 90, 58,162,123,247,238, 56,126, +252,248,200, 22,132, 86,171,218,200, 74,161,245, 39, 78, 14,135,179, 60, 62, 62,254,157, 27, 55,110, 76, 90,186,116, 41,125,208, +160, 65, 0, 0,185, 92,174, 4, 96,108, 13,167, 74,165,218, 9,160,126,229,108, 81, 81,209,129, 37, 75,150,164, 44, 90,180,136, +111, 46,159, 56,243,212, 77, 49,112, 51,188,255, 59,159,244,234, 30, 30,242,249,214,184,243, 37,165, 21,113,210,172,147, 82,107, +234, 78,146, 36,244,122, 61, 76, 38, 19, 92, 92, 92, 20, 85, 85, 85, 16,137, 68,133, 34,145,104,222,163, 71,143, 90, 85,247, 23, +217,231,109,156, 54, 78, 27,167,141,243,127, 20,214, 71,134, 39, 73,210, 96, 50,153,112,229,202, 21,196,199,199, 27,117, 58,221, +187, 66,161,176, 97,180,234,109,169,169,169,137,227,199,143,223,151,147,147, 67,205,204,204, 4, 73,146,198,214,148, 70,173, 86, +235, 9,226,207,219,254,106, 45,247,238,221,139,242,242,114, 93,105,105,233, 69,131,193,112,252, 47,174, 94,252,203,171, 14,247, + 2,154, 55,180,218,139,107,250,244, 25,188, 58, 49,145, 53,243,227,143, 53,211,223,126,251, 67,163, 86,171,167, 50, 24, 38, 38, +143, 71, 49,178, 88,244,140,228,100,246,214,185,115, 93, 84, 26,205,185,184, 86, 56,152,155, 45, 90,253,251,247,197,244,153,139, +160,106, 96,209,186,121, 39, 23, 26, 29, 90,101,209,210,104, 52,225, 66,161, 16,108, 54,187, 4,128,231, 91,111,189, 5,147,201, + 4,149, 74, 5,185, 92, 14,129, 64, 32,125,251,237,183,141,117,226,137, 54,110,220, 56, 7,107,120, 3, 2, 2,188,233,116, 58, +206,157, 59, 7, 58,157,126, 26, 0,232,116,250,233,196,196,196, 17,147, 39, 79,134,143,143, 79, 64, 65, 65, 1, 1, 11,254,105, +238,225,163, 15,147, 64, 16, 8, 4, 62, 53,193, 33,144, 31, 62,250, 1, 1,228,213, 69,141,207,234,218,181, 43, 96,165, 95, 86, + 67,212, 45,238,216,162,215,235,143, 44, 91,182,108, 94,143, 30, 61,134,172, 89,179,134, 64, 93,168,134,191,136,220,178,178,178, +215, 86,172, 88,113,158, 36,201,103, 68,191,168,178,250,114,207,216,249,164, 68, 34,189, 39,206, 58,245,176, 85, 22, 83,131,225, + 47,133,179,176,193, 6, 27,108,176,225,133, 89,181,254,132,102,133, 22, 65, 16,187,250,245,235,247, 46, 0, 42, 65, 16, 59, 4, + 2,193,159,110,254, 66,161, 48,215,219,219,251,171,118,237,218,205, 6, 64, 18, 4,177,171,149,133,170, 32, 73,124, 73,161, 16, +203,158,138,187,231, 10, 80,105, 78, 75,178, 12, 0, 65,161, 80,247,165,165,165,125, 92, 82, 82, 34,182,210, 2,209, 34, 94,196, +170, 67, 0,248, 21, 40,124,189,184,248,252,146,136,136,232, 97,115,231,162,211,176, 97, 14,222,109,218, 24, 85, 58,157,233,225, +181,107,196,141,163, 71, 25,247, 18, 19,233, 42,141,230,220,113,160,164,181,229, 44, 43, 43, 75,190,156,148,124, 97,194,184, 17, + 67, 2,218,121, 63, 21, 13,133, 2, 84, 86, 75, 47,180, 70,100, 53, 18,189,163,183,111,223,126,138,193, 96,208, 26,166,178,209, +233,116,213, 26,141, 38, 28, 0,106,106,106,188,119,237,218,245, 27,133, 66, 41,182,196,151,153,153,121,114,245,234,213,227,138, +138,138, 46,148,150,150, 22, 1, 64, 73, 73, 73,145, 94,175,223, 39, 20, 10,199, 21, 23, 23, 31,131, 21,139, 0, 72, 32, 40,227, +218,145, 72, 0, 8,239, 51, 17, 25,215,142,176, 1, 68,134,247,153, 8, 0,120,222, 92,134, 13, 81, 23, 6, 97,213,205,155, 55, + 15, 14, 25, 50,100, 22,254, 66, 76,175,198, 98, 75,167,211,181,105,188,209,108,217,106, 13,145, 86,171,213,171, 84, 42,131,209, +104,164,233,116, 58, 82,171,213,234,109,247, 57, 27,108,176,225,223, 10,146, 36,187, 3,224,155,111,155,117,239,252, 70,159,181, +168, 75, 23,104,190, 85,214,125, 23, 19, 4,113,167, 1, 71,253,118, 43,142, 5,128, 74, 0, 15, 8,130,104,206, 8,178,171,185, +239,205, 10, 45,129, 64,112, 12, 86, 36,141,182,118,191, 22,176,162, 46, 11,222,235,141, 0, 0, 32, 0, 73, 68, 65, 84, 79, 28, +240,252,121,216,234, 57,140, 70, 99, 69, 73, 73,201, 95,110, 80, 10,133, 82, 56,114,228,200, 86,237,111,105,159, 67, 64,241,251, + 26,205,254,132,239,190,235,114,110,199, 14, 31,163,193,224, 74, 0, 36,149,201,172,210,106,181, 69,124,189,254,126,107, 45, 89, +207, 88, 99, 30,151, 13, 45,120, 92,134,192,192, 64, 50, 63, 63,255,169,173,231,175,225,190, 66,161,240,179,212, 5,148, 74,101, + 95, 43,197,224,175,101,101,101,191, 54, 33,216,127, 19, 10,133,191, 89, 91,168,250,164,210, 0,197, 68,152, 38,132,247,153,120, + 20,128,201,156, 84,250, 69,162,188,188, 60, 7,117,113,222,254,110, 40, 46, 46,214, 16, 4,113,224,203, 47,191,156,122,239,222, +189, 67, 2,129, 64, 99,187, 21,219, 96,131, 13,255,102,145, 69, 16, 68, 66,221,247,216, 58,163, 80, 66,227,207,230,125,204,251, + 53,220,199,204,209,120,123, 75,199, 2,192,242,229,203, 63,222,176, 97, 3, 23,128,181,201,152,159, 59,169,244,203, 66,197,223, +132,163,161, 40,216,253, 50, 42,250, 29,160,133,193,112, 11,134, 6, 62,249,250, 23,107,136,200,207,207, 39,254,205, 23,156, 57, +169,116, 3, 68,252,175,222,124,138,138,138,182,251,251,251,239, 20, 8, 4, 6,216, 96,131, 13, 54,252,123,193,111, 74, 24, 53, + 35,202, 98, 91,250,253,153, 7,247, 38,246,107,234, 59, 65, 16, 9, 27, 54,108,136,109, 69,121,235, 45, 90, 20, 91,219,217, 96, +195, 63, 27,255, 31, 43,105,109,176,193, 6, 27,254, 13,104,108,197, 50,139,175,198,223,151, 47, 95,254, 49, 90,158,113,242,194, + 83, 43,150, 87,221,247,122,127, 45, 2, 79, 87, 14, 52,133,214,172, 38,136,126,142,250, 93,180,113,218, 56,109,156, 54, 78, 27, +167,141,211,198,249, 63,199,105,137,251, 98, 19,130, 40,166,185,169,190,150,166, 17, 27,127,182,116,172,165,125, 9,130,104, 46, +204,143,121,170,176,241,251, 75, 71,180,141,211,198,105,227,180,113,218, 56,109,156, 54, 78, 27,231, 95, 1, 73,146,221, 73,146, +140,193,211, 5, 83, 36, 73,146, 49, 36, 73, 14, 91,190,124,249, 10,243,182,229,203,151,175, 32, 73,114,144,121,191,186,125,234, +143, 49,111,107,252,222,120, 91, 75,251,182, 80,196,119, 27,125,174,255,254,119,241,209,178,193, 6, 27,108,176,193, 6, 27,108, +104, 18,230, 21,131, 13,172, 77, 98, 0, 15, 55,108,216, 80,211,192,119, 74, 12,224, 62,128,206,117,251,137,235, 68, 90, 67,223, + 42,109,221,119,109, 19,251,104,173,217,183, 25,236,106,230,179, 77,104, 53,135,206,158,148, 79,253,125,221,163,234, 26, 0,100, + 93, 18, 96, 83, 93,188, 34,210, 28,184,200,100, 2, 73,146, 16,136, 36,169, 15, 69,248,228,121,255, 47,216, 27, 46,238,108,246, + 22, 19, 73,246,169,219,148, 44,173,210, 44,202,144, 65, 98, 45, 71,168, 7,194,216, 20,124,104, 34,209, 9, 0, 40, 4, 30,168, + 77,248, 42,187,162,245,241,164,154,234,231,225,124,188,203,228,112, 95,119,116,114, 14,172,169,169,204,211,169, 53, 71, 50,197, +216,137,214,231,101, 68,128, 51, 94, 53,145,248, 24, 0,133, 78,193,215,121,213, 86,175,228,176,193, 6, 27,108,248,171,214,145, +191, 20, 23,143, 32, 8, 99, 19,156,196, 95,228,180, 5,195,179, 66,108, 53,177,249,143, 38,182,221,249, 59,149,187, 85, 66,171, + 35, 31,115, 65, 96, 45, 0, 18, 36,214,101,138,241, 99,171,142,247, 66, 52,155, 74,253, 9, 0, 85,173, 51, 46, 33, 77, 72,105, +242,100, 82,240, 26,155, 65,253, 26,128, 73,109, 52,206,200, 20, 90,239, 47, 22,238,131, 97, 52, 19,229,128,137, 36,233, 70, 19, +185, 15, 36, 18,236, 24,184,126,171, 12,234,214,148,213,223,215, 61,234,196, 31,194, 33, 73, 63, 46, 64,143, 78, 29, 64, 26,255, +143,189,243, 14,143,162,106,184,248,153,153,173,217,244,178,233,133,158, 70,104, 2,161, 55, 65, 90,248, 40,130, 52, 1,225,165, +136, 40, 34,138, 10, 10, 8, 74, 81,105, 74, 7,149, 38, 29, 41, 1, 41, 81,122,137,244, 84, 2, 9,164,247,158,108,182, 77,185, +223, 31, 41, 38,144,182, 1,245,149,119,126,207, 51,207,108, 61, 59, 51,119,118,230,204,185,101, 56, 64, 96,161,234,254, 17,126, + 91, 51, 1,129,126,158, 32, 2, 11, 8, 28, 44, 6,126,139,129, 1,214, 36, 44,179, 97,247,193,246,118,133,157,151,131, 99,248, +182,109,219,157, 93,155,250, 83, 2,103,196,131, 63,206,142,127,127,222,194, 62, 45, 81, 16, 80, 31,179,213,218, 5,255,241,108, +228,243,209,156,197,171, 25, 23, 87, 15,115,129,213,115,233, 79,162,218,125,247,245,194,195, 50, 58, 97,213,253, 52,108,175,239, +190,236,175,198,116,137, 66, 62,202, 76,105,222,188,164,164,232, 17,111,100, 15,210, 82,201,128,111,190, 93,219,182, 87,191, 65, + 22,124, 81, 58,205, 10,240, 63,176,127,159,215,247, 27, 54, 14, 10, 79,227,255, 15,128, 96,202, 58, 11, 4,243, 98,118, 77, 27, + 36,149, 48,148,223,228,109, 12,192, 53,200,104,249, 57, 98, 44, 69, 80,231,240, 18,132,194,229,168, 76,236,109,200,111,248, 58, +226, 7,138,192, 27, 20, 14, 81, 4,251, 34,179,144, 41, 30,242, 68, 68, 94, 46,104,154, 62, 47, 8, 66,239, 23,108, 12, 58, 17, + 66,110,136, 91,247,127, 27,211, 18, 45, 10, 95, 70,196, 38,217,130, 55,162,165,119,211,165,128,105, 70, 75,201, 48, 59,111, 62, +204,112, 6,103,196,182,175,102,238, 55,176, 0,199, 26,193,115, 44,120,142, 5,199, 25,193,179, 44, 8,171,199,194, 31,207, 3, +134, 34,180, 15,104,177, 19,224, 93,234,251, 27, 82, 66,239,190,125,229,172, 29,101, 40,192,222, 77,203,223, 77,202, 42,126, 55, +228,126,106,182,191,163,246,211,200, 76,252,100,138, 33, 56,191,121, 54,246,252,114, 50,121,221, 15,154,104,129, 16,216, 89,153, +249,140, 15,138,240,216,117,236,124,210,218,157,186,104, 0,176, 54,151,251, 76,188,255,208,243,121, 10,193, 81,169, 92,187,101, +227,247,206, 46,246,102, 20,119,109, 5, 56,158,135,135,215, 96,230,211, 89,227, 93,190, 92,179,125, 13, 10,245,147,106,251,190, +143, 35,252, 27, 53,246,155,187,243,228, 53, 79, 77, 97,166,225,236,207,243, 99,161, 7,235,236,230, 39, 93,186,124, 53,179,224, +227,217, 31, 24,248,228,208, 7,153,136,172,235, 88,227,231,136, 99,203, 87,124,219,186,207,192, 32, 11,161, 56,139,209,105,138, +189,183,253,184,125,177,111,235,142,170,238, 1,238,178,204,131, 51, 40,109, 81, 46,140,180, 82,209,167,101, 95, 43,237,155, 99, +216,109, 59,246,204,138,204,196,119,166,172, 51, 79,254,220,247, 4,161,225,163,174, 83, 4,221,239,222, 56, 63,157, 79,189, 9, +194,179, 0,111,172,152,131,103, 65,132,210,121,224,140, 31, 1, 52,204,104,209, 4,175,133, 92,185,233,146,145,158,214, 97,205, +183,203, 62, 37, 55,111,254, 10, 30,187,163,114,113,209, 84,131, 9,192,187,137, 61,115,134,229,161, 79,202,231,189,203, 95,236, +227,173,232,226, 98, 65,189,154, 88, 64, 93,186, 28,171,189, 40, 30,154, 68, 68,254,145,196,132, 35,132, 72, 94,176,230, 32, 66, +200,169,231,148,249, 8,192,127,202, 30,111, 7,240,205, 11, 88, 52,119, 0,206,101,143,211, 1, 36,139,123,192,115,241,116,227, +247, 6,143,163,165, 4, 17,128, 67,195, 0,192,204,212,165, 32,128, 18, 20, 3,176, 26, 12, 29,216, 15, 14,142,206, 0, 91, 2, + 24, 75, 0, 86, 11,176, 26,128,213, 34, 59, 45, 1, 48,106,128,184, 95,193, 17,162, 48,121,117,245, 5, 64,204, 65,188,218,206, + 19,106,107, 37,102, 15,245,119,216,122, 58,102,251,246,179, 15,250, 70,102, 98,116,189,150,149, 16, 4,182,106,142,117,219, 53, +209, 39,238,100,245, 7,128, 65,109,236, 79, 7,250,123,121,172,221,169,139, 62, 21,150, 55, 0, 0, 6,180,180,250,181,163,143, +139,167,128,134,167,190, 2, 33,221, 93, 27, 53,167,248,187, 91, 32, 20, 38,163,176, 80,139,228, 39,187, 96,235,246, 10,205, 11, +232, 89,215,247,205, 24,124,242,222,130,149,210,146,194, 12,131, 96,204,226,213, 76, 30, 35,145, 11, 20, 82, 46,234,139,133,124, +126,206,180, 9,220,220,207,191,250, 4,192,248,218,116,252, 29, 49,107,213,170,181,173,186,182,247,117, 76, 63, 60,155, 42,206, +203, 0,199,168, 20, 67, 59,119,133, 77, 11,127, 33,227,194, 42, 74,222,180, 47,108,236,155, 34,229,218,207,136,191,113,132,234, +214,110,132,226,167,189,178, 55, 1, 99,181, 70,171,185, 3,186,245,239,209,113,127, 83, 79, 87, 23, 66, 4, 8, 2, 1, 17,120, + 20,235, 88,124,122, 32, 14, 60,207,227,245,254,221, 94, 53,151, 83, 68, 16, 4, 16, 34, 32, 41, 61,167,228,247,208,232, 87,227, +242, 16, 90,159,164,170, 77,167,222,221,238,223,190,225,203,198,156, 64,251,241,203,163, 41,224, 74,165,125,174,219,157, 51, 63, +249, 2, 63, 54,220,203, 81,224,227, 79,175,128,103,143,105,204,150,189,167,213, 5, 89, 41, 19, 15,239,218, 56,114,211,150, 45, +123,162, 51, 49,195, 20,147,245,126, 15,249,149, 53,191, 23,218,119,110,106,158,149, 84, 41,167,108, 98, 75,247,223,124, 42,242, +189,235, 75, 2,125, 23,156, 36,249,151, 98,117, 97,226,113, 75, 68,228,239,133, 16,242,194,205, 86, 66, 66, 66,234,243,152, 45, + 55, 55,183, 30, 41, 41, 41, 95,151,183, 86,161, 40,234,235, 70,141, 26, 45,252,243, 66,181,202,181, 94, 1,207,243,227, 83, 82, + 82, 46,213,166, 57,120,240, 96,215,147, 39, 79, 54,174,164,217, 24, 64,227,234, 62,107, 99, 99,195,119,233,210, 37,254,228,201, +147,169,226, 30,210, 32,195,101,178,209,138, 78, 60, 56,187,157, 62,173, 24, 0,162,235,241,249, 42, 85,126, 58,150, 95,177, 99, +241,132, 21, 45, 27,217,161, 72, 99,192,217, 91,241,224,121, 22, 60,199,149, 37, 91, 28,120,142, 69,255, 54, 14,232,162,155,129, +239,130, 31,128,227,133,229,181,105, 62,141,145, 8, 99,219,246,125,227,128, 32, 16,185, 66, 74, 23,120,123,216, 59,206,125,189, + 13, 61,123,104, 75,104,141,220, 27, 63, 95,136,253, 61, 42, 19,219,234,165, 41, 60, 59, 60, 17,169,238, 53,158,171,115,221,107, + 73,163, 2,251,246,234,110, 69,244, 5, 96,179,227, 80, 84,194, 34, 46,135, 69,186, 46, 31, 10, 42,173, 94,154, 2, 65,107,119, + 55, 23,213,213,253, 31, 63,177,103, 10, 37,142, 12, 39,147,211, 28,120,129, 48, 36, 63, 82,111,231,219, 79, 90,222,110,171,182, +229, 52, 83, 89, 78,232,241,218, 96,235,196,159,167, 81,102,222,253,225,216,206, 3, 79, 46,237, 64,230,173, 96,228,164,198, 83, + 86,186,124, 56,217, 55,195,192,241,163,241,205,232, 14, 40, 42, 44, 2,147, 22,107, 45,151, 42,108, 0, 99,181,154,132,199,248, + 85, 43,191,114,145, 48,116,233,246, 44,159,120, 22, 90,189, 30,224, 57, 40, 37, 2, 40, 82,254, 30, 11,158, 53,170, 90,143,248, +120, 38,192,135,214,181,238, 81,153,216,235,175, 70,119, 8,172, 47, 97,181,160,128, 43,145, 89,127,154, 31, 63, 71,140,125,165, +255, 91,221, 9,133,203, 13, 41,163, 0,123, 4,181,111,108, 97,110, 94, 24,141,228, 67,239, 34, 22, 74,226,212,245, 63, 24, 59, +121,150,106,235,214,173, 67, 0,242, 54,170,182, 81,171,208,244,117, 98,166,179, 60, 22, 2,128,150, 37, 59, 44,229,212,228, 85, +251,174,219,131,249,243, 14, 15,229, 73, 86,108,142,144,103, 60,255,217,131, 78,115,131,123,181,186,219, 43,137,162, 20,137, 23, + 31,233, 11, 76,217,151, 76, 68,212, 20, 53,255,114, 77, 43, 43,171, 38,141, 26, 53, 90,200,178,108, 15,153, 76,230,100, 52, 26, + 33, 8, 66,186, 92, 46,191, 28, 31, 31,191,164,176,176,240,241,127,219,186,223,191,127,223, 20,179, 85,167,166, 84, 42,197,131, + 7, 15, 30,153, 96,182, 66,158,250,254,238, 43, 87,174,224,192,129, 3, 0,128,152,152, 24,180,104,209,194,188,186, 47, 62,121, +242,196,188, 87,175, 94,187, 1,120,212,166, 25, 22, 22,214,228,196,137, 19, 56,116,232, 16, 0,224,193,131, 7,240,246,246,174, +118, 97,174, 92,185,194,140, 27, 55,174, 9,128,212,191,161,140, 94, 6,147, 85,121,254,167,209, 10, 14, 14, 38, 65, 65, 65,212, +211,143,171, 33,206,211, 86,222, 14, 58, 30, 0,226, 76, 93,130,168, 12,172, 92,183,235,204,128,223, 14,109,232,161,148,209, 88, +180,109,110, 82, 86,110, 81, 39, 9, 85, 90,253,194, 17,208,182, 22,242,235,203, 39,182,241,204, 43,214,225,248, 31, 41,151, 34, + 51, 77,139, 72, 35,211,112, 14, 16,108, 74,159,241,208,105, 51,189, 39,126,115,110,223,190, 79, 6,180,158, 51,180, 53,142, 93, +139,159, 3,112,117,142,250, 78, 4, 1, 68,224, 42, 26,191,151, 93, 58, 0, 66,213, 27,248, 10, 32,165,175, 9,166, 37, 90, 61, + 1, 73,158, 35, 6, 90,170,228,235,167, 79,159,106,197,102, 61, 68,174, 65,134,164, 60, 29,210,181, 82, 20, 75, 28,145, 18, 29, +198,211, 20,206,213, 25,185, 80, 40, 36,156,206,198, 86,110, 65, 7,244,155,233, 86,120,122,126,158,156,226, 24,171,225, 95,218, +100,255,182, 58,158,211,100,105, 40, 10,117, 14, 63,111,109,109,211, 66,151, 19,207, 20,228,101,195,198,185, 37, 6,188, 17,132, + 47, 6,251,163,168, 80,131,172,220,235,164,185,139, 21,149,112,121, 15, 22, 12,244, 67, 78, 70, 26,244, 44, 64,105,244,185, 58, +131,174,184,198,237, 72, 99,203,251, 31,206, 27,235,229,162, 54, 47,239, 84, 64, 4, 30,109,252,154,162, 95,143, 64,156,187,114, + 21, 55,195, 98, 32,148,117, 42, 32,130,128,228,204,188, 12,157,145,223, 97,210, 6,229, 57, 16, 86, 87,173, 17, 67, 3,170, 12, + 3, 28,161,226,129,207, 59, 52,177,156,242, 73,144,151,165,185,130,130,142,229,161, 51,176, 40,186,186, 30,246,141, 90, 65,165, + 84, 82,237,160,149,220, 65,245,219, 86,199, 98,225,227,180,124, 23, 20,167, 99, 92,191,150,239,237, 92,254,142, 57,165, 44,221, + 53, 89,190,106,146,117,117,113,135, 51,227,150, 30, 61,127,224,224, 24,215,111, 62,154,208,171,255, 7, 59,206, 3, 56, 45, 30, +183, 68,254,141,140, 28, 57, 82,153,145,145,113,193,195,195,195,191, 95,191,126,170,238,221,187, 67,163,209,224,236,217,179,208, +104, 52, 94, 30, 30, 30, 94,103,207,158, 29,145,152,152, 24,233,238,238,222,235,208,161, 67,245,110, 67, 91,102,128,152,138, 67, + 48,192, 81, 20,133,178,215,168,178,215, 26,124,159, 91,185, 92,142,132,132,132, 23,158,108,165,164,164, 60,106, 72,178, 85, 92, + 92, 44,115,115,115,131, 90,173, 6,207,243,208,104, 52, 56,122,244, 40, 10, 10, 10, 32, 8, 2,204,204,204,240,229,170,109,136, +190,115, 1,161,161,161, 40, 40, 40,144,213,165,153,156,156, 76,181,105,211, 6,122,189, 30, 28,199, 65,167,211, 33, 36, 36,164, +226,185, 68, 34,193,188,165,107, 16,115,235, 2,238,222,189,139,228,228,228,191,229,110, 35, 38,120,145,255, 70,106, 28, 51,235, +111,239,117,200,243,220,167, 91,119,238,187,254,233,140,209,152, 53,166,175,199,146, 13, 71,250, 70,101, 99, 39, 0,248, 57, 96, +226,155,189,155,123,218,168,164,248,226,231, 91, 0, 33,159, 62,239,239, 69,228, 34,198,223, 73,152,243, 75,104,194,133,249,163, +219,161,169,139, 85,139, 60,121,174, 60, 46,174, 30,247, 20, 20, 56,216, 90, 40,124, 6,181,177, 63, 13, 65,128,141,165,194, 23, + 60, 7, 27, 11,133,207,128,150, 86,191, 2,128,149, 74,234, 91, 93,242, 85, 19,237, 61,164,211, 84, 10,201, 52,115, 75, 27,207, + 73, 67,250,153, 13, 26, 50,194,204, 66,202, 33, 39,244, 44, 10,165,238, 96,237,188,160,103,115,145,252, 56,150,255,237, 70, 84, + 74,118,145,126,110,157,139, 73,112, 41,229,241, 3,117,147,214,253,108,179,131, 23,100, 54,121,235,231,198, 52, 4,186,104,207, +240, 12,115,199,142,102,127,196, 61, 46, 22, 72,181,137, 78, 21, 10, 11, 10,226, 89, 30, 46, 90, 94, 98, 25,123,254, 39,124, 50, +176, 21,242,114, 51,161, 51,114, 40,208,114, 70,103, 27,165, 66,255, 56, 28,122, 35, 7, 3, 43, 64,106,227,134,179,215,195,178, + 5,150,253,181, 38,205,184, 28,220,141, 59,122,215,162,242,107, 77, 29,208,230, 99, 43,179,187, 96,181, 72, 72, 78,197,206,147, +215,219,197,229,224,238,243,148, 51, 17,184,210,234,231, 74, 73, 22, 69,208,189, 33,141,224,125, 29,209, 81,166,148,125,255,245, +156,113,254,157,189,237, 20, 66,242,117, 80,130, 17,230,188, 4, 90, 57, 15,107,143,166, 16, 12, 69,164, 68,167,203,143, 0,106, + 43,124, 6, 0,136, 81,131,111, 38,180, 52,167,108,155,130,143, 59, 13, 73,219,105, 96,203,210,254,216, 28, 33,204,120,254,179, +232, 46, 31,158,232,185,244, 92,239,168,212,147,139,162,220, 70,174,111, 3,236,104, 36,158,174, 69,254,141,248,248,248, 56,167, +164,164, 68,124,248,225,135,118,195,135, 15,199, 47,191,252,130,194,194, 66,236,216,177, 3,107,215,174,197,226,197,139,193,178, + 44,182,110,221,170, 58,124,248,112,199,141, 27, 55, 38,123,122,122,182, 76, 76, 76, 76,175,195, 96, 81, 0, 20, 0,164,101,231, + 46, 10,128,112,234,212, 41, 12, 26, 52, 8,167, 78,157, 18,202, 94,227, 81,122,241,211,160,123,127,202,229,114,200,229,114, 20, + 20, 20,188, 16,179, 37,149, 74, 97, 97, 97, 1,185, 92,142,162,162, 34,147,205, 22,199,113, 76,114,114, 50, 10, 10, 10,208,111, +200, 16,172, 89,190, 28,189,123,247, 70,191,126,253, 64, 8, 65, 72, 72, 8,250,118, 13,192,232,255,235,133,168,168, 40,112, 28, + 87,175,229, 77, 79, 79, 71, 70, 70, 6, 6, 12, 25,130,109, 27, 55, 34, 48, 48, 16, 62, 62, 62,224, 56, 14, 23, 46, 92,192,200, +254, 93,161, 28,214, 23, 49, 49, 49,226, 78, 93,255, 52,235,133,180,209,122,110, 34,178,112, 67, 56,118, 49,120, 76,255,142, 65, + 67,186,249, 99,219,254,223,190,130,186,112, 31, 0,216,235, 21, 95, 78,232,221, 20,145,137,121,248,237,110,106,112, 84, 54, 94, + 72,111, 13,129,135,131,189,149, 10, 96,228,208, 26, 5,206, 42,174,238, 6,204, 2, 33, 80,245,248, 24,111, 14,137,244, 8,244, +247,240, 40,239,117,104, 49,104, 53, 38,134, 61,242,236,224,227,236, 9,158, 5,120, 22, 86,163,127, 6,150,154,215,185, 28, 93, + 27,203,207,189, 63,123,118,151,129,195,222, 48,147,171,172,193, 23, 38,129, 77, 15, 67,206,195, 75,208,168, 90, 32, 61, 33, 14, + 7,206,132, 22, 60, 76,206, 41,164,105,156,205, 40,208,127, 20,151,135,226,186,116,117, 44,150, 47, 92, 48,119,240,129,125,251, + 45, 21, 77,187, 81,177,235, 7, 21,200, 37,156, 66,221,248, 21,186, 68,233, 64,150,237,216,111,165, 49, 96, 69, 93, 58, 37,154, +194, 35, 33,103, 79,143,110,222,164,155,229,147,155, 39,161,213,233,161,103,129,150, 29,123,129,231,137,156,162, 41,193,138, 97, +168,204,156, 60, 80, 44,159,113,249,222,147,180, 43,247,226, 24,189, 37, 86,212, 58,186,200,211,238,158, 98,222, 27,210,171, 45, +192,106,241,127, 61, 90, 97,205,158,223,222, 5,248,183,158,175,144, 75, 19, 45, 2,116,243, 87, 99, 51, 33,232,118,235,232, 90, +223,246,195,222,135, 41,137, 86, 75, 7, 12,244,107,226,250,211,154, 47, 63,182,179,119,111,193, 80, 2, 11,226,220, 26, 40, 76, + 38, 84,242,117, 88,187, 5,130,119,237,138,173,223,125, 91, 44, 8,100, 31,106, 25,218,130, 23, 0, 33,241, 34,248,232, 95, 16, + 23, 23, 7, 7,175, 91, 0, 69,131, 52,122, 2, 35, 87,250, 53,189,145,156, 92,183,227, 68,239,143,250, 44,111, 57,196, 87,226, +121,253, 94,108,230, 27,147, 93, 85,157, 60, 25,239,200, 52,115, 58, 91,163, 17,196,227,151,200,191, 9,157, 78,119,100,229,202, +149,118, 65, 65, 65,229,137, 12,174, 95,191,142,237,219,183,195,220,188,234,113,114,208,160, 65, 32,132,216, 45, 90,180,232, 8, +128,206, 53,105,118,233,210,101,200,221,187,119, 83,219,182,109, 27, 87,102,182,100, 0,232,240,240,112, 58, 41, 41,137,178,181, +181, 37,174,174,174,108,106,106,170, 0,128,159, 60,121, 50,115,240,224,193,230, 26,141,230, 98, 67,141,150, 92, 46,127, 33,109, +182,164, 82, 41, 40,138,130, 92, 46,135, 76, 38, 3, 33,196, 36,179,197,243,188,228,212,169, 83,184,117,235, 22, 22,183,109,139, + 57,110,110,176,179,179,195,133, 11, 23, 64, 8,129,185,185, 57,114,115,115,177,111,223, 62,244,233,211, 7, 28,199,201,234,163, +123,232,208, 33,220,190,125, 27, 75,219,183,199, 28,107,107, 88, 88, 88, 32, 36,164,180, 54, 80,161, 80, 32, 33, 33, 1, 33, 33, + 33,232,213,171,151,184, 83, 63, 39,245,222,121,122, 2,146, 92, 10,206, 70,131, 22,132, 35, 0, 5, 87, 63, 63,200,162,162,170, + 54,206,169, 15, 52,141, 5,223,237, 12, 30,188,250,253, 33,212,180,161,237, 92,151,252,116,254,109, 0,152,242,186,183,155, 74, + 33,193,186, 99,145,132,166,177,224, 69,172,160,159, 31,100, 84, 14,222,238, 23,232,131,212,124, 3, 98, 83,243,127,143, 2,234, +117, 23,231,223, 86,191,137, 93,199, 47, 36,173,221,165,139, 38,132,192,198, 66,225, 51,241,126,172,231, 79,167,110, 39,174, 58, +160,139, 38, 2,129,141, 74,234,251, 86, 84,215, 58,123, 29,182,247,144, 78,251, 96,238,220,174, 67,223,250, 80,201, 69, 31,132, + 33,246, 12, 4,163, 22,133, 70, 25,242, 25,103, 36, 39, 38, 98,217,214,224,164, 66,141, 97,116, 68,150,105, 6,243, 97, 14,138, + 37, 84,225,240,101, 95,204, 63,183,252,203, 69, 22,218,184, 11,197, 12,197,105,153, 70, 61, 37, 95, 46, 94, 77, 21,233, 13,111, +196,229,161,168, 46, 29,189, 37, 86,172, 92,245,221,224,169,227, 71, 68,123,183,232,105,207,167, 62,182,215, 21, 22,102,254,124, +250,182,115,217,149, 34, 5, 0,177,201, 57,200, 42,208,112, 60,199, 94,180,148, 98, 73,100,125,210,193, 50,154, 56, 66, 29,212, +173,229, 56,181,165, 12,218,226,124, 56, 90, 74,209, 63,176,217, 56,246,143,152,143, 31,103,154, 98,215,158, 54, 90, 44, 8,171, +197,141, 21,125,124, 9,207,250,130,103, 97,188,191,219,244,100,140,194,156, 89, 61, 44,172,108, 13, 79,104,104,204, 1, 51, 7, + 80, 86, 94,128,117, 99, 74,234,247, 6, 82,227, 34,184,119,199,141,207,121, 28,159,252,131,131, 89,237,213,218,172, 64, 32,196, + 95, 64,113, 70, 44,194, 83,141,104,153, 89, 90,219,110,149,113, 7,188, 56, 98,142,200, 75, 74, 66, 66,194,132, 79, 63,253,244, + 74, 96, 96,160,147,131,131, 3, 90,181,106,133,227,199,143,227,195, 15, 63,172,248, 76,219,182,109, 65, 8, 65,110,110, 46, 86, +174, 92,153,158,154,154, 58,161,214, 11,244,136,136,232, 93,187,118,245,240,247,247, 55,202,100,178,124, 0,138,252,252,124,101, +110,110, 46,165,211,233, 32, 8,130, 96,109,109,205,167,166,166,178,163, 71,143,214, 95,187,118,173,153, 70,163, 73,120,158, 68, +203,195,195, 35, 60, 39, 39,167,128,162,168,231, 30,250,161,220,100, 57, 56, 56,168,139,139,139, 5, 0,121, 13, 25,250,129,227, + 56,180,111,223, 30,103, 46,221,193,169,223,174,161, 48,245, 1,222,158, 58, 1,173, 90,181,194,153, 51,103, 26, 92,102,109,218, +180,193,233,144, 43,184,114,235, 30, 18, 98,238,227,221,183,167,162,101,203,150, 56,125, 90,108,189, 96, 2, 39, 81,181,109,214, +201,167,141, 86,175,224,224,224,242, 67,255, 51,246,213,215, 1,109,164, 54,242,221,139, 6, 54,243,147,246, 91, 4, 74,106,134, +131, 45, 78,119, 93,176,108,125, 52,227,152, 48, 62, 60,179,238,222, 97, 85,254, 52,153,136, 32,161,209,123,239, 69,249,142,251, +191, 64, 15,108, 59,174,250, 28, 0,222,232,222, 4,127, 60,204, 66,104, 76,230,222,200, 44, 68, 60,239, 90, 7, 56, 66,197,103, + 99,239,202,247,134,246,242,114,119,198,246, 95,174,128,162,112,164, 94, 39, 92, 66, 72,160,191, 23,214,238,122,186,135,161,179, +231,170, 3,186,232,179, 17, 69, 3, 1,160,159,175,234,215, 14,205,108, 61, 73,229,134, 91,213, 96, 38,151, 76, 31, 56,226, 77, + 37, 23,115, 28,136, 15, 1,197,233,161, 53, 10, 72,203, 46, 66,137,181, 7, 46, 92,191,167, 45,208, 25,222,143,204,106, 88,138, + 23,149,141, 56,217,205,123,137,197, 26,173,139, 74,221, 76,199,208,130, 80,172, 39,248, 35, 50,190, 48, 50, 29, 15,234,163, 17, + 23, 7, 67, 39, 55,174,251,230,157, 7, 22, 74,101,242, 55, 24, 10,148,163,141,185,122,243,234,165,176,180,180,128, 96, 40, 6, + 52, 89, 24,254,206,178,172,240, 84,182, 9, 0,180,176,135, 69,247, 38,210,157, 18,154, 74, 62, 31,107,252,172,174,223,160, 88, +204, 24,223,191,173, 84, 48,104,240,222,202,253,216,242,241, 80,188,249,170,159,244,228,213,152, 25, 0,150, 52,180,172, 9,207, +129,176, 90,116,158,127, 41,154, 2,174, 16,160,219,173, 3, 95,250, 2,119,234,173,209, 14,144,242, 18,202,175,181,167,185, 76, + 72,190, 10, 33,249, 42, 97, 60,186,130,242,236, 65, 81,206,237,201,247, 95, 47,214,108,219,182,253,172, 64,227,139,122, 12,149, + 1, 94, 0,178, 99,174,192, 96, 48,128,229, 1,157, 78, 7,141, 70, 3,243,216,211, 21,109,180,100, 82,106,192,236, 73, 67,218, +144,226,212,146, 19,209, 92,226,246,169,190,157, 73,113,106,201,141, 68, 62, 38, 91,163, 23,211, 44,145,127, 35,113,169,169,169, + 3, 6, 13, 26,244,219,153, 51,103,236, 2, 2, 2, 0, 0,183,110,221, 42,189,232,108,223, 30,222,222,222,200,200,200,192,152, + 49, 99,178,211,210,210, 6,160,142, 54,191, 69, 69, 69,143, 15, 29, 58,228,164,209,104,218,126,246,217,103,153, 94, 94, 94,133, + 58,157,142,202,207,207, 23, 56,142,131,173,173,173,188,109,219,182,232,210,165, 75,241,245,235,215, 27, 37, 37, 37, 21, 1,136, +111,200,194, 15, 29, 58, 20,151, 46,149,118,218,123, 17,227,106,201,100, 50, 4, 4, 4,184,197,197,197,165,148,157, 91, 76, 62, +198, 87, 62,189,220,187,119, 15, 23,239, 36, 67, 98,208, 66,158,149,138, 27,191, 28,194,144,233, 51,193,113, 13,191,183,252,189, +123,247,112, 52,228, 6,204, 21, 18, 60,120, 16,129, 67,135, 14,225,237,183,223,126, 46,205, 6, 82,171, 23,249, 47, 39, 13, 53, +180,211,146, 0, 64, 80, 80,208,197,242,180,162, 50, 77,155, 66,174, 40,198,162,126,237,220,230,189,209,173, 25,195, 22,166, 66, +224, 5, 48, 82,192,209,193, 10,187,119,239,109,178,119,255,254,235, 27, 55,108,252, 78,224,184, 5,225,153, 40, 49, 97,161, 22, +173,222,127,229,141,221,115,123, 73,222, 30,232,107, 7, 0, 50, 9,141,117,199, 35, 56, 0,139,158,103,109, 59,185, 65, 89,204, + 98,154,163,189,245,231,159,254,103,176, 93,175,246,222,184, 24, 26,142,239, 14, 93,191, 36,207,196,174,122,239,220, 2,139,167, +253, 83,117,189, 14, 33,212,221,238,146,231,137,179,204,220, 22,198,248,243,128, 81, 7,157,222,136,164, 28, 30, 73,185, 58, 72, + 84, 50,220,138, 73,214,218,167, 35,248, 57, 86,155, 50, 87, 41, 93, 23,126,181,202, 93,167, 45,230, 10,243,178, 57,153,252,134, + 84,101,166, 72, 51,165,169,194,141, 20,232,122, 52,150,190, 2, 8,140, 92, 73, 74,230,127, 48,201, 60, 37,242, 12,154,211,169, +160, 8,129,153,223, 96, 88,154, 49,178,110,141,164,137, 0, 96,110,174,146,175,252,226, 67,235,247, 63,254,162,206, 54, 96,126, +128,204,187,169,243,251, 1, 94,182,184,116, 59, 26,151,194, 18, 34, 46,221,122,208,178,119, 43, 87,120,187,219,204,150,231,229, +175,136,130,233, 9,105,105,193,112, 0,171,171,232,117,232,231,136,177, 29,222,248,172,166,222,134,213,210, 24, 16, 98,120, 2, +138, 97, 0,138, 46,237, 1,153,116, 21, 18,155,166,100,239,129,163, 37,219,183,239, 90, 26,149, 93,255,206, 25, 44, 15,190,176, +176, 16,230,230,230, 56, 29,195,233,223,236, 47, 83,208, 52,141,164,152, 59,127, 54,134,183,163,253,101,189,191,244,189,186,184, +195, 25, 75, 57,165,112, 29,252,133, 31, 23,182, 43,185,161, 39, 9, 17,145,255, 6, 10, 10, 10,238, 71, 69, 69,245,111,221,186, +245,142,247,222,123,207,114,252,248,241,174, 83,167, 78,165, 1, 32, 35, 35, 67, 88,187,118,109,234,247,223,127, 95,144,157,157, +253, 22,203,178,245, 25,202,132,164,165,165, 93,251,225,135, 31,178, 46, 95,190,220,178, 99,199,142,138, 87, 94,121, 69,176,181, +181,149, 40, 20, 10,222, 96, 48,232, 98, 98, 98,248,184,184, 56,151,252,252,252, 71, 0, 98,209,128, 59, 86,148,165, 87, 75, 24, +134, 89, 72, 8, 9,120, 17,109,180, 84, 42,149, 43,128, 71, 20, 69, 53, 55,181,218,240,153, 19,182, 68,130,188,188, 60,148,164, + 71, 64,153,252, 16,173,205,105,248,219, 90,192,202,202,234,185, 76, 81, 65, 65, 1,160, 73,193,149, 43,247, 0,142,131,181,181, + 53,172,173,173,255,118,163, 85,147, 23,249,151, 48,173,154,215,106,111,163,229,175,198,219,102, 6,172,157, 62,184,153,172,177, +167, 59,244,201,183,112, 47,169, 24, 11, 58,117,140,100, 20,150,186,233, 19,134,182, 31, 49,178, 17,122,117,233, 64, 53,118,177, +158,189, 98,245,166,119,252,145,253, 97,100, 38,214,213,103,137, 34,179,240, 88, 64,230,246,243,247,147,103,184,171,180, 16, 4, +130,243, 97,105, 8,139,207,219, 30,157,133,199,166,172,157,191, 11,250, 74, 64,239, 39,132, 40,173,205,205,139,252,189,221, 29, +250,118,110, 67, 15,232,217, 30, 50, 6,184,242,199, 61,204, 89,125,228,134, 32,144,193,119,234, 89,109, 88,218,195,176,170,129, + 42,237, 97,200, 86,233, 97, 72, 8, 33,165,189, 14,107, 15, 31, 24,134, 74, 47, 73,184,233, 44,181,111, 1,109,236,121,196,231, + 9, 72,200, 44, 66,161,196, 25,250,148, 20,128, 8,137, 23,107,111, 88, 93, 43, 14, 14, 14,142, 77,252,189,155,173,223,121, 8, +198,146, 2, 60,190,176, 3,197,121,105,248,114,243,241,102,110,110,246, 61, 83, 82, 82, 46,154,112,176,241,254, 45,120,175, 35, + 8,192, 72, 21, 56,185,241, 0,178,237,205,224,160,146, 65,208,102, 97,250,251,227,173, 7,246, 27,111, 13, 0, 9, 15,238,194, + 75,165,173,151,174,209, 30, 35,222,232,237, 99, 3, 86,139,157,167,239,234,104, 96,192,174,179, 17,177,189,125,109,148,111,116, +243,178, 93,146,154,255, 58,114, 26, 54,168,104,121,162, 85,145,240, 53,160,183,225, 33,128,247, 21, 16,187,255, 90,166,249,200, +126,175,168,100, 18,138, 34,197, 41, 32,102, 14,216,180,243, 96,177,156, 53,237, 78,236, 2,176, 36,112,249,227,133,165,251, 9, +118, 12, 92,126,235, 63,231, 62,239,164, 78, 79, 79,135,177,172,238,240,113,174,240,251,132,126,254,124,114,129, 96, 56,187, 98, +248, 72,202, 76, 45,255,232,155, 93, 23, 8, 32,142, 38, 45,242,175, 70,171,213,222,214,106,181,173, 62,250,232,163,177,243,231, +207,239, 97,110,110,222, 4, 0, 52, 26,205, 99,150,101, 47,149,253, 63, 77,233, 29, 72, 0, 60,138,141,141,125, 28, 27, 27,235, +180,103,207, 30, 27, 0,202,178,247,116, 0,242, 1,100,224, 57,122, 28,150,155, 42,138,162, 22,190,168,237, 80,110,170, 40,138, +106,222,144,239,211, 52,205, 83, 20, 5,138,162,160, 80, 40,112,249,242,101,140, 26,220, 15, 81, 39,243, 17, 96, 99,129,142,111, + 77,199,254,115,231,192, 48, 12, 40,138, 2,195, 48, 38,157, 71, 36, 18, 9,174, 92,185,130, 55,199,140,132, 66, 2, 88, 91, 91, +227,163,143, 62,194,177, 99,199, 32,145,136,119,233, 51,129,173,149, 12, 87, 61,199,209,162,176,228,220,142,101, 50,240, 44, 78, +236,248, 22,193,225,197,134, 7, 89, 88,224,147,133,181,135, 80, 36,100,173,222, 53,227,220,149,240,111, 38,143, 14, 82,245,233, +221, 15,125,122,245,150,180,236,208,243,115,160,138,209,234,139, 90,198,218,224, 5, 44,221,122, 58,122,250,254, 11, 49, 20,140, + 69, 24,253, 90, 7,194, 11, 88, 90,199,202, 60,163,105,109,102,177,255,202,245,235,182, 48, 22, 35,254,238,239,202, 70, 77,154, + 1,188, 17,143, 30, 61,196,247, 59,127, 17, 46,252,241, 96,183,129,195,123,113,121,208,212, 87,179,244, 76,201,193,218, 92,238, + 51,160,165,213,175, 2, 8,108, 84, 50, 95, 34,240,176, 81, 73,125,251,249,170,126, 37,132, 16, 75, 51,169, 47,225,217, 58, 53, +181, 6,110,203,206, 31,183,175,154, 50,101,138,121,118,114, 58, 82, 11,195, 81, 44,119, 3,171,242, 64,236,221, 75,218, 18, 61, + 87,159,147,120,141,219, 51, 59, 59, 59,243,118,104, 46,246,111, 94, 14,214,160, 71,102,114,169, 87, 77,205, 46,132,149,131,219, +245,148,148,148,122,107, 26, 57,161, 96,196,248,105, 50, 51, 75,152,189, 57, 34, 72, 30,155,163, 71, 59, 87,203,210,131, 70,113, + 22,162, 66,174,160, 87, 89, 27,211,184, 36, 26, 94,109, 92,235,181,156,150, 74,217,123, 3, 95,113,195,227,196, 52, 92,142, 72, +217,249, 56, 23,169,124,116,218,206,216,212,252, 25, 67, 59,121, 98,205,177,200,119, 1,118,175, 41,235,238,231,136,177,132,160, + 91,105, 99,120, 45, 8,208,205,207, 17, 99,235,217,211,240, 25, 77,137, 12,227, 86,253,154,240,217,193,155,217, 67,231,141,235, +110,213,165,203, 32, 57, 56, 3,138,180,122, 54, 42, 31,133,166,104, 22,106,133, 45, 0,182,148,191,113, 59, 89,216,221,125,209, +245, 75,123,167,122,168,203,189,250,165, 88,253,117, 0,215, 39, 7,154,125, 46,235,253,165,207,245, 37,129,103,194,210,132, 61, +151, 98, 43,198,208,170,243,127,212, 64, 68, 77, 81,243,239,208,228, 1,236,102, 89,118,119,126,126,254,139,212, 76,197,179,227, + 58, 61,215,186, 87,174, 38, 36,132, 72,202,210,172,186, 26,195,215,170, 89,185,154,144, 16,114,170, 44,205,170, 43,213,170,162, + 41, 8, 66,106,251,246,237,237,134, 12, 25, 2,158,231,241,240,225, 67, 36, 36, 37,161,239,140,119, 97, 99, 99,131, 75,247,239, +227,193,131, 7, 88,184,112, 33, 88,150,197,209,163, 71,147,235,210,148, 72, 36,198,102,205,154,201,134, 13, 27, 6,142,227, 16, + 23, 23,135,148,148, 20,204,153, 51, 7,214,214,214,184,125,251,118,133,102,118,118, 54, 36, 18,137,177,154,116,235,175,216,151, +254,237, 60, 99,178,106, 55, 90, 0, 15,158, 69,193,185, 69, 88,119, 25, 70, 35, 11,223,200, 44, 60,137,252, 51,145,218,196,132, +222, 63,113, 63, 60,250,241,237,171,125,228,200, 12,131,169, 87, 18, 15,115,144,102,169, 44, 42,130,177,200, 10,113,191,226, 73, + 70, 81,241,195, 28,164,153,124,197, 32,240, 20,140, 37, 64,218, 45, 92,187,116, 17, 23,110,220,195,205,176,104,254,218,237,152, +253,180,128,165, 81, 57,120,216,128,171, 16, 88, 12, 94,131, 73, 97,143, 60, 59,120, 59,121,130,231, 64, 4, 22,214,163,247,226, +173,200, 46,158, 29,154,218,120,150, 38, 89, 44,108,255,243, 59,176, 74, 89,171,222,173, 36,118,171,252,216,153,215,139,242,115, + 58,189,218,179,179,185,181,223, 64,100, 63,138,193,195,123, 87,180,183,195, 99,175,221, 74, 98,183, 62, 79,233,186,185,185,245, +120,181,167, 15, 70, 79,255, 20,198,146, 2,196, 93,248, 17,197,185,233,184,124,221, 2,209,133,133,157, 1,212, 59,209,186,158, +200,181, 68, 98, 30,186, 54,146, 38, 90, 66,239, 60, 33,104, 8, 20,148, 14,130,190, 16, 84, 73, 54, 98, 83, 12, 5,175,111, 78, +226, 1, 64,165,160, 36,230,164,192,170, 94,201,163,151,125, 11, 21,195, 98,215,185, 8, 8, 66,233,237,155, 4, 1,155,118,253, + 30, 59, 99,233,155,237,224,239,105,219,230,110, 74, 38, 5, 19, 34,127,138,160,251,205,253, 95,248,234,126,251, 28, 16,140,184, + 50,219,206,183,251,186,220,238,104,224,237,118,194, 83,145, 2, 96, 6, 36, 37, 91,102,175, 59,253,121,251,115,145,221,230,254, +103,168, 21,200, 11,233,161, 27, 19,153,206,247, 8, 92,145,112, 70, 32, 85,235,115, 75,147, 45, 63,146, 90, 72,238, 94,138,213, +139,163,194,139,136,136, 0, 0,138,139,139,167,191,245,214, 91, 91,164, 82,169, 26, 0, 37, 8, 2, 4, 65,144,124,243,205, 55, + 82,158,231,105,154,166,121,134, 97,184, 83,167, 78,177, 60,207,103,233,116,186,233,117,105,114, 28, 23, 59,115,230,204,102,117, +245, 80,220,183,111, 95,185,201,138, 21, 75,162, 94, 38,171,242,188, 34,229,146,212, 18,210,126,209,245,205, 69,139, 0, 80, 32, + 88, 28,153,133, 39, 79,127, 36, 44, 23,169,254,140,113, 78,203, 14, 61, 23,149,127,199,212, 37,211,241,252,200, 14,173,188,247, + 1,128,158,240,111, 54,100,237, 10,245,218, 55,218,118,232,188, 95, 32, 68,194, 17,178,157, 22,112, 88,199, 33,170, 62, 61,237, +106, 34, 53, 51,255,246,192, 0,107, 2,148, 86, 25, 86, 84, 23,150, 13,227, 64, 8, 33, 21,213,133,223, 42,145, 93,160,175,115, + 28,168,171, 79, 12,253, 12,220,205,105,103,175,222,157,206,243,196,153, 97,168,116,173,129,219,242,188, 38, 11, 0, 82, 82, 82, + 46,134,156, 75, 57,123,191,141,211,107, 14,170,178,148,171, 4,200, 46,193,217,148,172,226,139, 13,209,204,211,176, 67,113, 22, + 77, 53, 0, 0, 32, 0, 73, 68, 65, 84,231,175, 61,118, 92, 46,101, 36, 32,164,116, 64, 81, 66,160, 51,242,185,215, 19,185,150, + 0,208,202, 14,174, 31, 29,229,246, 49, 12,149, 80,151, 94,232,131,180, 53,163, 87,132,124, 24, 17,159,183, 61, 62, 31,225, 0, + 16,159,143,240, 3, 87,158,124, 30,155, 94,244, 97,120, 66,222,183, 48,177, 93, 5,161,112,185,195,232, 69,207,188,246,188,219, + 51, 58, 13,247, 0, 12, 7,146,251,141,158,251,253, 92,138,194,139,186,253, 68,140,214, 72,188,158,126,177, 60,217, 18,143, 85, + 34, 34,255, 29,148,167, 90, 52, 77, 47,121,129,154,167, 40,138, 26, 4,224,145, 9, 95, 11, 45, 46, 46,110,245,130, 87, 47,135, +227,184,156,250,124,240, 31,104, 16,255,111,101,235, 63,245,195,125, 69,205,191, 95,179,121,243,230,196, 4,195, 34,110, 79, 81, + 83,212, 20, 53,255,167, 52, 9, 33,204,243, 76, 53,104, 82,207, 51,137,101,244,175,103, 90, 77,207,197,150,110, 47, 33,143, 30, + 61,162,196,173, 32, 34, 34, 34, 82, 61, 20, 69,241,127,129,166, 56, 58,158, 72,185,193,170,146,110,209,226, 54, 17, 17, 17, 17, + 17, 17, 17, 17,121, 33, 38,171,242,188,212,132,163,230,248,207,148,222, 4, 13,137, 16, 67, 68, 77, 81, 83,212, 20, 53, 69, 77, + 81, 83,212,252,159,211,172, 75, 91,236,205,248, 23, 27, 48, 81, 83,212, 20, 53, 69, 77, 81, 83,212, 20, 53,255,247, 52,255,205, +212,216, 70, 75,172, 58, 20, 17, 17, 17, 17, 17, 17, 17,249,139, 16, 27,195,139,136,136,136,136,136,136,136, 60, 31,117,222, 84, + 90, 68, 68, 68, 68, 68, 68, 68, 68,164, 97,212,126, 83,105, 17, 17, 17, 17, 17, 17, 17, 17,145, 6, 99,250, 77,165, 69, 68, 68, + 68, 68, 68, 68, 68, 68,234,197, 86,113, 19,136,136,136,136,136,136,136,136,252, 61, 84,237,117, 24, 28, 28, 76, 42,207, 69, 68, + 68, 68, 68, 68, 68, 68,254, 78, 94, 86, 47, 34, 86, 29,138,136,136,136,136,136,136,136, 60, 31,211, 68,163, 37, 34, 34, 34, 34, + 34, 34, 34,242,215, 80, 99, 27,173,242, 1, 75,123,149, 69,117,189,196,109, 37, 34, 34, 34, 34, 34, 34,242, 15,240,114,123, 17, +177,125,150,136,136,136,136,136,136,136,232, 69, 68, 68, 68, 68, 68, 68, 68, 68, 68,254,155, 16,239,117, 40, 34, 34, 34, 34, 34, + 34, 34,242, 55, 27,174,191,220,104,137,119, 54, 23, 53, 69, 77, 81, 83,212, 20, 53, 69, 77, 81,243,127,201,100, 85, 49, 91, 98, +175, 67, 17, 17, 17, 17, 17, 17, 17,145,231,163,206, 94,135, 34, 34, 34, 34, 34, 34, 34, 34, 34, 13, 99, 26,128,160,178,199, 65, +168,148,106,137,137,150,136,136,136,136,136,136,136,200,243,177, 21,128, 75,153,193, 58, 9, 32, 77, 52, 90, 34, 34, 34, 34, 34, + 34, 34, 34, 47,134,202,237,178, 6, 87, 50, 95,162,209, 18, 17, 17, 17, 17, 17, 17, 17,121, 78,106,108,163, 69,161,230,158, 3, + 33, 38,252, 64, 67,122, 31,132,136,154,162,166,168, 41,106,138,154,162,166,168,249, 63,167, 89,151,118, 8,254,125, 76, 51,197, +124,189, 72,196,174,175,162,166,168, 41,106,138,154,162,166,168, 41,106,254,207,242,194,123, 29,182, 3,204,196,205,250, 82,226, + 84, 54,137,136,136,136,136,136,136,212,206, 95,211,235,208, 15,248,207,248, 0,245,102, 54, 60,203, 42, 28, 40,169,237,179,106, +181,122,139, 74,165, 26, 95, 82, 82,162,161, 40, 74, 40,127,157, 16, 2, 0,149,239,117, 20,151,149,149,213,189,174,223,150,203, +229,107,157,156,156,254, 83, 92, 92, 92, 66, 81, 20,161, 40, 10, 20, 69, 1,192, 51,115,158,231,147,115,114,114,218,255,171,139, +144, 16,198,193,201,233, 15, 41,195,184,153,250, 85, 94, 16,158,100,102,100,116, 54,225, 43,203, 41, 10,243, 74,127, 22, 95, 3, +248,244,101,251, 71, 16,128,169,207,231, 2, 0,203, 24, 96, 52, 79,211,239, 74,129, 13,122, 65,216, 12, 0, 20,192, 55,244,183, +245,161,104, 70, 17,180,161, 40, 88, 19,130, 2, 66,225,158, 34, 16,177,255,208,166, 24, 33,149, 74,135, 90, 89, 89, 89,228,228, +228, 92, 4,176, 15,192, 24,123,123,251,158,133,133,133,197, 44,203, 30, 3,112,164, 33,194,221,219,224, 99,185, 76, 58, 89,103, +100, 87, 94,189,135, 31,123,182,131, 61, 39, 96,133, 82, 38,233,174, 55,112, 95, 95,185,143,237, 38, 74, 82,101, 83,249, 49,195, +228,123,164, 29,172,103,185, 3,192, 81, 91, 91,111,133,218,234, 55,169,156,121,146,159, 81, 60,126,100,102,102,210,168,231, 40, +247,255, 70, 28, 28, 28, 38,209, 52,253, 21, 33, 4, 60,207, 47,200,205,205,221,241,130,164, 23, 0,176, 41,123,156, 15,224,171, +231,212, 75, 0,224, 89,246, 56, 17,128,151,120, 94,111, 48,155,126,249,229,151, 25,189,123,247,198,154, 53,107,176,105,211,166, +248,172,172,172, 21, 0,118, 2, 48,252, 3, 58, 34, 53,225, 15, 12,250,166,127, 32,207,254,180, 84,168,244,114,223, 26,254,204, + 63, 76,152, 48,193, 72, 8, 33, 15, 30, 60, 32, 6,131,129,176, 44, 75, 56,142, 35, 28,199, 17,150,101, 43, 38, 55, 55,183,148, +167,190,254,140, 38, 77,211,235, 94,127,253,245, 34, 66, 8,185,117,235, 22,209,106,181, 68,175,215, 19,131,193, 64,116, 58, 29, +209,106,181, 85, 38, 39, 39,167,140,218, 52,173,172,172,110,217,218,218,102,216,218,218,102,216,217,217,101,216,217,217,101,216, +219,219, 87, 76, 14, 14, 14, 21,147, 90,173,206, 80,171,213, 25,118,118,118,183,234, 90,206, 50,250, 3,184, 88,143,169,127, 53, +223,237, 91,217,104,185,184,184,100,144, 6,224,238,238,158, 84,143,229, 44,199,137,162,192,151,127,151,162, 32, 40, 20, 10,207, +202,239,227,217,164,171,206, 72,217,213,213,245,117, 23, 23,151, 16, 23, 23,151,115,174,174,174,175,215, 99, 23,171,162,105,105, +105,121,203,193,193, 33,195,217,217, 57,179,124,114,113,113,169, 50,185,186,186, 86, 76, 78, 78, 78, 25,182,182,182, 53,150, 17, + 1,152,154,166, 11,128, 68, 1,244,145, 48, 76,176,147,147, 83, 97, 88, 88, 24, 79, 8, 33, 52, 77,167,148,127,198,148,117,127, +218,100,149, 92,193,130,236,243,138,208,226, 39, 43, 10,178,207, 43, 66, 75,174, 96,129, 62, 20,205, 26,170, 89, 79,170,211,156, + 56,113,226,196,123, 25, 25, 25, 41,249,249,249,105,155, 55,111,142, 81, 42,149, 87, 54,111,222, 28,147,159,159,159,150,145,145, +145, 50,113,226,196,123, 0,102,154,160, 9, 0,232,220, 6,157,166,140,112, 41,185,119,244,205,146, 62, 29, 36,119,187, 6, 32, +168, 95,103, 89,202,250, 79,252, 74, 46,109,235, 86,210,251, 21, 58,220, 68, 77, 74, 34,145,116,241,244,244,156,172, 86,171, 39, +148, 77,111,150, 79,206,206,206,111, 58, 59, 59,191,105,107,107, 59,170, 54,205,131, 0, 83,159,201, 67,169,236, 50,170,137,103, + 73,194,146,197, 36,236,253,119,201,228,166, 30,133, 35, 29, 29, 27,253, 3,101,244,151,106, 58, 58, 58,166,178, 44, 75,140, 70, + 35,177,183,183, 79,125,129,203,249, 45, 33,228, 91, 66,200,183, 0,190,125, 1,154, 21,199, 51, 19, 12,118,109,154, 74, 9, 77, +207, 85,201,229,231, 20, 18, 73,166, 66, 34,201, 84,201,229,231, 36, 52,253, 33, 0,229,127, 83, 25,253, 5,154, 22,106,181,250, +241,218,181,107, 73, 73, 73, 9, 41, 41, 41, 33,107,215,174, 37,106,181,250, 49, 0, 11, 19, 52, 27,170,243, 50, 37, 88, 79, 79, + 47, 46,209,242, 3,218,247,105,211,252,240,236, 73,163, 33, 28, 90, 75,213,113,197,244, 67,231,246,237, 39,239,220,185, 19, 0, + 48,126,232, 80,188,214,177, 35, 44, 45,204, 33,151,151, 46, 14, 69, 40,200,164, 50, 12,155,243, 65,125,126,254,235, 97,195,134, +141, 59,116,232,144, 5, 0,108,218,180, 9, 35, 70,140,128,157,157, 29, 84, 42, 21,100, 50, 25,164, 82,105,149,121, 93, 48, 12, +227,158,146,146,226,168, 84, 42, 43, 82, 54, 65, 16,170, 76,132,144,242,244, 13, 28,199,161, 69,139, 22,245,221, 92,159, 20, 20, + 20,244,208,104, 52, 21, 26,213, 77, 77,154, 52, 1,128, 51,245, 17,252,234,203,165, 16, 56, 13, 36, 18,128,227, 0,189,145,134, + 64,170, 53, 55,152, 57,115,102,197,114, 55,132,193,131,131, 40,138,162, 14,221,190,125,251,112,102,102,102, 99, 65,224,167, 54, + 48,233,122,231,225,195,135, 22, 0,224,237,237, 61, 19,192, 97, 83,150, 67, 34,145,184,223,191,127,223, 81,161, 80,212,152, 92, + 86, 74, 48, 97, 52, 26,209,174, 93, 59,206,148,223,112, 2, 60,115,105,122,106,219, 87, 94,153,182,104,216, 48,229, 31,127,252, +161,164,105, 26, 28,199,225,155,111,190,225, 8, 33, 54,254,128, 85, 36, 80, 88,139,204,124, 0,147,202, 78, 6,219, 1,124, 83, +197, 45, 16,180,209,178,138,160,184,226, 97, 29, 3, 27,125,140,200,136,176,142, 77, 45,142,194, 82,162,143, 5,254,222, 84,203, +202,202,106,232,154, 53,107,212,219,183,111, 47,124,240,224,129,113,243,230,205,234,233,211,167, 91, 26,141, 70,204,152, 49, 35, +203,199,199, 71,182,102,205, 26,245,145, 35, 71,250,104, 52,154,141, 38,149, 23,133,165, 99,134,190, 6, 29, 75,131,101, 57,181, +139,218,114,247,236,137,189,164,132, 24,176,235,216,109,176,156,240,163,137, 73, 86,231,145, 35, 71, 54,221,187,119,175, 36, 58, + 58, 90,226,235,235, 11, 65, 16,192,243, 60, 88,150, 5, 0, 8,130,128,230,205,155, 63,247,118,153, 12,120, 59, 56,217,157,235, + 60,104,160,153,139, 82, 1,187,188, 44, 76,145, 73, 44,119,168,244,123, 0,116,121,169,146, 93, 66, 32,145, 72,144,148,148, 4, + 71, 71, 71, 51, 65, 16,210, 0, 44,206,203,203,219,138,151,151,142,114,137,228,240,174, 31,215, 57, 7,118,233,194, 56,185, 56, + 34,230, 97, 34, 36, 20,223,247,254,205,219,189, 38,191, 61,119,182,129,227, 94, 7,240,199,203,182,226,206, 93,102, 14,167,104, +102, 19, 69, 4,124,177,254,120,209,242,175,215,170,102, 76,157,200,204,153, 51, 7, 30, 30, 30,141,135, 15, 31,254, 53,128,183, +235,212, 9,156, 57, 28, 12,189, 9,132, 96,209,247,199,139,150,125,189, 86,245,118, 3,116,254,229,212,248, 31,121,110,163,229, + 7, 52,109,233,225,120,118,249,188,183,165,228,215,159,232,146,156,204, 26, 63,171, 86,171,183, 12, 24, 48, 96,252,142, 29,127, +166,209,157, 3, 2, 48,188, 79, 55, 56,218, 91, 67,101, 46, 47, 61, 29, 9, 20,238, 61,120, 82, 47, 67,224,225,225, 49,227,240, +225,195, 22,149,205,132, 76, 38,171,152, 42,155,172,242,169,252, 4, 92, 27, 74,165, 18, 33, 33, 33,144, 72, 36, 96, 24, 6, 18, +137,164, 98,170,252,156, 97, 24, 56, 57,153,212,116,105,133,181,181,117,235,162,162, 34,171,252,252,124,120,122,122, 22, 2,184, + 95,233,253,214, 89, 89, 89, 86,166, 8, 10,156, 6,115,166,248, 65,106,184, 1,131,180, 35,180,146,174,184,118, 51, 10,193,103, + 46, 34, 37, 53, 29,221, 58,181,197,132,177, 35,113,238,220, 57,240,188,201, 53, 29, 25,132,224,235, 33, 67,130, 62, 6, 40,170, +111,223,190,249,179,102,205,162,163,163,163,199, 13, 31, 62, 44,224,225,195, 71,101,169, 34, 53,143, 16,172, 3,144, 81, 79, 93, + 57, 0, 92,186,116, 9, 0, 20, 13,217,247, 20, 10, 5,174, 95,191,142,242,106, 98,154,166, 65,211, 52, 24,134,193,137, 71, 14, +208, 24,104,148,100,132,227,221, 32, 79, 52,105,210, 4, 52, 93,119,147,196, 94,128,242, 26, 48,156,146, 74,231,184,184,186, 54, +238,217,180,169, 42, 36, 36,132, 1, 0, 47, 47, 47,146,150,150,150,127,236,216,177, 34, 9,176,201,139,144,157,181,153, 44, 15, + 15,143,174, 41, 41, 41, 95,149,111,115,138,162,190,110,212,168,209,194,138,114, 19, 4, 44,254, 81, 35,157, 61,251,125, 89, 96, +175,207, 0, 0,129, 67,246,162, 48,110,185, 31,149, 59,223,250,239, 62, 74, 20, 22, 22,238,111,222,188, 57,147,147,147,115, 13, + 64, 2,203,178,159,236,222,189,219,113,202,148, 41,153,123,246,236, 89, 1,192,117,229,202,149,189, 52, 26,205, 1, 83,116,187, +181,198,160, 87, 90, 7,116,242,244,240,192,197,107,127, 64, 38,151,218,204,156, 20, 4, 11, 11, 9,190,221,126, 82, 72, 72,206, +157,117,229, 62,118,154, 96,178, 58,142, 28, 57,178,241,222,189,123,229, 0,112,255,254,125,164,167,167, 67,173, 86,195,204,204, + 12, 82,169, 20, 12,195, 64, 42,149,190, 16,147,101,237, 97, 31,122,244,232, 49, 51, 59, 59, 27,172,255, 96, 54, 38,100,102,192, +198,210, 2,108,177,166,241, 75,118,162,240,238,222,189,187,146,231,121,104, 52, 26, 92,184,112,193,218,204,204,204,218,221,221, +125, 17, 76,232, 61,165, 84, 42, 51,116, 58,157, 99,217,227, 76,157, 78,231, 4,160, 80,161, 80,148, 31,167,139,203,230,245,173, + 78, 76,192,179,213,132,137, 20, 69, 85,126,173,161,116,232,216,161,117,200,145, 67, 63, 91, 20, 20,165,195,198, 54, 19, 52, 10, +176,117,235, 6,152,153, 89, 97,209,162,249,146, 39,125,251,184,245, 31,244,122, 72, 68, 84, 76,223,151,206,108, 17,106,107,223, + 33,227,237,204, 84,150,101,231, 18, 22, 59,182,205, 6, 77,211, 88,184,112, 33, 90,182,108, 57, 45, 34, 34,226, 51, 0,185,181, +203, 96,107,171, 30,111,216,201,149,165, 69, 44,240, 44, 54,239,251,176, 84,231,211,233, 24, 51,164,201,180,143, 70, 62, 62,221, +178, 41,138,202, 46,204,181, 82, 26,137, 84, 32, 42, 12, 67,112,112,112,207,160,160,160,139, 53, 61,255, 23,224,130, 63,199,207, +170, 98,190, 36,193,193,193, 36, 40, 40,136,170,180,114, 85,158,215, 70, 27,192,193,214, 90, 21,178,105,241,108, 11,201,141,147, +140, 54,241, 17, 82,117, 85, 78,228, 85,186,104,170, 84,170,241, 59,118,236,168, 18, 41,121, 58, 57, 66, 38,147, 66, 42,163, 96, +211,189,116,244,250,252,203,193,160,168, 26, 77, 86, 21, 77,141, 70,163,187,123,247,174,197,246,237,219,225,232,232,136,198,141, + 27, 67,165, 82, 65,169, 84, 86, 49, 87,149, 13, 87, 53, 70,171,138,102,249,251, 18,137, 4, 52, 77,227,220,185,115,224, 56, 14, + 35, 71,142,124,198,100, 73, 36,146,154,140, 91, 77,221, 83,207, 0,184, 79, 8,233, 81,118, 2,190, 15,160,103,165,247,251,171, +213,234, 79, 0,172,168,175, 38,195, 16, 48,186,107, 16,220,215, 66,146, 52, 27, 6,105, 27,156,191,114, 27, 59,182,172, 1, 0, + 52,246,237,128, 81,195,131, 42,210,184,122, 46,103, 5,110,110,110,251,178,178,178, 7,246,233,211, 7,121,121,121,236,226,197, +139,209,186,117,107,120,123,123,215,171,140,106,184,114,206,184,127,255,190,135, 86,171, 5, 33,164, 62,230,236, 25, 77,138,162, +176,123,247,110,232,116,186,103, 62,108,219,115, 25, 62, 28,225,133,183,222,221,137,175, 31, 28,192,198,141, 27,107, 93,119, 21, +208, 90,103,221,124,157,156,225, 90,175,152,255,142, 98,194,132, 9,204, 91,111,189,133,196,196, 68, 76,153, 50, 69,119,238,220, + 57, 67,122, 90,218, 49,185, 32,172, 55, 86, 53,198, 53,106, 42, 20,138, 93,103,206,156,193,129, 3,165,190, 36, 38, 38, 6, 45, + 90,180, 48,175, 98,146,115, 15,162, 40, 97, 61, 66, 79, 68, 35,112,200, 94,132,158, 24, 11, 62,255,164,180,125, 11, 20,152,178, + 61, 27, 64,117,154, 7,114,114,114, 42, 76,212,158, 61,123,204,246,236,217, 51, 12,192,113, 0, 7, 0, 32, 55, 55,119,181,137, +154, 0,133,183,222, 24, 49, 12, 18,153, 37,162, 31, 37,163,103,231,118,112,114,116,196,253,168, 88, 36,164,228,102, 80, 20, 38, +245,239, 34, 95,161,213, 26, 62,187,124, 15, 63,212,161, 73,185,187,187,123, 31, 60,120, 80, 86, 41,129,174,248,143, 51, 12, 83, +241,188,220,120, 55,100,255, 44, 55, 89,150,238, 22,161, 75, 55,116, 53, 15, 13,219,131, 22, 94,131, 96, 59, 40, 8, 63,156, 61, +139,135, 17,145, 58, 67, 9,247,234, 63, 80, 70,127,149,166,247,136, 17, 35,174,253,252,243,207, 54, 73, 73, 73,184,116,233, 18, + 26, 55,110,140,146,146,146,250, 92,240, 86,209,212,233,116,142,229,223,161, 40,202,177, 60,120, 55, 24, 12,229,133, 81,254, 71, +180,169,244, 57,155, 90, 52, 61, 43,125,174,220, 92,121,189,128,117,151, 43,101,178,131, 71,143,236,179,136,140,190,132,182,109, + 58,193,194,218, 31, 2,159,142,156,220, 98,228, 61, 74,197,151, 95,126,141, 69,139, 23,224,248, 47,135, 44,124,252,218, 28, 54, +112, 92,115, 0,186,151,166,220, 41, 50, 45,228,196,158, 77, 20, 17,160,205,136, 86, 72, 53,143, 85,227,199,190,206,140, 30, 61, + 26,199,143, 31, 71, 68, 68,196,166, 90, 76, 86, 72,165,100,126, 90,248,165, 3,155, 64, 8,180,153,209, 10,153,246,177,106,226, +184, 81,204,132, 49,175,225,198,239,235,240, 90,219,199,225,174,142, 24,158, 87,102,177, 37, 12,114, 20, 74, 92, 37,161,184, 81, +201,108, 93, 0, 64, 85, 50, 88, 23,240,103, 27,204,127, 3,131,203,140,213,180,167, 47, 76, 36, 13, 49, 88, 0,208, 2,176,160, +228,178,208, 29,139,222,113, 85, 37, 70, 72,244,225,215,145,170, 23,200,230,120, 78,104, 7,152,221, 1,180, 79,127,167,164,164, + 68, 19, 27, 27,107, 54,105,248,112,116, 9, 8,128,139,189, 61,154,187,187,195, 76, 33,135, 92, 38,173,114,201, 90,239, 58, 4, +138, 34, 62, 62, 62, 24, 50,100, 8,164, 82, 41, 84, 42, 21, 44, 44, 44, 32,151,203,171, 77,179,234,123,149, 75, 8, 1,195, 48, + 8, 15, 15, 71, 66, 66, 2,108,108,108,112,245,234, 85,188,250,234,171,207,164, 90,149,205,153, 41, 17,125, 53, 39,254,114, 35, +118,198, 20, 45,158,167, 80, 76,218, 64, 25, 63, 11, 37, 84, 59,232,245, 28,244,122, 61,126,184, 98,196, 31,177, 26, 24,141, 6, +232,245,250,218,126,179, 38,104, 87, 87,215,241,205,155, 55,159, 57,118,236, 88, 86, 46,151, 67,163,209,160,164,164, 4, 17, 17, + 17,236,192,129,131,242,135, 12, 9,178, 62,121,242, 36, 41,171, 58,204, 48, 65, 59,199,205,205,205,163,172,122, 54,167, 33,123, + 53, 69, 81, 21, 38,230,105, 38,173,142,132,132, 41, 45,147, 77,155, 54,129,231,121, 16, 66,106, 44, 36, 29, 69,253,182,120,217, + 42,235,149,107,127,132,181,157, 19, 46, 94,188,200,159, 62,125,186,136, 2, 98, 30, 70, 68,172,254, 63,224,212, 65,192,104,202, +242,229,229,229,153, 53,110,220, 24,238,238,238, 16, 4, 1, 44,203, 86,164, 47, 57, 57, 57,208,106,181,176, 51,207, 71, 51,123, +119,112, 69, 23,144, 22,254, 5, 92, 44,162,177,243,140,129,125,197, 27,247,254, 11, 14, 28, 63,149, 77,207,121,213, 12, 55, 71, +103, 15,208,132, 69,106,102, 14,134, 13,126, 13,140,204, 2, 79,146,178,209,198,191,169,203,184,255,235,234,194, 80, 28,230,173, +216, 59, 19, 16,126,168, 75,174,184,184,152,143,142,142,198,253,251,165,126,215,202,202, 10,230,230,230, 85,254,227, 52, 77, 63, + 87,162, 85,110,178,150,109,122,213,156,150,106, 80,200,135, 96,251,238,219,104,227, 19,132,205,161, 55,117,124, 70,110,223,111, +117,186,152,125,255,226, 48,195,217,217,121,186, 32, 8,139, 8, 33,249,221,186,117,115,218,187,119,175,109, 74, 74, 10,110,223, +190,141,133, 11, 23,102,241, 60,207, 17, 66, 40, 66,200, 23, 47,224,231,132, 74, 6,235, 69, 34, 85, 41,241,174,131, 21, 53, 84, + 66, 91, 53,230, 10,139,159,100, 27,200,177, 18, 78,248, 30, 0, 91,235,193,141,166,255,115,104,255, 38, 87, 7,181,128, 94,234, + 62, 72,203, 48, 98,217, 7, 19,145,147, 83,132, 31,182, 45, 7, 32,135,145, 99,208,163,215,235,112,116,116,195,180,169,211,156, + 55,109,217,252, 14, 39, 8,223,226, 37, 33,253,218,198, 95, 0,132,168,213,234,136,119,166, 77, 83, 55,110,252, 38,148, 74, 37, +246,237,219,135,189,235,215,243,107,129, 81, 10,224,252, 12,224,151, 90,117, 66,255,212,153, 61, 99,134,218,207,111, 6, 20, 10, + 5,126, 63,253, 19,116,233,187,139, 6,119,129,177, 68,135,193,141,134, 16,187,248, 19, 84,174, 84,138, 71, 0, 32, 85, 34, 13, +192,211,213, 96,255, 54,131, 85,206, 73,252,217, 46,107, 90,149, 68,171,193,199, 78,169, 60,108,219,251, 99,188,156,160,167, 12, + 87, 78, 32, 69, 47,240, 43, 31, 26,153, 59, 5,228,195,168,106, 76, 86,217,142, 45,120,122,122,162, 79,251,246, 24,222,189, 59, + 36, 18, 9,148,114, 25, 44,149,102, 32,124,105,146, 85, 94,117, 88,203, 57, 17,213,165, 79,246,246,246,144,201,100, 21, 6,203, +132, 52,171, 90, 77, 65, 16, 32,145, 72,112,255,254,125,116,235,214, 13, 30, 30, 30, 56,112,224, 0,250,247,239,255, 76, 85,162, +169, 38,171,220,104, 61, 85,141,215, 31, 64,121,146,101,146,209,210, 25, 40,100, 27,218,128,162, 2,192,113, 0, 79, 0,189, 78, + 7, 66, 0, 66, 0,214,104,128, 78,167,171,248,205,250, 84,201, 58, 59, 59,123,154,153,153, 45,249,248,227,121,126,109,218,180, + 69, 86, 86, 22, 4, 65,128,185,185, 57, 74, 74, 74, 96,101,101,133, 46, 93,186, 60, 89,178,100, 73, 26, 33,152,102,162,201,122, +110,202,183,249,217,179,103,171, 84, 27,150, 79,154,180,100,188,245,222, 30,200, 37,165, 85, 75,229,109,120,106, 59,238,246,238, +209, 21,215,238,196,112,255,153,183, 78, 47,205,185,189,194, 89, 16,118, 36, 63,199,122, 17, 66,144,157,157,141,140,140, 12, 12, + 29, 54, 12,123,127,254, 25,241,241,241,240,247,247, 71,239,222,189,225,232,232,136,248,248,120,252,113, 89, 15,125, 94, 46,114, + 13,183,161,178, 12,196,209,139,177,250,133,155,140,177,255,224, 1, 99, 40,128,137, 86, 86, 86, 77, 74, 74, 74,210, 56,142, 59, + 8,224, 32,128, 81, 18,137,100,148, 74,165,114, 41, 44, 44,124,140,210,222, 68,199,234, 18, 51, 83, 42,237, 21, 74, 43, 8,156, + 30, 18,137, 4, 30, 30,141, 65,120, 3,242, 10,181,152, 52,122, 8,238,220,143,194,233,243, 55, 56,150, 21,190,171,207,102,101, + 24,134,120,123,123, 35, 51, 51, 19, 82,169, 20,102,102,102,176,176,176,192,167,159,126,138,245,235,215, 87,152,172,134, 26,173, +201,128,183,149,167,197,141,175, 54,148,154,172,244,212, 52,100, 36, 75,161,182,119,194,119,235,215,106,242,226,211, 3,127, 4, + 98,254,237, 39, 89, 65, 16,190, 72, 73, 73,113,148, 72, 36,206, 28,199, 33, 41, 41, 9,183,110,221,194,172, 89,179, 50,114,114, +114,122,161,129,235,168, 84, 42, 51,203,147,172,178,170,195,154,170, 19,243, 43, 37, 89,249,181, 72,214, 84, 77,216,180,177,187, +229,185,109,107,230,120,118, 8,236, 66,171, 36, 86,121,197,143,210,187, 93,185,116,177,203,172, 53, 63,188,147,144, 87,252, 26, +128,184,154, 68, 21, 82,233,192, 78, 93,187, 74, 64, 50, 32,145,119,195,215, 43, 71, 35, 43,187, 16,121,185, 69,144,201,204, 97, + 96, 25,240, 2,133, 46,221,186,227,167,157,251,209,114,234, 20, 70, 46,149,246,227, 12,134,151,198,104,149,177,252,251,239,191, +247,244,241,241,193,142, 29, 59,112,126,215, 46, 76, 40, 40,192, 69,154,102, 88,169,212,225, 20,203,110, 69, 29, 70,171,178, 78, +203,150, 45,241,227,143, 63, 98,247,238,221,137,227, 95,205, 60, 60,103, 60, 28,141, 70, 12,184,253, 0,118,141,134, 0,183, 31, +192,238, 21, 31, 52,231, 36,120, 68, 81, 85,135,131, 10, 14, 14,238, 89,121,254, 47, 35, 13, 53, 84,177, 75, 0,244, 10, 14, 14, + 38,149,231,117, 30, 56,213, 45,102, 44,127,173,137, 87, 64, 51, 79,138, 61,176, 14, 73, 26,206,240,217, 3,163,252, 97, 49,153, + 19, 5,172,173,229, 10,130, 48, 12, 3, 75, 51, 51,168,109,108, 74, 99,126,154, 6, 4, 64, 96, 1,138, 47, 53, 0, 68,160, 64, +120,147, 14, 24,144,203,229,213, 54,124, 55,181,109, 86,101,205,162,162, 34, 60,121,242, 4,211,166, 77,131, 74,165, 42,117,238, +233,233,240,242,242,130, 68, 34, 65, 74, 74, 10,126,255,253,119, 52,105,210, 4, 10,133,194, 36,183, 85, 41, 93,106,141,210, 94, +134,173,211,210,210,172, 92, 92, 92, 96,114,162, 37, 16,148,232, 41, 24, 12, 60, 30, 62,124,136,212,212, 84, 60,121,252, 8, 29, + 52,133, 32, 96, 64, 8, 49, 41,209,114,115,115, 11,104,218,180,233,230, 21, 43, 86,200,220,221,221, 65, 8,129,173,173, 13, 74, + 74, 74,144,157,157, 3,127,127,127,120,120,120, 96,197,138, 21, 0,176,247,239, 54, 89, 79,237, 83, 21, 70,171,178,225,122,239, +255, 60,145,155,107, 1,134,161, 43,140,115, 29,109,180,100, 0,208,235,181, 17,146,115,167, 79,153,115,192,146,116,134, 89, 34, +169,187, 28, 89, 94, 16, 84, 53,189,159,148,148, 4,169, 84,138, 67, 7, 15, 34, 55, 35, 3,109,218,180, 65,199,142, 29,241,232, +209, 35,220,185,115, 7,246,246,246, 80,187,119,198,197,199, 70, 68,166,106, 97,109,109,141,216,100,250,159, 28, 50, 96,106,223, +190,125, 23,174, 94,189,218,209,217,217, 89,154,149,149,229,179, 97,195,134, 54, 27, 54,108,152,253,206, 59,239, 56,189,243,206, + 59,182,106,181, 90,146,158,158,238,253,193, 7, 31,188, 18, 18, 18,210, 4,192,170,218, 4,205,205, 45,237, 24,153, 57, 40, 74, + 2, 27,107, 91, 72,228,230, 16, 56, 9,120, 1,176,178, 86,227,218,157, 67,184, 26, 86, 52, 61, 51, 7, 7,235,149,143,149,149, +187,189,189,253, 51, 73,245,172, 89,179,176,109,219,182,138,106,196,134,154,172,101, 27, 94,181,160,202, 76, 86,122,146, 4,148, +190, 9, 78,252,114, 61, 63, 47, 62,189,219,203, 96,178,202,143,113,132, 16, 60,126,252, 24, 37, 37, 37,184,124,249, 50,190,248, +226,139,172,167, 77,150,163,163,227, 84, 43, 43,171,197,197,197,197, 95,167,167,167,175,171,243,194,175,212, 68,149, 63, 46,159, + 87, 91,157, 88,207, 69,245,170, 46,201,242,112, 81,158,185,115,121,143,151, 53,185, 71, 33, 97, 26,240,176, 48,194, 50,212,177, +199,160, 14,131,233,118, 27,151, 54,234, 56,253,211, 51, 73,133, 58,159,154,146, 45,129,231,219,153, 91, 88, 2,200,196,237, 91, + 23, 42, 76, 86, 78,110, 1,244, 70, 6,122, 3, 5,157,145, 70,159,190, 3,176,126,243,110,164,100,230,130,231,249, 86, 47,153, +201,178, 11, 8, 8,152, 49,106,212, 40, 44, 89,178, 4, 33,171, 87, 27,222,166,168, 66, 9, 64, 78,242, 60, 4, 66, 40,186,126, +141,216,171,232,124,251,237,183,191, 0, 24,179, 98, 22, 58,231, 21, 99,146,235, 16, 98,215,104, 72,233, 7, 71,126, 76, 0,192, + 46, 43,164,234, 41, 51, 40, 40,136, 42,175, 89, 51,181,134,237,191, 29, 73, 80, 80,208,197,224,224, 96, 84,158,215,246, 5, 75, + 39,159, 65, 31,205,157,185,178, 67,255,238, 84,218,220,126,200, 45,212,113,243, 35,141,242,100,109,237, 38,171, 50, 31,109,216, +128, 59, 49,165,255, 99,119, 71, 71,204, 27, 55, 14,132, 3,174, 70, 68, 98,127, 72, 8, 70,247,237, 11,115,165,178,222,201,134, + 32, 8,213,166, 88,149,211, 44, 83, 83,167,252,252,124, 28, 60,120, 16, 29, 59,118,132, 74,165,130, 68, 34, 65,235,214,173, 17, + 21, 21,133,166, 77,155,130,162, 40, 28, 61,122, 20,195,135, 15, 71, 92, 92, 28, 58,119,238,108,145,144,144, 96,178,209,138,140, +140,180, 34,132,244, 40, 79, 63, 26,138, 94,175, 71,116,116, 52,134, 12, 25, 2, 91, 91, 91,184,185,237, 69,200,153, 61, 80, 5, + 76, 0, 69,193, 36,163,197,243,252,228,193,131, 7,203, 40,138,130, 86, 91, 2,165,210, 12,230,230, 22,176,180,180,130,183,183, + 15, 82, 83, 83,209,191,127,127, 67,108,108,236,198,180,180,180, 3,166, 46,171,159,159,159,121,124,124,252,132, 70,141, 26,201, + 1,192,204,204,204,191,105,211,166, 31,198,197,197, 21,153,154,106,149, 27, 44,138,162,192, 48, 76,133,209,146,208, 52, 92,156, + 29, 43,158,151,181, 79,163,106,209, 42, 76,201,209, 43, 0,192,211,211, 19,235,183, 28,167, 7, 15, 30,140,217,179,103,131,101, + 89,108,220, 88,218,201,110,236,216,177, 48, 26,141, 56,124,184,180,147,164, 68, 34,169, 53, 54,185,117,235, 22,110,223,190, 13, +150,101, 81, 80, 80,128, 95,127,253, 21, 23, 47, 93,194,190,163,191, 33,254,241, 35,180,246,241,194,148, 41,147, 33,149, 74,177, +115,231, 78,116,235,214,237, 31, 61, 32, 72,165,210,241,219,182,109,115,217,177, 99, 71,254,209,163, 71, 53,157, 58,117, 82,172, + 93,187,214,113,253,250,245,106,131,193,128,247,223,127, 63,243,198,141, 27,250, 97,195,134,153,111,221,186,213,165, 89,179,102, +253, 56,142,171,206,104,153, 3, 24, 13,224,205,188, 34,131, 36,191, 72, 11,129, 51,224,113,252, 19, 20, 20, 27, 32,240, 70, 36, + 38,167,162, 88,199, 35, 39,183, 8,173,219,189,246,253,133, 11, 23, 22, 24,141,198,249, 0,130,235, 90,206,136,136, 8,220,184, +113, 3,241,241,241,120,252,248,113, 85,167, 56,117, 42,118,239,222,109,114,162, 85,189,201, 98, 64,233,155, 34,248,104,104,126, +230,163,180,151,198,100,149, 29,131, 22,185,184,184, 44,114,113,113, 81,158, 61,123,214,186, 81,163, 70,224, 56,206,240,116,146, +213,171, 87,175,207,182,109,219,230,210,180,105,211, 89, 0,214,253, 55, 44, 59, 77, 99,234,215,155,102, 56, 88,202, 19, 83,241, +112, 85,217, 88,130, 12, 80, 82, 8, 92,248, 25,146,174,159, 63,153, 53,236, 99,219, 79,118, 44,153, 42, 64,168,177,135,108,108, + 92, 18, 54,109, 90,143, 57,239, 79,194, 79, 63,124, 13, 65,144, 64,207, 50,240,108,220, 9,122,163, 0,138,150,160, 77,187,246, + 56,127,225, 50,164, 52,112,112,199,166,151,204,103, 33, 55, 60, 60,124,227,209,163, 71,223,157, 61,123, 54, 4, 65,144, 47,222, +180, 73,155,149,149,181, 28,166,141,127,245,180,206,240, 77,155, 54,197,124,178, 62,235,151, 57,227,193,196,159,160,114,111, 63, +128,221,200,143, 9, 14,173,164,240,138, 15,114, 85,213,159,226, 47, 61, 53,127, 57,140, 86,185,147,172, 60,175,142,118, 45,154, + 44,181,182,179,157, 76, 91,186, 57,204,155,253,182, 36, 46, 93,135,195,141,198, 21,255,190,235, 59,243,116, 78,241,125, 44,116, +107, 77,249,225,253,191,255, 94,241,248,155,189,123,171,125, 47,109,228,200,122, 95,153,213,148, 98,153,154,100, 1,128, 74,165, +178,233,215,175, 31, 94,125,245, 85,188,254,250,235, 21,109,178,218,182,109,139,125,251,246, 97,196,136, 17,184,123,247, 46, 92, + 92, 92,224,235,235, 11, 95, 95, 95,156, 58,117,202,212,131, 28,120,158, 71, 64, 64, 64,121,175,195,214,201,201,201, 86, 13, 45, + 72,189, 94,143,156,156, 28,216,217,217, 65, 46,151, 35, 48,176, 35,222,125, 47, 16, 14, 46, 63, 34,192,207, 7, 26,141,166,162, +251,123, 61, 78,182, 1,205,155, 55, 71, 86, 86, 22,178,178,178,160, 86,171,225,234,234, 10,103,103,103,172, 90,181,138,172, 91, +183,238,180,209,104,220,152,157,157,109,114,146,229,236,236,220,157,162,168,207,180, 90,173,188,210, 21,174, 92,173, 86, 31,211, +106,181,203,211,210,210,234,221, 16,148,162, 40, 24,141, 70, 80, 20,133,147,143, 93,161, 49, 80, 40, 76,190,141,217,255,231, 85, +197,120, 73,165,210, 58,171, 75, 9, 33,154, 49, 99,198, 56,122,120,184, 35, 41, 54, 2,135, 14, 17,172, 94,189,186,188, 87, 36, + 98,202, 46, 12,202,159,247,238,221, 27,141, 27, 55, 6, 49, 97,172, 12, 65, 16,112,255,254,125,236, 61,118, 17, 46, 94,126, 72, +124, 24,141, 59,167, 78,160,145,218, 14, 45,219,181, 7,203,178,207, 53,244,198,139,128,101,217,237, 45, 90,180, 32, 6,131,225, + 34,128,245, 97, 97, 97,147,210,210,210,222, 63,126,252,184,235,168, 81,163, 82, 79,156, 56,177, 22,192,142,176,176,176, 25, 95, +126,249,229,171, 28,199, 85,219, 91,144, 97,152,159, 62,248,224,131, 94,163, 70,141,162,100, 52,107, 56,123,102,167,132,227, 88, +234,163,249,219,249, 11, 87, 46,210, 28,199, 82,175,143,249, 64, 56,245,123, 24, 61,253,189,111,248,182,157, 6, 35, 60, 60,220, + 57, 40, 40,232, 75,150,101,107, 53, 90,229, 73, 85, 77, 9, 37,195, 48,152, 52,105, 18,246,237,171,127, 11,170, 41, 64, 83, 43, + 47,139, 27,203, 54,244,181,160, 36,197,149, 76, 86, 51, 4, 31, 13,205,207,120,152,250, 82,153, 44, 0,200,201,201,217, 2, 96, +139, 32, 8, 25,230,230,230, 40, 42, 42,170,110,255, 83,134,133,133, 41,229,114, 57, 94,123,237, 53,187,144,144,144, 24,154,166, +215,165,166,166,214,232, 56,170,171, 38,172,174, 58, 17,207,209,235,208, 86,141,160,192,238,237, 44, 31, 88, 47,177, 84, 74,116, +119, 27,197, 40,173, 40, 0, 5,122,167,199,215, 18, 70, 23, 82,153,138,182,237,123,191, 2, 43,137,121, 80, 62, 87, 84,173,209, +162, 25,230, 78, 65, 94,254,192,194, 34, 3,174, 92, 13,199,152,209,205,161, 55, 82, 16, 4, 26,197, 26, 61,192, 72, 65, 3, 24, + 59,110, 34, 8, 37, 65,110, 70, 42, 24,134, 9, 3,199,225, 37,227,211, 25, 51,102, 12,156, 63,127,126,147,121,243,230, 97,222, +188,121, 94,219,182,109,219,178,108,217,178,121, 89, 89, 89,173, 80,199,224,227,181,232, 52, 58,177,239,243,185,199, 46,111, 46, + 24,220, 69,251,240, 21,159,210,228,235, 21, 31,228, 74,165,120, 36, 97,144, 67, 72,213,102, 70, 65, 65, 65, 61, 43,207,255,101, + 60,221, 8,190,226,121,189,218,104, 53,111,226, 54,160, 93,219,128,247, 22,204, 95, 96, 25,117,237, 2, 62, 89,186,158,180,104, +223,175,104,203,229, 59,134, 98,243,198, 3,139,179, 31, 93,173,175,191, 0,128, 1,125, 70,160,181,127,199,103,222,236,214,187, +116,176,246, 43,231,111, 33, 35, 43,165,222, 39,219, 50,115, 80,109,155,172,250,116,233,127, 26,173, 86,155, 31, 30, 30,238,152, +156,156, 92,165,225,123,227,198,141, 65, 81, 20, 66, 67, 67,113,227,198, 13,140, 25, 51, 6, 18,137, 4, 82,169, 20, 23, 47, 94, + 52, 41,141,169,148, 46,149,247, 58,236,239,238,238, 94, 83,111,195, 58,181,180, 90, 45, 10, 10, 10,112,230,204, 25, 52,111,222, + 28,203,150, 45,131,171,139, 19, 22, 44,152, 11, 65, 16, 80, 88, 88, 8,158,231,235,155,104, 9,229,105,145, 32, 8,200,202,202, + 66,147, 38, 77,176, 97,195, 6,172, 93,187,246,203,180,180,180,227,166, 46,163,135,135,135, 13,207,243, 31, 13, 30, 60,184,223, +176, 97,195,208,191,127,213,241, 88,127,254,249,103,203,195,135, 15, 47,255,238,187,239, 6, 24,141,198, 21,153,153,153, 89,245, +209,253,241,199,210,225,151, 84,157, 22,225,147, 81,141,240,230,204,157, 88,181,234, 8, 20, 10, 69,149, 19,239,146, 37, 75,106, + 53, 49, 2, 33, 45,100,217,215, 82,231,126,252,173,227,242,229, 33, 8, 9,201, 4, 77,211,112,113,113, 1, 77,211,120,242,228, + 9,104,154,134,151,151, 23,104,154, 70, 74, 74, 74,121,155,192, 60, 84,211,235,177,250,171,112, 26, 58,157, 14, 73,137,241, 72, +142,141,129, 69, 97, 58,212, 86, 42,228, 69,220, 71,235, 41, 83, 43,198,127,250,135,217,109, 48, 24,118, 87,122,254,237,137, 19, + 39, 12, 20, 69,189,142,210,118, 26,229,137,198,151, 28,199,125, 89,147, 72,167, 78,157,218,206,159, 63, 95, 90, 62,220,134,171, +231, 87,156,209,104, 20, 0,192,167,117,143, 42,110,255,209,163, 71, 88,181,106, 21, 52, 26, 13,100, 50,153,172, 62,219, 65, 16, +132,138, 30,134,213,153, 48, 83, 76, 22, 0,216,123,185,127, 31,122,251, 34,127, 47,118,179, 54,236,193,175,102,105,137, 52,104, +195,203,107,178,158, 78,182,220,221,221, 23, 9,130, 64, 8, 33,159, 87,122, 75,225,233,233,121,249,236,217,179,246, 28,199,225, +187,239,190,179, 73, 79, 79,183,233,209,163,199, 39, 0,106, 52, 90,213, 85, 19, 86, 87,157,136, 74,189, 14, 21, 10,133,157,193, + 80, 99,120,242, 76,175, 67,158,135,183,149,165, 13,242,144, 12,189, 3,219, 54,223,158,203, 61,151, 54,245,174,107, 66, 59,127, +115,158,109, 66, 23, 26,224,166,178,129, 64, 72,141, 93,163,245, 44,251,235,221,219,119, 94,243,244,104,206, 28, 15,190,132,161, +195, 71, 65,175,167,161, 99, 41, 80,140, 20, 20, 35, 67,171,214,237,224,219,178, 53, 8,128, 91,127, 92,227, 12, 44,123,238,101, + 42,123,151,174,239,142,161, 40,172, 3, 17, 72, 53,227,104, 53, 25, 62,124,248,114, 0,239,213,165,227,216,233,221, 49, 52, 93, +170, 83,121, 28,173, 15,222,157,129,136, 63,164,214,151,110,175,148,245,239,132,147, 89, 33, 20, 84,202, 63,123, 29, 74,233,231, + 26,154,227,223, 98,184,234, 54, 90, 30, 30, 30, 54, 86, 10,229,143,239, 76,153,108,153,112,239, 58,210, 35, 67,113,245, 82, 76, +222,254,195, 71,114, 53, 57,153, 83, 76, 48, 89, 21,213,124,246,206,141,208,216,239, 89,163,165,180, 80, 3, 0, 26,251,117, 4, + 99,110,218, 48, 66,213,165, 89, 13, 49, 89,149, 15,216,213,141,161, 53,125,250,116,108,219,182, 13, 93,187,118, 69,139, 22, 45, + 42, 14,246,166,166,102,213,164, 75, 38,247, 54,172, 76, 81, 81, 17,188,188,188,176,117,235, 86,132,133,133,193,210,210, 18, 99, +198,140, 65, 81, 81, 81,133,193,170,111, 99,120, 66,200,163,179,103,207,118,120,227,141, 55,136, 84, 42,165,242,243,243, 97, 99, + 99,131, 13, 27, 54,104,210,210,210, 78,101,142,174, 25, 0, 0, 32, 0, 73, 68, 65, 84, 54,192,100,141,146,201,100,115, 71,143, + 30,205,248,248,248, 32, 35, 35, 3, 86, 86, 86, 44, 69, 81, 82, 0,176,177,177, 97,205,204,204, 48, 99,198, 12,180,105,211,166, +251,188,121,243,186, 74, 36,146, 13,169,169,169, 59,107,219,151, 40,138,170, 56,161, 78, 89, 23, 13,131,161,244, 4,189,113,227, + 70,148,181,117,251,179,138, 32, 54, 22,168, 71, 79, 22, 11, 11, 11,180,104,209,162,218,178,239,222,189, 59,110,221,186, 85, 90, + 53, 41,145,192,209,209, 17, 87,175, 94,173, 87, 79,170,242,129, 32,195,195,195,225,215,216, 1, 97, 33,103,225,160,146,162,141, +171, 51,220,187,247, 68, 76, 76,204, 63,153,102, 81, 40,109,135,209,183,108, 31,220, 14, 96,122,165,231, 27, 0,124,111,138, 32, +199,113,132,166,105, 42, 41, 41,201,168, 82,169, 40, 59, 59, 59,137, 66,161,128, 94,175,175, 48, 92,143, 30, 61, 66,112,112, 48, +146,147,147, 97,103,103, 71, 91, 91, 91,195,104, 52,230,213, 71,223,219,219, 27,206,206,206, 85, 26,190, 79,153, 50,165, 65, 38, +107, 18, 16,176,237,171, 21,141, 20, 52, 99,237,231, 48, 0,143,163,159,232,104, 3,148,255, 11, 38, 11, 0,242,243,243,183, 0, +216, 82,254,220,193,193,225, 45,134, 97, 22,232,245,122,235,139, 23, 47,218,168,213,106,106,231,206,157,236,231,159,127,158,207, + 48, 76, 30, 69, 81,107,254,121,115,136,200,236,130, 88, 47,169,173,171,112, 79, 71,174,189,159,244,137,111,158,180,185,154,106, + 25,128,225,153, 81, 87,222,226, 98,187,100,164,165,211, 4, 66,100, 45,199,224,237,159,204, 95,242, 81, 76,244, 29, 79,165,149, + 18,211,103,204,199,201,211,231, 65,209, 82, 92,190, 22, 10,131,145, 71,118,110, 1, 70,143, 29, 15,119, 23, 7, 68,222, 56,147, +197, 9,194,134,151,203,100, 11,235, 95, 27,250,150,173,194, 76, 85,182, 77,120,236,254, 97, 46,104,122, 29, 22, 46, 92,136,128, +128,128,153,225,225,225, 95,160,142,113,180, 40, 74, 88,223,170,231, 88, 91,153,162, 84,135, 8, 60,182, 30,252,164,108, 28,173, + 57,216,176,229,112,171,150,141, 31, 47,174,109, 28,173,151,200,100, 85,158,215,110,180,188,188,188, 20,230, 82, 76,147, 50,146, +121,239,140, 27,166,206,140,141, 64,114,212,157,210,234, 5,163,214,152,254, 48,170, 62, 67,161,247, 69,213,241, 59, 72,109, 85, + 87, 58, 93,189,174,232,171,104,150,159,112,159, 78,179, 76, 52, 89,207,104, 86, 54, 91,149,199,205,242,240,240,192,242,229,203, +235, 51,142,214,211,235, 94, 78,127,148, 54,128,175,220, 24,190,127, 61, 77, 86,181,154,106,181, 26, 57, 57,165, 35, 36,244,234, +213, 11,189,122,253,217,159,193,104, 52, 86,164, 88,150,150,150,213, 37, 90,207,104,154,153,153,125,114,228,200,145,201,215,174, + 93,123,227,195, 15, 63,148,190,250,234,171,229,102,174, 4,245,187,183, 91, 21, 77,158,231,103,156, 57,115,134, 17, 4, 1, 91, +183,110,197,173, 91,183,136, 74,165,250, 76,165, 82,173, 55, 51, 51,227,181, 90,237,244,169, 83,167,142, 95,188,120, 49,221,189, +123,119, 92,191,126,157,110,210,164,201, 68,160,202, 32,150,213,174,123,104,104, 40,104,154, 6,151,155,136,153,159,236,135,185, +153, 4,209,209,209,200,205,205,125,102, 16,211,250,108,207,202, 73, 73,249,212,189,123,247,138,106,200,192,192, 64, 48, 12,131, +187,119,239,214, 84, 13, 91, 89,147,216,219,219, 87,236, 31, 50,153, 12,231,207,159,199,210,165, 75,225,105,103,131,188,168, 48, + 56,247,234,131,126,147,167, 98,204,152, 49, 96, 24, 6,118,118,118, 21,201,111, 61,246,165,231,161,178,230,100, 63, 63,191,137, +145,145,145,238,173, 90,181,114, 9, 15, 15,239, 29, 16, 16,224, 21, 22, 22, 86,254, 92,129,250,181,205,169,208,188,121,243,230, +161,245,235,215,207,152, 52,105,146, 76, 16, 4, 62, 33, 33,129, 5, 64, 57, 59, 59, 51, 55,111,222, 20,142, 31, 63, 14,173, 86, + 11,119,119,119,218,205,205,141, 58,119,238,156, 16, 21, 21, 21, 74, 8,153, 95,159,117,231,121,190,202, 48, 14,229,143,127,254, +249,103,147,255,239,141,124,189,151,189,218,195,199, 35, 59,245, 46,210, 82, 98,193, 23,168,141,193, 71, 79,232, 77, 52, 89,127, +117, 25,253,157,154, 75, 30, 62,124,232,166,215,235, 33,151,203,177,113,227, 70,227,242,229,203, 35,179,179,179,187,161,250, 30, +229, 85, 52, 27,216,235, 48,183, 22,205,103,122, 29, 22,228,224,228,209, 99, 55, 59, 88, 12,223,142,153,169, 89, 21, 13, 27, 9, + 69,217, 29,113,242,239,166,234,216, 42,133, 62,181,136, 46,226, 75, 78,214,178,238, 6,173,193, 48,106,248,136,177,191,237,219, +183,215,226,243, 69,139,112, 53, 52, 12, 57,249,197, 16, 8, 3,129,162,176, 96,193,231,112,118,176, 67, 97,234,195, 18,189,209, + 56, 28, 85,199,208,250,215,151, 59, 69,209,179,206, 29,223,185,142,166, 32,104, 50, 30, 40,152,162, 88,213,155, 99,134, 75, 70, +141, 26,133, 35, 71,142, 32, 60, 60,124,115, 45, 38,171, 66,147, 16,122, 86,216,197,253,235, 40, 64,208,102, 61, 80, 72,138, 31, +171, 38,142, 27, 46, 25, 51,102, 12,126, 9,190,134,125, 39, 30,111,218,119, 2, 39,240,114, 99,250,200,240,150, 18,132,119,243, +111,234,214,189, 93, 75,165,132,215, 34, 57, 42, 22,185, 26, 29,206, 69, 36,228,211,132,110,240,216, 58,165, 7, 72, 25, 18, 19, + 31, 86,115,101,165, 44, 59,161,235, 76,210,164,105,186, 74,154,245, 60, 73, 86,229,229,116,114,114,170,114, 59,151,202, 39,238, +242, 54, 64, 13, 24,218,225,147,196,196, 68,171,196,196, 68, 16, 66, 16, 26, 26,106, 21, 24, 24,248,201,243,164, 89,115,231,206, +173, 72,173,158,158, 87,247, 90, 93,148, 53, 74, 95,203,178,236,193,121,243,230,205, 12, 12, 12,124,109,209,162, 69, 20, 76,184, + 1,239, 83,105, 14, 39, 8, 2, 46, 92,184,128, 35, 71,142,240, 70,163,113, 90, 90, 90, 90, 88,165,143,124,119,251,246,237,115, + 35, 70,140,216,249,224,193, 3, 38, 50, 50, 18,132,212,221,239, 84,171,213,162, 69,139, 22,224, 56, 14, 43,103,122,160,168,168, + 21, 56,142, 3,207,243, 48, 55, 55,175, 72,241, 42,155,231,186,246, 35,158,231,159, 49, 90,161,161,161, 96, 24, 6,221,186,117, +195,157, 59,119, 42, 18,173,186, 18, 40,163,209,152,232,228,228,228,180,100,201,146,138,229,202,202,202,194,217,179,103,209,169, +115, 23,248, 79,155,142,212,212, 84,172, 89,179, 6,174,174,174, 88,182,108, 25,114,115,115,193,113,220,223, 29,167, 15,140,140, +140,116, 31, 55,110, 92,102, 88, 88,152,123,112,112,176, 77, 80, 80,144,249,216,255,103,239,186,195,154,200,218,239,153, 76, 26, + 36,161,119, 1, 21, 81, 96, 81,172,168,235,138,139, 29,187,107,175,107,239, 13, 59,174,186,150,181,174,186,186,186,246,142,189, +187, 98, 23,197,134, 93, 20, 20, 65,165, 9, 33,244, 80,210,147,201,204,239, 15,202, 15,149, 18,208, 45,223,247,229, 60, 79,158, + 36, 51,147,147, 59,247,206,220,123,230,125,239,125,223, 33, 67, 50, 34, 35, 35, 93, 8,130,248, 14, 85,156, 4, 77,211,244,130, +133, 11, 23, 94, 89,181,106, 85,208,244,233,211, 91,142, 28, 57,146,195,225,112,104,177, 88, 76, 29, 61,122,148,240,240,240, 96, +113,185, 92,226,234,213,171,244,227,199,143, 31, 82, 20,181, 22,192,221,170, 88,156, 75,139, 44,146, 36, 13, 21, 89, 31, 33,208, +158, 63,194,140,149,233,247,199,182,213, 44, 47, 55, 23,109,240,209,107,201,119, 31,188,141, 35,213, 84,224,190, 10, 66, 3,252, + 55,131, 36,201, 19,222,222,222,163,166, 78,157,106, 26, 16, 16,192, 95,186,116,105, 94, 65, 65, 65,121, 34,171,140, 7,230,191, +101,213,225,222, 5,115, 66, 2,103, 53, 28,229, 62,214,177, 54,110,200, 51, 32,101,147, 44,115, 75, 22,154,214, 34, 81,144,245, +206,238, 66,232,129, 4, 0,149,197,101,123,242,236,101, 84,199, 6, 13,155,156, 94,187,106,173,253,162,249,243, 56,167, 67, 46, +131,161,180,120,116,251, 54, 68, 92, 61, 19,253,236, 70,186, 90,171,249, 1,255,133, 41,120, 36,247,183, 28, 3,112,222,218,218, +250,197,232,145, 35, 61,188,189,135, 64, 32, 16,224,212,169, 83, 56,180,121,179,126, 19, 48,144, 15, 60,159, 88, 73, 60,189,140, +135, 37, 60, 17,227, 70,143,246,108,218,116, 44, 4, 2, 1, 78,158, 60,137,131,155, 54, 25,204,243, 31,142,226,200,240, 23,241, +255, 17,226, 43,153,163,197, 34, 10, 30,190, 77,146, 61,122,155, 36, 3,205, 48, 52,195,168, 89, 44, 36,203,181,218, 85,111,227, +197,213, 18, 5,197,174,195, 21, 43,167,126, 61,159, 71, 41,241, 83,221, 37,221,101,136,172,148,210, 57,210, 74, 15,210,229,125, +214,233,116, 41, 6,210,175,169, 89,179,230,103,219,170,111,250,101,170, 36,178, 12,141,163, 5, 0,217,217,217, 18, 0,139, 30, + 60,120,112,164,115,231,206,227, 0,136,171,217, 70,187,252,253,253,199, 3, 32, 9,130,216,145,154,154, 26,249,217, 13, 47,145, +196,214,168, 81, 99,157,155,155,219,132,194, 7, 83, 98, 87, 37, 3,121,124,195,134, 13,181,101,181, 69,121,223,105,154,174,180, +141,114,115,115,209,162, 69,139,207,114, 90, 50, 12,131,164,164,164, 98,139, 83, 73,221, 87, 36,224,100, 50,217,132,105,211,166, +237,228,112, 56, 53, 1, 16,197, 34, 87,175,215,147, 91,182,108, 49,209,235,245, 36, 0,130,197, 98, 81, 28, 14, 71,117,230,204, + 25,138,162,168, 15,106,181,122,194,223,220, 65,156, 36, 10, 83, 49,200, 95,191,126,237, 85,100,201, 74,137,138,138,138, 56,118, +236,152, 29,128,227,213,228,189,171, 80, 40,238,174, 94,189,186,205,182,109,219, 22, 76,152, 48,161,197,224,193,131,217,109,219, +182,197,197,139, 23,245, 97, 97, 97,143,148, 74,229,154,170, 8,172,162,182,204,115,117,117, 45, 17, 92,149,220,203, 21, 78,228, +181,169,197,255, 99,216,164, 26, 38,187,214, 92,147,101,165,106,194,117, 50,205, 79, 7,128, 40,252, 15, 35, 61, 61,125, 14,128, +197, 27, 55,110, 76,109,220,184, 49,159,203,229,106, 12, 21, 89,127, 35, 40, 58, 87,214,237,183, 78,253,207,251, 47,156,230,214, +169,157,159,192,181,182,189,115,244,251,116,188,123,112, 81,254,226,194,202, 68, 70, 45,237, 13,192,144,153,235,143,213, 90,109, +189,217,243,102, 79,230,113, 56,157,245,122,125,163, 14,215,207, 49, 36, 73, 70,106,116,186,235, 69,238, 66,213,127,113,147,175, + 88,183,110,157,135,183,183, 55, 78,157, 58,133,235,135, 15, 99, 80, 86, 22,110,145, 36,201,226,114,109, 46,104,181,235, 97,152, + 64, 90,177, 97,195, 6, 79, 31, 31, 31,156, 56,113, 2, 87, 15, 30,196,192,234,241,148, 55,214, 53, 7, 96, 87,244, 53, 11, 64, + 12,128,102, 0, 76, 1,168, 81,152,218,201,182,244, 16, 86,180,175,120,255, 29,130, 32,254,202,137,176,149, 71,134,255, 20, 81, +239, 18,155,125,237, 82, 40,149,202, 28, 15, 15,143, 42,173,185,214,233,116, 21,250,112, 41,138, 74,113,119,119, 55,216,106, 97, +136, 40,202,201,201,241,253, 11, 27,227,139,230, 98,125, 52,136,208,116,162,147,147, 19, 93, 60,232,151, 37,194,202,218,198, 0, + 9, 85,249,159,180,180,180, 24, 0,179,170, 91,206,212,212,212,211, 48, 32,105,180,161,199, 1,128, 84, 42,253,234,201,124, 9, +134, 17, 47, 93,186,180, 74, 2, 27, 12, 83,145,248,140,148,201,100, 45, 13,249,111,173, 86,139,127, 16, 39,138, 94,172,168,168, +168,113, 4, 65, 4,160,208, 37,176, 3, 95, 39,154,247,221,252,252,252,187,191,254,250,107,155, 93,187,118, 5, 50, 12,131,252, +252,252, 77, 85, 21, 88, 37, 79,207, 25, 25, 23,191,214,137,231,164,107,110, 30,221,145,210, 94,153,171, 13,220, 45,211, 28,132, + 17, 37,198, 40,134, 97,246, 15, 31, 62,252, 91, 0, 7,190,148,172,156, 85,135, 95,138, 4, 90,154,215,248,214,236, 95, 70,223, +178, 52,235, 14, 61,219, 11, 26,214, 5,104,178, 47, 2,216, 7,195,166, 57,148,156, 47, 69,211, 27, 40,141,102, 67,169,193,229, +127,161,157,173,125,124,124, 2, 71,141, 26,133,197,139, 23,227,234,250,245,218, 73, 4,145,199, 1,152, 43,133, 15,154, 44, 2, +152,111, 40,207,136, 17, 35,176,120,241, 98, 92, 90,187,182,186, 60, 21,193,142, 32,136, 16, 0, 8, 10, 10,250,105,245,234,213, + 86, 11, 22, 44,104,180,102,205,154, 85, 69,223, 95, 21,239, 47, 26,235,122, 44, 88,176,160, 65,169,253, 5, 0,158,252,197,245, + 89,102,100,248,191, 26, 29,141,156, 70, 78, 35,167,145,211,200,105,228, 52,114, 26, 57,191, 4, 12,195,116, 47,124, 43,255,189, +188,207,165,222,255, 17,176, 97,132, 17, 70, 24, 97,132, 17, 70, 24,241, 31,136,210, 86,172,234,236,255,138, 40,158,163, 85, 26, +187,128,194,101,221,229,169,210,170,172,122,168,142,178,189, 97,228, 52,114, 26, 57,141,156, 70, 78, 35,167,145,243,127,142,179, + 50,238,207,126,207, 48, 76,119,130, 32, 66, 24,134,233, 81,222,123,177,176,250,244,115,169,247,175, 54,237,160, 12, 20,207,205, +250,108,142,214, 95, 13,163, 89,213,200,105,228, 52,114, 26, 57,141,156, 70, 78, 35,231, 23,161,216, 5, 8,128, 9, 10, 10, 90, +240, 47,116, 29, 58, 21,137,172,210, 47, 0, 21,184, 14, 25,230, 36, 41, 22,195,156,199, 19,112, 1, 64,163, 81,104,157,157,145, + 79, 16, 3,254,201,132,183, 70,252,103,162,120,185,119,250, 87, 62,214, 8, 35,140, 48,194,136,255, 13,100, 22, 91,170, 0,100, + 2, 32,138,190,107,138,222, 51,139, 4,217,167,159, 63,218,255, 23, 66,130,114, 44, 89,236,242, 68, 86, 86,150,192,150,205,150, +122,234,245,170,111, 0,128,205,102,189,201,202,178,138,101,152,147, 89,213, 17, 91,182,246,246,207, 56, 36,233,108,200,177, 58, +189, 94,156,149,158,254,113,232,120,130,248,111, 16,120,134,138,136, 47, 17, 27,127,185, 80,177,181,181,117,112,112,112,232,101, +110,110,222, 42, 55, 55,247,113,102,102,230,217, 10,242, 30,174, 38, 8,204, 43,188,174,240, 43,128, 5, 21, 80, 87,229,216, 79, +225, 33, 16, 8, 38, 19, 4,225, 83,116,131, 69, 41, 20,138,109, 0,222,254, 15,118, 72,166, 0,126, 96,179,217, 35,108,109,109, + 91,164,165,165, 45, 5, 80,221,104,222,108, 0,179, 45, 45, 45, 7, 89, 90, 90,186,231,228,228,196,229,231,231,159, 0,176, 1, + 64,165, 75,165,151, 78,119,106,213, 54,160,237,162,176,171, 97, 43,150,110,150, 60,248,108,255,108, 39,155,206,157, 90, 47, 14, +187, 16,190,252,167,173,169, 57, 85, 44, 27,171,232, 5, 20,174,142,100,240,121,176,215, 47, 5, 7, 64, 79, 0,109, 1,132, 1, +184, 96,200,121,151,131,111, 1,252, 84, 84,230, 13, 0,110,253,203,175, 35,161,131,131,195, 90, 0, 61,217,108,246,107,177, 88, + 60, 30, 64,202, 63, 92, 38, 54,128,230, 0,124, 80, 24,134,227, 9, 12, 11,225, 80, 41,108,108,108,122,176,217,236,201, 69,161, + 93,182,101,103,103,135,252, 91, 27,134,199,227,109,114,116,116, 28,171, 84, 42, 21, 4, 65, 48,165,227, 61, 82, 20,149,146,149, +149,229,251,223,214,169, 17, 4,241,228, 95, 94,196,241,101,108, 43, 63,142,150, 88, 12,115, 54, 91,234,153,145, 22, 57, 40, 85, +242,114, 32, 0,212,112,106,116,194,222,177,225,113,177,152,167,117,244,234, 35,226, 8,216,219, 72,146,211, 68,165, 81,219,114, +216,156, 44, 45,165,139, 96,105,152,201,105, 49,103,203, 12,182,200, 33, 73,231,196,216, 91,246,148, 54, 7, 28,147, 26,224,152, +214, 44,183,180, 53,106,212,168,214, 89, 90, 89,185,155,105,249, 38,129, 28, 14,217,137,102, 40, 31,134, 6, 88, 4, 39,138,210, +235, 66,185,106,245,111, 82,105, 92, 65,117,107,208,203, 6,142, 12, 48, 24, 4, 58,129,193,117, 2, 56, 22,147,141,180, 42, 80, + 24, 42, 34,190, 68,108,148,254,237, 70, 0,115,190,246,149,228,236,236,108,213,163, 71,143, 77,191,252,242,139,169, 72, 36, 34, + 62,124,248, 16, 48,127,254,252,239,159, 62,125, 58, 75, 44, 22,167,126, 42,250, 8, 2,243,104,154, 97, 1, 0,139, 69,204,183, +179,179, 23,144, 36,249, 89,108, 35,189, 94, 47,200,204,204,152, 74,211, 12, 81,116,236, 60,134,193,239,134, 8, 70, 19, 19,147, + 33, 62, 13,155,204, 90,187,110,131,200,193,222, 94, 72,233,105,109, 66, 82,162, 96, 81,208,156,150,239,223,189,253, 93,165, 82, + 29,173,206,125, 77,146,228, 32, 62,159,223, 3,128,119,209,182,104,181, 90, 29,162,215,235,143, 27, 58,160, 59, 56, 56,220, 33, + 73,178,118, 85,254, 88,175,215,127, 72, 79, 79,247,171,102, 19, 13,168, 89,179,230, 62,127,127,127, 65,139, 22, 45,192,227,241, +176,120,241,226,217, 18,137,164, 50,161,197, 6, 48, 91, 32, 16, 12, 18, 10,133,238, 50,153,236,189, 82,169, 60,205,227,241, 58, +254,254,251,239,174,173, 91,183, 54, 75, 79, 79, 39, 72,146,116,184,116,233,210,143,155, 54,109, 10,160, 40,170, 67,101,131, 92, +222,123,102, 17,191,167,119,155,188,247,183, 22, 1,232,250,233,126, 74,101, 50,130, 33, 93,123, 40,153,231,201, 69,226,195, 96, +145,197,225,112,126,119,116,116, 28,165, 42,140, 21,192,124, 58,224, 0,128, 70,163,145,230,230,230,122, 85,231,150, 7, 48,198, +210,210,114,212,220,185,115,173,186,118,237,138,195,135, 15, 79,217,189,123,183, 52, 63, 63,127, 63, 10, 3, 97,198, 84,145,115, + 94, 90, 90, 90, 55, 14,135, 67,184,186,186,146, 74,165,178, 42, 66,203, 19,133, 73,152,159, 0,216,134,194,208, 5,237,128,194, +251, 29,192,175,197,194,141,197, 98,109,243,242,242,234, 21, 29, 29,189, 29,192,138,234,222,235,142,142,142, 59,183,110,221, 58, +176,119,239,222,100,102,102,166,115,227,198,141,143,164,165,165,181,249, 10,221,200,104, 62,159, 63,179, 81,163, 70,245, 99, 98, + 98, 98,243,243,243, 55, 20,213,103, 69,247,148, 11,128,142,150,150,150, 29, 22, 46, 92, 40,234,209,163, 7,118,237,218,213,109, +247,238,221,178,130,130,130, 80, 20,206,233,249, 34, 17,200,102,179, 39,167,164,164,216, 50, 12, 3, 39, 39,167,201, 0,254,149, + 66,139,197, 98,253,222,183,111,223, 81, 71,142, 28, 17, 36, 38, 38, 10,156,157,157, 75,130,103, 19, 4, 81,237,241,211,136, 47, +198,174, 82,130,171,242, 56, 90, 60,158,128,171,215,171,190, 73,149,188, 28,248,189,255, 22, 11, 0,184,115,123,218, 64,123,199, + 6, 81, 60,158, 32,150,111,110,114,166,111,207,142, 77,250,247,240, 39, 92,156,236,145, 34,201,112,216,123,236,106,151,144,171, +183,206,160, 48,128, 88,153,160,180, 57, 48,213,222, 64,204,189,205,176,109,155,138, 63, 46,165,224,193,139, 4, 40,242,178, 80, +219,209, 20,235, 2, 59,195,209, 74, 80,189, 71, 47,123,143,118, 20,155,127,124,232,144,225, 22,189,126,240,230,212,114,116, 4, +195,240, 17,251, 94,246,221,229,107,183,154,159, 62,121,116,178,144,227, 49, 72,158,241,214,224,206,173,169, 19, 76,229, 90,252, +192, 38,137, 31, 91,251,214,239, 48,164, 91, 27, 86,125,239,122,120,253, 42,186,243,249,155,143,214,177,194, 95,133, 82,122, 38, + 88,200,197,185,231,146, 10, 3,250,125, 38, 56, 58,116,232,216,134,207,231,127, 20, 60, 73,173, 86,115, 67, 67,111,124, 91, 29, +177, 81,252, 31, 26,141,154,197,225,240,192, 98, 17,179,124,124, 26,122,103,101,101,221, 34, 8, 98, 95,106,106,213,172, 5,211, + 0,158,148,205,110,198,226,243,157,244, 26,141, 13, 0, 16, 60,158, 52,129,197,106,184,240,167,159, 68, 36, 73,210,217,217,217, + 80, 40, 20,196,184,113,227, 76,222,191,127,223, 87, 44, 22,111,174,228,137, 4,187,119,239,246,116,114,114,250, 44,123,172, 68, + 34,225,245,238,221,171, 58, 77,239,217,168,113,211,153, 87,175, 94,241,206,207,145,170,118,111,220,249, 76,103, 34, 80,215,241, +246,226,108,219,117,208, 98,252,168, 97,211,222,188,121, 21,129,170,229,171,171,105,106,106,122,102,253,250,245, 62,237,218,181, +227,216,219,219, 35, 61, 61, 29,209,209,209, 62, 55,111,222,252,225,224,193,131,179,149, 74,101, 95,192,160,132,168, 30,161,193, +251,236,133,214, 54,208,235,116,168,209,168,105, 73,124,179,119, 55,175,129,210,106, 65,235,116,240,238,241, 67,145, 53,153,129, +183,183,119,117,163,238,214,104,208,160,193,161, 85,171, 86,113,213,106, 53, 30, 61,122,132, 91,183,110,209, 18,137,164,178,128, +184,108,130, 32,174, 45, 89,178,196,197,207,207,207, 44, 43, 43, 11,122,189,222,246,220,185,115,147,155, 52,105, 98,238,234,234, +202, 11, 14, 14,134, 76, 38, 3, 69, 81,214,238,238,238,214, 67,134, 12,209, 4, 7, 7,207, 6,176,182, 60, 75, 86,254,123,102, +145,132,112,239,226,213,108, 4,210,136, 43, 93,102,118,193,101,243,186, 68,137,101,171,139,187,187, 89,190, 88, 48, 95,100,222, +208, 58, 95,124, 99,126, 23,119,247,221, 87,226, 12,122, 24, 98, 21, 13, 54, 67,143, 29, 59, 38,136,142,142, 22,120,123,123,131, +166,233,146, 8,252,197, 1,103, 61, 60, 60,170, 83,143,107, 38, 78,156, 56,127,224,192,129,104,212,168, 81, 73, 80,212,159,127, +254, 25,243,231,207,183,186,115,231,206,236,163, 71,143,206, 62,123,246,236, 90, 0, 65, 85,180,198, 20,163,170,109,188, 44, 62, + 62,126,192,153, 51,103,134,205,155, 55,207, 3,192, 84, 0,139,179,179,179,253,139,172, 49,188, 34,161, 53,122,246,236,217,147, +130,130,130,208,173, 91,183,197,143, 30, 61, 90, 89, 77, 43, 31, 73, 81, 84,183,222,189,123,147, 58,157, 14, 66,161, 16, 58,157, +174,238,151, 26, 37, 0,108,157, 48, 97,194,164,137, 19, 39,194,202,202, 10, 58,157,206,243,216,177, 99,187, 23, 47, 94,220, 10, +192,152,114,202, 58, 98,210,164, 73,253,134, 15, 31, 14, 95, 95, 95,176,217,133,213,184,126,253,122, 44, 95,190, 92,116,237,218, +181, 31,130,131,131,127, 56,127,254,252,105,124,156,182,171, 74,160,105, 26,108, 54, 27,201,201,201,176,183,183,231,211, 52,125, +149, 32,136, 93, 57, 57, 57,103,255, 69,131,249,175, 3, 6, 12, 24,122,228,200, 17, 17, 0,172, 91,183, 14, 51,103,206,132,131, +131, 3, 68, 34,145, 81,234,252,123, 44, 90,227, 43,181,104, 85, 6,133, 66,209,116,193,244, 31,193, 98, 21, 62, 53,214,171, 83, + 19,171,127, 26, 79,156, 15,185,218,180, 66, 27,188, 73, 13,196,220,219, 12,190,107, 32,212, 58, 10, 15, 95,196,227,250,186,128, +194,209,178,235, 66,168,181, 29,138, 7, 27,107,158,169,233,175, 26,189,254, 62, 28, 29, 31, 33, 41, 41,179, 50,145,101,231,232, + 16,178, 99,199, 90, 83,159,186, 94,208, 82, 58,136, 51,196, 32, 8, 62, 92,156,205, 48,122, 68, 87,142,191,127, 13,219,101,203, +118, 94, 76,163,209, 71,145,245,182,210,128,161,158,182, 56,208,212,199, 99,224,144,238,126,252,134, 62, 13,192,229,155,150,236, +107,230,235,139,102,190,190,172, 32, 89, 65,167,199, 79,158,117, 58,117,237,161, 90,161, 75, 58, 17,155,133,145,149,116, 50, 37, +130, 99,198,140, 25,112,112,112,248,232,128,244,244,116,220,188, 25, 90,230,111,170,208,145,149,252,199,202,149, 43,205,164, 82, +105,215, 61,123,246,180,167,105,122,101, 90, 90,218, 61, 67, 72,134, 3,181,243,248,252, 14,163, 54,108,160,155,244,234, 69, 90, + 58, 58,178,104,189,158, 72,141,139,179,217,184,121,115,219,156,119,239, 76,229,214,214, 57, 82,165, 82, 17, 27, 27, 11, 19, 19, + 19,130,205,102, 55, 47,131, 42,157, 97,240, 43,139, 69,204, 39, 8, 2,124,190, 73,236,196,137, 19,159, 23,237,171,125,225,194, + 5, 65,207,158, 61, 21, 0, 18, 1,128,207, 55,113, 38, 73,150,103, 97, 36,118,252,106,136,192, 20, 10,133,211, 87,172, 90, 43, +204,207,201, 85,106,229,114,157,157,185,136, 32, 68,102,100,126, 94, 65,129, 88,146,169, 94,184,116, 57, 57, 97,244,240,233,114, +185,124,178,161, 34,171,113,227,198,143,207,156, 57, 99,111, 99, 99,131,220,220, 92,100,103,103,227,241,227,199,160,105, 26,125, +251,246,229,127,215,178, 69,211,159, 22, 46,122,144, 44, 22,183, 50, 68,108, 9,173,109,177,206,175, 73,225, 96,157,152, 93,210, + 62,187, 6,244, 40, 57,102,121, 74, 94,177,117,238, 75, 82, 72,181,234,208,161, 3, 23, 0,198,140, 25,147, 95, 80, 80,176, 26, +192, 17, 84, 30,209,127,246,162, 69,139,156,235,212,169, 83,235,200,145, 35,144,201,100, 0, 96, 95,167, 78, 29,120,122,122,234, +195,194,194,224,233,233, 9, 51, 51, 51,220,185,115, 7, 15, 30, 60,128,175,175,175, 25,151,203, 29,168,213,106,203, 20, 90,109, + 3,218, 46,226,247,244,110,227,213,108, 4, 68,230, 78,216,125,244, 56, 98,158, 29,108,163,214, 70, 47,226,234,111, 15, 87, 50, +252,145,153, 31, 68, 65,181,125,253,109,234, 53,232,133, 90,205,158,219,170,244,119,227, 23,117,170,179,134,109,162, 58,184,116, +131, 36,187, 60,145, 5, 96, 93,223,190,125, 7, 28, 59,118,204, 18, 0, 34, 35, 35,145,158,158, 14, 59, 59, 59,152,152,152,128, +195,225,148,228, 39,173, 38, 70,110,219,182,173, 68,180, 81, 20, 85,146, 5, 64, 32, 16,224,251,239,191, 71,147, 38, 77,112,246, +236,217,145,229, 8, 45,191,150, 45, 91, 30,174, 85,171,150,107,233,141,114,185, 28,131, 7, 15, 6, 0,248,251,251,119, 48, 53, + 53,101,138, 5,161, 68, 34,145, 61,121,242,164, 19,128, 71,229, 40, 75,165, 88, 44,198,220,185,115,145,144,144, 48,101,199,142, + 29, 73, 0, 76,120, 60, 94,201,243, 49, 0,207, 6, 13, 26,252, 62,115,230, 76,188,127,255, 30,175, 95,191,126,140,234,187, 82, +245, 66,161,240,157, 78,167,243,165, 40, 10, 74,165, 18,125,250,244, 49, 57,125,250,116, 58, 73,146,111,178,178,178,134,161,112, + 78,138,161, 48, 1,176, 97,226,196,137,147,230,205,155,135,208,208, 80,156, 63,127, 30,195,135, 15, 71, 96, 96, 32, 68, 34,209, +168,192,192,192, 7, 40, 76,104,254, 41, 58,108,219,182, 13,122,189,254,179,123,195,196,196, 4,126,126,126,168, 95,191, 62,206, +159, 63,223,225, 11,132, 86, 45, 63, 63, 63, 30, 77,211,144,203,229, 8, 11, 11, 19,153,154,154,138, 92, 92, 92,198, 1,248,215, + 8,173, 90,181,106, 77, 60,118,236,152,168,180,247,135,207,231,163,212,117, 96,196, 63,111,209,170,240, 9,171, 4, 26,141, 66, +203,102,179,222,212,112,106,116,226,206,237,105, 37,174, 67,128,245, 70,163, 81,104, 1, 64, 79, 51,200, 87, 80, 48,229,179,144, +152, 86,128, 87,113, 89,101, 81,125,180, 68,147, 99, 90, 19,252, 22,137, 96, 24, 6, 26,173, 30,234,188, 52,172,190,168, 64,116, +138, 10, 26,185, 20, 26,109,225, 52, 44, 91, 91, 91,246,213,171,151,103,222,184,113,115,210,254,253,251,201, 20, 11,139,215, 5, + 64,211,178, 56,173,172,220,205,104, 30,239,196,246, 29,139, 77, 25, 50, 14,177, 31,228,168,231,210, 2,182,150,174, 72,203,146, +227,254,235, 75,120,243, 54, 4,117,156,106, 33,112,122, 23,147, 21,171,142, 28,231, 82,110, 53,115,115, 19,242,203, 43,103,241, + 83,212,206, 43,177,160,114,226,160,207,126, 15,125, 65,234,103, 7,136,236,106,162, 89, 59,103,216,185,214,229,143, 12, 92, 62, + 2,248, 72,104,149,230, 76, 39, 8,214,118, 22,139,152, 68, 16, 4, 26, 53,106,156,178, 97,195,134,178, 66,129,107, 27, 53,106, +156, 66,146, 44,151,194,142,157,181,141, 97,232,244, 74,202,249,145,168,225,241,248,243, 10,205,254, 78,201, 23, 47, 94,212, 14, + 24, 48, 0,235,215,175,231,205,159, 63,127, 33, 73,146, 99,202,112,239,125,196,217, 7,168,105, 89,183,110,231,149,247,239, 51, + 28,157,142,200,121,252, 56, 63, 87, 34,161,210, 10, 10,120, 39,223,188,233, 54,118,206, 28,158,171,171, 43,238,133,132,216,100, +202,229, 76,174, 90,173,204,205,205,101, 40,138,122, 92, 14,231, 2, 59, 59,123,193,238,221,187, 61, 39, 78,156,248, 92, 34,145, + 44, 0, 0, 39, 39,167,213, 0,234, 3, 72, 44,181, 13, 59,118, 28, 23,143, 27, 55, 46, 54, 35, 35, 99, 65, 69,229, 44,133, 6, +246,118,246,130,163, 59,131, 95, 90,155,153,178,236, 92,106,176, 56,150,150,108,138,103,202,165, 1,101, 29,215,186, 66, 0, 13, +202,249,237,167,156,132,169,169,233,153, 63,255,252,211,158,195,225, 64,175,215,195,206,206, 14, 9, 9, 9,200,205,205, 69, 65, + 65, 1,226,223, 68,195,205,213, 21,203,130,230, 59, 77,157, 31,116, 70,161, 80,248,126, 50,152,125,158, 0, 89,167,253,204,178, + 87, 86, 22,131, 79,221, 94, 6,182,123,105, 36,124,248,240, 1, 34,145, 8, 62, 62, 62,162,251,247,239,223,173, 64,100,149, 78, + 2, 60,176,117,235,214,102, 71,142, 28,129,175,175, 47, 44, 44, 44, 16, 22, 22,134,200,200, 72,104,181, 90,150, 76, 38,131, 72, + 36,194,154, 53,107, 80,179,102, 77, 20, 20, 20, 32, 49, 49,209,134,195,225,216,126, 18,209,190,132, 51,236,106,216,138,188,247, +183, 22,165, 17, 87,186,236, 62,122, 28,227,134, 12,130, 35, 19,119,215,162, 46,177,162,115,207,214, 63, 51,164,107, 15,161, 89, + 35, 43, 15,159,158,224,242, 68,152, 58,111, 57, 98,163, 46, 88, 41, 10, 94, 78, 33,244,201,174, 75, 55,156,156, 81,198,185, 19, + 0, 88,174,174,174, 99, 79,158, 60,105, 86, 98,122, 33,201,146,156,135,165,147,192, 87,144,240,189,210,250, 36, 8, 2, 9, 9, + 9,176,183,183,135, 72, 36, 42, 73, 32, 30, 29, 29,141,135, 15, 31,162, 56, 27, 69, 57,156,195,110,220,184,225, 42, 20, 10, 63, + 58,128, 97, 24,100,101,101,129,162, 40, 8, 4, 2,232,245,122,104,181, 90,232,116, 58,168, 84, 42, 81,253,250,245, 39,235,116, +186, 71,101,113,210, 52, 61,107,224,192,129,173, 31, 61,122,228,190,121,243,102,104, 52,154,117,105,105,105,232,215,175, 31,104, +154, 70,135, 14, 29,190,101, 24, 38,102,225,194,133, 0,128,153, 51,103,234,228,114,249,196,234,156,123, 17,234, 55,107,214,204, + 61, 52, 52, 20,109,218,180,129, 90,173,198,250,245,235,205,119,236,216, 97, 30, 28, 28,108, 55,111,222,188,125,153,153,153, 1, +149,112, 18, 0,214, 57, 58, 58, 78,106,219,182,173,105, 81, 14, 83, 28, 60,120, 16,203,150, 45, 59, 6, 96,225,229,203,151,151, +156, 63,127,126,196,216,177, 99,177,108,217,178,192,220,220,220, 61,229,113,198,199,199,195,206,206, 14,230,230,230,133,157,165, + 86,139,136,136, 8, 92,191,126, 29,223,124,243,141, 33,231, 84, 94, 57,107,245,237,219,119,223,209,163, 71,205,146,147,147,113, +231,206, 29,184,185,185, 65,161, 80, 24,146, 27,246,198, 95, 48, 96,151,203,169, 84, 42, 85, 31, 62,124, 16,173, 93,187, 22, 78, + 78, 78,168, 85,171, 22, 76, 76, 76, 64, 16, 4,116, 58, 93, 69,233,213, 42, 45,167,191, 63,216, 89, 98,171,222, 22,150, 86, 83, + 24,134, 97,231,229, 73,119,106,145,123, 42, 46, 14,154,191,241,220,255,147,209, 20,192,115,124,156,243, 80, 82, 34,180, 66, 66, + 66,152, 30, 61,122, 16,197,239,206,206,200,207,202,178,138,181,119,108,120,220,222,177, 65, 81,222, 47,214, 27,146,180,138,117, +112, 80,228, 3,128,150, 98, 16,254, 38, 23, 47,223,165, 33,242, 93, 26,132,124,195,140, 47,106, 45, 85, 56, 99,149, 97,160,146, +253,255, 67,171, 86, 33,133, 90, 91, 56,221, 67,163, 86, 32, 47,243, 53, 49,160, 79, 39,147, 73,147, 38,192,201,201,217,174, 60, + 62, 45,223, 36,112,234,204,110,150,214,150, 28,132,220,191,130,111,191,233, 3, 19, 62, 7,217,121, 42,128, 0,222,198, 93, 7, +104, 51, 68,197,126, 64,203, 6, 2, 4,116,246, 22,157, 61, 21, 51, 7,192, 98, 67,202, 75,165, 60, 6,215,163, 43, 56,122, 29, +116, 89, 49,160,115,147, 0,161, 35,148,132, 8,217,146, 36,188,185,123,218,160,103, 70,154,166,167,216,218,218,230, 46, 92,184, +176,109,189,122,245,180,147, 39, 79,126,145,148,148, 52,235,147,167,149,223,182,109,219,134,119,239,222,137, 87,174, 92, 25,150, +149,149,181,168,138, 13, 29,196, 48,216, 84,228,138,203, 58,119,238, 92,179,219,183,111, 7,110,218,180,201, 97,218,180,105,188, +105,211,166,141, 6,240, 75, 69,238,194,124, 62,191,227,202, 59,119, 24, 42, 37, 69,125,104,203, 22,222,214,240,240,133, 90,154, +174, 97,107,111, 79,124,215,178,165, 92,192, 98,101,101,167,167, 83,118,238,238,100,194,245,235, 54,140,169,105,234,229,203,151, +243,101, 50, 89,185,169,115, 72,146, 84,148,229, 46, 44, 11, 78, 78, 78,154,178,230,112, 85, 48, 32,230,211, 12,163,181,172, 83, +135,233,220,161, 85,189,119, 49,113,113, 38,150,150,164, 71, 61, 55,175, 87,111, 18, 30, 51,122,189,138, 32,136,124,131,124, 37, + 36, 57,104,211,166, 77, 13,205,205,205, 65,211, 52, 44, 44, 44,144,153,153, 9,141, 70,131,252,252,124,104, 10,242,160,201,203, + 67,100, 82, 2, 90,183,109,139, 1, 93, 58,123, 7,159,251,115,144, 94,175, 63, 86,161, 63,175, 81,211, 18, 75,214,242,218, 54, +255,239, 11, 74,206, 45, 17, 93,107,155,122,128, 43, 18,161,211,172,160, 47,185,209,159, 95,188,120,241, 82,223,190,125,187,205, +153, 51,135, 37,145, 72,174, 36, 36, 36,180, 6,240,186,162, 31,137, 68,162,186, 89, 89, 89,144,201,100,176,176,176,192,166, 77, +155,224,224,224, 0,133, 66,129, 39, 79,158, 48, 46, 46, 46, 68, 88, 88, 24, 92, 92, 92,144,157,157, 13,173, 86, 11,165, 82,153, +166,209,104,202,117,151, 23,185, 7,187,206,236,130,203, 49,207, 14,182,113, 38,226,159, 12,156,237,255, 46, 38,242,205,135,107, +215,239,255, 66,169, 76,146,115, 83,110,204,175,211,252,185,237,148,185,203,240,199,186, 37,136,121,116, 39,199,161,102,254, 86, + 83, 66,125,160,162,242,202,229,114,213,155, 55,111,204, 94,188,120, 1,130, 32, 96, 97, 97, 1,129, 64, 80,166,216,170, 6, 88, +165, 45, 80,114,185, 28, 92, 46, 23, 54, 54, 54,216,179,103, 79,201,192,235,230,230, 86, 17,199,206, 78,157, 58, 13,170, 89,179, +166, 89,233,141,205,155, 55,199,132, 9, 19,176,125,251,118,132,135,135,127,148, 79, 51, 45, 45, 77,162,211,233, 42, 58,239,220, +244,244,244, 46,125,250,244,121,118,247,238, 93,243, 61,123,246,128,162,168, 50, 95,187,119,239,198,195,135, 15, 23, 3,120, 83, +205,235,232,155,126,253,250,221, 57,124,248,176,101,102,102, 38,138,175, 13,185, 92, 14,189, 94, 15, 47, 47, 47,130,162,168,202, +230,189,177, 72,146, 60,183,101,203,150,158,227,198,141, 3,155,205,134, 70,163,193,150, 45, 91, 48,127,254,252,244,162,135, 82, + 45,128,133, 7, 14, 28, 24,209,171, 87, 47, 52,110,220,216,251,214,173,242,103,118,200,100, 50,200,100, 50,112, 56, 28, 56, 58, + 58, 98,197,138, 21,208,104, 10,187, 21, 79, 79,207,146,219, 24,192, 78, 79, 79,207,158,177,177,177,235, 81, 56,119,237, 51, 56, + 58, 58,246, 97, 24,102,188, 94,175, 47,104,211,166,141,205,209,163, 71,205,196, 98, 49,158, 61,123,134,197,139, 23, 75,105,154, +214,211, 52, 77, 40,149,202,120,123,123,251,103,124, 62,223, 84,161, 80,228,100,103,103,175, 2,112,229,159, 26,201, 9,130, 32, + 56, 28, 14,198,140, 25, 3, 54,155, 13, 83, 83, 83,168, 84, 42,232,116,186, 18, 49,143, 42,186,165,235,213, 19,217,176,193, 29, +103,101, 86, 63,112,192,140, 30,118, 78, 53,156, 97,105,206, 71,116,244,235,214, 55, 67,175,111,225,177, 99,118,208, 26,221,142, +152,196,188,191, 60,217,253,167, 90,228, 63, 84,104,125,150,243,144, 93,118, 99, 14,208, 51,204,201, 44,177,152,167,229,241, 4, +177,197, 86, 46, 7, 7, 69, 62, 65, 12,208,219, 53,232, 13, 74,171, 43,234, 40,152,162,151,129, 66, 75,167,199,187,152, 40,220, +189,246, 39,108, 21, 98,100,197, 55, 1,184, 13,161, 81,230, 65,165,209, 22,137, 18, 61, 94, 60, 11, 69,126, 94, 14,124,124,123, + 0, 44,214,195,242,248, 44,108,136, 30,223, 53,107, 68,190,251, 16,133,230,158,253,225,238,210, 6, 73,146,124,228,202,212,144, +230,171,208,196, 39, 8,153, 82, 37,242, 21, 42,188,126, 23, 12,231, 26,238, 44,130, 29,215,193, 80,161,165,126,125, 6,234, 55, +231,193,173,213, 26, 60,175, 94, 32,107,249,225,195,203, 91,120,113,121, 35, 82, 94,221, 3, 67,235,225,228,217,194,208,155,100, +203,149, 43, 87, 90,180,110,221,154,221,177, 99,199,198,151, 46, 93,106, 44,145, 72, 94, 20, 9,140,198, 29, 59,118,108,108,103, +103,135,223,127,255, 93, 73, 16,196,150,106, 54,118,137, 5, 44, 35, 35,227, 49,128,149,103,206,156,217, 50, 97,194, 4,216,219, +219, 55, 76, 77, 77, 45,247,135,153, 28, 78,227,145,171, 86, 49, 28,146,100,142,253,241, 7,119,217,149, 43, 27,246, 31, 56,192, +109,223,174, 29,193, 48, 12, 34, 34, 34, 4,107,255,248, 67, 48,180,119,239,196,164,140, 12,234,118,120,184, 86,146,146, 82,144, + 33,151, 47,147, 72, 36,105,255,196,149,173,211,233, 30,196, 39,196, 59,251,182,108, 98,226,180,160, 87, 0, 0, 32, 0, 73, 68, + 65, 84,247, 60, 58,254, 85, 64,251,239,190, 99,177, 88,172,152,184,164,112, 59, 59,115,193,245,107,215,181, 58,157,238,129, 33, + 92,124, 62,191, 71,251,246,237,217, 82,169, 20, 53,106,212, 64,102,102, 38,196, 98,113,161,197, 33, 79, 10,109, 94, 30,116,249, +185,208,203,101,136,127,242, 24, 77,220,235,240, 79,242,249, 61, 20, 10, 69,133, 66,171,248, 41,179,172, 68,215,197,219,120,102, +102,224,137, 68, 32,170,238, 54,236,109,105,105, 57, 63, 55, 55,247, 18,128, 21, 90,173,118,234,252,249,243,155,111,222,188,217, +118,229,202,149,230,227,199,143, 63, 41,147,201,154,160, 48,169,106,121, 3,216,123,138,162,108, 0, 56,132,134,134,194,222,222, + 30,121,121,121,197,150, 22,141, 66,161, 48,201,206,206,134, 90,173,134, 70,163,129,185,185, 57,158, 62,125,154, 67, 81,212,133, +202, 10,103, 94,151, 88,161,214, 70, 47,178,241, 22,166,106, 41, 43,255,140, 28, 90,186,116,131,100, 57,128, 13, 93,220,221,119, +107,233, 59,241,111,163, 46, 88, 37, 60, 9,203, 73,125, 43,119,223,115, 41,190,162, 57, 90, 12, 0,154, 32, 8,198,211,211, 19, +153,153,153, 32, 73, 18, 2,129, 0, 34,145, 8, 11, 22, 44,192,150, 45, 91,170, 35,180, 76,132, 66,225, 42, 22,139, 53,136,197, + 98,217,233,245,122, 4, 5, 5,161,103,207,158,224,241,120,208,106,181, 37, 22,205, 98, 43, 85, 37,150,142,136,135, 15, 31,154, + 63,124,248, 81,183,213,206,214,214,246,166, 90,173, 70, 92, 92, 28,206,157, 59,215, 22,192,237, 42,182,117, 92, 68, 68, 68, 23, + 63, 63,191,131,205,154, 53,171,203, 48, 12, 26, 54,108,136,193,131, 7, 35, 56, 56, 24, 47, 94,188, 64, 94, 94, 30,125,253,250, +245,253, 0,214, 87,117, 12, 47,170, 95,175,126,253,250,221, 59,114,228,136, 85,118,118, 54,148, 74, 37,228,114, 57, 78,158, 60, +137,214,173, 91,195,214,214, 22,135, 15, 31,166, 24,134,169,168,237, 89, 44, 22,107,207,142, 29, 59,122,142, 29, 59, 22, 91,183, +110,197,177, 99,199,208,171, 87, 47, 12, 26, 52, 8,153,153,153, 14,235,214,173, 27, 81,228, 38, 92, 50,120,240, 96,200,100, 50, + 60,121,242, 36,218,192,123, 30,185,185,185,200,205,205,133,169,169,105,233,123,140, 0, 16,188,113,227,198, 33,129,129,129,112, +119,119, 95, 18, 31, 31,191, 17,101,172, 18,165,105,122,162, 88, 44,182, 98,179,217, 54, 20, 69, 33, 57, 57, 25, 79,159, 62,197, +148, 41, 83,114,114,114,114, 38, 0, 72, 2,176,112,204,152, 49, 43,102,205,154, 85,114, 45,205,154, 53, 43,228,210,165, 75, 93, +254,110,107,142,167,167,101, 3, 30,201,159, 33, 45, 32,109,164, 82,105, 73,223,161,209,104,160, 86,171, 63,178,100,113,185, 28, +155,230, 77,106, 94, 84, 42, 10,126,122,253, 54,183,220, 4,233,222,117, 45, 26, 9,132, 22,129,173,219,180, 31,214,185,203, 15, + 36,165,211,225,234,213, 11,216,187,119, 27,218,249,121,194,189, 94, 67, 76,155, 62,195, 66,173,161,130,174, 95,191, 50,223,242, +225,221, 43, 5,249,185, 11, 42,226,252, 31,199,197, 34,113,117,177, 76,215, 97, 89, 10,178, 40,132,131,180,232,171,173,149,149, +213, 31,122,189,190,157,185,185, 57,232,220, 88,188,126,250, 8, 57, 82, 14,212, 74, 61,104,166, 80,108, 25, 36, 92,212, 26,220, +185,122, 30,155, 54,110, 64,118,118, 54,252,190,111, 11, 25,219, 21, 53, 93,107, 66,165, 84, 20,221, 52,128, 86,163,131,157, 67, + 45, 60,127,254, 66,151, 47,151,151,219, 33,113, 77,180,222, 53, 29, 60,161,214,182,130, 9,143,135,188, 2, 13,164, 69, 34,235, +240,169,129, 80, 43,148,160, 52, 90, 80, 26, 29,236,106,246,195, 55, 14,237, 65,235, 47, 52,168, 82,245,209,122,104, 19,238, 64, +155,112, 7,166,173,166,227,207,213, 67, 62, 25, 72, 13,203,187,155,153,153,153,241,234,213,171, 11, 17, 17, 17,125, 6, 14, 28, +136, 91,183,110,141, 7, 48,169,200,125, 51,126,224,192,129,136,136,136,192,171, 87,175, 46,100,102,102,102,124,141,150,231,241, +120, 74,181,186,112,140, 21, 8, 4, 38,149, 28,235,220,188,111, 95, 86,222,243,231,249, 27,239,223, 95,178,123,207, 30,110,199, + 14, 29, 8, 29, 69,129,214,235, 81,207,195,131,232,220,185,179, 48,248,196, 9, 27, 82,167,123, 56,119,234,212,208,237,195,135, + 23, 60,150,203, 13,157,104, 94,187,200,101, 8, 0,181, 43,216,102, 48,212,106,245,230,137,227, 70,117,188,125,231,158,107, 77, + 87,103,243,171,215,111,191,224,155,242, 88,238,110,117, 73,105, 94, 14,123,249,146,159, 76,213,106,181,161,162,213,219,214,214, + 22,105,105,105,120,247,238, 29,212,106, 53,116, 58, 29,104,133, 28, 26,105, 46, 52,121, 57, 32, 84, 74,240,245,122,168,178,210, + 81,219,189, 14,240,255, 43, 18, 43,117, 69,149, 37,180,138,223, 77,204,205,193, 21,138,192,226,112, 12, 78,142, 14,160, 89,139, + 22, 45, 78,156, 62,125,154, 59,122,244,232,150, 55,110,220,248, 3, 64,146, 88, 44,238,176,120,241,226,199,127,252,241, 7,127, +194,132, 9, 94,235,215,175, 31, 1, 96,103,121, 36, 42,149,234,196,197,139, 23,135,214,170, 85,203, 33, 50, 50, 18, 42,149, 10, + 52, 77,163,107,215,174, 64,225,220, 26, 0, 64, 76, 76,140, 82,165, 82,101, 68, 69, 69,229, 39, 37, 37,105, 97,192, 42,193,165, +155, 37, 15,242,211,238,244,117,112,116,126,104, 98, 90,219,141,145, 61,239, 51,179,191,243,186,141,167,196,170, 43,113,113, 5, +139, 58,213, 89, 35, 47,120, 57,197,210, 69,182,245, 74, 72,188, 33, 19,225, 75, 86, 23,218,216,216,128,205,102,131,195,225,128, +203,229,130, 32, 8, 76,159, 62, 29,187,118,237,170,204,117,248,145,200, 50, 51, 51,123,181,108,217, 50,151, 9, 19, 38,112, 77, + 76, 76, 32,149, 74,113,248,240, 97,140, 25, 51, 6,123,247,238, 45,115,254,139, 1, 46,165, 79,173,165,129,195,135, 15,135, 70, +163,193,224,193,131,177,123,247,238, 64,189, 94,127,187, 26,183,244,195, 23, 47, 94,120,188,120,241,194, 28, 64,175, 65,131, 6, + 29,232,215,175, 31,110,223,190,141, 11, 23, 46,180, 69,225,162, 15, 37,128,213, 0,236,139,222, 43,186, 63,133, 14, 14, 14,219, +104,154,238,101,103,103,247,194,211,211,211,231,200,145, 35,150, 25, 25, 25,197,139, 31,144,144,144,128,125,251,246, 73,246,236, +217,147,175,215,235,109, 88, 44,214,197,220,220,220, 5, 21, 8,182, 61, 27, 55,110, 28, 85,228, 14,196,233,211,167,153, 13, 27, + 54, 16,139, 23, 47,134, 84, 42, 69,187,118,237,176, 99,199,142, 25, 50,153,172,241,134, 13, 27,198, 13, 24, 48, 0,203,151, 47, +135, 92, 46,223, 88,217,195, 74, 5,226,139, 0,240,221,198,141, 27,107, 5, 6, 6,226,244,233,211,104,214,172,153,105,124,124, +252,118, 0, 99,203,106, 63,134, 97, 16, 31, 31, 15,133, 66,129,123,247,238, 97,201,146, 37,210, 82, 34,107,198,164, 73,147, 86, +204,152, 49, 3,171, 86,173, 98, 34, 35, 35, 51,250,245,235,231,176,107,215, 46,178, 94,189,122, 51, 20, 10,197,223, 38,180,188, +234, 89,175,105,222,172,205,124, 39,231,122, 56,124,228, 40,114,114,114, 74,234,164,184, 94, 24,134, 65, 65, 65, 1,210,210,210, + 96, 97,110,134,117,235, 87,116,155, 60,126,148, 43, 10,195, 96,124,110,178,116,183, 90,223,111,208,232,217,131,135,142, 66,228, +139,103, 8, 62,176, 19, 81,145, 17, 37,124,148, 78,139,216,232,167,136,141,126, 10, 7,199, 90,232,220,177, 45, 49,100,200,144, +174,195,135, 14,178, 3,240,151,133,142,248, 15,182,102, 1,159,199,209,218,245,145,208,170,196, 92,103,107,101,101,245,234,248, +241,227, 54,126,126,126, 36, 69, 81,184,114,245, 42,166, 76,250, 17, 35,134, 7, 65, 11, 43, 80, 26, 46,104,174,137, 65, 37, 81, + 42, 21, 96,192, 64, 46,151, 35, 60, 60, 28, 12, 77, 33,120,215, 6, 48, 12, 93, 34,180, 0, 6, 26,173, 22,206, 53,189,176,109, +247, 74, 10, 28,206, 99,232,202, 14, 93,147,159, 77,234,117, 20, 3,113,198, 7,124,144, 68,193,194,172, 38,216,156,154,200,206, + 85,128,205,114,132, 78, 21, 3,125,209,111, 21,242, 20, 40,181, 95,214,126,250, 50,172,167, 76, 21, 58, 93,165, 82,121,232,208, +161, 67,221,126,251,237, 55, 94,247,238,221, 61, 79,157, 58,245, 29, 0,116,239,222,221,211,220,220, 28,135, 14, 29,210, 40,149, +202, 67, 95,209,226,211,190, 69,139, 22,144, 74,165, 72, 72, 72,120, 81,225,185,105, 52, 54, 34,123,123, 50,227,214, 45, 93,166, + 84,234,218,190,125,123, 66, 71, 81, 96, 17, 4,114,242,242,144,148,152, 8, 75, 75, 75,226, 85, 76,140,104,203,180,105,103, 61, +125,124,216,197, 43, 18, 13,193,133, 11, 23, 4, 40,156,151, 85,225,182, 42, 66,158,145,158, 54,106,234,212,169,103, 15, 29, 58, +108,145,158,145, 30,203,231,241, 40,145,200,164,198,240, 97,147,217,185,185,185, 67, 1,200, 12, 37,147, 74,165,136,143,143,135, +169,169, 41,184, 28, 14,104,165, 2,122,185, 12,170,156, 76,144, 90, 13,120,122, 61,172, 5,124,184, 58, 56,160,166,157,173, 65, +156,239,110, 94, 43,153,248, 94,218, 93,184,174,133, 55,120, 66, 17,120,102, 34, 76, 14, 9, 43,122, 26,229, 2,139,127, 49,132, +214,214,217,217,249,207, 35, 71,142,112, 51, 51, 51, 17, 17, 17,241, 2, 64, 30, 0, 51, 0,116,116,116,244,141,168,168,168, 30, + 69,171,238, 42, 91, 45,182,225,204,153, 51,157,252,252,252, 40, 55, 55, 55, 97, 70, 70,134,171, 84, 42,165, 37, 18,201, 71, 38, +161,107,215,174,241, 11, 10, 10,228, 52, 77,159, 45, 18, 89,149,198, 47,154,217,223,217, 36,252, 57,166,251, 7,212,110,104,110, +219, 8, 57,212,243,134, 15, 95, 72,166,207,236,239,188,121,227, 41,177,202,148, 80, 31, 32,244,201,174,108, 19,149,161,147,152, + 25,160,112,174, 84,120,120, 56,146,146,146, 16, 31, 31,255,145,160, 26, 63,126, 60,130,131,131, 13,178,104, 9,133,194, 85, 75, +151, 46,117, 9, 12, 12,228,150, 18, 69,152, 58,117, 42,242,242,242,176,123,247,110, 76,157, 58,181,202, 3,255, 39,168,211,190, +125,251,238, 78, 78, 78,200,206,206,134,163,163, 35,252,252,252,122,222,190,125,219, 13, 64, 66, 53,175,251,201, 1, 1, 1, 43, +150, 45, 91, 6,157, 78,135, 49, 99,198,224,237,219,183, 39,222,190,125,187,169,102,205,154,211,231,205,155,231,224,224,224,128, +129, 3, 7, 10, 41,138,234, 91, 30,137,181,181,245,234,157, 59,119, 14,237,222,189, 59, 75,171,213,126,127,243,230, 77, 36, 38, + 38, 66,163,209,128,162, 40,188,127,255, 30, 83,167, 78,149, 20,173,110,124,111, 64,185, 70, 47, 92,184,112,212,244,233,211,177, +118,237, 90, 44, 93,186,116,191,133,133,133, 79,147, 38, 77,154, 46, 93,186, 20,115,231,206, 69,173, 90,181, 96, 99, 99,243,205, +226,197,139,189,103,205,154,133,205,155, 55, 99,201,146, 37,251, 1,236,171, 78, 69,208, 52, 77,172, 89,179,166,241,198,141, 27, +157,138, 69, 22,139,197,194,241,227,199,241,252,249,243,158,113,113,113,101,253,102,135,163,163,227,120, 39, 39, 39,222,245,235, +215, 69,181,106,213, 2, 69, 81,186, 34,145,181,165,102,205,154, 83,222,191,127,143,238,221,187, 35, 46, 46,238, 16,128, 17, 22, + 22, 22,242, 89,179,102, 9, 76, 77, 77, 45, 20, 10,197,223, 53,120,131,100, 17, 35, 87, 45,159,139, 39,207, 99,112,230, 12, 23, + 79,158, 60,129,131,131, 3,248,124, 62, 24,134,129, 90,173, 70,102,102, 38,116, 90, 53, 26, 54,168,131,131,123,214, 32, 35, 35, + 19, 96, 17,229, 78,185, 33, 88,196,176, 81, 63,246,193,221,123, 87,177,125,251, 78,200,100,242,114, 30,190, 77, 80,207,211, 27, +206, 53,236,145,156,146, 12,130, 5,219,191,242, 92,255,195, 93,135, 37, 93, 16, 12, 9,239, 80, 26,150,150,150,155,142, 29, 59, +102,211,174, 93, 59, 82, 46,151,131,166,105,180,241,243,195,244,192, 64, 92, 56,114, 4, 30, 45, 7,131,208,136, 64, 9, 12, 91, +245,160, 82, 42, 80,191,233,119, 24, 48,112, 16, 62, 36, 37, 33,160, 71, 63,168, 84,138,146, 39,140, 98,139,150, 70,163,133,173, +189, 43,174, 93,187, 70, 98,204,152,215,216, 82,182, 81, 66,175,229,189,140,125,175,106,157,171,124,142,240, 39,193,208,170,181, +104,216,112, 49,180,180, 13,236, 93,198, 67,167, 59,135,252,204,155,133,110, 12,155,118, 72,249,240, 1, 44,146,251,170,186, 53, + 72,203, 51,191,168,211,205,203,203,203,139,143,143, 63, 21, 30, 30, 62,172,111,223,190,184,118,237,218, 56, 0,232,219,183, 47, +194,195,195, 17, 31, 31,127, 42, 47, 47, 47,239,107,180,182,147,147, 83,175,182,109,219, 14,110,222,188, 57, 66, 66, 66,192, 48, +204, 93,131,110,108, 14,135, 97,177, 88,160,105, 26, 4,128,236,220, 92,188,125,251, 22,217, 89, 89,208,233,116,144,203,100,180, +183,167,167,140,161,105,179,170,148,167,244, 10, 67,148,177,234,176,120, 91, 53, 78, 53,233,241,195,251, 31, 10,100, 50, 59, 43, + 75,171, 2, 30,143,167,151,230,230,230,189,126, 21,169, 49,112,112, 40, 70,116, 84, 84,148, 79,106,106, 42, 62,124,248, 0, 74, + 94, 0, 82,173, 1, 75,173, 64,135,239, 90,193, 20, 12, 76, 64,131, 67,235,192, 33, 57, 40, 40, 92,157, 87,169,187, 67, 95,234, + 33,161, 88,100, 17, 4, 81,232, 46, 20, 10,193, 19,153,125,100,225, 50,228,122,226,243,249, 71, 78,158, 60,233,228,236,236,140, +229,203,151,195,197,197,229,155, 26, 53,106, 40, 44, 44, 44, 76, 29, 28, 28, 80,191,126,125,124,247,221,119,184,124,249, 50, 12, +168, 3,138, 97,152,206,119,239,222,157,125,255,254,253, 1, 66,161,144,152, 54,109, 26,187,107,215,174,224,243,249, 80, 40, 20, +144, 74,165, 56,122,244,104, 22, 77,211,197,139, 82,108, 4, 2,193, 62,130, 32, 18,228,114,121,224,167,132, 7,127,107, 88, 35, + 35,135, 30,195,200, 4,125,252, 3,106, 55,108, 31,208, 17,117, 60,218,163,125,192, 7, 0, 88, 99,205, 78, 28,252,235, 66,203, +179,150,102,196,190,107, 87,174, 47,241,243,111,191,112,190,236,214,138,181,187,114, 43,157, 79, 71, 16, 4,104,154,254, 40,118, +208,167,251, 71,140, 24,129,227,199,143, 87, 90,143, 44, 22,107,208,132, 9, 19,184,159, 88,158, 33, 22,139,209,163, 71, 15,244, +237,219,247, 35,161,101,107,107, 11, 71, 71, 71, 36, 38, 38, 2, 64,182,129,215,213,244,209,163, 71, 19, 74,165, 18, 99,199,142, +197,238,221,187, 49,120,240, 96,226,246,237,219,211, 1, 4, 86,245, 98,103,177, 88,235,230,205,155, 55,123,234,212,169,200,201, +201,193,165, 75,151,208,181,107, 87, 28, 63,126,220,238,210,165, 75,171,218,181,107, 7,146, 36, 17, 18, 18, 2,138,162, 42,140, +245,197,229,114,123,117,239,222,157,149,156,156, 12, 46,151, 11, 95, 95, 95,164,164,164, 64,161, 80, 64, 44, 22, 99,198,140, 25, +105,217,217,217,109, 13,189,143,184, 92,110,224,244,233,211,113,236,216, 49, 4, 5, 5, 29, 0, 48, 54, 47, 47,111,192,253,251, +247,143,245,238,221, 27, 98,177, 24,103,207,158,197,146, 37, 75,136, 17, 35, 70, 96,235,214,173,152, 49, 99,198,254, 34,171, 83, +121, 23,126, 65, 70, 70,134, 69,221,186,117,145,158,158, 14,153, 76,134,179,103,207,218, 95,190,124,217,205,217,217,217, 60, 62, + 62, 94,255,203, 47,191,240, 2, 3, 3,177,105,211, 38, 68, 68, 68, 32, 56, 56, 24,237,219,183,167,226,226,226,202,180,146, 21, +133,108, 56,203, 48,204,117,161, 80,136,130,130,130,226,251,110, 78, 80, 80,208,212,213,171, 11,141,236,169,169,169, 24, 57,114, +228,240,208,208, 80,186, 93,187,118, 2, 46,151, 11,149, 74, 37,255, 59, 71,109, 90, 79, 3,160,225,230, 42,194,213, 11,123,240, +236, 69, 28,158,189,136, 2,143, 95, 56, 9, 94,169, 84,160,105,195,122,104,233,219, 2,169, 18, 49, 14, 5,239,129,181,173,115, +133,253, 8,195, 48,224,178,245,240,246,116,196,145,224,157, 8,185, 20,138,224, 67, 71, 75,230,188,177,217, 28, 52,105,218, 18, +190,190,126,136,139,127,143, 61,123,182,195,206,222,213,232, 28,172, 38, 74, 92,135,165,223, 63, 81,254,237,253,252,252, 72,153, + 76, 6,149, 74,133,180,180, 52, 36, 38, 38,194,210,202, 18,113,169, 9,104, 43,208, 34,141,206, 71,244,139, 87,122,130,228, 68, + 84,246,135,221,253,155, 0,254, 77, 48,101,244,224, 10, 30, 89, 25, 8,205,109, 11, 93, 55, 20,245, 14,155, 55, 83,229, 9, 45, + 74,175,187,113,245,250,205, 22,163, 71,244,226, 92,187,185, 27, 58, 13, 13,165,206, 2,114,149, 6,114, 45, 7, 44,139,174, 64, +214,109,144,108, 62,190,109, 92, 15,103,207, 92,214, 50,148, 46,212,224, 10,114,240, 1,149, 30, 85, 74,104,101,124,226,119,176, + 54,216,117, 88, 50,240,234,245,199, 15, 31, 62,252, 67,171, 86,173, 4,237,218,181,171, 91, 52,112,106, 15, 31, 62,172, 40, 10, +134, 89, 85,124, 20, 13,222,209,209,177, 41,151,203, 29,220,181,107,215,166,163, 70,141,194,235,215,175,113,232,208,161,216,122, +245,234,221,146, 72,202, 95,145, 77,242,120,217,178,140, 12, 75,145,155, 27,219,202,204, 44,245,242,165, 75,181, 58,118,234, 68, +124,248,240, 1,217,217,217, 80,169, 84,136,120,241,130,225,144,100, 10, 97,110,206,138,121,254,156, 69,242,120,217,229, 89, 27, +203, 64, 98, 37,171, 14, 87, 87,215,186,229,234,100, 85,119, 73,208,196, 58, 42,181,202, 39, 63, 63,159, 98,115, 56, 28, 23, 71, +203,164,152,247,134,247,137,106,181, 58,228,198,141, 27, 63,116,236,216,145, 31,251, 50, 2, 84, 94, 30, 52,121, 82,112,105, 61, +172,155, 54, 6,169, 85, 3, 26, 29,156,189, 25,168,114, 5,184,253, 40, 70,167, 86,171, 43, 13,106, 88, 44,180, 88,159, 8, 3, +158, 72, 4,190,153, 57,248, 34,209,167,130,161,178, 39, 57, 65,231,206,157, 59,124,251,237,183, 96, 24, 6,187,118,237,130, 86, +171,229,105,181, 90,104, 52, 26,104,181, 90,228,231,231, 35, 56, 56, 24,219,182,109,187, 15, 96,191, 1,167, 79,153,154,154,246, + 38, 8,194,158,205,102, 43,236,236,236,132,199,143, 31, 47, 9, 55,209,164, 73, 19,152,153,153,113, 81, 20, 20,210,222,222,158, +179,119,239, 94,203,158, 61,123,222, 41,211,221,209,240,155,185,117, 40, 43,127, 19,211,218,110,230,182,141, 80,199,163, 61, 0, +160, 83,143,209,168, 83,175, 38,242,179, 94,186,169,148,137,125,184,108,169,213,171,205,226,215,166,221,125, 70,201, 51,194,222, +162,236,229,253,101, 14, 20, 44, 22,171, 92,119,172, 33, 34,171, 80,179,176,236,138,231,249, 0, 64,118,118, 54, 36, 18, 9,162, +163,163,225,229,229,133,156,156, 28, 56, 59, 59, 67,163,209,160,121,243,230, 80, 42,149,216,184,113, 35,238,221,187,119, 31,192, + 12, 3,254,195,212,195,195, 99,100,211,166, 77,113,233,210, 37, 60,121,242, 68,124,245,234, 85,103, 63, 63, 63,184,185,185,141, + 74, 72, 72,248,169,200,213,103, 40,132,126,126,126,211,166, 78,157,138,168,168, 40, 76,156, 56, 49, 59, 57, 57,249,236,137, 19, + 39,198, 46, 89,178,132, 21, 16, 16, 0,137, 68,130,117,235,214,233,239,221,187,183, 30,192,242, 74,234,241, 77,114,114,178,139, + 74,165, 66, 78, 78, 14, 40,138,130, 66,161,192,229,203,151, 17, 28, 28,156, 94, 36,178,222, 25, 90,184,198,141, 27,215,103,177, + 88, 56,118,236, 24, 0, 44, 66, 97,196,254,179,125,250,244, 17,255,242,203, 47,206, 11, 22, 44,192,184,113,227,160,213,106,177, +118,237, 90, 44, 88,176,224, 98,145,200,170,168, 19,253,205,209,209,113,252,196,137, 19,191,153, 53,107, 22,194,195,195,237,159, + 62,125,234, 27, 17, 17, 1, 87, 87, 87,100,103,103,179,109,108,108,176,105,211, 38,204,156, 57,243, 52,128,172, 7, 15, 30, 12, +138,143,143, 95, 13, 96, 93, 37,162,125,135,179,179,243,120,134, 97, 24,133, 66,145, 24, 20, 20,180,110,229,202,149,152, 57,115, + 38, 94,189,122,133,188,188, 60,152,153,153, 17,243,230,205, 27,185,104,209, 34,140, 25, 51,134,145,203,229,219,254,238,129,154, + 97,244, 80, 72,163,160, 87, 91,161, 73, 67, 47, 52,241,169,141,171, 55,159, 1, 0, 58,244,243,131, 66, 94,128, 3, 7,118,225, +221,187,183, 96,115, 56,176,180,118, 52,196, 18, 8, 77,254, 27,228,106, 37,232,216,206, 23, 93, 3,218, 98,255,193,227,160,116, + 90,140, 29, 61, 20,210,220, 92, 28, 60,184, 7,113,241,239,193,230,112, 96, 99,251,215, 7, 66,173, 72,139,252,199, 11, 45, 3, +220, 79,160,105, 26, 98,177, 24, 79,159, 62, 69, 66, 66, 2, 4, 2, 1,148,148,158,222,126,227, 30, 77, 16,220, 20,154, 97,238, + 51, 84, 73,148,226,207, 57,244,122,113,169,136,181, 22, 86, 86, 86, 60,181, 90, 9,138,210,149, 26, 85, 8,128, 0,184,108,192, +169, 70, 29, 36,127, 72,102, 84, 42, 85, 88,133, 79, 80,106,213,166,243,103, 79, 78,253,174,181,159,109,215, 14,203,112,246,220, + 98, 72,243,243,161,210,114, 32, 87,105,161, 80, 1,150,214,158,104,222,176, 17, 82, 83,179,241,242,201,109, 25, 91,173, 48,100, +162,232,219, 45, 11, 71,123,140,158, 50, 23,166,181, 90, 67, 29,125, 22,180, 44,189,196,162,101, 34,178,130,117, 77,111,228,202, +213, 56, 25,250, 12,168, 66,170,151,140,140, 12, 5, 73,146,135,167, 78,157,186,246,217,179,167, 46, 0,240,236,217,179, 20,137, + 68, 50, 63, 35, 35,163,170, 54,233,226,104,240,132,137,137,233,179,122,245,234,165,250,250,250, 90,244,233,211, 7,182,182,182, +136,136,136,192,234,213,171,223,104,181,218,185,183,111,223,174,208,213,163,209,104,196,207,206,157, 51,111,251,227,143,150,115, +123,246, 92, 55,117,234,212, 77,203,151, 47,231,120,120,120, 16, 58,173, 22,145,145,145,204,145,195,135,117,219, 22, 44,216,200, + 19, 10,217,143,207,159,231, 80,106,181,248,159,190,136,157,157,157,253,253,190,111,227,189,254,183,205, 80, 41,101,120, 20,126, + 17, 82,105, 38,118,238, 58,227,237,236,204,248,139,197,226,219,134, 10,224,125,251,246,205,110,217,180,105, 83,119, 87, 87, 68, + 38, 37,128, 71,235,193,165, 40,144, 90, 53, 88,148, 10,174, 62, 12, 8,150, 25, 36,105,249, 88,121,236, 84,148, 33,194,248,155, +110,189,176, 60, 37, 15, 4, 65, 96, 67, 43, 31,240,204, 68,224, 10, 69,152,252,231,205, 18, 97, 16,178,124, 1,120, 34, 17,234, +182, 52, 40, 32,188,226,214,173, 91, 79, 35, 35, 35,155,251,248,248, 96,246,236,217, 72, 76, 76, 4, 77,211, 72, 79, 79, 87, 73, + 36, 18,113,102,102,102, 34, 10,227,255,236,174,100, 16, 43,173, 58,156,111,223,190, 93,226,110, 8, 13, 13, 69,141, 26, 53, 96, + 97, 97,129,252,252,124, 76,152, 48,193,242,231,159,127, 6, 0, 60,125,250, 20,165, 5,202,167,136,124, 22,189, 62,183,128,145, + 50,178,231,125,114,168,231, 13,219, 7, 36,163, 83,143, 81,184, 30,178, 31, 55,175,222,128, 53, 59, 49, 1,194,130,203, 89, 9, + 89,249, 41,114,143, 29,222,205,198,146, 18,249,213, 29,211,122,197,146, 78, 78,244,201, 5,219,243,115, 43, 42,171,135,135, 7, + 28, 28, 28, 74,230,104,177,217,108,140, 25, 51, 6, 12,195, 24, 42,178,138,198, 26, 58, 83,165, 82, 57,152,152,152, 32, 45, 45, + 13,239,223,191, 71, 92, 92, 92, 73,232, 0,154,166,117,115,230,204,225, 76,155, 54, 13,219,183,111, 71, 88, 88,216,125, 0,203, + 0, 24,250,176, 54,116,224,192,129,102, 26,141, 6, 71,143, 30,165, 0,244, 56,121,242,228,211,230,205,155,179,187,116,233, 98, +182,117,235,214,161, 69,109,100,176,208, 50, 55, 55,231,106,181, 90,108,221,186, 21,201,201,201,254, 0,162, 31, 63,126,188, 99, +224,192,129,219,124,124,124,234, 69, 69, 69,189,149,201,100,147, 1,188,172,140, 44, 61, 61,125,180,175,175,239, 73,154,166,107, +117,236,216, 81,248,219,111,191,153,199,196,196,192,197,197, 5, 52, 77, 71,162,138, 41,172,222,190,125, 27, 45,145, 72,188,219, +182,109,139,203,151, 47,175,209,235,245,171, 0,172,157, 52,105,146,115, 82, 82, 18,154, 54,109, 10,107,107,107,196,196,196, 20, + 72, 36,146,109, 40, 76, 73, 84,153, 9, 55, 30,192,252, 29, 59,118, 52,218,177, 99,199, 96,107,107,235,111, 35, 34, 34,112,247, +238, 93,172, 95,191, 30, 63,255,252, 51,218,180,105,131,217,179,103,103, 1, 24, 12,128,138,143,143, 55, 40,110, 94,177,101, 11, + 0,154, 53,107,150,186,122,245,106,140, 29, 59,150,217,187,119,239,239,135, 15, 31, 14, 28, 58,116,104,201, 24, 56,114,228, 72, +230,208,161, 67, 35, 81,152,134,233,239,132, 78,171,213,192,220,186, 14,100,185, 31,144,153, 28, 14,129,153, 35, 2,218, 55,134, + 66,169,193,133,243,167,241, 50,242, 5, 88, 44, 22, 28, 28, 93, 97,105,101,139,216,216,183, 64,197,171,141,117, 90,173, 22,102, + 86,181, 33,203, 75,134, 38,227, 25, 76, 69,246, 24,245, 99, 31, 40,148, 90,156, 57,123, 26, 81, 81, 47, 65,146, 36, 28,157, 92, + 97, 97, 89,200, 73, 48, 21,175, 96, 54, 2, 64, 25,241,180, 42, 21, 90, 36, 73,222,186,114,229, 74,255,150, 45, 91,178,223,189, +123,135,119,239, 10, 31,110,164, 82, 41, 69, 64,127, 42, 35,242,252,144, 10,126,222, 17, 69,171, 51, 74,231, 46, 20,153,153,137, + 99,222, 68, 59, 72,115,210,241,226,249, 61,188,139,141, 68, 66, 92, 52,180, 90, 21, 72, 22, 11, 44,146,133,218,117, 26,224,222, +253,112,141,138,162,194,203,227, 44, 44, 71, 92,129,208,222, 99,208,138,229, 63,133,204,156,187,212,116, 64,255,237,120, 25,243, + 26, 50,202, 17, 12, 3, 56,218, 8,209,196,125, 30,196,169,153, 56,182,127,171,130,214,106,135,125, 18, 67,235, 51, 78, 0,112, +200, 66,253,109,187,246,143,217, 29,124,100,233,220,105, 19, 28,122,247, 29, 6, 94,206,107,232, 82,159,161, 78,243,174, 32,248, +150,184,116,237, 38,110, 63,125,157, 78,235,153,165, 14,217,216, 27, 91, 9,103,105,228,230,230, 62, 72, 75,147,184,148,138, 2, +239,194,231,155, 84,182, 58,238, 83,206,143, 34,206,147, 36,171,217,138, 21, 43,116, 14, 14, 14,218,168,168, 40,108,223,190,157, +126,246,236,217, 53, 22,139,181, 69, 34,145,168, 42,227,180,211,233, 94, 28, 9, 10,170,223,162,111, 95,102,200,180,105, 10,240, +249,211,215,109,216, 16,148, 41,149,214, 96,104, 26,118,214,214, 41,235, 22, 44, 88,221,127,224, 64,233,171,123,247, 76,195,207, +157, 51,229, 81,212, 51, 3,202,249, 53, 80, 46,167, 88, 44,190, 29, 22,118, 23, 7,118,255, 6,173, 86, 13,137, 56, 9, 0,144, +149,157,135, 74, 68,214,167,156,140, 66,161,232,187,232,231,159, 31, 46,154, 25,232,248,125,135,142,248,240, 34, 2,218,156, 76, + 16, 58, 10, 28,130, 13,121,134, 0, 25,233, 50,204, 63,116, 34, 67,166, 80,244, 45, 99,144, 40,179,156,197, 22, 43,190,185, 25, +184, 66, 17,120, 34,179,143,172, 88, 38,230,230,224, 9, 69, 96,243,120,101, 77,224,254,140, 83, 38,147,245,235,223,191,255,203, +199,143, 31, 91,141, 29, 59, 22,223,125,247,221,115,165, 82,217, 14, 64, 65,117,235,147,166,105,241,247,223,127,207, 34, 8, 66, + 52,108,216, 48,126,102,102,102, 73,100,117,153, 76,134,203,151, 47,195,203,171,112, 85,255,171, 87,175,208,160, 65,131,114, 57, +199,205,143, 18, 3, 88, 62,179,191,243,186,135, 47, 36,211, 1,172,169, 83,207, 21, 55,175,222,192,221,155,225, 65,223,250,208, +155,187, 13,107,254,139,160,221,192,185,222,205,198,146, 34,115, 39, 28, 60,115,154,140,126,182,103,165, 66, 17, 89, 23,219,207, +206, 41,175,156, 4, 65,128, 97,152,207, 66, 57,144, 36,137,195,135, 15, 87,245,220, 79,236,222,189,123,210,196,137, 19,185, 18, +137, 4,111,222,188,129, 92, 46,135,137,137, 9,174, 94,189, 74, 1,216,122,248,240,225,171,135, 15, 31,238,130,194,213, 68,161, + 85,185, 62,133, 66,225,212,128,128, 0,188,121,243, 6, 79,158, 60, 57, 13,224,229,243,231,207, 79,191,123,247,110, 80,155, 54, +109,176,127,255,254,169, 74,165,114,119, 85, 56,105,154, 46, 29, 51,169, 56,227,195, 11,153, 76,246,109,120,120,120, 85,219, 93, +146,157,157,221,186, 72, 88, 39, 59, 56, 56,152,191,120,241, 2, 53,107,214,132, 86,171,109, 89,213,107, 41, 47, 47,239,183, 45, + 91,182,236, 29, 61,122, 52,126,249,229,151, 97, 39, 78,156, 24,214,173, 91, 55,116,239,222, 29,251,246,237,195,203,151, 47,215, +192,176,180, 98,101,157,251, 75, 0, 47, 29, 28, 28,166,184,186,186, 98,253,250,245,136,140,140, 92,189,124,249,242, 5, 47, 95, +190,132,151,151, 23, 63, 58, 58,154,170, 78, 31, 2, 0,230,230,230,230, 58,157, 14,231,206,157,123, 4, 96,230,176, 97,195,236, + 55,109,218, 52, 88, 36, 18, 33, 39, 39, 71, 25, 21, 21, 53, 20,192,249,191,187,175, 99, 8, 98,225,216,113,211,119,140, 27, 59, +212,196,183, 89, 19, 40,242, 83,160,148,165, 67, 81,144,134, 45,187,175,129, 32, 88,176,179,115,130,189,163, 11,146,146, 62,224, +254,197, 75, 26,185, 66,185,137,167,163,215, 84,204, 57,173,144,179,105, 33,167, 66,158, 1,165, 44,163,132,211,222,190, 70, 17, +103, 18,238,133, 95, 82, 41,229,242,223, 52, 12,241,235, 95,124,238,255,201,168, 90,174,195,210,144, 74,165, 51, 38, 76,152,208, +110,254,252,249, 54, 20, 69,145,214,214,214, 72, 74, 74,162, 78,157, 58,149, 35,147,201,102, 84,167, 52,108, 14,231,165,135,167, + 87,187,222,189,123, 83,189,122,245,228, 14, 31,221,133,109,103,111,143,188,220,108,196,190,137, 64,204,235,103,240,240,106,140, + 37,203, 55, 2,150,150,149, 38,146, 44, 74,171,211, 99,217,162, 57,199, 91,251,119, 54,247,106,208,152,219,164,174, 5,180, 58, + 10, 41, 41, 41, 56,127,238,133, 54,234,233,221,124,154,210, 12, 82,100, 25,150,130,231, 54, 64, 33, 27, 59,125,236,181,135, 87, +173,219, 50,123,235,206, 3,115,231, 79, 31, 43,108,227,215, 9,145, 55,246,227,116,200,113,185, 74,173, 89,199, 37,177, 33, 42, + 27,138,216, 42,214,129, 74,165,210,126, 58,158,170, 84, 42,237,151,182,244,190,125,251,144,158,158,174, 73, 76, 76,188, 66, 81, +212,137, 10,146, 61,127,134, 45,128,166,143, 90,125, 99,145,159, 95,151, 69, 87,175,154,140,156, 55, 79, 51,108,248,240, 57, 80, +171,181,224,241, 24,182, 80,200, 2,159,207,121,117,239,158,233,239,147, 38, 89, 19, 26,205,245, 3, 21,132, 13, 40, 3, 95,125, +213, 97,177, 69,171,109,219, 54, 24, 57,118, 38,148,165, 44, 90, 15,158,196, 66,173,133,193, 22,173, 34,124, 72, 76, 78,254,118, +250,194, 69,103, 6, 5,116,240,246,169, 85,155,111,231, 86, 27, 34, 71, 71,100,103,102,226,222,147, 24,221,242,227,103,162,138, + 68,150, 65,113,101,104,154, 46,156,228, 14,160,195,140,249, 32, 72, 18, 40, 10,227, 80,188,114,200,173,249,119, 32,216,108,232, + 25, 26,106,181,218,144, 73,127, 41,239,223,191,239, 55,108,216,176,208,144,144, 16, 86, 64, 64, 64,147,179,103,207,210, 95,114, +237, 40,149,202,111, 1,192,196,196, 36,193,210,210,210,121,244,232,209,208,233,116, 80, 40, 20,200,203,203, 67, 74, 74, 74,238, +232,209,163,181, 0, 96,106,106,202,235,223,191,191,121,101,156, 27, 79,137, 85, 51,251, 59,111,182,102, 39, 14,206,207,122,233, +102,205, 78, 76,248,214,135,222,188,241,148, 88,101, 94, 67,190, 34, 43,241,118,172, 68,126,117,199,193, 51,167,201, 17,125,250, +233, 93, 68,111,131, 76,236,153, 83,149,241, 18, 4,241, 89,112, 82, 3, 69,214, 71, 40, 40, 40, 88,176,120,241,226,238, 82,169, +212,165, 75,151, 46, 92,111,111,111, 60,124,248, 16, 33, 33, 33,212,131, 7, 15,146,229,114,249, 79, 0, 84, 0,174, 85,167, 78, + 61, 61, 61,221,216,108,118,177, 43,237,143,162,205,127,156, 61,123,118,208,216,177, 99, 81,187,118,237,250,209,209,209,124, 84, +225, 62, 98, 24,166,196,203,240, 53, 65, 16, 68,220,239,191,255,238,236,232,232, 72, 92,190,124,153, 34, 73,178, 58,150,155,125, +123,246,236,105,169,211,233,198,141, 31, 63, 30,254,254,254,160, 40, 10,135, 14, 29,194,158, 61,123, 12, 21, 89, 21, 34, 54, 54, +246, 89,114,114,242,247,115,230,204,193,250,245,235, 23,204,153, 51, 7,201,201,201,136,141,141,141,248, 18,222,252,252,124,229, +135, 15, 31, 4,173, 90,181,242,141,138,138,138,106,215,174, 93,131,177, 99,199, 98,205,154, 53, 76, 88, 88, 88,127, 0,151,255, +137,209, 59,230, 93, 78, 48, 71,207,190,186,124,197,111, 63,215,117,119,155, 56,102,212, 64,210,211,163, 1,228,121, 41,176,177, +117,128,139,107, 29,100,102,100,225,202,149,203,250,172,172,220,125,122, 22,177,236,221,187,156,212, 47,225,116,118,169,131,140, +140, 12, 92,186,116, 73,159, 43,205,223, 5, 29,107,121,116, 82,110, 58,140, 48,196,146, 53, 30, 21, 68,137,175, 8,182, 86, 86, + 86, 71,205,205,205,211,205,205,205,211,173,172,172,142, 2, 6,173, 62,232, 88,170,119, 32, 63,122,245,239,111, 2, 19,147,111, +193,102,207,178,180,178,186,108, 97, 97,145,221,182,109, 91,205,142, 29, 59, 84,209,209,175,104,177, 56,153,177,176,176,200, 43, + 57,190, 44,206, 79, 96,101,229,110, 38,116,106,240,179,133, 75,147,123, 34,167,250, 5, 34,167,250, 5, 22, 46,141,239, 11,157, +234, 47,181,178,114, 55, 51,168,156,229,160,142, 61,236, 60,108,177,213,203,142, 80,122,216, 98,107, 29,123,216, 25,124,238, 21, +187,253,244, 4, 1, 61, 10,151, 97,163, 26,156,197, 28, 52, 73,146, 7, 92, 92, 92,156, 80,181,128,117,159,113, 14, 7,106, 15, +231,243,199,157, 12, 10, 26,153, 16, 22, 54, 44, 63, 62,126, 72, 94, 92,220,192,136,227,199, 7,253, 49,104,208,240, 33,124,254, +248,254,128,187,161,156, 78, 78, 78,171,159, 61,123, 22, 98,232,171,148,240, 50,184, 62,221,235, 56, 95, 13,232,216,146,153, 58, +161, 47, 51,117, 66, 95, 38,160, 99, 75,198,189,142,243,213, 47,104, 35,130, 36,201,193, 2,129,224,168, 80, 32,136, 20, 10, 4, +145, 2,129,224, 40, 73,146,131, 81,241, 28,170,143, 56,109,108,108,158, 58, 56, 56,164, 87,229,101,107,107,251,188, 10,229, 28, +226,230,230,150,204, 98,177, 54, 86,241,158,174,136,211,195,212,212, 52, 78, 40, 20,166,148,126,153,154,154,150, 14, 12,101, 35, + 16, 8, 46, 8,133,194, 77,134,112,254,186,176,193,207,247,175, 77,121,249,235,194, 6, 63,127,186,111,218, 15, 86,163, 31,134, + 46,203,158,246,131,213,104, 67,202,105,111,111, 31,102,111,111, 47,177,183,183,151, 56, 56, 56, 84,248,178,181,181,125,106, 0, +167,137,153,153,217, 38, 51, 51,179,116,161, 80,168, 23,137, 68,233, 66,161,112, 35, 74,133,182,168,110,125,178, 88,172, 53,245, +235,215, 87,145, 36,185,247,147, 93,235,235,214,173,171, 98,179,217,235,170,200,105,222,166, 77, 27,253,139, 23, 47, 24,127,127, +127, 6,128,213, 87,108,119, 71, 43, 43,171,203,230,230,230, 31,204,204,204,182, 0, 16, 86,147,147, 0, 48,216,217,217, 57,162, +125,251,246, 10,103,103,231,112, 0,189,191, 98, 57,187,255,240,195, 15,244,135, 15, 31, 24,134, 97,152, 15, 31, 62, 48, 63,252, +240, 3,141,194, 64,145, 95,210, 39, 47,156, 52,105, 18,243,224,193, 3,230,193,131, 7, 76,120,120, 56,211,189,123,119, 26,192, +143, 95,216,207,227,107,157,187,119, 29, 91,247,111,234, 89,157, 24,218,207,143,190,118,126, 35,179,228,167,137, 76, 39,255, 6, +140, 87, 93,171, 51, 30, 30, 54, 30, 95,131,243,231,159, 38, 48, 29,191,175, 79,123,187, 91, 29,247,174, 99,235,254, 55,159,251, +127,163, 85, 11,127,245,132,179,255, 55, 45,126, 44,150,202, 70,141, 26, 53,144,157,221,210,132,205,246,227,243,249,237, 88, 36, +121, 43, 39, 51, 51,176,232,113, 75,255,119,153,106, 43, 28,208,221,193,171, 32, 37, 65,117, 56, 63,154,200, 94, 77,206,170,112, + 24,196, 89, 94, 82,105, 90,173, 78,181,161,168,167, 91, 80, 97, 29,124,196,233,236,236, 60,142,166,105, 55, 67, 11,196, 98,177, + 18,196, 98,241,238,234,212,103,189,122,245,152, 34,247, 54,241, 53,219,253,175,184,150,254,151, 56, 15,254,214,176,134, 87,195, +111,230, 70, 62,139, 94, 95,228, 86, 44,193,210,105, 86,102,126,237,219, 46,190,119, 51,236,151,165, 91,164, 5,255,240,185,179, + 96,224,156,182,175,192, 89, 28, 36,180, 74,156, 28, 14,103, 71,139, 22, 45,198, 61,124,248,112,175, 94,175, 31,255, 63,122,125, +118, 39, 73,114,142,167,167,103,147,216,216,216, 8,189, 94,191, 30,101, 4,138,172, 70, 57,127,114,115,115,155,204,229,114,249, + 50,153, 76,154,154,154,186, 24,192,137,127, 91,125,122,215,179,246,101,152,146,160,219, 43,223,188,207,121,252,213, 56, 25, 90, + 79, 51,228,138,216,248,236,231,255, 64,187,255,183,137,172, 93,127,199, 31,119, 52,114, 26, 57,141,156, 70, 78, 35,231, 87,231, + 52, 53, 62,225,159, 41, 0, 0, 32, 0, 73, 68, 65, 84,214,167,145,243,191,144,243,191, 18,108, 99, 21, 24, 97,132, 17, 70,252, +199, 65,105,172, 2, 35,140,248,215,161,180, 85,171,196,154, 69, 84,160, 74,171, 98, 18,172,142,178,189, 97,228, 52,114, 26, 57, +141,156, 70, 78, 35,167,145,243,127,142,243,191, 85,100,237,170,224,251, 95, 6,163, 89,213,200,105,228, 52,114, 26, 57,141,156, + 70, 78, 35,231,255,130,208, 42,243,187,209,117,104,196, 95,142,205,125,224, 12, 0,211,207, 66,252, 87, 28,111,132, 17, 70, 24, + 97,132, 17,255, 48,118,161, 28,215,225,191, 65,104,213, 0,240, 45, 10, 19,223,198, 0,184, 11, 64,250, 5,124,182, 0, 6, 18, + 4, 49, 0, 0, 24,134, 57,137,194, 85, 35, 89,134,252,216,196,196, 36, 93,165, 82,217, 23,125,206, 80,169, 84,165,115, 25, 16, +248,124, 53, 27, 83,234, 85, 38,220,220,220,210,213,106,181,189, 1,127,159,199, 48,204, 75, 22,139, 21, 41, 18,137,110,198,198, +198,134, 84,229,196,219,181,107, 55,146, 36,201,149, 0,160,215,235, 23,222,186,117,235,192, 95,216,110, 45, 93,107, 56,238,215, +234,180, 84,122,102,206, 98,124, 30,200, 15, 0,176,181, 7, 86, 19, 20,230, 22,125, 94, 55, 37,164,226, 56, 58, 85, 61,190, 2, +248,114, 56,156,169, 14, 14, 14, 93, 83, 82, 82,158, 2,152, 7, 84, 30,213,216,213,213,245, 71, 54,155, 61, 76,175,215,187,147, + 36, 25, 71, 81,212,225,228,228,228, 96, 99, 31, 98,132, 17, 70, 24, 97,132, 1, 98,235, 51, 84, 73,104,121,217,192,145, 1, 6, +131, 64, 39, 48,184, 78, 0,199, 98,178,145,102,232,239,187,121, 65,167,163, 10,255,147,203,130,254,242,123,214,174,174, 93,187, +186, 76,155, 54, 13,223,125,247, 29, 30, 62,124,216,106,223,190,125,163, 79,156, 56,241,146,166,233, 91, 0, 30, 2, 6,133, 82, + 16,162, 48, 78,203,208,174, 93,187,118, 92,185,114, 37,217,160, 65, 3, 40,149, 74,132,133,133,249,173, 91,183,110,211,253,251, +247,111, 0, 56, 82, 36, 8,202, 77,128,167, 82,169,236,139,147,113, 18, 4, 97,223,191,127,255,199,165,197, 85, 81,126, 53,130, + 97,152, 7, 4, 65,132,235,245,250,135,167, 78,157, 74,246, 2, 90, 78,112,227,158, 10, 76,208,186,124,202,169, 86,171,237,207, +253,186, 10,108, 62, 31,234,130,124,180, 26,245,255,162,247,250,207,115, 65,208, 20, 72, 48,210,118, 43, 54,189, 4, 16,153,154, +154,250,210,223,223, 63,161,170, 45, 76,146,228,202, 43, 87,174, 56, 49, 12,131,128,128,128,149, 0,254, 42,161,197,255,214,183, +241,173, 11,167,143,154,200,114,210,209,165,247,160,195,111,147, 51, 70, 2, 56,253,145,104,234, 10, 7,130,192,220, 73,171,142, +144, 0,176,237,167,161,243, 54,118,198,230,153,215,144, 6,160, 93,145,248, 1,128, 95, 1,220,218,218, 21, 14, 0,230, 79, 90, +117,132, 0,128,237, 63, 13,157,187,181, 43,126,159,114,185,202, 97, 43, 38,143, 28, 57,114,243,202,149, 43, 73, 39, 39, 39,136, +197,226, 46,245,235,215,247,204,207,207,175,143, 10, 38, 17,215,174, 93,251,120,155,246, 61,235,244, 29, 48, 88, 96,103,107,133, + 84, 73,150,249,241,163,123, 39,144, 15,194,186, 38, 38, 38, 14, 50,246, 33, 70, 24, 97,132, 17, 70,148,131,234, 71,134,111,234, + 4, 83,185, 22, 63,176, 73,226,199,214,190,245, 59, 12,233,214,134, 85,223,187, 30, 94,191,138,238,124,254,230,163,117,172,240, + 87,161,148,158, 9, 22,114,113,238,185,164,226,149, 48, 58, 10,236,107,231,142, 20,142,132,163,135,146,143, 31, 63,174,215,172, + 89,179,146,212, 48, 29, 58,116, 64,135, 14, 29,136,109,219,182, 53,190,118,237, 90,227, 61,123,246,104, 67, 67, 67,247,163,226, +248, 40, 83,235,214,173,187,110,243,230,205,124,127,127,127,240,249,252,146, 29, 34,145, 8, 61,123,246, 68,207,158, 61,201,212, +212,212,128, 11, 23, 46, 4,252,250,235,175,154,164,164,164, 57,248,255, 40,205, 21, 98,241,226,197,190,101,108,190, 66, 16,196, +123,138,162, 34, 26, 55,110,156,236, 9,212,155,208,237,187,235,147, 91,123, 8, 3, 23,236, 43,147,135,205,227,225,224,200,194, +177,186,180,208, 74,184,121, 25, 34,115,179,108,129,153,217, 75, 0,145, 0, 94, 50, 12, 19, 25, 23, 23, 23,253, 13,208,248, 91, + 43,214,254,189, 82,186, 81, 21,196, 22,146,147,147, 97, 97, 97, 97,234,239,239, 47, 33, 8, 98,105, 88, 88,216,215,158,144,215, +114,233,220,201, 92,105,226, 75,164,189,121,128, 89, 3,252, 4,129, 91,254,252, 69,165,209,157,174,232, 71, 4,193, 98,253, 26, + 78, 7,161, 48, 25,239,226,236,236,108,127, 0,176,177,177,225, 1,184,181,241, 17,186,205,108, 77,124, 73,108, 55, 46, 73,146, + 91,247,237,219, 55,246,199, 31,127, 44, 76, 29,113,239, 30, 68, 34, 17,150, 47, 95, 94,123,246,236,217,171, 41,138,154, 81,158, + 37,171, 77,251,158,117,126, 95,255, 75,253,130,156, 60,245,206,173, 39,158,212,240,241, 98, 77,154, 58,219,236,119,173,218, 81, +175,215,255,104,180,108, 25, 97,132, 17, 70, 24, 81, 21,107, 86,165, 66,203,211, 22, 7,154,250,120, 12, 28,210,221,143,223,208, +167, 1,184,252,255, 15,221,210,204,215, 23,205,124,125, 89, 65,178,130, 78,143,159, 60,235,116,234,218, 67,181, 66,151,116, 34, + 54, 11, 35, 13, 45, 85,113, 82,218,149,189, 29,218,203,115, 51, 76, 0, 64,104,105,175,250,233, 92,218,205,214,173, 91,195,197, +197,133, 27, 26, 26, 58,166, 18,161,245, 83, 76, 76, 12,159, 36, 43,142,135, 90,163, 70, 13,244,239,223, 31, 94, 94, 94,188,182, +109,219,254, 84,158,208, 50, 49, 49,201, 32, 8,194, 30, 0,172,173,173,245, 75,151, 46,141, 96, 10, 1, 0, 12,195, 48, 15, 88, + 44,214, 67,154,166, 31,253,249,231,159, 41,245, 1,251, 46,205,188,238, 78, 30,222, 95,192,156,218, 84,174, 72, 80,229,231,151, +185, 93, 32, 18,102,154, 10,133, 47,249, 2,147, 72, 20,230,242,138,116,113,113,137,174, 15,184,180,240,114,187,182,109,230, 80, +179,189,227,127,169,180, 46,155, 54,109,234,217,168, 81, 35, 19,189, 94, 15,185, 92,142,237,219,183, 91,152,154,154, 90,116,237, +218,117, 73,233, 11,192, 27,104,216,175, 6, 57,126, 89,170,126, 74, 53, 46, 36,203, 54,173,124, 19,251,247,236,106,238,251,109, + 27,188,189,117, 8, 57, 57, 5,200,203,149,129,166,233,207,226,250, 76,185,140,244,173, 61,176,110,219,130,161,243, 9, 22,139, +104,220,103, 30,122, 57,230, 77,223,177, 99,199, 43, 0, 28, 30,143, 87,250, 58,172, 97,234,236,179,174, 94,231, 54,216,190,112, + 56, 24,154,102, 0,172,171,130, 53,203,222,204,204,236,252,181,107,215, 90, 54,111,222, 28, 15, 31, 62, 68,124,124, 60, 38, 79, +158,172,153, 50,101, 10,119,196,136, 17,196,172, 89,179,166,253,250,235,175,167, 0,220,255,236, 70, 96,179,135,245,238, 59,136, + 39,203,205, 87,105,212, 90,141,181,173, 37,173,150,171, 20, 89,210,124,213,160,161,227, 52,175,158, 63, 26, 6,224, 51,161,245, +133,245,105,132, 17, 70, 24, 97,132, 1, 96, 24,166, 57, 0, 59, 0,153, 4, 65, 60, 41,253,189,232,144,226,108, 45,159,126,207, + 66,161, 87,202,166, 20, 93, 22, 10,167,251,216, 1,208, 3,120, 76, 16,132,244, 11,139, 88,241, 42,195,144,144, 16,166,244,123, + 41,161,197, 48, 12,195,232,178,223, 51,234,216,203,140,226,201,238,207, 94,202, 87,167, 25,201,227, 19,204,163, 35, 63, 51,158, +182, 21,103, 97,239,230, 5,221,208, 70, 96, 38, 53, 7, 51,163,173,165,234,241,227,199,161, 52, 77,135, 4,181, 1,195,188, 62, +194, 48,175,143, 48, 51, 91,129, 57,117,234,212,149,213,171, 87,135, 4, 7, 7,135, 0,168,108,158, 82,122,193,147,112,230,145, + 61,152,242, 16, 19, 19,195,236,216,177,131, 89,176, 96, 1,179,119,239, 94, 6,149, 68, 80, 15, 8, 8, 8,139,138,138, 98, 70, +140, 24, 17,129, 10, 2, 3,122, 3,194, 97,181, 29,223,168,143,111,210,106,126,108,200, 72,191, 55, 41,243,252,157,156,156, 62, + 42,207, 26, 15, 71,230,143, 22, 30,204,129, 78,205,210, 24,134,185,194, 48,204, 26,134, 97, 6, 49, 12,227, 5, 0, 77, 1,243, +222, 78, 54,239, 84, 39,126, 87,106,198,127, 91,105,222,187,166, 77,155,122,206,153, 51, 39, 71,163,209, 48, 9, 9, 9,204,206, +157, 59,153,235,215,175, 51,231,206,157, 99,252,252,252, 82, 75,149,215, 97,180, 87,173,116,205,158,101,234,234, 92, 69, 28,146, +252,227,201,245, 83,204,187,187, 39,153,199,199, 86, 51,135, 23, 13, 97,166,245,110,169, 53, 55,229,171, 0,180, 47,239,119, 83, + 90,163,158, 87,109,187,216,164,164, 36, 70,171,213, 50,163, 70,141, 98, 2, 2, 2,152,206,157, 59, 51, 29, 59,118,100, 58,116, +232,192,180,111,223,158,185,121,243, 38,147,154,154,202,116,108,211, 76,222,195, 27,190, 85, 40,154, 79,173, 90,181,210, 18, 18, + 18, 24,173, 86,203,132,134,134, 50,135, 14, 29, 98, 66, 67, 67,153,160,160, 32, 6,192,129, 73,147, 38, 41,165, 82, 41, 19, 16, + 16,144,130, 50,162,198,215,170, 85, 43, 58, 42, 54, 57,121,227,170,221, 55, 15,254,113,244,230,153, 83,215,111,158,191,250,248, +226,185,171, 79, 78, 60,122, 17,119,174, 86,173, 90,209,101,180,255, 23,213,167, 17, 70, 24, 97,132, 17,149,107,145, 34,161,213, +189,200,216,209,157, 97,152,142,159,124,239, 94, 36,156, 62,251, 30, 20, 20,180,160,244,247,226, 99,130,130,130, 22, 0, 96, 90, +181,106,117,148, 97,152,122, 95,161,248,227,203,120, 85,110,209, 42, 6,149,242, 24, 92,143,174,224,232,117,208,101,197,128,206, + 77, 2,132,142, 80, 18, 34,100, 75,146,240,230,238,233,138, 19, 73, 20,225, 82, 12, 56, 0, 66,163,163,163,241,230,205, 27, 36, + 39, 39, 67, 32, 16,124,118,220,189,123,247, 96,106,106, 10, 39, 39, 39,195,148,174,230,227,113,238,101,179, 90, 16,181,242, 71, +214,144,137, 8, 13, 13, 69, 70, 70, 6,184, 92, 46,120, 60, 30, 40,138,170,148,143,197, 42,204,248, 91,108,197, 42,235, 24,127, +128,205,183, 22, 93,216,182,100,134, 27,235, 65, 8, 71,249,225, 29, 82, 85,122,195, 44,121, 34, 33, 4, 66,129,196,212, 84, 80, +226, 46, 4, 16, 73, 16,196,219,166, 0, 71, 40, 50,185,176,127,197, 44, 71,242,121,168,137,242,221,203, 50, 57, 58,118,236, 56, + 1,192, 18,134, 97,114, 27, 53,106,228,176,114,229, 74, 43,177, 88,140,215,175, 95,227,196,137, 19,153, 84,225,137, 18, 12,195, + 44, 3,128,111, 1, 19, 75, 59,203,171,127,252, 60,195, 12,183,142,243,170,115, 21, 89,120,247,188,216,111,196,164, 41,155,103, +244,132,188, 64,137, 35,215,159,255, 31,123,215, 29, 22,197,181,190,223,153,221,157,173, 32,210,139, 10, 86,148,162,160, 40, 54, + 20, 73, 52, 49, 17,141, 37,198, 18, 75, 98,162,215,222, 35,106,140, 37,137,144,104,108, 81,163, 38, 49,150, 27, 11,118,177,183, +128,177, 43, 74, 81,196,134,128,176, 32,157, 5,182,207,156,223, 31, 44, 43, 34, 11, 11,154,223,205,205,221,247,121,246,153,157, +157,153,111,207,156, 51,115,206,123,222,243,157,239,224,228,173, 71, 3, 0,252,137, 26,252,222, 54, 92,194, 67, 32,231,237,193, +131, 7,223,142,137,137,113,248,229,151, 95,160,215,235,171,253,252,242,203, 47, 56,123,241,214, 52, 0, 55,205, 76,150, 91,179, +102,205,206, 94,187,118,205, 81, 42,149,226,204,153, 51, 40, 44, 44, 52, 42, 89, 99,199,142,165, 10, 11, 11,135,255,244,211, 79, + 67,158, 62,125,186,242,226,197,139,121, 40, 95, 11,242,165, 7,129,199,227, 61,210,235,181, 94,174,222,173,248, 67,251,247,232, + 81,146, 23, 7, 43,123, 63, 92,185,243,232,104, 97, 65,158,146,199,227, 61,170,124,254,155,200, 79, 11, 44,176,192, 2, 11,234, + 6,138,162,162, 8, 33,161, 20, 69, 69, 85,253,173,234,247,138,243,194,195,195,141,251, 21,215, 68, 68, 68, 44,175,180, 95,246, +134,146, 87,163, 51,124, 47, 3,131,236, 85,221, 73,234,187, 7,160, 78, 58, 12,198,163, 59,132,109, 6,128,231, 17,132,180,184, + 11,184,115, 98, 53,158, 37,254, 9,194,177,112,109, 29,104,110, 66, 84, 94, 94, 94, 80,169,202, 93,179,212,106, 53, 24,153,173, +106,214,248,145, 98, 0,224,248, 98,117, 37, 6,107,150, 65,235,238, 33, 8,204, 38,184,238, 92, 46, 84, 4,102,151, 95,247,205, + 39,159,128, 97, 24, 48, 12, 3,202,224,250, 99, 14,209,162, 12, 39,115,229,195, 87,213, 37,130, 42, 19, 9,126,223,189,120, 74, +160,232,105,188, 80,157,112, 5,153,106,142, 28,205,102,143,153,147, 94,169, 76,154, 33,145, 74,227, 37, 86, 50, 35,209,162, 40, +234, 17, 0, 16,129, 96,199,206,165, 83,252,100,217,143,101,170, 27,231, 32, 87,113, 90, 19,102,150,158, 56,113,194,137,207,231, +187,176, 44,139,180,180, 52, 36, 38, 38, 98,237,218,181,217, 10,133,162, 87,108,108,108,114,101,238,200, 74,132,123,119, 44,155, +222,156, 31, 23, 45, 86, 63, 74,168,243,211,227,208,118,224,187, 3,122,249, 31,155, 48,106, 33, 6,190,255, 14,198,244,242, 33, + 41,153,249, 42, 0,103, 12,210,107,109,200,136,141,141,237,211,179,103,207,127,183,111,223,222,155, 16,130,118,237,218, 97,248, +240,225,216,177, 99, 7,238,220,185,131,226,226, 98,237,233,211,167,215, 0,216,106,102,178,164,182,182,182, 39,207,159, 63,239, + 40,149, 74,113,250,244,105, 40,149, 74,184,186,186, 98,242,228,201,194,136,136,136,237,197,197,197, 67,195,195,195,197, 41, 41, + 41,235, 79,157, 58,213, 20,229,235,206,189,242, 16,104, 52,154, 45,191,239,216,182,110,242,148,169,141,206, 95,189,123, 78, 93, +162,176,241,240, 72, 47,118,180,181,178, 94,243,221, 82,119,141, 70, 51,161,250,252,252,163, 94,249,105,129, 5, 22, 88, 96,193, + 43,168,145,139, 84, 38, 79, 85,201, 86, 93, 72, 26, 0,101, 88, 88,216, 2,138,162,162,194,194,194, 22,132,135,135, 43, 1,100, +254, 21, 36,203, 72,180, 66, 67, 67,163,163,162,162, 16, 26, 26, 26,109,210, 4,199, 66,155, 18, 3,109, 74, 12, 36, 93,167,225, + 72,248,136, 42, 55,207,213, 59,117,253,151,157, 57,175, 86,171,249,219,182,109, 51,250,109, 1, 0,203,178,111,188, 20,235, 66, +180, 12, 68,239,149, 68, 52, 19, 89, 69,111,153, 57,180,139, 61, 91, 38,208,252,121, 20, 25,106, 78,191,242,161,182,236, 70, 33, +249,222,148,205, 67, 51, 38, 32,253,226, 89, 72,173,172,210, 63,139,137, 55,170, 88, 6,146,245, 4, 0,154,138,172,207,109,154, + 62, 48,200,133, 1,163, 57, 22,137, 76, 53,167,222,244, 84,183,213,196,195, 6, 66, 8,158, 60,121,130,178,178, 50, 92,190,124, + 25,251,247,239,207,169,134,100,161,153,200,234,143, 95,191,248,184,115, 3, 69, 22,163,185,113, 22,153,106,206,172,161, 46,135, +118, 3,187, 51, 52,117,154,162,121,146,183,187,180,198,140,207, 7, 97,245,175, 71,244, 26,167, 30,161,235, 14, 31,255,168, 68, +173, 93, 96, 38,201, 50,138,141,177,177,177, 62,177,177,177, 34, 0, 33,195,135, 15, 63, 62,100,200, 16, 68, 71, 71,227,232,209, +163,158, 0,228,134,243,150,161,124,161,236,239, 1, 60, 54, 37, 60, 50, 12,179,251,236,217,179,190,110,110,110, 56,123,246, 44, +148, 74, 37, 38, 78,156,168,153, 50,101, 10, 51,118,236, 88,170,168,168,200,168,100, 93,190,124, 57,207, 20,201, 2,128,140,140, +140, 19,251,247,238,236,214,179,103,207, 65,205, 61,219, 52,120,172, 40,126, 46,149,138, 37, 23,163, 47, 48, 55,174, 93, 90,159, +145,145,113,189,250,252, 60,103,118,126, 90, 96,129, 5, 22, 88, 96, 26,102,113,145, 42,202, 84, 93, 80,233, 58, 65,120,120,120, + 98,120,120,248, 75,138,215,107,162,234,172,195, 99, 21,109, 90,189,226,104,177, 69,105,175,222, 0,199,213,229,102, 95,249,205, +214,214, 86, 47,145, 72, 94, 34, 90,156,153, 54,243, 15,238,194,227, 73, 35,141, 74, 86,133,178,133,190, 99, 95,139,104,113, 28, +119, 25,192, 75,137,144, 58,181, 30,177,166,191,119,119,159,230,141,104,221,222,181,120, 86,166, 87, 45,190,175, 85, 37, 41,200, +128,123,213, 56, 89, 27,109,234,117, 16,203, 36,169, 18, 43, 89, 85,146,245, 20, 0,100,206,158, 67, 86,190,215,166,151,127,155, +150,180,126,207, 42,100,148,233, 74,194,238,105,181,143, 75,201, 1, 19,121,184,248,157,119,222, 89,108,111,111, 47, 94,183,110, +157,141,135,135, 7,244,122,189,166, 42,201,146, 58,181, 30,177,118, 96,219,238,173, 93,108,105,221,190, 31,145,174,100,203,214, + 62,214,109, 55,135,100, 57,216, 88,157,218,180,124,146, 68, 42, 18, 64,165, 82, 33, 98,227, 62,156,190,148, 16,154,155,112,232, + 20,128, 83,175,241, 64,126, 22, 26, 26,186,122,217,178,101,208,233,116, 24, 55,110, 28, 30, 61,122,116,250,254,253,251,107,221, +221,221,231,124,241,197, 23,110, 46, 46, 46,248,232,163,143, 24,157, 78, 55,214,132,141,239,126,255,253,247, 80,127,127,127, 68, + 71, 71,163,176,176, 16,174,174,174,152, 50,101,138, 48, 60, 60,124,123,113,113,241,208,229,203,151,139,159, 60,121, 82,163,146, +245,210,115,205,178,223,108, 94, 61,105, 78,167, 46, 65,244,195,135,201,250,180,192, 96,250,194,217,163, 49,246,246,246,219,211, +210,210, 94,228,231,160,118,117,206, 79, 11, 44,176,192, 2, 11,222, 12, 40,138, 58,102,240,187,122, 73,229,170, 74,194, 42, 20, +171,202,251, 85,207, 55, 28,127, 19,157,229, 45,213, 16,175,151,195, 59,132,134,134,154, 61,173,158, 43,205, 49,139, 60, 85,197, +251,109,160,107,100, 5,254,130, 96, 26,140,204, 86,213,127,217,153,243,166,206,149,201,100,102, 43, 90,156, 90, 85, 91,161,212, +137,104, 25,124,180, 78, 18, 66, 94, 34, 90, 54,206,173,131,231,125, 49,125, 77,208,144,190,116,246,231, 93, 81, 88,162, 86,127, +113, 87,207, 61, 43,171,153,100,149,183,226,186, 20,169,204, 42, 94, 44,147, 86, 38, 89,105, 0, 32,118,106, 25, 56,119,198,228, +141,111,141,232, 79,229, 76, 12, 66, 65,161, 82, 61, 39, 81, 79,101, 40,201,208,123,192,133,234,204,157, 63,127,126, 51,128,205, +193,193,193,217, 50,153, 12, 37, 37, 37,175,148, 65, 69,122,187, 15,233, 75,103,127,214, 25,249,165, 90,245, 23,137,122,100, 42, +185,221,181,145, 44,199,134,214,167, 54,125, 59, 73,154,249,236, 41, 24,134,129,149,149, 21,206,252, 25,143,220,196,195,175, 67, +176, 64,211,244,146,176,176,176,197,147, 39, 79, 70, 94, 94, 30,142, 30, 61,138,247,223,127, 31,187,118,237,242, 56,126,252,248, +234,144,144, 16,240,120, 60, 68, 69, 69, 65,167,211, 61, 48, 97,102,208,248,241,227,231, 12, 25, 50, 4,215,175, 95,135, 92, 46, +127, 73,201, 42, 44, 44, 28,190,113,227,198, 33, 41, 41, 41,181, 42, 89, 85, 16,216,172,101, 7,102,254,162, 31,160, 46,123,206, +207,201,184, 26,125,238, 12,125, 37, 63, 63, 95, 10,160,168,190,249,105,129, 5, 22, 88, 96,129,217,170,150, 41, 46,146, 99, 32, + 81, 57,213,237, 87, 34, 88,213,237, 83, 85, 84, 48, 77,149,227,119,254,202,123, 50, 75,209,226, 59,183,133, 62, 59,161, 18,209, +122,254,210,113,177,181,157, 89, 67,135, 58, 61,248,155,182, 26,227,104,137,243,242,242,196, 14, 14, 14,170,202, 4, 65, 42,149, +194,205,205, 13, 5, 5, 5,216,178,101, 11, 80,187, 83,180,190,193,144, 81, 8, 28, 49, 14, 55, 26, 11, 65,116, 90,163,178,181, +233,147, 79, 94, 34, 91, 12,195, 84,248,134,213,214,232, 94, 51, 40, 77, 87, 0,144, 14,158,205,191, 22,203,100,159,136, 29,154, + 56,204,152,244,153, 32,229,185, 26,231,131,230, 23,238,251,110,158, 85, 58,177,154,156,134,162, 75,181,216,123,252,193, 79, 59, +171, 42, 89,207,218,123, 54, 95, 40,150,138, 63, 23,218, 53,117, 9,155, 53, 73,144,146,173,166,206, 7,126, 81,188,255,251, 47, +164, 79, 96, 61,231, 25, 10, 47,152, 81, 60,139,223,127,255,253,197,132, 16,194,113,220, 34, 0,168,156,222, 89, 83, 62, 23, 60, +206, 82,225, 92,208,194,130,253,223,205,179, 78, 71,205,233,117,104, 55,176,187,179,109,131, 83,155,150, 79,150,202, 51, 82, 33, + 18,137, 96,109,109,141,244,236, 34, 8,248, 60,229,107, 62,111,162, 30, 61,122,204,155, 52,105, 18,226,227,227, 49,113,226, 68, +121, 90, 90,218,129, 61,123,246, 76,252,234,171,175,248,239,190,251, 46,228,114, 57, 86,172, 88,161,251,243,207, 63,151, 3, 88, + 81,237,243,200,231,127,246,245,215, 95,147,204,204, 76,234,201,147, 39,112,117,117,197,212,169, 83,133,203,151, 47, 55,250,100, +213, 69,201,170, 64, 70, 70, 70,244,233,179, 87, 48,224,196, 26,232,117,234,232,194,188,180,152,164,199, 5,209,118, 66,225,236, + 70, 29,218,213, 43, 63, 45,176,192, 2, 11, 44,120, 35, 42,214,141,154,246,255, 6,168,110,232,208, 44,162,245,224,199,133,159, +122,126, 58,121, 46, 36, 30,221,161,190,119, 16, 92, 73,182, 81,209, 18, 91,217,194,206,221, 27,133,165,106, 68,158,187, 5, 0, + 15,234,146, 42,133, 66,129,128,128, 0,108, 24,219,250, 45,149, 34, 79, 44, 1,160, 22, 53, 80, 29, 18,246, 56,127,252,248,241, + 50,142,227,118, 3, 56, 94,139,153, 37,190,190,190,235,127,248,225, 7,161,247,136, 79, 81,114,245, 98, 85, 5, 5, 18,137, 4, + 34,145, 8,113,113,113, 56,127,254,188, 6,192,146, 90, 10,244,154, 94,175,191,179,103,207,158,103,173,154, 55,234, 27,208,222, +111,218,130,249, 97,214,119, 47,158,198,162,229,235,185, 86, 29,223, 45,138,216,117, 72, 81,100,229,254,182, 82,126,255,182, 25, +183,122,167, 10,201,202,244,106,214,228,173,246,109,125,231, 46, 90,180,176, 65,226,197, 51,248,234,251, 77,196,211,191,119,209, +247,251, 15, 23,231, 74,155,190,163,122,158,116,221,156, 60,140,142,142,222, 12, 96,115,197,126,213,244,134, 45, 91,203,181,238, +212,183, 32, 98,215,254,210, 98,107,247,222, 53,165,215,209,123, 80,183,198,142,182,167,126,252,230, 95,210,172,140, 52,136, 68, + 34, 88, 89, 89, 33, 77, 94,136,197,107,246,150,106, 57,174,239,235, 18, 45,107,107,107,145, 86,171,197,134, 13, 27,144,150,150, +214, 21, 64,218,205,155, 55, 55, 13, 27, 54,108, 93,187,118,237,188, 18, 19, 19, 31,148,148,148, 76, 6,144,100,202, 72,195,134, + 13,187, 58, 58, 58, 82, 87,174, 92,193,191,254,245, 47,205,212,169, 83,153, 49, 99,198, 80, 5, 5, 5,245, 85,178, 0, 0,141, + 26, 53, 10,238,243,118, 23,116,239, 51, 49, 90,163, 42,140, 73, 73,218, 30, 77,147, 75,226,250,230,167, 5, 22, 88, 96,129, 5, +255, 51,168, 95, 96,240, 96,128,223,218, 30, 19,124, 27, 49, 89, 59,190,155, 74, 20,143, 47, 19,229,245,205,164,248,224,231,228, +216,138, 49,228,248,143, 51,200,196,126,190,196,203,137,202,106,109,143, 9,193,175, 18,183,151, 86,247,126,191, 13,116,125, 90, +130,244,105, 9,210,175, 53,116, 0, 22,116,232,208,225,208,148,192, 23,113,180,166, 4,130, 0,248, 23, 0, 43, 19,201,170,110, +197,112, 87, 0, 91, 2, 2, 2,244, 23, 46, 92, 32,247,135,246, 38,177, 94, 14,100,242,228,201,228,171,175,190, 34, 35, 71,142, + 36,142,142,142,122, 67, 70,184,214,102,115,192,128, 1,141, 1,160, 73,147, 38, 13, 59,122,183,202,138, 59,119,148,196,236, 88, + 71,126,157, 50,152,116,110,231,157,235,226,213,243,142,196,181, 77,251, 90,178,207,104,211,197,197,101, 62, 33,164, 47, 33,196, + 21, 0, 60, 61,237,173, 58,120,181,202,188,115,246, 40,185,184,115, 61,249,117,202, 96,210,197,207, 39,175,177,119, 72,146,216, +201, 43,208, 28,155,213,161,218,244,182,245,202,117,110,213,237,118, 13,233, 53,218,108, 30,248,209,225,103,153,217,228,218,181, +107,228,248,241,227,228,226,197,139,100,199,158,195,196,189,211,208, 18,135,118, 3,187,215,225,209, 49,149, 78,155,126,253,250, +145, 7, 15, 30,144,247,222,123,143, 0,176,169,167,205, 67, 41, 41, 41, 36, 33, 33,129, 44, 88,176,128, 0,216, 54,105,210, 36, +101, 81, 81, 17,233,221,187,119,154,129, 96,241,235,147,206, 22,205, 26, 69, 12,234,223, 99,201,148,127, 13, 9,126,221,252,124, +131,176,216,180,216,180,216,180,216,252, 95,176,249,223, 12, 87,131,170, 85,177,237, 96,150,162, 21, 13,232,145,135,205,109,157, +180,255, 94,190,226,199,217, 27, 54,111,155, 59,111,218,103,178, 30, 65,125, 16,127,246, 55,236,143,218, 83,170, 82,107, 86, 48, + 60,252,144,144,135,178,228, 90, 82, 97,136,163,245, 18, 98, 99, 99,165,118, 45, 95,196, 96,122, 88, 30,155,117, 83, 29,111, 80, + 14, 96,252,173, 91,183,126, 8, 9, 9,249,246,243,238,129,131,167,116,123, 11, 58,157, 14, 59,118,236, 64,106,106,234, 1, 0, + 11,205, 85,220,226,227,227,115,125, 90,122, 76, 23,240,248,115, 39,143, 28,228,152,243,232, 46,158,221,139, 5, 0,168,213, 74, + 93,214,131, 24,255,186, 36, 78, 34,145, 92,115,116,116,188,239,232,232, 88,208,186,121,147,241, 34, 8, 22, 77, 28,254,129, 83, + 94, 74, 18,210, 19,203, 71, 70,213,170, 50,237,179, 7, 23,188,234, 83,186, 30, 30, 30, 34,153, 0, 19,170, 77,175, 70,165,203, +126,152,212,222, 28, 59,101,106,205,242,165,171,119,188,243,205,220, 79, 68, 13, 26, 52,192,173,132,135, 88,180,106, 87,169, 82, +163,235,155, 27,127,232,141, 12,143, 17, 66,160,211,233,204,158,232, 96, 2,243,252,253,253,219,124,251,237,183,158, 99,199,142, +197,235, 42, 89,149,241, 56, 37, 35,172, 81,147, 22, 62, 15,239,223, 10,177,147, 48,255,126,157,252,180,192, 2, 11, 44,176,224, +127, 6,253, 12, 98,206,248, 74,219,216, 90,137, 86, 5, 18,158,163, 12,192,178,230,188,146, 77,243,191, 93,189,152,166,214,124, +194, 17,242,155,158,198,210, 39,121,200,121,205,196,149, 9,248,208,191, 51,112, 36, 31, 0, 4,252,250, 53,144, 6, 60, 0, 48, +228,231, 75,215, 59,253,124,233,250,151,134,223,190, 1, 80,167,177, 92,107, 62, 18,130,124, 90, 52,234,209,193, 87,204, 99,149, +120,118,239, 17,242, 75, 85, 56,147,152, 90, 72, 19,250,183,186, 38,234,201,147, 39,127, 0,128,179,141,244, 94, 15,159,150,238, + 61, 3,124,165, 2, 74,131,103,119,111,161, 72,169,193,233,196,212, 34, 80, 84,189, 29,170,223, 84,122,179,227, 15,223, 56, 2, +170, 55, 69, 81,103, 23, 76, 25, 33, 90,188,106,247, 27, 37, 89, 0,202, 50, 50, 50,242,202,202,202,236, 51, 51, 51, 53,168,127, +144,184,135,197,197,197,237,102,204,152,177,108,206,156, 57,115,191,251,238, 59,166, 62, 62, 89,166, 80,144,145,122,176,167,239, +155, 43,127, 11, 44,176,192, 2, 11,254, 39, 48,190,202, 22,102, 19, 45, 35, 97,120,142, 28, 0,147, 91,180, 32,179, 30, 63,134, +230, 77,165,172, 58,165,235, 53,113, 3, 64,255,122, 95, 77, 83,138,171, 15, 82, 75,174, 61, 72, 45, 1, 71, 8, 71,136,154,166, +145, 94,170,213, 46,127,240, 36,163,254,179,238, 40,138,189,241, 48, 77,121,243, 81,186,138,112, 28,225, 8,209, 80, 20,178,116, + 58,110,121,226,147,212,195,127,135,244,230,198, 31,186, 20,165,167,122, 92,186,150, 48,171,180, 84,187, 62,247,222,161,203,111, +176, 92,116,241,241,241, 31,119,237,218,245, 83,150,101, 55, 1,208,189,134, 45,141, 94,175,159, 23, 17, 17,113, 32, 62, 62,126, +239,229,203,151,229,111,130,100,253,165,229,111,129, 5, 22, 88, 96,193, 63, 21,245, 91, 84,218, 20,222, 36,201,250, 59, 34,225, +225,211,128,191,194,110,226,195,167,109,255, 27,210,155,125,239,224,205,108, 96,248, 95,148,189,167, 89,150, 61,253, 38, 73,245, +201,147, 39,155,161,154,101,117,254,110,229,111,129, 5, 22, 88, 96,193, 63, 22,227, 77,145, 47,190, 37,111, 44,248, 7,128,188, + 41,146,101,129, 5, 22, 88, 96,129, 5,245,128, 73, 69,139,130,233,153, 3,103,235,240, 7,245,153,125,112,214, 98,211, 98,211, + 98,211, 98,211, 98,211, 98,211, 98,243,127,206,230, 63, 17,174, 40,119,136, 63,102,216,214, 72,190,222, 36, 44, 83, 95, 45, 54, + 45, 54, 45, 54, 45, 54, 45, 54, 45, 54, 45, 54,255,233,168,214, 17, 30, 40,119, 30,182,192, 2, 11, 44,176,192,130,255, 38,136, + 12,159,250, 30,183,192,130,191,154,108, 25, 9, 87,125,124,180, 90, 25,182, 15,255,194,196, 78,113,117,117, 29,239,231,231,231, +205, 48, 12,173, 80, 40,150, 94,184,112, 97, 73,213,147,122,248,240,111,242,104, 52,126,241, 11, 5, 80, 60,128,166,193, 18, 60, +187, 24,167,236,104, 41,247,191, 53, 60, 36, 13, 28,143, 80, 52, 79,200,234,181, 96,117, 90,148,187, 91,149,131,227,244,169,172, + 86,253,174,169,139, 93,252, 7,185,235, 89,238, 59,128,108, 0,232, 73, 0,183,145, 2,127, 34,129,254, 39, 10,188,127,129, 71, +190, 7, 75,125,193, 23,240,230,203, 99,247,165,255, 19, 50, 44, 50, 50,146,247, 58,215, 15, 29, 58,180,218, 5, 68,221,220,220, +162,164, 82,105, 75, 83,215,149,150,150,202,229,114,121,200, 63,252,121,236, 9,224, 71, 0,190, 85,126, 79, 2, 48, 29,192,185, +215,253,131, 96,128,239, 12, 76, 96,128, 47, 0, 64, 11,124,159, 13,108,142,254, 27,249, 24, 58, 58, 58,198,240,249,124,207,210, +210,210, 82,133, 66,209,194,218,218,250,177, 76, 38,147,233,245,250, 7, 57, 57, 57, 61,107,186,150,148, 79, 74,169, 21,109, 1, +235,100, 96, 24, 75,211, 83, 5,192, 6, 53,199,109, 50,212,224,230, 44,112, 59, 9, 47,150,231,154, 11, 96, 99, 29,143, 91, 96, +193, 95,129,215,154,117,216,186,188,126, 64, 48,128,158,157, 58,117,114, 46, 45, 45, 69, 82, 82, 82, 54,128, 24, 0,209,134, 79, +242,155, 72, 41, 77,211, 43, 87,175, 94, 61,123,234,212,169,198,197,160,227,226,226,224,239,255,106,140, 80, 30,141,198, 23,142, +158,117,186, 17,159,140, 78,189, 63, 52, 16, 45, 26, 40,149, 35,164, 79, 96,125,147, 96,109,107,107,187,148,162,168,161, 52, 77, +215, 90,105,112, 28,199, 18, 66, 34, 11, 10, 10, 22, 3, 80,212,229,143,100, 82,145, 78,207,178,213,254, 7,159,199, 99, 75,203, +212, 38,195, 94,216,217,217, 93,166,105,186,121,229, 5,179,129,151, 23,208, 54,117, 76,175,215, 63,203,205,205, 53,135,132,138, +105, 62, 51,157,162,152, 62,160,185,214, 0, 5, 10,116, 50,199,106,206,112,122,237, 90, 0,170,215, 33, 89,174, 77, 90, 92,156, +185, 48,162,113,194,189, 36, 44,152, 50, 18,223,253,184, 13,243,167,127,138,181, 91,118, 97,250,248, 17,240,241,241,173,177,214, +229,192, 44, 95, 56,109,104,239,240, 13,123,131,230, 79, 30, 42, 10,223, 16,217, 99,193,148, 97,194,229,235,247,246, 88, 48,229, + 35, 81,248,250,189, 65,243,167, 13,149, 44,223,184,143, 3, 48,170, 62,137, 28,225,233, 86, 74,233,245,213,246,140, 9,159,175, +222,245, 32, 83,246,159,120,163,199,142, 29,235,167, 84, 42,111,141,236,211, 33,162,125,235, 70, 25,213,157,147,151,149,209,232, +241,253,216, 48, 1, 35, 9,248, 32,108, 91, 92,141,242,128, 72,212, 60, 41, 41,201,147,227, 56,176, 44, 11,189, 94,111,220,106, + 52, 26,244,236,217,243, 77, 77,156,233, 15, 96,105,249,203,138,112, 0,123, 95,195,150, 21,159,207,159, 41, 20, 10,131,245,122, +189, 55, 0, 8, 4,130,123,106,181, 58, 90,175,215,175, 6, 80, 82, 71,123,107, 50, 50, 50,124,172,172,172,160,213,106,141, 11, +208,243,120, 60, 47,119,119,247, 13, 42,149,202,243,117,111,222, 25,152,208, 45, 40,104,237,152,217,179,121,202,152, 24,172,221, +186,117, 13,138,139, 1, 96, 67,109,215, 10,133,194, 83, 52, 77,123,212,229,255, 56,142, 75,213,104, 52,239,214,229, 26, 62,159, +239,153,153,153,233,228,230,230, 6,133, 66, 1,153, 76, 38,171,216,127, 29, 68, 3, 84, 95,160,167,158,199,155, 97,239,224,208, +227,214,233,211,178,182,109,219,210, 60, 30,111, 62,204, 15, 82, 45, 2,176,130, 16, 34, 49,180, 23,107,187,116,233,210,149,162, + 40, 61, 0,194,113, 28,125,237,218,181, 17, 28,199,241, 13,117,222, 10, 0, 91, 1,168, 45, 60,192,130,255, 7, 53,107, 75, 93, +137,214,113, 0,193,157, 58,117,146, 12, 31, 62, 28,193,193,193,240,244,244,132, 88, 44, 46,175,196,243,242,156,111,223,190,253, + 81, 76, 76,204, 71, 71,143, 30,197,221,187,119,149, 0,254, 4, 80,237, 75,253,118,104,208, 84,177,149,104, 29, 0,228, 60,203, +147, 63,123,242,124,157, 92, 46, 95, 1,160,114,136,240, 22,163, 70,141,154, 53,109,218, 52, 68, 69, 69, 97,215,174, 93, 80,171, +213, 80, 40,106,224, 47,101,207, 81,112, 62, 2,144,165, 0,105,209,128,212, 9,144, 57,215, 59,167,108,109,109,151, 78,159, 62, +125,134,143,143,143, 49,138,185, 78,167,131, 94,175,135, 78,167, 67, 65, 65, 1,102,205,154, 85,222,208, 18, 2,142,227,112,226, +196,137,169,227,199,143, 71, 65, 65,193,204,234,108,118, 9,104,114,147,166,232,198, 21, 90, 13, 97,217,103, 87,111, 63,235,168, +103, 89,158, 74,165,173,118,165,114,177,152,169,145,228, 9, 4,130,198,119,143, 28,113,162,133, 66, 16,150, 5, 56, 14,132,227, + 12,217,105,248,144,242,223, 8,203,129,232, 88,112,122, 14,122,165, 26,129,147, 38,153,147, 21,221, 4, 66,201,174,143, 63,159, +237,210,185, 75, 23, 65,211, 38,110,208,179, 28, 30,165, 60,115,185,117,243,106,247,200,237, 27, 38,106,148,138, 17, 0,234, 21, +103, 75, 40,109,112,122,253, 79, 63, 55,190,113, 59, 1,231, 46,196,224,236,249,104, 0,192,169, 11,151, 43, 8,119,173, 69, 5, +125, 73,187,233,227, 6,138, 34,214,239, 22, 76, 31, 55,136,247,221,250, 61,130,105,159,126,192,139, 88,183,139,153,246,233, 7, +188,136, 31,119, 49,211,198, 13,228,133,175,253,213, 15,128, 45,128, 2, 83,198, 76,149, 17,165,215,139,254,253, 56,155, 7, 0, + 57,155, 54, 65,247,252, 57,220, 22, 47, 6, 0,124,220,194,217,236,161, 9, 7, 7,135,155, 2,129,160,113,109,231,233,116,186, + 90, 73,240,216,177, 99,253,149, 74,229, 77,189, 94, 79,248,124,126,216,200, 65,239, 28,234,219,195, 63,175,242, 57,113,113,119, +236,151, 47, 63, 50,112,239, 45, 5,249, 40,192,250, 86,212,202,177, 29, 67,231,108,187, 83, 67,131, 76,171,213,106, 60,120,240, + 0,149, 23,121,175, 4,182,158,175, 20, 13, 96,173,189,189,125,231,188,188,188,143, 1, 44, 40, 46, 46,246,227,241,120,176,179, +179, 91,160,209,104, 30,217,216,216,252, 82, 84, 84,116,217,160, 26,153,187,100, 64,207, 6, 13, 26,236, 56,120,240,160,109,135, + 14, 29,232,220,220, 92, 52,107,214, 12,249,249,249,129, 49, 49, 49, 1,227,198,141, 27,167, 80, 40, 70, 27, 58,131,230,162,141, + 84, 42, 37, 99,198,140,161, 88,246,197,237,254,250,235,175,120,183,173,190,165, 99, 67,105,153, 74, 67,138,206, 61,176,249, 23, +195, 48,127,166,166,166, 22,213, 53, 51, 24,224,139, 49,179,103,243,172,158, 62,133,213,157, 59,248,184,184,152,255, 93,185,186, + 85, 43,209,162,105,218, 99,199,174,223, 60,133, 66, 33,244,122,189,145, 12, 86,212, 81, 58,157, 14, 90,173, 22, 58,157, 14, 44, +203, 66,167,213, 33,252,155,239,235, 93, 23, 74,165, 82,169,171,171,107,182, 84, 42,149,190, 38,185,116,207,167,233,207,219, 7, + 4,140, 95, 60,112,160,248,250,245,235, 98,154,166,161,215,235,177, 98,197, 10, 61, 33,164,161, 15,208,224, 46, 80, 92, 87,219, + 34,145,136,191,125,251,246, 17, 66,161, 16, 0,160,209,104,208,182,109, 91,202,210,230, 91,240, 31, 36, 91,175,168, 92, 53, 17, +173,247,138,139,139,193,178, 44,172,173,173,193,227,189,220,238,219,219,219,163, 79,159, 62,232,217,179, 39,134, 15, 31,142,187, +119,239, 74,134, 15, 31,222,199,148,177,145,179, 67,209,196,211,217,208,152,112,174,151,142,221,142,248,245,235,125,142, 89, 89, + 89,179, 43,157, 54,110,194,132, 9, 84, 94, 94, 30,134, 14, 29, 26,163, 86,171, 7,160,134,151,143,229,240, 44,100,248,199,224, + 8, 37, 89,125,237,103, 74,163, 82, 18,154,166,149, 21, 67,135,245,201, 37,138,162,134,186,185,185, 97,247,238,221,208,104, 94, + 13, 23,214,160, 65, 3, 36, 38, 38,190, 80,213,120, 60,116,233,210,133, 71, 81,212, 80, 0, 51,171,183, 73, 55,190,116,227,169, + 83,197,126,104, 31, 95,166, 75, 0,157,157,153, 93, 74, 0, 80, 11, 23, 46, 52, 18, 55, 0, 88,186,116,169, 57,233, 4, 45, 16, + 32, 39, 58,250, 69, 69,204,167, 65, 51, 20, 40, 1, 64,243,203, 71, 81, 65, 0,194, 2,156, 30,224,116,128,216,181,137, 57,217, + 16,216,200,221, 51,106,249,170,141, 13,213, 58,130,221,135,207, 33, 37,229, 9,120, 52,141, 22, 45, 61,241, 78,175, 30,130,128, + 78, 93,155,124,191,100,246,209,204,180,135,239, 1,184, 94,231,140,230,136,184,165,187, 3,126,249,245, 22, 28,109,173, 48,116, +224,251,144,136, 69,248,238,199,223,240,205,252, 41,240, 57,211, 49,121, 0, 0, 32, 0, 73, 68, 65, 84,108,225,129,205,107,190, + 53,121,185,141,141,205, 50,111,207,150, 30, 27,183, 31,131,183,151, 23,111,227,142, 99,240,246, 49,108,125,189,121, 27,119, 28, +131,143,175, 15,111,227,142, 99,240,243,109,211,244,166,252,218,178,252,252,252, 41,166,243,179, 74, 25,189, 83, 94, 70,130, 18, +206, 88,105, 63,157, 56, 17, 0,140, 68,171, 46, 16, 8, 4,141, 51, 51, 51,157,106, 59,175, 54,213,192,160,100,221,212,235,245, +120,254,252, 57, 85, 88, 88, 72, 26, 54,108, 56,240,228,230, 5, 7,223, 13,242,207, 7,128, 59,119,238,216,133,135, 47, 31,184, +231,102, 49,148, 87,215, 83,255, 62, 18,205,125, 60, 32,248,230,225,136,177, 1, 48, 44, 9, 81, 21,106,181, 58,165,125,251,246, +196,240,189,145, 72, 36, 98,170, 60,111,110,173, 90,181,122, 69,181, 54, 99, 72,113,237,149, 43, 87,166,248,248,248,192,203,203, +235,114,231,206,157, 27,200,100, 50,156, 60,121, 18,222,222,222,190, 13, 26, 52,184, 22, 25, 25, 41,152, 55,111,158,255,214,173, + 91, 1, 96,170, 25,217,217, 59, 36, 36,100,119, 84, 84,148,152, 97, 24, 40,149, 74, 36, 38, 38,194,198,198, 6, 66,161, 16, 31, +124,240, 1,175,123,247,238,246,189,122,245,218,159,156,156, 60, 2,117,152, 1,165, 82,169,200,130, 5, 11, 32,149, 74, 33,149, + 74, 33,147,201, 32,147,201, 96, 37, 6,181,105,186,187,100,218,150, 66,201,204,197,155, 34,118,108, 92,114,161, 73, 19,238,171, +244,244,244,194,186, 62, 11,202,152, 24, 88,221,185, 3, 84,122,119,205,133,141,204, 14, 97, 97, 97,181, 41, 82, 96, 24, 6,221, +186,117,171,213,158,157,157,221, 1, 62,159,255, 82,207, 84,175,215,139,195,194,194,216,228,228,100, 25, 77,211, 50,142,227, 16, + 22, 22,198,234,245,122,177,147,147,211,101,142,227,178,115,115,115, 7,215,100,183, 23, 32,190, 12, 12,162, 4,130,153,174,110, +110,205,130, 91,180,144,158, 61,123,150, 7, 0, 30, 30, 30, 68, 46,151, 23, 30, 62,124, 88,193, 7,126,242, 32,100,123, 29, 72, +150, 26,192, 92,154,166,215,138, 68, 34,126,211,166, 77, 83, 23, 45, 90,116,197,160,144,130, 16, 66, 55,109,218, 52, 80, 34,145, +120,168,213,106, 61,202,135, 14, 45,106,214, 63, 0,132,144,128,114,222,110,132, 6,128,176, 66,192, 47,111,237,224, 80,229,119, + 0,200, 53,116, 20,157, 77,236,231, 1,184, 11,160, 13, 0, 39,195,177, 27, 20, 69,229,215, 35,153,166, 21,173,168,168, 40, 99, + 23, 54, 52, 52,212,216,176, 88, 91, 91,227,198,141, 27,160, 40, 10,214,214,214,104,208,160, 1,108,108,108, 80, 92, 92,140,187, +119,239, 34, 41, 41, 9, 79,159, 62, 5, 69, 81,104,209,162, 5, 42, 30,246, 74, 48, 86,112,191,255, 16, 5,177,149, 8, 20, 5, +116,120,203, 15,126, 61,219,162,211,245,199,211,111,158,165,182,200,229,242, 7, 0,248,109,219,182, 29,215,165, 75, 23,172, 90, +181, 10,106,181,122,149, 9,146,101,180,121,241,174,190, 35, 0,184,186,186,206,217,121,242,145,116, 84,223,150,101,114,185,124, +101, 61, 50,231,165,138, 56, 55, 55,215,236,181,248, 56,142, 67, 65, 65, 65,141, 54,171, 42, 4,171,215,174,111,168, 40,202,198, +215,223,237,132, 78,167,195,236,217,179,193,113,156,241, 83, 88, 88,104, 86, 58, 9,203,190,170, 29,208,229,163,167, 20, 31,112, + 31, 86,206, 43,210,118,175, 7, 69, 0,138, 5,240,234,125, 85,109,132,196, 60, 70,178,103,201,119,235, 26,198, 38, 61,195,225, +115,177,208, 22,103, 64,126,231, 96,185,228,216,109, 4,246,170,121,232,236,215, 18, 51, 22,126,111,251,229,140,209,123, 52, 74, +133, 23, 94, 30, 70, 60, 91,251, 75,195,226,235,101,203,176,101,221, 42,124,191,106, 29,138,139, 10, 33, 16, 56, 24, 42,122, 22, + 44,203,214,124,239,132,244, 13,155,254, 9,245,221, 79, 7, 16,232,227,138,253, 39,175, 35,168,189, 7, 14,158,190,137,158, 1, +205,112,248,108, 44,222,234,220, 18,199,163, 19, 48, 99,194, 8,106,196,169,173,125,235, 82, 70,107,214,172,111,168, 40,206, 70, +212,183,219,241,124,195, 6,164, 78,153,130, 64,195, 57,215, 41, 10, 76,227,198, 0, 83,123, 25, 85,197,189,123,247,160, 86,171, +171,235,153,195,219,219,187,214,114, 87, 42,149,183,244,122, 61,201,206,206,166,178,179,179, 33,147,201,168,196,196, 4,214,215, +183,237, 32,146,180,239,103, 0, 8, 15, 95, 62,104,239,173, 98,148, 93, 94, 7,229,149, 31,193, 52,139,163,183, 44,157,160, 29, +191,120,243,173, 74,239,232, 75,233,204,202,202,122, 47, 43, 43, 11, 0,208,188,121,243,164,228,228,228, 54, 21, 67,205,134, 33, + 68, 70,175,215,123, 86, 12, 39,234,245,122,168,213,106,244,238,221,155, 87,211,189,219,218,218,118,241,246,246, 70,108,108, 44, +214,173, 91,103, 23, 18, 18,130,135, 15, 31,130,162, 40, 44, 95,190,156,242,241,241, 17,228,230,230,226,221,119,223,197,129, 3, + 7,186, 21, 23, 23,215,150,159,214, 50,153,108,235,209,163, 71,197, 52, 77, 67,161, 80,128,227, 56,116,239,222, 29, 52, 77, 35, + 33, 33, 1, 11, 23, 46,196,129, 3, 7,112,232,208, 33, 73, 64, 64,192,214,178,178, 50,111,188, 60,172,111,170,140,136, 74,165, + 34, 34,145, 8, 34,145, 8, 98,177, 24, 98,177, 24, 66,161, 16, 37, 42, 96,252,234, 84, 53, 79,236,192,249,182, 15,106,249,201, +180,229,244,202, 69,159,158, 7,112,216,220,103, 30, 40,247,201, 90,251,219,111,235, 62, 46, 42,162, 1,224, 23,138,226,180,132, +124,111,206,251, 14, 0, 37,170, 34,120,180,104,140,253,123, 14, 97,200,176,129,213,146, 44,129,128, 1, 35, 16,160,129,157,172, + 86,155, 12,195, 56, 39, 37, 37,217, 11, 4, 2, 16, 66,192,178, 44,180, 90,109,246,151, 95,126,233,216,175, 95, 63,235, 19, 39, + 78,208,253,250,245,227,108,109,109, 75,175, 95,191,254, 92,175,215,219,247,232,209,195,164, 77, 41,224,167,178,105,181, 86,200, +211,251, 69, 44,152, 44, 26, 61,122, 52,239,147, 79, 62, 65, 90, 90, 26,198,141, 27,167, 58,115,230,140, 38, 75, 46, 63, 44,228, +184,245, 90, 32,206,220, 58,185, 10, 54,250,249,249,117, 56,120,240,224,167, 97, 97, 97, 55,231,204,153,243,117,229,131, 43, 86, +172, 88,118,252,248,113,143, 65,131, 6,237,184,115,231,206,198,186,212, 75,175,219,118, 88,108,190, 30, 76,113,145, 10,113,148, +162,168,168, 74,117,118,104,197,126, 88, 88,216,130,240,240,240, 68,138,162,162, 42,255, 94,113,158,161,179, 24, 85,221,190,225, + 90,187,249,243,231,183,141,136,136, 88,222,181,107,215,221,151, 47, 95,126, 2,160,174, 68,171,102, 31,173,138, 27,170,124,147, + 85, 26, 53, 20, 23, 23,163,184,184, 24,233,233,233,216,180,105,147,225,133, 22,128,207,231,131,207,231, 27,253, 25, 76,225, 92, +212,159, 63, 2,248,177, 67,135, 14,130,248, 43,145, 39,190,216, 50,237,237,142,189, 59,240,110,157,139,255, 16,229,235, 17,190, + 55,102,204, 24, 7, 0,216,190,125,123, 46,128, 19,255, 33,214, 28,249,224,193,131, 25,174,174,174, 70, 31,149,202,195,135,122, +189, 30, 98,177, 24, 21,190, 44, 42,149, 10,155, 54,109,210, 19, 66, 34,107,176,137,228,196,243,120,144,120,161,252, 58,142, 3, +199,190,184,126,201,146, 37, 32,132, 24, 27,251,137, 6,229,164, 86,146, 87, 93,158,147, 42,219, 42,191, 19,150,173,101,120,130, +153,246,225,232, 41,174, 28,197,199,145,243,183, 33, 16, 8,192, 85, 82, 51, 5,188,242,222,114,226,195, 76,184, 57,251, 98,192, +136, 9, 46, 7,119,172,159,166,215,170,190,171,107, 94,123,249,117,197,244, 25, 51,240,243,150, 45, 88,184,120,153,145, 1,232, + 89, 22,250, 90,211, 73,211,189,187,183,133,190, 36, 19, 60, 30, 15,111, 5,182, 4,143,199, 67,159,174,173,193,227,241,240,110, +119, 47,240,249,124,244, 13,242, 65,171, 86,173,192,231,243,233, 90,202, 29,201,137,231,240, 32,241,143, 74,164,151,128, 0,208, +202,229,175,156,175,147,203, 65,220,237,235,250,108, 97,220,184,113,133,233,233,233,218,170,199,154, 52,105,194,196,196,196, 52, + 52, 49,108,103,132, 68, 34, 9,224,243,249,183,242,243,243, 57,169, 84, 74,115, 28,203,249,250,182,229,157,220,188,224, 96,197, + 57,243,231, 47, 56,248, 81, 64,131, 65, 59, 35,163, 8,211, 52,136,162, 4, 34,253,231,139, 55, 51, 2, 70, 18, 0, 40,205,233, + 60,208,106,181, 26,247,239,223, 71,109,233, 33,132,212, 56, 76, 83, 80, 80, 48,198,219,219, 59,230,199, 31,127,180,163, 40, 10, + 23, 47, 94, 4,143,199, 51,126, 30, 63,126, 12,154,166,241,197, 23, 95,104,139,139,139, 63,171, 45,109,124, 62,127,198,254,253, +251,109,132, 66, 33, 20, 10,133,241,189,225,241,120, 72, 74, 74,194,202,149, 43, 49,102,204, 24,164,165,165,193,205,205, 13,179, +103,207,182,138,136,136,152,161,213,106,151,153, 81, 68,113, 26,141,166,163, 84, 42,133, 88, 44, 70, 5,225, 2,128,211,137,130, + 4,165, 82,217,206,222,190,204,197, 49, 58,234, 72,183,144, 1,254,246,142,174, 93,229,114,121,157,150,206,122, 4,108, 73, 97, +217, 47,223, 59,120,208,233,210,193,131,220,213,163, 71,159,137, 20,138,205,102, 63, 67, 58, 26,169,143,159, 33, 32, 32, 0,183, +110,221, 66, 64, 64, 64,101,210, 4,161, 80, 8,134, 97,192, 48, 12, 28,108,205,114,161, 32, 52, 77,227,210,165, 75, 96, 89, 22, + 26,141, 6, 26,141, 6, 62, 62, 62,249, 23, 46, 92,176, 2,128,199,143, 31,147, 81,163, 70, 21, 94,187,118, 13,237,219,215,188, +158,186,138,162,206, 45, 89,254,131,205,119,107,182,194,198,206, 25,209,209,209,236,201,147, 39, 21, 20,144,252, 32, 49,113,213, + 0,224,120, 36,160,173, 75,158, 57, 59, 59,199,240,120,188,166,149,127,203,203,203,179, 29, 60,120, 48, 10, 10, 10,222, 31, 60, +120,112,144,161, 78,200,216,183,111,223, 40, 0, 16, 10,133,160,105,154,133, 5,255, 85,168,141,139, 84, 38, 74, 85, 9, 87,120, +120,120,104,213,223, 42,147,170,234,190, 87,190, 54, 34, 34, 98,121, 37,219,202,122, 36,191,118, 31,173,168,168, 40, 82, 13,131, + 52, 27,181, 17,173, 10,196,198,198,234,220,220,220,126,126,112,251,233,219, 45,253, 90, 64, 34, 19,189, 3,224, 71,145, 72, 52, +107,244,232,209,184,122,245, 42, 18, 18, 18,126,197,107,206,194,105,219,182,237, 41,145, 72,228, 97, 98,152, 36, 53, 33, 33,225, + 93, 19, 13,195,226,163, 71,143,162, 38,103,248,243,231,207, 87,110,148, 42, 59,195, 87,255, 96,112, 4, 58,173, 14,165,101,202, + 23,141,184,129,104,149,150,150, 98,216,176, 97, 47, 41, 90,207,159, 63,175,245,254, 40,138,194,202,195,135,113, 38, 50, 18,239, +251,251,227,192,245,235,136, 24, 61, 18, 94, 30,141, 64, 88, 10,132, 2,210,118,173, 71, 94,113, 9,126, 63,119, 9,249,138, 50, +124,220,163, 7, 60, 27, 56,212,108, 87,192,244, 9,236,210,149, 57,123,249, 46, 4, 2, 62,104,112, 32,186, 50,184,121,247, 2, +143,166, 97,227,220, 12,140, 64, 0,129,128,143,199,233,185,240,110,219, 73, 24, 37, 20,247,169, 15,209,106,226,209, 12, 44,203, + 98,204,152, 49,216,189,123, 55,236, 93, 60, 96,211,164, 45,190, 89,181, 5,239,247,238, 81,235,253, 87,244,224,249,124, 62,120, + 60,222, 43,219,138,239,230,168,147,132, 35,208, 86, 45, 35,142, 0,132,160,241,183,223,162,241,183,223,226,186,225, 63,125, 74, + 75,161, 84, 42,129,206,190,117, 34, 89, 26,141, 6,233,233,233,218,172,172, 44,231,106,142,103,107, 52,154, 90,137,205,182,109, +219,226,198,142, 29,219,209,206,206,238,102,220,157, 59, 58, 63,127,127,193,137, 77, 11, 14, 85, 12, 27, 2,128,191,191,127,254, +130, 5, 11, 14,141, 26, 26, 58,112, 99,216,112,118,210,178, 29,124,145, 68,210, 49,116,206,182,184, 93, 67,135,214, 62, 54,163, + 86,167,248,249,249, 17,115,238,171,172,172, 44,171,134,195,253, 1, 44,237,208,161, 67,131,144,144, 16,196,196,196, 96,200,144, + 33,106,173, 86,251, 0, 0,250,245,235,215,250,247,223,127, 23,222,189,123, 23,142,142,142,130,212,212,212,173,168,197, 65, 94, + 40, 20,246,234,212,169, 19,173, 86,171, 95, 33, 89, 17, 17, 17, 24, 49, 98, 4, 90,183,110, 13,142,227, 80, 82, 82,130,144,144, + 16,193,186,117,235,122,153, 73,180,166,123,121,121,173, 68,249,172,195,202,117,225, 61,195, 16, 20,242,242,242,178,110, 95, 59, +151,216,163,247,224,142, 77, 91,181,117, 77,136,187, 85,163, 65, 39, 39,167,249, 52, 77,127,196,113, 28,175,184,184, 56,253,182, + 70,211,202,199,195,195,185,251,192,129, 40, 18, 8,120,107,207,157,163,179, 21, 10, 43, 0,102, 13, 65,170,116,165,240,104, 81, +238,234, 55,100,216, 64,220,186,117, 11, 31, 14, 31, 4,134, 97,192,231, 11,202,223, 77,166, 92,209,106,232,208,192,172,103, 83, +167,211, 25,235,240, 10, 63, 47,173, 86,139, 10,215, 44,169, 84,106, 60,166, 86,171, 65, 81, 84, 77,207, 6, 29,210,179, 59, 46, +199, 38,235, 63,251, 98,173, 90,144,119, 43,194,133,227,182, 61, 3,178, 95,163, 58,247,220,187,108,145,147,164,129, 13, 88,157, + 14,190, 3, 63, 52,190, 39,215,126,217, 40, 1,199, 73, 10, 83, 83, 48, 53,242,232,155, 94, 51,215,130,255, 0,106,227, 34,149, +137,210,235,130,162,168,168,176,176,176, 5, 0, 72, 88, 88,216,130,138,253,240,240,112, 37,128,140,122,146,173, 87, 84, 46,254, +155, 32, 89, 21,195, 11, 53, 33, 36, 36,100,170,181,181,245,186,138,253,244,171, 25, 72,191,154, 1,239, 54,190,221, 59,248,119, + 44, 26, 49, 98, 4,236,237,237, 49,103,206, 28, 2,224,215,186,254,255,227,228, 68, 43, 0,196,213,213,117,142,161, 66,246,191, +126,253,186,227,141, 27, 55,208,169, 83,167, 23,210,189, 86,139,160,160,160,154, 76, 41, 12, 78,237, 51,223,156, 74,198, 65,171, +213,162,172, 76, 9,141, 70, 11,189,142,131, 94,175, 71,128,175, 53,118,108, 9, 43,255, 77, 95,161,158,149,171,102,141, 93,172, + 97,109, 37,208,209, 52,165,188, 25,151, 85,109,141,169,209,104, 16,151,154,138, 59, 79,159, 2, 0, 6,132,215,236,248,186,227, + 92, 12,124,124,124,106, 75,109,203,198,110, 46,200, 60, 19, 87, 94,121, 43,211,113,227,207,189,176,182,182, 2, 0,248, 6,127, + 12,134, 41, 39, 90,165, 74, 45, 28,218, 52, 1, 69,136,201,176, 0, 82, 91,151, 83,124, 70,236, 65, 88, 14,132,112, 32, 28, 11, + 66, 56,240, 4,140,116,234,196, 79,193,113, 44, 2, 3, 3, 65,241,120, 96,117,106, 12,237,223, 7, 5, 69, 10,216, 55, 52,175, +145, 96, 24, 6,193,193,193, 18, 83,199, 31, 62,124,168,172, 76,204,106, 46, 35, 29, 74, 75,149, 80,171,213,208,106,244,208,234, +244, 96,155, 51,248,250,203,145,208,107,245, 40, 27,222, 21, 90,157, 30,220,140, 65,208,106,116, 72,147,210,180,159,183,131,142, + 6,165,188,125, 47,167, 65,109, 68,171,130, 28,152, 66,117, 62,129, 38,200,214,157,177, 99,199, 6,248,249,251,223,250,168,183, +255, 15,241, 9,137,153,241, 9,137,175,156,231,209,218, 63,101, 82,196,238,217, 2, 70, 18, 16, 58,167,230, 89,135,149, 81,121, + 24,241, 53,177, 64,161, 80,248, 89, 89, 89, 33, 57, 57, 25, 60, 30, 15, 20, 69, 61, 4,224, 7, 0,174,174,174,143,248,124,126, + 11, 30,143,135, 13, 27, 54, 80,124, 62,191, 93,215,174, 93, 23,168, 84,170,189, 53,116,232,188,173,173,173, 95, 82,179, 24,134, + 65, 88, 88, 24, 70,141, 26,101, 36, 89, 12,195, 96,219,182,109,232,216,177, 35, 52, 26,141,183,153,233,189, 1,160,135, 25,138, + 31,101, 32,231,181,146, 81,189, 94, 63, 54,239,163,143, 90, 33, 58, 26,221, 91,180,240, 9, 8, 8,128, 86,251, 66,208,105,209, +162, 69, 19,133, 66,145,165, 84, 42,255,141,242, 48, 4,183,107, 36, 69, 42, 14,169,143,203,221, 79,111,221,186,133,192,192, 64, +163,130, 85, 89,205, 98, 24, 6, 18,161, 85,157,136, 22,199,149,215, 75, 10,133,130,142,142,142,118,240,242,242,162, 0,192,203, +203,139,186,125,251,182,157, 84, 42,205,109,217,178,101,109, 29, 96, 6, 0,122,189, 51,152,127,230,228,113,153, 30, 88,150,197, +227, 45,227,215, 90, 71, 18, 29,203,113, 38,157,238, 37, 13,108,176,109,236, 48, 0,192, 87,189,251, 26, 59, 91, 39,151, 46,128, + 64, 32,192,219,115, 22,188,242, 46,113, 28,199,131, 5,255, 40,146, 85,157,162,245,122,109,243, 11, 69, 43, 60, 60, 60, 49, 60, + 60,252, 21,117,172,142,168, 93,209,170, 44,221,213, 21, 21, 47,171, 41,172, 90,181, 10,237,218,181,171,177, 33, 90,183,110, 29, +118,238,220,185, 10,192,227, 58, 75,142,111,119,240,197,234,131,137, 45, 90,251, 82, 0,176,108, 70,127,186,180,180, 20,151, 46, + 93,130,141,141, 13, 30, 62, 52, 59,236,151,181,141,141,205, 82,154,166,135,242,170,206, 0,168,158, 96,178, 28,199, 69, 22, 21, + 21,153, 12,239, 64, 8,160,213,233, 81, 90,166,130, 70,163,193,140, 47,214,215,154,136,112,128,210,106, 20,252,224,158, 93, 37, +166, 20,157,192,118,189, 48,121,180,213, 43,141, 55,143, 6,104, 26,104, 31, 88,174,184,220,190,158, 8,142, 3, 88, 14,112,112, +178,197,175,187,126,168,145,228,235, 89,206,208, 59,102, 81,162,102,225,221, 37, 20,207,238, 69, 27, 21, 36, 33, 83, 62,100,204, + 8, 4,224, 8, 85, 30,245,193, 84,173, 43,148,120, 20,200, 31,123,110,137,138,199,248,208,118,216,119, 54, 14, 31,246,246,195, +133,107,119, 17,210,217, 7,137, 15,158,194,215,179, 41, 54,108,141, 4, 33, 80,252,180,250,155,172, 23, 13,154, 62,213, 28, 69, +235,234,213,171,202,170, 42, 86,229, 45,169,189, 61, 4, 33, 47, 20, 45,165, 74,141, 57,243,205, 10,189, 83, 94, 70, 61,186, 72, +204, 57,185, 38,197,202, 28, 34, 86, 85,217, 66, 45,225, 89,154, 3,232, 8,204,251, 79, 86,156, 44,203,226,216,177, 99,198,242, +168,174, 28, 43,151,157, 25, 36, 7,169,169,169, 72, 76, 76, 68,151, 46, 93, 80, 84, 84, 4, 1, 77, 99,118,124, 60,124, 70,143, +134,134, 97,192,113, 28,132, 66, 33, 38, 76,152, 96,118,126,214,177,118, 54, 56, 94,179,181, 25,255,161,107,215,174,173,146, 75, + 75,145,152,148,132,222, 75,150, 0, 0,142, 31, 63,254,210, 51, 49,107,214, 44,225,221,187,119,199,221,188,121,115, 92,102,102, +230, 42, 0,179, 77,214,179, 68,109,244,209,250,104,228, 16,180,242,106,142,157,191,237, 50, 30,159, 53,119, 58, 4, 2, 6, 2, + 70,128,134, 54, 13,205,186, 27,157, 78,103, 36,173,101,101,101,244,241,227,199, 27,247,233,211,135,153, 62,125, 58, 5, 0, 59, +119,238,164,127,252,241, 71,217,153, 51,103,152, 70,141, 26,201,107, 81, 8,138, 51,242,212, 34, 0,112,119,119,199,250,205, 71, +232,126,253,250, 97,250,244,233,208,233,116,216,184,177,252,189, 26, 49, 98, 4,180, 90, 45,246,239,223, 95,241, 30,215,168, 70, +233,181,218, 87,158, 27,138,162, 32, 16, 8,192, 8, 25,128,227, 64, 81,148,108,197,138, 21,203, 18, 19, 19, 59,121,121,121, 65, +173, 86,143, 70,249,228, 15, 75, 28,173,255, 50,178, 85, 19, 23,169,206,215,202,160, 74,153, 66, 78,101,191, 45, 83, 68,173,178, +207, 22,234, 55,129,194, 60, 31,173,234,192,227,241,106, 85,171, 42,166,234,214,132, 89,179,102,193,218,218,218, 84, 3, 68,226, +227,227,239,202,229,242, 45, 0,214,215,171,112,206,197, 38, 46,157, 57, 72, 1,195,216,106,195,134, 13,115,223,122,235,173, 18, + 0,218,189,123, 95,238, 32,171,213,106,147, 13,184,141,141,205,210, 95,126,249,101,218,192,129, 3,233,170, 33, 6, 42, 15,239, + 85,124,116, 58, 29,246,238,221, 59,109,222,188,121, 40, 42, 42,154, 89, 83, 35, 94, 86,170,132,210,224, 8,253, 40, 97,159,185, +149,186,201, 67, 86, 13, 93,209,184,185,159,201,198,132,102,202,125,136,156,221, 95, 52, 96,214,214, 98,176, 53,216,164, 40,250, +241,211,180,204, 70, 77, 92,236,240, 40, 61, 7,206, 77,219,161, 32,227, 69, 62,240,249, 60, 8, 12, 67,135, 13, 27,200,144,243, +252, 57,104,154, 87, 35, 49,254,230,247, 88, 92, 75,120,138,253,103,111, 67,171, 42,197,234,237, 39,161, 85,151, 64,171, 42,133, + 86, 85,190, 93, 62,239,115, 80, 20,178,116,234,210,214,117, 41,119, 62,159,143,206,157, 59,155, 36, 58, 25, 25, 25,102, 42, 90, +196,168,104, 41, 85,117, 44, 35,243,122, 78, 53, 42, 86, 21,199,235, 75, 12, 42, 66, 62, 72, 36,146,142,219,182,153, 14,227, 80, + 29, 92, 92, 92, 78, 88, 89, 89, 53, 51,247,252, 58, 4, 47, 93,222,176, 97,195,165, 94, 94, 94,222,171, 87,175, 22,240,120, 60, +188,253,246,219,173, 93, 92, 92, 82, 1,192,215,215,215,173,162,142,153, 52,105, 18,185,122,245,106, 66,121, 31,195, 52,132, 66, + 97,146,141,141, 77,199,144,144, 16, 20, 21, 21, 33, 61, 61, 29, 50,153, 12, 62, 63,252,128,248, 73,147,224,191,105, 19,232,183, +222, 2, 69, 81, 16, 10,133,136,143,143,135, 68, 34, 73, 82,169, 76,134,124,235, 12,224,123, 0,221,241, 98,184,144, 0,184,132, +242,176, 11,215,170,169,239,104, 0, 96, 57,174,182,194, 26, 57,103,206, 28, 20, 10, 4, 64,191,126, 96, 30, 63,134, 86,171, 69, +151, 46, 93,140, 42,123,151, 46, 93,192,231,243,225,231,231, 7, 55, 55, 55,108,216,176, 97,100, 77, 68, 75, 85,162, 69,234,227, +103,232,218,181,171, 81,185,234,215,175,159, 81,209, 18, 8, 4, 70,101,139, 98,107, 39,174, 20, 69,145,202,157,100,150,101, 41, + 62,159,207,159, 57,115, 38, 53,100,200, 16,162,209,104, 56,161, 80, 72,239,223,191,159,186,112,225, 2,191,180,180,180, 54,181, +161,116,248,240,225, 78, 77,154, 52, 70,250,163, 68,236,219, 71,176,106,213, 42,196,196,148, 71,217, 72, 78, 46,159,184, 90,177, + 31, 18, 18,130,102,205,154,129,212,242,224,183, 29, 52, 20, 95,245,121,175,188, 62,105,230, 8, 1, 35,128,144, 97, 48, 39,233, +153,177,172, 27,108,219, 45,140,136,136,248,208,203,203,171,124,104, 31,224, 91,226,104,253,119,161, 22,161, 39,167, 10, 73,210, + 84,218,207, 1, 64, 25,246,115, 42, 17,170, 28,138,162,110, 16, 66, 58, 85, 57,183,226,184,166,202,182,226,248,157,122, 36,191, + 98,173,195, 87,200, 87, 77, 61,226, 7, 87,174, 92,241, 12, 8, 8, 64, 90, 90,218, 43, 51,225, 42, 26, 46,153, 76, 6,137, 68, +130,203,151, 47, 3,192, 3, 83,198, 46, 92,184,240, 35,202,163, 46,195, 48,108,208, 53,228,163, 94,151, 3,251,118,194,239,225, +187,138,228,114,185, 31, 94,196,208,161,220,220,220, 70, 9,132,252, 97, 45,218,186, 7,131,227,190, 63,119,244,210,146,154,238, +176, 69,107,223, 18, 0,202,138, 89,135,245,156,125, 8,154,166,135, 14, 28, 56,144,190,123,247, 46,134, 13, 27,134,157, 59,119, +154, 60,119,212,168, 81,216,189,123, 55, 6, 14, 28, 72,207,159, 63,223,100,120,135,151,213, 18,205, 27,123, 40,147, 31,222,193, +142,221,191,152,244, 65,114,114, 42,247,199,122,254, 60,215,248, 91,167,128,154, 71, 70, 56,189,230, 76,236,205,235, 93,187,245, +124,155, 73,207, 46, 4,167, 87, 67,165,120,113,125, 89, 97, 54,136, 94, 5, 70,106, 7, 23, 7, 27,220,186,114, 90,163,213,168, +206,212,100,115,218, 64, 95, 76,234,239, 13, 16, 14,131,102,255,138,168,245, 83,141, 61,232,160, 33,211,113,110,239, 90,179,125, +252,170, 66, 32, 16, 32, 62, 62, 94,105, 74,205,226,241,120,230,196,228, 50,168,142, 58,148,149, 41, 81,166, 84,189,201,186,195, +209,217,217,249, 39, 91, 91, 91,177, 9, 34,229,232,232,232,248,147,189,189,189,216,220,161, 67, 83, 36,203, 16, 87,235,230,216, +177, 99,235, 68,182, 68, 34, 81,179, 7, 15, 30, 24,131,149,214,180,213,104, 52, 8, 9, 9, 49, 55,120,233, 81, 0, 79, 92, 93, + 93, 47,249,248,248,216, 60,122,244, 8,187,118,237, 98, 4, 2,129,123, 69,253,161, 80, 40,192,227,241,240,252,249,115, 29,128, + 79, 81,203,208,153, 90,173,142,142,142,142,110,223,191,127,127, 94, 82, 82, 18,120, 60, 94,121,186,186,118,133,255,166, 77, 72, +152, 57, 19,193, 79,159, 66,165,213, 66, 44, 22,227,212,169, 83,218,178,178,178,104, 83,246, 36, 18,201,150,148,148, 20, 95,177, + 88, 12,173, 86, 11,142,227, 64,211, 52,197,231,243,131, 26, 54,108,184, 14, 64,167, 42,133,229,228,223, 41,164, 13,171,215,179, +242,180, 71, 57,181,101, 64, 94, 94, 30,142, 30, 61,138, 46, 93,186, 32, 56, 56, 24, 25, 25, 25,120,252,248, 49,222,127,255,125, +227, 57,119,238,220, 65,108,108, 44, 90,182,108, 89,187,162, 71,235,208,178, 77, 51, 48, 12, 83,174,230, 8, 24, 67,199, 71, 96, + 84,178, 24, 1, 3, 1, 95, 0,177, 68,108,182,162, 69, 81, 20,104,154, 6, 69, 81,144, 72, 36, 21,157,108,174,113,227,198,242, +252,252,124, 87, 0, 60,137, 68, 2,150,101,107,236,180,112,132,120, 50,185,151, 51,103,207, 91,233, 20, 30,126, 22,103,207, 62, + 7, 77,211,112,117,117, 5, 77,211, 72, 73, 73, 1, 77,211,240,240,240, 0, 77,211,200,200,200,168, 32,137, 5, 48, 77,134,141, +239, 13, 69, 81, 70,146,197, 8, 25,163,178, 5, 0,133,133,133,170,129, 3, 7,254, 91,173, 86,127,130,250,173,122, 98,193,223, + 24, 20, 69,221,248, 79, 92, 91, 7,244, 51, 16,171, 87,156,226,107,122, 24,223,239,214,173,219,166, 17, 35, 70,188,189,102,205, + 26, 88, 89, 89, 65, 46,151, 27, 27, 68,161, 80,136, 38, 77,154, 32, 63, 63, 31,155, 55,111,198,179,103,207,206, 3,152, 96,110, +138,228,114,249,213,135,183, 31,228,133,124,216,205,222,183, 91,155,134,233, 15,158,117,145,203,229,151, 13, 36,235,215, 17,179, +222,255, 36,100,112, 32, 24,161, 0,233, 15,179,112,238,232,165,255,151,194,228,241,120, 60,138,162, 48,108,216, 48,179,206, 31, + 62,124, 56,162,163,163, 81,211, 48, 35, 87,161,104,149,169, 80,170,124,115, 29,171,201, 83, 71, 97,242,212, 81, 70, 50, 97,206, +208, 11, 0,184,185,237,169,129,104,105,215, 68,237,217, 60,190, 67, 96, 87,143,142,190,205,112,237,230,109,252,190,233,133,200, +176,245,199,101,248,110,235,121, 52,113,182,133, 86, 93,138, 19,251,126,206,210,170,203,214,212, 83,148, 43, 39,183, 20, 5, 66, +184, 58,221,123, 5,121, 18, 8, 4,104,219,182,173, 73, 69, 43, 63, 63, 95, 89,155,154,101, 44, 35,141, 14, 37,165, 74, 40,203, +222, 24,209,242, 15, 10, 10, 58, 19, 25, 25,105,239,228,228,132,204,204,204,170, 68,203,191,123,247,238,103, 34, 35, 35,237,157, +157,157,145,158,158,110,118, 88,145,106, 72, 22,114,114,114,168,130,130, 2,206,214,214,182, 78,100,139,166,105,168,213,106,220, +187,119,207,220,191, 53,123, 54,151,141,141,205,182,221,187,119,219,228,230,230,130,199,227,225,222,189,123, 47,205, 58,172,248, +252,250,235,175,204,160, 65,131,126, 41, 44, 44,172,113, 90,155, 94,175, 95, 53,106,212,168,113, 25, 25, 25,182, 78, 78, 78,144, +203,229, 16, 10,133, 32,132,128, 10, 9, 65,143, 39, 79,160,101, 89, 72, 36, 18, 36, 39, 39, 99,203,150, 45,165,134, 80, 49,213, + 10,100, 20, 69,121, 50, 12,131,143, 63,254,248,165, 3,219,183,111,199,128,142,188,142,142, 54,252, 18, 61,196,234,108,201,123, + 39,120, 60, 30,229,223,249,173,214,157,123,246,107,123, 63,225,218,163,156,236,103,181, 85, 74, 58,141, 70, 3, 47, 47, 47,220, +184,113, 3,103,207,158,197, 91,111,189,133,224,224, 96,196,197,197,225,244,233,211,136,141,141, 5, 69, 81,176,183,183,175,112, +191,168,209, 7, 67, 83,166,199,243,204,188, 87,212,171,170,251, 12,195, 64,173, 52,111,114, 95, 82, 82, 18,110,220,184, 97, 12, + 45,195,227,241,244,163, 71,143, 6, 33,132,164,164,164,192,218,218,154,140, 29, 59,150,229,243,249,250,140, 12,243,252,131,173, +172,172,224,233,233,249, 82,199,167,226,211,163, 71, 15,220,188,121, 19, 52, 77,131,207,231,195,201,201, 9,151, 46, 93,170,245, +193,175, 32, 85, 21, 36,139,207, 8, 94, 34,125, 28,199, 41,226,226,226,198, 3,136, 51, 40, 89,128, 37,142,150, 5,255,127, 56, +134, 87, 23,150,174, 85,209,122, 2,160,247,174, 93,187, 70, 30, 58,116,104,213,186,117,235, 28, 67, 67, 67, 81, 80, 80, 0, 15, + 15, 15,184,186,186, 34, 42, 42, 10,199,143, 31,207,101, 89,118, 54,128,234,164,159,222,168, 33,102, 77,198, 35,121,164,186,164, +100, 82, 64,176, 55,206,239,189, 24,238,226,226, 50,129,199,227,205, 24,187,224,131, 79,122, 13,236,132,228,216, 20, 92, 61, 29, +143,236,180,220, 90,109, 86,117,134,111,216,176,225, 56,169, 84, 42, 68, 53, 83,137,171,153,117,104,180,201,178, 44,171,209,104, +176,103,207, 30,179,200,214,174, 93,187,160, 82,169,192,190, 58,190,106,180, 73, 56, 66,241, 5, 34,184, 53,241,130, 86, 91, 10, +142,171,247,132, 74,163,205,138, 30,232, 35,161, 16, 78,185,185,184,118,237,154,121,148,187, 95,191,218,202, 72,165, 81, 41, 62, + 94,251,237,156,168, 41, 97,223, 55,124,171, 91,123,124,245,195,118,104,181, 91, 65,243,104, 72, 68, 12, 2, 2,187,131, 7, 53, +126,138,152, 91, 88, 86, 92,240, 49, 94, 93,138,231, 37,155,164,166, 17, 22, 2,176, 28,135,179, 49,215,205,190,247, 74,195, 28, +224,243,249,120,248,240,161,178,186,217,134, 60, 94,249, 48,103, 69, 79,189, 38,155,132,227, 40, 1, 35, 70, 19, 15, 31,104,212, + 37,111,164,140,156,156,156,230, 30, 60,120,208,190, 34, 84, 66, 92, 92, 28, 40,138,186,247, 66,113, 44, 63,174, 84, 42,145,144, +144,128,184,184, 56,160,124,134,155,217,239, 81,133,146,149,147,147, 67,201,229,114, 72,165, 82, 58, 46, 46, 78,237,231,231,119, +179,150,247,219,104, 83,165, 82, 61, 53,229, 63,169, 82,169, 26,137,197, 98, 65,149, 6,207,173, 85,171, 86,201,213, 12, 33,190, +146,206,162,162,162,107,243,230,205, 11,232,219,183, 47,230,206,157,155,111,107,107,107,253,211, 79, 63,241,121, 60, 30, 53,101, +202, 20,246,249,243,231, 37, 63,255,252,179,205,161, 67,135, 80, 88, 88,120,217,140,123, 87,168, 84,170,241,221,186,117,219,126, +242,228, 73,169,167,167, 39,138,139,139, 65, 8,193,182,109,219, 48,101,202, 20,136,197, 98, 36, 39, 39, 99,192,128, 1,101,101, +101,101,227,241,170,239,100,133, 77,138,162, 40,194,113, 28, 22, 45, 90,100, 12, 78, 90, 17,172,212, 90, 66, 97,203,172,230,178, +233, 63, 23,201, 70,126,245,243,104, 0, 96,245,122,246,126,194,181, 71,219,214,127,117,129, 97,152,152, 90,202,104,225,244,233, +211,127,234,215,175,159,196,202,202, 10,249,249,249,184,116,233, 18,174, 92,185,130,171, 87,175, 66,163,209,192,222,222, 30,182, +182,182,144,203,229, 72, 74, 74, 82, 2, 88, 88,147, 77,161, 84,128, 22,173, 43,102,254,150, 43, 88,130, 74,179, 13, 43,171, 91, +140, 64, 96,214,123,212,179,103, 79,116,238,220,185,130,172,176,169,169,169,114,181, 90, 77, 85, 34,253, 25, 21,132,220,221,221, + 93,191,115,231, 78, 82,155, 77,142,227, 94, 33,211, 61,122,244, 48,118, 10, 59,119,238, 12, 30,143,135,219,183,111,155,114, 77, +121,201,230,213, 45, 27,112,242,235,133, 16, 50, 12,102,223, 75, 55,146,174,237,111,117,128, 64,200,192,187,255,144,202,215,110, + 68,249,112, 33,170,144,172,154,218,163,215,126,223, 45, 54,255,231, 33, 71, 61,150,224,169,192,239, 42,149,234,196,231,159,127, + 30,225,239,239,255,249,234,213,171, 41,134, 97,176,100,201, 18,146,153,153,249,155,161,199, 80, 80,159, 84, 17, 66,126,251,227, +192,229,137, 99,194, 6, 82,179,214,140, 13,186,121, 46, 33,169, 93, 55, 79,180,235,230,137,155,231,239, 98,253,130, 93, 59, 89, + 29,187, 40, 43, 43, 43,173, 22, 83,234,222,221,219, 84,117,134,183,143,190,112,206,190,174,179, 14, 57,142,139,220,181,107,215, +180,193,131, 7,211,215,175, 95,127,197, 39,171, 98,217, 29,142,227,112,230,204, 25,104,181, 90,252,246,219,111, 28,199,113,166, +227,104,129, 28, 94,187, 38, 98,204,111, 59, 14, 11,133, 12,133, 43, 49,251, 81, 84, 80,243,172, 46,134, 17,224,215,109, 7,180, + 12, 35,184, 95,221,113,173, 86,155,126,238,220, 57,231,119, 89, 86, 64,211,116,117, 4,170, 90, 68, 70, 70,234, 56,142, 75,173, +229,180,203,217,207,210,250,127, 51,247,211, 93,253, 62,250,220,185, 91,183, 32,129,131,147, 51, 40,138,194,243,236,231, 72, 78, +184,174, 59,177,255,151,236,210, 50,243,150,224,249,116,229, 31, 70,159, 44, 0, 8,157,178,206,232,159, 5, 0,253,199,206, 67, + 72, 23, 95, 80,230, 72, 79, 47, 72, 22,167,215,235, 33,147,201,160,215,235,171, 13,241, 96, 99, 99, 35, 81,169, 84, 74, 67, 32, +198, 26,123,204, 4,120,227,101,196,178,172,119, 65, 65, 1, 74, 75, 75,113,229,202, 21,242,237,183,223,230,228,228,228, 24,157, + 54,117, 58,157,119,126,126, 62, 74, 74, 74,112,249,242,101, 18, 17, 17,145,147,151,151,183,160, 46,239,144, 68, 34,233,200,231, +243,111, 22, 20, 20,112, 82,169,148,214,233,116, 58, 63, 63, 63,145, 68, 34, 49,123, 65,117,185, 92,222,215,212,177, 22, 45, 90, + 60,120,240,224, 65, 43,150,101, 43,175,129,200,168, 84, 42,207,110,221,186,153, 83,127, 76,223,186,117, 43, 14, 28, 56, 16, 88, + 92, 92, 60, 42, 53, 53,117, 59,128, 64, 62,159,143,219,183,111,223, 83,169, 84, 35, 6, 15, 30,188,173,160,160,224, 26,202,151, +224, 49, 7, 39,147,147,147, 63,246,246,246,222,186,116,233, 82,171,224,224, 96,190,155,155, 27, 58,117,234,132,228,228,100, 28, + 59,118, 76,183,113,227,198,210,178,178,178, 79, 1,156,169,185,216, 65,233,245,122, 8,133, 66,227, 71, 36, 18,129, 97, 24, 40, +148, 4,159,253,240, 88,169,135, 68,185,106,201,248, 99, 4,160,178,210, 31,231, 62,207, 74,191, 70, 81, 84,140, 92, 46, 47, 50, +145,103, 66,149, 74,213,158, 16,194,163, 40,106,141, 86,171, 29, 59,117,234, 84,215,229,203,151,163, 77,155, 54,200,205,205,133, + 76, 38,131,167,167, 39,114,114,114,112,253,250,117,182,172,172,108, 19,128,101, 48,248,143,152, 66, 97,110, 49, 26,187,184,191, +164,124, 18, 66, 64, 88, 64,167,102,193,106, 9, 52,148, 14, 2,129, 14, 12,195,152, 51,164, 66, 56,142, 67,129,171, 43,184,132, + 4, 92,189,122, 21,132, 16,147,170,154,151,151,151, 89, 10, 41,203,178,175, 16,173,107,215,174,129,199,227, 33, 40, 40, 8,177, +177,177, 70, 69,203, 44,191, 68,194, 65, 40, 18,190, 52, 92, 72, 81, 20, 24,161, 16, 2, 33, 83,221,108, 28,139,138,101,193,223, + 6,230,142, 99, 23, 2,152,112,231,206,157,237,189,122,245,138, 34,132, 8, 80, 62, 30,121,241,117,254, 60, 43, 43,235,214,229, + 99,183,230, 59, 55,182,141,120,111, 84, 16,218,180,247, 0,171,103,113,233,248,109,252,182,252,208,238,140,244,140,177, 48, 99, +237, 51,142,227, 46,116,239,216,134, 70,165, 88,221,110,110,110, 92,125,102, 29, 22, 21, 21, 45,158, 61,123, 54,230,206,157, 91, +159, 89,135,213, 34, 62, 41,103, 2, 5,210,184,255,123, 61,222, 5, 69, 19,141, 70, 93, 67,197, 7, 99,228, 82,134, 17,220,191, + 17, 39,247,171,238,188,156,156,156,119, 63,249,228,147, 51,124, 62,191, 89, 93,242,156,227,184,212,236,236,236,183,107, 63, 83, +127, 73,173, 44,246, 60,186,123,243,204,147, 7,182,190,203,113,108, 75, 10, 0,143,207, 60,210,105,181,167,212,202,226,213, 48, +115, 81,233, 21, 19,186, 98,250,218,211,216, 48,183, 63,166, 70,236,197, 47,139, 62,195,252, 31,118,225,251,185,211,241,237,186, +127,227,171,233, 31,227,195,145,159,112,132,162,255, 52,247, 62,120, 60,222,201,205,155, 55,143,249,236,179,207,140,147, 22, 8, + 33, 47, 85,194, 58,157, 78,201,113, 28, 54,109,218,196, 1, 56, 89,147,189,151,203,136, 34, 53,249, 75,153, 91, 70,197,197,197, +159,118,237,218,117, 27, 0, 17, 33,228, 97, 65, 65,193,191,128, 23, 75, 67,149,148,148,124,218,173, 91,183,109,132, 16, 17, 69, + 81,175, 28, 55, 7,134, 80, 15, 29,109,109,109,111, 26,148, 44, 81,125, 28,226,107,202,234, 26,134, 21,205, 25, 66,228, 0, 76, +173, 20,241,125,121, 96, 96, 96,229, 69,165,239, 21, 20, 20,116,172, 71,186,206, 40,149, 74,223, 69,139, 22,205, 20,139,197, 33, +101,101,101,173, 1, 64, 38,147, 37,171,213,234, 11, 74,165,114, 53,106,143, 77,165,225, 56, 46, 89,175,215,183,117,116,116, 44, +159, 81,107, 32, 91, 0,112,228, 38,123, 19, 96, 59,149,139,226,191,155,157,176,227,199,143, 55,181,181,181,125,135,162,168, 15, + 9, 33, 94, 10,133, 66,189,104,209,162,203,145,145,145, 69,205,154, 53,123,175, 95,191,126,148,157,157, 29,110,220,184, 65,242, +242,242,246, 3, 88, 0, 51,102, 90,115, 28,151,186, 98,197, 10,212,245,125,175,233,184, 86,171,205, 58, 32,240, 92,174, 0, 0, + 32, 0, 73, 68, 65, 84,126,252,184, 67,223,231,207,249, 28,199,161,127,255,254, 47, 17,184,170,184,127,255, 62,212,106,117,173, +193, 28, 11, 11, 11, 17, 24, 24,248, 82, 7,181,226,147,154,154, 10, 59, 59,187,151,254,167,182, 62,150,186,168, 0,111,205,156, + 7, 24,102,148, 86,160, 92,201, 34, 32, 26, 11,175,178,224,239,139,191,122,241, 77,179,164, 69, 87, 87,215, 97, 98,153,104,178, + 71,107, 87,191,204,199,207,239, 42,138,202,118,202,229,242,205, 38, 42,114,179,108,214, 49, 96,169, 69,254,253,139,108,190,136, +163,197,130, 16, 22,132, 35, 32,132, 3,199,177,229, 11, 94, 19, 14,132,101, 41,138,194,159, 26,101,141,145,193,171,166,211,214, +193,193, 97, 25, 33,164, 47,143,199,163, 43, 87,212,149,191, 27,148,172,147, 57, 57, 57, 95, 85,163,188,254,215,229,103,100,100, +100,181,228,223,220, 89,135, 67,135, 14,101,235,248,110, 94,144,201,100,174,213, 29, 43, 45, 45, 77,147,203,229,239,252, 77,242, +179,242,140,193,186,216,172,243,172,195,218,108,122,120,120,136,180, 90,109, 7, 0,158, 20, 69, 53, 4,144,175,213,106, 79,229, +230,230,102, 3,232, 8, 96,145,225,154,175, 1,220,252, 15,191,239, 18, 7, 7,135,173, 52, 77, 55, 54,231, 98,189, 94,175,201, +207,207, 31, 83,165, 67,240, 98, 8, 30,224,137, 25,230, 58,104,186, 81,117,239,163,169,239, 32, 36,163, 84,169, 12,164, 94,212, +249, 70,155,246,246,246, 55,249,124,126, 99, 51,210,246, 44, 47, 47,175,163,165, 78,254,175,182,249,223,140,170, 78,240, 38, 35, +197,255, 21, 68,203, 98,211, 98,211, 98,211, 98,211, 98,211, 98,211, 98,211, 98,243,159, 78,180,170,221,183, 76,129,181,192, 2, + 11, 44,176,192, 2, 11, 44,120, 61, 28,171, 66,182,142, 85,124,161,106, 96,165,117,145, 4,235,195,108,207, 90,108, 90,108, 90, +108, 90,108, 90,108, 90,108, 90,108,254,207,217,180,224, 13,194, 34,171, 90,108, 90,108, 90,108, 90,108, 90,108, 90,108, 90,108, +254,211, 97,114,232,144,182,228,141, 5, 22, 88, 96,129, 5, 22, 88, 96,193, 95, 3,179,137,150,204,217,203,219,193,195,111,155, +109,227,118,113,182,141,219,197, 57,120,248,109,147, 57,123,121,255,143,230,155, 4,192, 72, 62,159,127,198,197,197,165, 24, 38, +150,222,249, 7,160, 1,128, 15, 81, 30,223,103, 16, 0,233,155, 52, 30, 12,240,135, 1,147, 71, 3,105,163,129,180, 97,192,228, +224,127,160,223,224,146,105,174, 93, 99, 78,140, 60,177,100,154,107,215,106,143,207,118,181,191,122,122,232,218,229,147,221,236, +222,208, 95, 90, 59, 57, 57,109,113,118,118,126,234,228,228,148,234,228,228,180, 21,128,141,165,186,179,192, 2, 11, 44,248,203, + 80,225,163, 85,241, 49,250,104,241, 1, 32, 42, 42, 42, 24,192, 31, 0,122,133,134,134, 70, 87,189,218,214,189,237,103, 45,155, +183,156,251,205,146, 5,148,139,147,131, 84,207,114,218,148,167,233, 62,139,191,137,216,151, 41,228,175, 42, 72, 75,248,165, 30, +137,162,120, 60,222, 48,145, 72, 20, 10,160,130,176,221, 83,171,213, 81, 44,203,238,129,121,211,180,225,236,236, 28,195,227,241, +154,214,229,143, 89,150, 77,203,206,206, 14,170,103,102, 14,117,119,119,223, 26, 28, 28, 44, 13, 12, 12,132, 80, 40,196,162, 69, +139,102,203,229,242,213,230, 26,176,181,109, 97,173, 21,137,103,240,133,194, 62, 68,167,105, 75, 64, 0, 90,148,192,233,213,231, + 24,181,122, 85, 65,193, 99,133,153,166, 22, 0, 24,107,200,171, 95, 0,172,120,157,167,100, 76,123,232,116,108,249, 51,193,240, +193, 30,126, 98,243,199,194,133, 11,249,161,161,161,248,229,151, 95,130,182,108,217, 50, 94,161, 80,156, 3,112, 4,192,163,215, +125, 42,157,129, 9,221,130,130,214,142,153, 61,155,167,140,137,193,218,173, 91,215,160, 60,222,210,134,186, 62, 75, 12,131, 15, + 29, 28, 4,161,132,160, 3, 5, 80, 20,112, 59, 39,143, 59,174,213,178,123, 96, 70, 44,182, 26, 48, 18, 47, 79,199,255,189,174, + 6,138, 30,145, 47, 69,253,189,123, 20, 61,186,240, 37,128,247,170, 30,215,171,196, 99, 8,175, 73,168,146,196,166, 3,248,225, + 53,179, 85,234,232,232, 24,119,248,240,225,198,129,129,129,124, 0,184,121,243,230,232,208,208,208,183,114,114,114,218, 2, 40, +254, 15, 85, 66, 98, 62, 77, 79, 22, 10, 4,125, 88,150,109, 7, 0, 60, 30, 47, 94,163,211,157,209,115,220, 6,152, 25,147,205, + 2, 11, 44,248,231,162, 54, 46,242, 55,135,201,200,240, 21, 55, 71, 42,111, 43, 67,230,212,198,167,203,219, 67,238, 23, 41,202, + 84, 79,159,102, 20,204,154,252,237,153,241,211, 87, 30,250,225,231,168,227,209,215,238, 93,245, 14,124,231,174,204,169,141,143, + 9,211,166,198,112,221, 37, 18,201,173,141, 27, 55,106,147,147,147, 73, 97, 97, 33,185,127,255, 62,217,191,127, 63,153, 56,113, +162, 74, 34,145,220, 2,224,110,142, 77,103,103,231,236,251,231, 79,147,103,113,177, 36,245,230, 53,162,211,233,136, 86,171, 37, + 90,173,150,220, 61, 25, 69,226,142, 28, 32,183,247,239, 33, 26,141,134,104, 52, 26,162, 86,171, 73,243,230,205, 51,205, 76,103, + 85,184,249,250,250,106,162,162,162,200,190,125,251,200,236,217,179,137,191,191, 63, 11, 96,138,185,247, 46,115,242, 12,177,110, +228,151,243, 89,216, 6,237,177,203,167, 72,226,147,219, 36,241,201, 3, 18,121,246, 30, 25, 59,103,157,214,186,145,127,142,204, +201, 51,164,182,123,183,181,181,237, 66, 81, 20,169, 0, 0,210,180,105,211,146,202, 31,119,119,247,151, 62, 77,154, 52, 41,105, +214,172,217, 35,123,123,251, 14,213,217, 28,209, 14,132,220,253,157,144,187,191,147,133, 61, 65, 18, 19, 19,175, 18, 66,254,168, +248, 40,149,202, 63, 14, 30, 60,248,199, 7, 31,124,240, 7,128, 1, 53,228,147, 89,249, 57, 26, 72, 83, 28, 62, 76,200,234,213, +132, 4, 7,147,123, 0, 25, 13,164,213,209,102,115, 23, 23,193,237,149, 43,198,107, 14, 31,254,141,156, 56,113,140, 28, 63, 30, + 69, 14, 29,220, 74,214,172,158,172,117,118, 22, 36, 0,104, 85, 7,155,124, 0,223, 2, 88,133,114,229, 50, 57, 39, 39,135,100, +101,101, 17, 0,201,134,223, 86, 57, 58, 58,254,128,234,213,183,222,149,149,172,153,125, 93, 78,124,244, 94, 16, 81, 20,101,146, +143,222, 11, 34, 51,251,186,188,164,108,245,109,209,194,122,106,255,118, 57,137, 55,119,178, 83,251,183,203,233,219,162,133,117, + 61,243,147, 66,249, 58,161, 27,207,159, 63,175, 39,149,160,211,233,200,246,237,219, 89, 91, 91,219,223,234, 96,179,181,163,163, + 99,170,157,157, 93,114,229, 31, 29,253, 6,117,243,234, 49,122,177,189,207, 7,193,117, 72,103,160,152, 97,158,157,217,251, 19, +155,151, 22, 79, 52,202,108, 82,244, 48,150, 60,187,119,149,108,223,188, 74, 39,228,243,159, 1, 8,124,157,103,169,142,176,216, +180,216,180,216,252, 27,218,172,137,139,252, 55,131, 95,245, 6,171, 66, 36, 18,134, 45, 94, 56,143, 42,204, 43, 84,170,138, 21, + 26,157, 74,165,162, 25,162,138,191,251,228, 57,205,231, 21,206,156, 62,205, 58,108,254,194,176, 82,224, 99, 51,255,211,221,223, +223,255,250,129, 3, 7,156,236,236,236, 80, 84, 84,132,188,188, 60, 92,191,126, 29,132, 16, 12, 30, 60, 88,212,185, 83,167, 14, + 95, 46, 90,116,229, 89, 70, 70, 87,152,110,120, 95,144, 23, 59, 7,172, 8, 42, 95,139,246,171,167,121,229,173, 14, 69, 97,203, +208, 80,227, 57,203,158,149,175,150, 33, 22,139,141, 11, 18,215, 3, 93,223,126,251,109, 6, 0,198,141, 27, 87,172, 80, 40,194, + 13, 10,135, 89, 43,173,202,156, 60, 67, 28, 92,221,162,126,218,180, 66,210,174,165, 39,180, 58, 61, 82,179, 50,193, 23, 52, 68, +227,198, 12, 62,249,184,143,160,103, 55, 59,135,111,191,222,114, 44,139,195,160,178,220, 7,167, 76,217,106,216,176,225,246, 61, +123,246, 96,239,222,189, 0,128,228,228,100,120,122,122,202,106, 75, 67, 66, 66, 66,139, 1, 3, 6,236,206,203,203,107, 85,219, +185, 85, 3,227,139, 68, 34, 4, 5, 5,193,199,199, 7,135, 15, 31,238,101, 80,182, 94, 11,202,152, 24, 88,221,185, 3, 68,215, +171,243,210, 60, 32,192,227,234,241, 99, 59, 29,142, 29,191,135, 31,126,216,138, 71,143,202,133,182, 22, 45, 90, 96,228,136,161, +130,248,248,203,190, 31,126, 56,242,242,197,139,143,130, 12, 68,169, 54, 44,253,249,231,159, 23, 52,107,214, 12, 31,126,248,225, + 80, 95, 95, 95,151, 6, 13, 26, 96,243,230,205,112,117,117,109,161,209,104, 30, 30, 62,124,216, 45, 43, 43, 11,211,166, 77, 67, +118,118,246,108, 83,134,122,189,219,235, 75, 81,127,239, 30,109, 2,198,192,170,129, 43,126,222,181, 7,247,111,109,239,161,214, +222,251,146, 97,163, 71, 41,137,104,108, 78,154, 85, 88,211,142,193,246,173,124, 7,192, 35, 32,214, 65,197, 94,124,242,101,159, +230, 17,124,177,106,251,146, 31,228,121,175, 24,253, 48,146,215,182, 56,201, 46,225, 12,242,128, 37, 92, 5,193, 50,170,181, 4, + 3,122,246,236,105, 44,184,167, 79,159, 66,173, 86,195,219,219,155,214,104, 52, 33,102,230,107,235,119,222,121,231,207,227,199, +143,219,183,110,221, 58, 39, 63, 63,223,120,192,197,190,225,187,209, 7,214, 76,251,118,237,191,189,118, 16,170, 48,231,222,161, +248, 90,108, 5,118,239, 18,112,246,196,129,157, 86, 84, 73, 58,132, 13,115, 1, 46, 15,143,119,255, 10, 74,106,135, 97, 19,103, +241, 67,222,126,171, 81,159,247,134,156,189,255,224,209,219, 0,110, 88,250,245, 22, 88,240, 63,173,106,145,127,218, 61, 25,137, + 86,104,104, 40, 85,221, 13,114,132,243,115,118,178,151,172, 89,185,237, 6, 79,171,209,200, 26,218,104, 4, 54, 13, 56,202,218, +134,167,213,232, 74, 60, 90,120, 8, 57,194,249,153,176, 95,117,138, 39, 37,145, 72, 14, 28, 57,114,196, 73, 32, 16,128,227, 56, + 56, 58, 58, 34, 37, 37, 5,133,133,133, 80, 40, 20,120,116,239, 30,154,185, 55,193,146,176,121,174,211,230,133, 29, 40, 43, 43, +235,136,151,135, 17, 95,153, 54,202,234, 94, 94, 55,186, 98, 9,150, 87,186,252,134,223,170, 57,102,238, 84,212,148,180,180, 52, + 88, 89, 89,161,109,219,182, 86,151, 46, 93,186, 88, 3,201,122,201,166,173,109, 11,107, 78, 36,220,187,241,167, 69, 18,173, 46, + 1,119, 31,231,163, 77,179, 30,112,182,119, 71,102,190, 6, 87,175, 31, 65, 66,220,239,104,217,200, 29, 83, 38,190, 37,142, 88, +177,111, 15,163,111,230, 94, 88,152, 82, 92,157,205,226,226, 98,171,230,205,155,195,221,189,124,221, 51,150,101,113,247,238, 93, +176, 44,107,220,175,188,221,182,255, 60,244,197,169, 24, 51,122, 52,242,242,242,172,170,179, 41,224, 65, 63,107,252, 72,190, 68, + 0, 8,101,118,154,146,146, 18,227, 50, 28, 90,173, 22,183,111,223, 70,215,174, 93,131, 35, 35, 35,107, 99, 69,102,229,167, 22, +248,126,237,111,191,173,251,184,168,136, 6,128, 95, 40,138,211, 18,242,189,185,207,146,147,147, 96,255,201, 19, 59, 28,120,116, + 18,236,108,190,195,245,235,169,208,106,203,211,155,151,247, 28, 83, 39, 23,131, 17, 88,227,240,225,127,219,123,123, 7,237,207, +202,210,182,197,203,195,136,213,165, 83,124,226,196, 9, 76,157, 58, 21,119,239,222,117,171, 88,163, 77, 34,145, 96,229,202,149, + 60,111,111,111, 55,153, 76,134,147, 39, 79, 34, 59, 59,155,170, 41,157,127,156,250,227,155,162, 71, 23,190,204,162, 78,246,253, +121,215, 30,124, 62, 98, 24, 92,200,227,139, 54, 45,169,111,222,233,223,253, 43,194,107, 18, 42,179,246,179,245,108,219, 31,140, +208, 10, 83,190, 88,134,228,132,163,182,101,138,184,201, 20,155,222,100,201, 15,145,211, 95, 73,231,190,161,236,184,223, 47, 5, +156,113,191,225,113,231,246,248,107,242,216, 45,113, 47,136, 86, 11, 62, 69,179, 54, 64,249,178, 38, 15, 31, 62,196,163, 71,143, +192,231,243,161, 84, 42,161,215,235,171, 77,167,155,155,219, 4,189, 94,255,149,161,156,183,137,197,226, 79,119,238,220,105, 95, +153,104, 59,250, 13,234,102,111, 45,123, 59,251,121, 94,193,229, 27,137,247,103, 77,248,176, 87,204,213,132,116,173,224,131,180, +162,184,195, 69, 38,242, 83, 44, 17, 10,247,159, 60,248,111, 43,221,147,243,144,121,247,130,192,202, 19,172, 46, 3,101, 5,165, + 80, 60,146, 67,253,211,122,180,159, 60, 19, 71, 15,237,179,242,109,215, 49, 82,173,211,121, 2,208,212,227,221,172, 11, 44, 54, + 45, 54, 45, 54,255,158, 54, 77,114, 17, 66, 72, 0, 0,103,195,110,158,129, 23, 56, 0,200, 69,249,138, 2,206,134,186, 67, 88, +233,178,170,251,149,207,173,186, 95,249,123,158,225,187,147, 97,123,131,162,168,252, 90,146,238,138,242,165, 9,143, 25,182,128, + 97, 40,177, 86,199, 99,138,162,139, 89,150, 19, 49,142, 78,170,113, 31,189,221,238,244,217,155,183,165, 14, 13,248,239,246,234, + 16,124, 61,254,201, 21,138,166,116, 20, 69,155,229,247,193,227,241,134,173, 89,179,166, 93,131, 6, 13,192,113, 28,108,108,108, +144,147,147, 3,141, 70,131,162,162, 34,168, 21,197,208, 42,138,113, 39,253, 41,186, 7,247,194,144,190,239,120,255,251,208,145, + 97, 44,203,238,174,201,174,155, 95, 7,163,146,181,172,169,253, 11,105, 34,189,208, 72,186,190,235,224, 9,198,202, 10,125,102, +133,189,206, 51, 16,123,236,216,177, 19,131, 7, 15,126,111,206,156, 57,180, 92, 46, 63,153,146,146,210, 29,192,221, 90, 73,133, + 72, 60, 99,210,140, 80, 91, 91, 43,130,200, 51, 71,208,179,195, 8, 72,133, 60,228, 21,107, 65, 81,192,189,196, 3,160, 40, 59, +196, 37,203,209,163,125, 3,188,243,174,183,213,161,125,247,230,224,133,127,208, 43, 69, 83, 80, 80,128,231,207,159, 67,167,211, + 65,167,211,225,195,161, 67,177, 99,251,118,148,150,150, 66,169, 84, 66,163,209,128,101, 89,208, 52,141, 51, 81,145, 72,127,114, + 15,221,186,118, 5, 76, 44,189,180,253, 54, 4, 0,174,222,191,127, 31,247,238,221,195,179,103,207, 32, 22,139,225,226,226,130, +101,203,150, 65,173, 46, 95, 79,108,232,208,161,193, 0,226, 95,247,133,122, 4,108, 73, 97,217, 47,223, 59,120,208,233,210,193, +131,220,213,163, 71,159,137, 20,138,205,230, 92,203, 48,248,112,197,247, 19,219,200,100, 50, 60, 75, 91, 3, 47, 47, 6,179,103, +218, 35,252,187, 92, 0,192,180,169,141,209,169,163, 3,138, 11,247,193,193,105, 1,214,173,155,222,114,236,216, 85,163,203,202, +216,109,181,152,254,242,200,145, 35, 67, 60, 61, 61, 27,197,198,198, 82, 66,161, 16, 18,137, 4, 18,137, 4, 98,177, 24,207,159, + 63, 71, 74, 74, 10, 89,177, 98, 69, 6,128, 47,107, 50,180,100,157,252, 10,128,247,102,246,197,137,251,183,182,247,104,196,123, +114,103,200,148,160,167,113, 87, 99, 21,167,207, 92,250, 90,175, 18,167, 23, 62, 59, 59,175,121,167, 88,135,201,115,151, 98,253, +138,197,184,127, 45, 38,223,217,189,120,131,132, 82, 87,155,206,224,224, 37,124, 87,103, 59,253,132,177, 67, 26, 30,117,190, 60, +225, 56,159,202,201,202,189,181, 18, 41,177, 74, 81,171, 14,163, 90,183,160, 53,231,207,159,151,244,236,217, 19, 42,149,202,168, + 76,238,220,185,147,211,235,245, 23,170,125, 54,181,218,175, 50, 50, 50, 92,149, 74, 37,250,246,237, 59,109,229,202,149,178,138, +245,228, 88,150,125, 73,201,250,102,245,142, 83, 51,190,218,112,225,212,238,239,220,190, 9,251,180,215,199, 83,190,189, 0, 19, +235, 72,242,105,122,242,209,131, 91, 93,196,182, 58, 72,236,222,129, 42, 91,137,251, 91, 62, 71, 89,177, 10,157,190, 89, 10, 64, + 8,141,142,198,230,254, 31, 66, 96,239,134,197,159,125,234,182,112,243,207, 19, 57,142, 91, 99,233,215, 91, 96,129, 5, 85,224, + 76, 81, 84, 20, 0,132,133,133, 45, 8, 15, 15, 79,164, 40, 42,138, 16, 18,106, 16, 80,162, 8, 33,161, 21,231, 24,200,217, 43, +251, 21,231, 86,221,175,250,125,254,252,249,190, 17, 17, 17,203,187,254, 31,123,215, 29, 23,197,181,182,159,153,237, 21, 88, 58, + 11,168,128, 34,168, 32, 16, 17,177,163, 70, 18,187, 70, 44, 81, 44,209,104, 18, 75, 52,137,221,216, 75,188, 70, 19, 91,212, 88, +162,198, 94,162, 98, 87, 20,123, 5, 21, 5, 5,233,189,195,178,189,204,204,247,135, 64,208, 80, 22,147,220,155,251, 93,158,223, +111, 88,118,119,230,217,115,166,156,243,156,247,188,239,123,130,131, 15,222,190,125, 59, 25, 64,125, 66,171,111,133,176,250,195, +210, 59,100,165,130,172,254,250,134, 69,139,166,175, 39, 38,167,170,123,247, 10,114,137,136,122,250, 96,220,184,190, 61,135,247, +239, 26,154,146, 94, 20,215,188,169,163,237,179,103, 79, 45,104,154,190,110,206, 89,226,243,249,253,122,244,232,193, 46, 41, 41, +129, 72, 36, 66, 65, 65, 1,178,178,178, 96, 48, 24,160, 45, 43,133,174,172, 20,218,210, 18, 24,202, 74,240,234,225,125,180,109, +238,193,175,112,150,175, 19,149, 86,151,183, 45, 85,213, 45, 91, 60,169, 20,124,169, 20, 68,195,167, 13, 7, 90, 89, 89,221,173, +236, 84, 13, 6,195, 23,179,103,207, 46,164,105, 26, 43, 86,172,176,144, 72, 36, 71, 0,240,235, 35,145,218,177,250, 5,251,251, +144,241, 41, 79,208,217,111, 12, 90,186,247, 65, 74,158, 6,133,229, 6,228,151, 26, 16,216,117, 35,154,249, 45,129,171,255, 42, +196,165, 21, 67,238,236, 73,130,205,175,115,241,231,140,140,140, 55,222, 31, 60,112, 0,106,181, 26,205,155, 55,199,200,145, 35, + 49,123,246,108,140, 28, 57, 18,114,185, 28,163,134, 13,192,162, 69,139,144,155,155, 91, 95, 81,117, 45, 91,182,212, 53,109,218, + 84,215,180,105, 83,157,193, 96,128, 82,169, 68,105,105,233,219,231,123,122, 67, 79,164,189,189,253, 92, 71, 71,199, 39,246,246, +246,207,248,124,254,217, 24,130,136,215, 54,109,234,208,105,208, 32,162,245,176, 97,172, 52,161,144,136, 2, 36,230,112,217, 90, +115,250,134,244,248,144, 87, 90,178,171,202, 72, 53,126,156, 29,110, 70,181,193,173, 27,237, 48,245,139,230, 32, 72, 1, 8,146, + 7,181, 42, 18, 65,237,131,185, 86, 86, 68,125,247,210,199, 0, 98, 58,117,234, 36,159, 50,101, 10,193,231,243, 49,109,218, 52, +195,132, 9, 19, 18, 70,142, 28,153,112,229,202, 21,170,105,211,166,112,117,117, 37, 92, 93, 93,157, 0,196, 84, 28, 83, 39, 44, +154, 19,203,117,134,184, 27, 86,158,226,100, 10,182, 29,149, 70,254,208,197,223,231, 20, 45,223,146,252,125,202, 11,181,199,139, +123,215,139, 18, 98, 79,211, 41, 15,174, 21,102, 39,148,123, 44,223,146,252,253,188,205,217, 53, 62,212, 81, 81,160,143, 71, 68, + 25,212, 42, 53,123, 80,255, 16,245,164, 79,134,183,180,150,180,217, 7,231,222,126,205,154,184,140, 90,180,114,131, 97,194,103, + 95, 26,118,236,220,197,148,151,151, 67,161, 80, 96,195,134, 13,166,211,167, 79,103, 81, 20,245,101,109, 99, 32, 0, 48, 26,141, +152, 52,105,146,216,194,194, 2, 25, 25, 25, 85, 22, 81, 0,200, 41, 40,122,122,235, 65,108,252,204,201, 97,221, 84, 58,157,238, +194,181,135,113,173, 61,155,186, 16, 4, 83,107, 32, 10,143,195,121,191, 93, 80, 16,139, 97, 74, 65,176,155,224,213,158,127, 65, +145, 91, 12, 69,126, 49, 88, 28, 49, 76,224,195, 72,243, 96,213,182, 61, 94, 62,136,134,179,157, 3,155,207,225,132, 54,246, 39, +141,104,196,255, 38,234,210, 34,213,197,210,234,213,171, 87,214,245,125,181, 87,253, 91,239,171,132,212,219, 34,172,250,255, 0, +176,122,245,234,149, 12,195,244,187,125,251,246, 1, 0, 26, 51,171,240,105,181, 87,243,243,104,177,180,250, 85, 95,207, 94, 0, +153,165,208,178,125,128,167,227,201,243, 81, 15,175,223,126, 24,215,204,213,214,142, 49,234,101,107,214,109,114, 33,212,154,213, +102, 22,162,149,173,173, 45, 12, 6, 3, 18, 19, 19,145,153,153, 9,131,193, 0,147, 74, 5, 93,105, 41,180, 37, 37,160, 84,229, +224, 82, 20, 52, 5,249,176, 17, 9,128,223, 35, 18,235,177,188, 17, 53, 10,173,202, 87,129,133, 5,248, 82, 11,144, 28, 78,189, + 43,197, 87,195,123,237,219,183, 63, 28, 27, 27, 27,212,171, 87,175,101,120, 29, 34,159,150,149,149,213,115,225,194,133, 58, 7, + 7, 7, 76,154, 52,201, 11,192,152,122, 69, 38, 79,223,170,169,163, 23, 90,122,140, 65, 51,215, 30, 40, 85, 25, 81,160, 48, 34, +191,212,128,109, 27,131,113,108, 71,123,220, 60,214, 5,177, 23,222, 71,169,209, 17, 18,249, 64, 48,148,190, 77, 93,156,151, 46, + 93,194,210,165, 75,177,108,217, 50,172, 88,177, 2,203,150, 45, 67, 86, 86, 22,124,124,124,144,158,158,142,115,231,206, 33, 39, + 39, 7,182,182,182,184,127,255, 62,214,175, 95,143,155, 55,111,214, 91,233, 74,225,106,198, 62, 13,154, 75, 55,153, 76, 99,115, + 6, 13,242,205,179,182,110, 29, 16, 16,240,225,180,105,211, 60, 58,117,234, 84,245,189,135,135, 71, 19,161, 80,152,139,215, 17, +148,254,117,113,209, 64,128,157,157, 15,244,186,248,138,107,204, 1, 65, 8,208,227,253, 56,116,234,242, 16, 6, 35, 23, 36,193, + 7, 73, 10, 96, 50, 21, 65, 38,147,131, 97, 8,159,122,138,184,176,160,160,192,243,242,229,203,100, 74, 74, 10, 4, 2, 1, 0, +164, 46, 94,188,120,211,247,223,127,255,220,198,198,134,138,136,136,192,111,191,253,134,126,253,250,177, 38, 76,152,224,233,234, +234,186,181,190,122, 47,222,144,115,103,255,186,115, 35, 56, 70,153,191, 64,216,204, 13, 42,201,192,207,187,217,138, 1,224,124, + 82, 82,185,125, 19,197,106, 85,249,147,116, 43, 23,229,119,231,147,234,139, 56, 93, 76, 63, 74,136,191,187,255,196,249,178,252, +188, 18, 78,128,111, 27,205,170,165,223,112,155,185,181, 88,179,104,246,100,199, 44,133,160,244,253,105,231,226,143,159,191,175, + 28, 61,110,162,233,147, 79,167,104,207,157,191,116,130,166,105, 95,212, 18,113, 72,211, 52,114,114,114,240,236,217, 51, 36, 37, + 37,161,160,160, 0,133,133,133, 40, 47, 47,175,154,110, 20,149, 43,206,108,218,125,250,177, 88, 40, 20, 5,249,122, 54,185, 23, +253, 60, 95, 44, 20,138, 60,221,154,180, 4, 22,215,216,142, 80, 20,229, 43, 16, 9, 1, 16, 40,141,189, 14,101,137, 18,202, 82, + 37,202,139,149,208, 25, 88,208,234, 72,104,244, 36,154,118,235, 13,165, 74, 11,101, 81, 25,104,138,242,107,236,110, 26,209,136, + 70,212,209,215, 71,204,153, 51,103,158,153,251,154, 61,189,249,182,240,154, 51,103,206, 60,130, 32, 34,230,206,157,219, 6,181, + 7, 84, 85,199,246, 26, 54, 0,102,164,119, 40, 42, 74, 80, 74,137, 86, 67,102,204,250,246,220,129,157, 27,237,117, 58,117,186, +141, 76, 66, 73, 68, 60,219, 79, 38,173, 64,185,178,100,176,202,252,116, 4, 40, 41, 41, 65,114,114, 50,132, 66, 33,184, 28, 14, + 40,141, 6,148, 70, 5, 77, 73, 17, 72,131, 14, 92,138,130,181, 72,136,166,114, 71, 52,115,112, 52,139, 51, 49,242, 98,149,227, +123,245,233,194,127,181,111, 5,158, 88, 2,158, 84,130,207, 35,174, 1, 0,184, 92, 46,176,112,153, 89, 70, 19,103,103,231, 83, +251,247,239,231, 22, 20, 20, 32, 38, 38,230, 49,128, 50, 0, 82, 0,116, 92, 92,220,229,216,216,216,126,158,158,158, 0,208,188, + 62, 50, 69, 33, 73, 25, 77, 12, 50,114, 83,145,146, 25, 13,107, 75,119,112, 68, 45,145, 95,106, 0, 95,232, 14,163,238,247,217, + 71,173, 34, 13, 26, 3,203,172,186,235,245,122,152, 76, 38,152, 76, 38,232,245,122,124,250,233,167,184,117,251, 54, 14,254,118, + 5,201,175, 94,194,203,205, 17,225,225,163,209,190,125,123,220,190,125,187, 78,174, 49,254, 48, 58, 75,192, 94,247, 33, 9,158, +196, 70,215, 97,246,133,123,245,137, 45,130, 32, 24,212, 50, 21,249, 22,190, 15, 14, 14,110,241, 82,165,194,179,248,120,244, 90, +188, 24, 0,112,246,236,217, 55,234, 50,115,230, 76,222,243,231,207, 63,121,248,240,225, 39,217,217,217,235, 0,212,236,108,206, + 0,103,206,220,193,228,201,207, 81, 80, 80, 0, 0, 56,116,224,119, 93,154,146,108,192, 7,125, 95,207,104, 89, 89, 89, 97,221, + 58, 31,179,206, 39, 69, 81,216,190,125,123,213,116, 33, 0,176,217,236, 78, 51,103,206, 28, 82,211,254, 45, 90,180,224,214,199, + 57, 99,168,179,224,230, 99,230, 11,203, 22,205,218, 88,216,182, 69,145, 49,218, 39, 58, 43,103,234,140,161,206, 63,172, 63,154, +165, 21, 18,186, 95, 8, 42,195,149, 45,208,238, 49,167,140, 73,231, 55,234,139,154,142,221,147, 91,160,152, 63,101,226,199, 54, + 22, 86,246,170, 29,155, 86,201, 72, 22,201,156,122,104, 40,109,227, 97, 99, 53,176,195,143,202,201, 51, 22, 70,235, 77, 25, 83, +144,113,234, 37,234, 72,113, 65, 81, 20,178,179,179, 81, 80, 80,128,244,244,116, 20, 22,190,158,126, 45, 44, 44, 4, 77,211,127, +166, 65,132, 38, 61, 29,105, 39,118,160,217,232,209, 8, 92,182, 20, 20,205,134, 70, 77, 97, 93,199,158, 40, 41,211, 64, 71, 19, +144,191,215, 17, 19,207,222, 0,201, 80,192,182,205,141, 61, 73, 35, 26,241, 63, 10,115,210, 59, 84, 10,162, 85,171, 86,245,251, +171,127,191,186,216, 90,181,106,213,179, 85,171, 86, 53,228,183,222,158, 50,172,122, 95,233,163,117,173,154, 3,218, 31, 58,205, +242,194,184,164,231,207,217,217, 42,141, 74,228, 96,111,167, 19, 9,248,116,153,162,156, 21,253,244,177, 65,149,251,234, 69, 3, +234, 17, 23, 27, 27,235,147,157,157,141,244,180, 52,152, 52, 42,144, 58, 61, 24,173, 26,189, 58,119,132, 0,128,128, 36,192,165, + 13, 96,179,120, 40, 87, 42, 0, 32,174,222,206,209,104,252,131,101,139, 32, 8,240,164, 82,240,196, 98,240, 36,210, 55, 44, 92, +230, 88,108,248,124,254,254, 35, 71,142, 56, 57, 59, 59, 99,233,210,165,112,113,113,241,150,203,229,106, 75, 75, 75,161,131,131, + 3, 90,183,110,141,142, 29, 59,226,220,185,115,128, 25, 57,165,140, 38,193,147, 23,169,232, 84, 88,124, 27, 55,174,253, 4,189, + 70,135,128,110, 63,193,192,110, 6,187, 54, 75, 64, 39,238,131, 58,247,228,107,235,129, 99,127,100,166,167,130, 96,241,158,153, +107,121,170,252,255,241,227,199, 56,112, 50, 10, 78, 77, 91, 33, 61, 33, 30,241, 87, 47,227,150,157, 13,154,182,106, 93, 53, 13, + 84,107, 25, 41,176,151,111,126,157, 38,106,193, 23, 31,243,139,139,139,249,214,214,214,186,202,115,231,228,228,244,103,196,214, +199, 95,127,253, 53, 74, 57, 28,160,111, 95,112,147,146, 96, 48, 24,208,161, 67, 7, 4, 6, 6, 2, 0, 58,116,232, 0, 54,155, +141,182,109,219, 66, 46,151, 99,243,230,205, 31,215, 38,180, 72, 2, 49, 38, 83,145,183,135,135, 71,149,208,218,179,183, 0,209, + 15,223, 7, 1, 30, 54,108, 74,172,218,183, 73,147, 38,200,205, 73, 2, 65, 48,177,245,148,113,153,163,163,227, 66, 39, 39, 39, +143,239,191,255,158, 37, 16, 8,240,217,103,159,185, 43,149,202,102, 21,166,100,204,157, 59, 23, 0,176,104,209, 34, 44, 94,188, + 24, 58,157, 78, 93, 27,217,158,117,190,242,252, 98,250, 19, 70, 41, 26, 28, 98,219,204,183, 71,104, 47,184,123,246, 64,143,208, +116, 0, 88,105,205, 78, 29,182,102,190,213, 9, 43, 41,177,235,226,249, 75,139, 58,119,235, 49,127,182,242,234,242,239,182,151, +214,235,243, 88,150,246, 75,249, 11,222,240,245, 27,183,238, 93,255,237,220,233,130,244, 2,125, 73, 86, 9,163,148,240,217,146, +230, 14,132,100,234,172,101,201,217,217, 73, 95, 33,227,124,189,145,150, 52, 77, 35, 41, 41,169,202,167, 79,171,213, 66,165, 82, + 33, 35, 35,163,234,158,209,136, 45, 62,152, 50,174,191,159, 74,163, 81,223,123,154,144,190, 96,218,168, 96,149, 70,163, 78, 72, + 73,127, 9,108,168, 81,141,145, 36,249, 84, 93,174,238,165, 46,213,162, 32,230, 5, 92,122, 54,133,209, 68, 64,111,162, 80, 80, + 84, 14,157, 9,160, 72, 14,218, 12, 11, 7, 69,176, 81,152,157, 5,146,197,122,140, 55,157,246, 27,209,136, 70,252,239,160, 78, + 45, 82,105,209, 10, 14, 14, 62, 88,221,234, 84,249, 63, 0, 29,234,118,229, 41,168, 46,166, 42,167, 19,107,251,157,183,120,205, +197, 31,124,180,234, 77,239, 80,249,155,174,150, 10,249,191, 22,141,114,161, 77, 38,175,252,194, 60, 19,155,205,231,184, 90,106, +114,138,211,205,255,117,157, 78, 23,113,249,242,229, 65,239,191,255, 62, 63,225,233, 99,232,203,202,160, 47, 43, 5,135, 54,193, + 90,216, 14,164, 65, 7, 66,175,135,179, 55, 13,109,185, 16, 81,183, 98,141, 58,157, 46,194, 92,161, 69,178, 88,111,250,101, 73, + 36,224, 75, 45,192,151, 72,222,158, 90,172, 79, 20,136,122,247,238,221,179, 67,135, 14, 96, 24, 6,219,183,111,135,193, 96,224, + 25, 12, 6,232,245,122, 24, 12, 6, 40, 20, 10,236,221,187, 23, 91,182,108,185, 5, 96,119,189,157,153, 73,127,249,194,165,200, +246,227, 71,245,227,156,141, 88, 7,147,158,130,134,112,129, 74,101,132, 82, 47, 2,101, 51, 26,200, 59, 3, 22, 91,128,224,182, +238, 56,121,244,184, 1, 38,221, 21, 51, 85,248, 27, 86,161,140,244, 84,100,190,122, 9,137, 34, 23,118, 22, 34,168,147, 94, 34, + 32,124,204, 59, 89, 39, 92, 93, 93, 65,211, 52, 66, 66, 66,170,156,171,223, 85,108, 21, 21, 21,225,244,233,211,232,208,161, 3, +186,117,235,134,172,172, 44, 36, 37, 37,161, 79,159, 62, 85,251, 60,126,252, 24,209,209,209,104,222,188,110, 35, 97, 97,177,241, +108,102, 70, 76,216,192,129, 3,185,119,239,222, 5,195, 48,240,244,180,128,133, 84, 12,130,228,163, 85, 43,123, 0,175,199, 0, +221,187,119,135, 66,145,100, 42, 41, 97,206,214, 83,221,253, 0,126,211,235,245,137, 93,187,118,149,191,122,245, 10, 51,102,204, + 96, 31, 58,116,168,210,148,140, 57,115,222, 12,166,208,104,106,159,186,247,242,245,254,198,221, 36,235, 38, 16, 54,115,179,176, +109, 11,119,207, 30, 0,128,247,251,141,135,123,139, 38, 80, 20, 62,113,211,106, 82, 7,115,217, 37,178, 39, 27,178,158, 11,251, +250,140,211,230, 95, 75,192,235,169,211,122, 47,187, 38,225, 80, 94, 58,103,244,225,223, 78,157,155,212,167,223, 0,142,145, 50, +153,124,154,114,172,142,156, 56,147,159,149,150,254, 35,210,207,199,254,110,255,171,211,138, 71, 41, 20, 10,136,197, 98,196,198, +198,234,250,246,237,203, 39, 73, 18,137,137,137, 85, 66,203,222,214,186,117,167, 64, 31,239,229,235,247, 94, 16,243,249,252,208, +238,237, 90, 61, 79, 72,203,100, 24, 34,181, 86,107,171,209,120,233,105,204,227, 16, 59,121, 11, 86,210,181,187,176,233,210, 7, + 58, 29, 9,141,158,134,206, 4,152, 88, 92, 56,249, 7,193,170,121, 43, 48, 0, 30,220,189,101,212, 25,141, 23, 26,251,154, 70, + 52,226,127,218,170,197,212, 37,146, 42,254, 47, 6,144,186,106,213,170,194,106,214,166, 2, 0,143, 1,248, 85,236, 87,240,214, +113, 5, 4, 65, 60, 96, 24, 38,176, 26, 79, 65, 53,193, 85,253,127,253, 91,251, 60,110,128,200,170,254,250,166,208,170, 45,164, + 18, 0,108,109,109,237, 3, 2,218, 53,255,121,231, 97, 48, 12,131, 23,209,107, 81,146, 31,143,133, 43,239, 52,119,118,118,238, +150,149,149, 21,101, 78, 9, 40,138, 58,180,107,215,174,175,130,222, 11, 8,112,115,113,193,227,212, 20,112, 25, 10, 92,138, 2, +105,208,129, 77,233,225,226, 67,129, 36, 36,200,206, 46,195,234,253,135, 99, 43,178,196,215, 9,239, 62, 3,176, 52,179, 12, 4, + 65,224,251, 96, 31,240,164, 18,112,197, 18,124,126, 42,178, 74, 92, 69, 44,157, 11,158, 68,130,230, 65,102, 37,132, 87, 95,189, +122,245,225,211,167, 79, 3,125,124,124,240,213, 87, 95, 33, 53, 53, 21, 52, 77, 35, 47, 47, 79,155,147,147,147, 85, 80, 80,144, + 10,224, 4,128,159, 97, 70,230,113,174, 78,251, 67,196,177, 61, 83,130, 59,119,179, 29, 56,120, 11,126, 59, 58, 19,165,101, 10, +168, 77, 66,168,180, 38,168,116, 44, 88,219,248, 34,168,109, 91,100,103,229,227,217,221, 11, 74,182, 78,189,182, 33, 55, 40, 65, + 16,136,142,142,134,135, 92,138,151, 55,162, 96, 43,226,192, 79,238, 8,121,167,206, 85,249,165,234, 2,135, 5,211,199, 31,127, + 92,149, 25,190,119,239,222, 41,163, 71,143,118,154, 57,115, 38,118,238,220,137, 91,183,110,253,193, 65,187, 91,183,110,184,126, +253,250, 18, 0,139,234, 51,234,233,245,122,120,123,123,227,193,131, 7,184,124,249, 50,122,244,232,129,110,221,186,225,201,147, + 39,184,120,241, 34,162,163,163, 65, 16, 4,108,108,108, 96,124, 45,158,141,181,145, 25, 12, 56,242,221,154, 93,243,214,175,223, +210,102,212,168, 81, 56,118,236, 32,198,143,243, 2, 65,242, 65, 16,124, 12,232,239,133,165,203, 30, 32, 40,168, 59,108,109, 57, + 88,191,238,100,178, 70, 67,237, 53,227, 52, 46,191,120,241,162, 92,171,213,162,180,180,148,145, 72, 36, 68, 81,209,235,136,214, +154, 44, 90,106,181, 90, 80, 27,209,211, 71,113,107, 75,203,153, 18, 70, 25, 61,184,216, 20,237,219, 35, 52, 3,239,247, 27,135, + 75, 17,187, 17,121,225, 50,172,217,169, 41, 16,151,159, 43, 76, 41, 84,228,168, 60,183,182,122,111, 2, 43, 83,117, 97,235,212, + 1, 47, 89, 78, 78,244,145,185, 63, 41, 74,235, 18, 90, 0,136,226,231,251, 78,157, 96, 48,160, 99,112, 80, 11,159, 38, 78,188, +146,194,124,230,232,201,115,177,134,148, 99,167,171, 9, 44,166, 30,161,190,116,206,156, 57,223, 86,252,255,203,130, 5, 11, 38, +172, 94,189,218, 46, 55, 55,183,202, 71, 43,191,176, 56,178, 99,223,169, 84, 81,105,153,126,215,250, 89, 67,133, 2, 62,111,193, +234, 93,215,140, 44,220,173,141,215, 68,211,155,135,205, 88, 56, 61,225, 69,180,115, 51, 33, 15, 39,103, 45,194,227,139, 87, 97, + 36,185,152,124,249, 30,116, 6, 10,165,133, 69,184,242,201, 23,144, 56,200,176,229,218,177, 60,154,166,127,106,236,106, 26,209, +136,255, 93,212,166, 69, 8,130,168, 41,199, 94, 94, 13,159, 61,168,235,184, 90,120,254, 10,212,154, 21,222,172, 16,188,194,194, +194,252,235,215,239,225, 90,196,114, 68, 69, 44,199,179,232,199,200,206,210, 35, 43, 79, 11, 11, 11,139, 59,117, 28,250,118,230, + 88, 70,173, 86, 15, 89,176,240,219, 92,129, 80,132,174, 61,123,194,209,206, 30, 34, 46, 7, 44, 19, 13, 22,193,129,178,192, 10, + 47,159,168, 49,123,215,190,124,165, 90, 61,164,134, 78,162, 87,109, 34,131, 32, 8,240, 45,164,224, 73,164,224, 75, 45,222,152, + 70, 20, 88, 88, 64, 32,181, 0,155,199,171,201, 25,254, 15,156, 74,165,242,163,161, 67,135,150,148,149,149, 97,194,132, 9,136, +138,138,138,190,112,225,130,197,147, 39, 79,132, 5, 5, 5, 45, 0,244, 6,176,173, 14,145,245, 6,103, 73, 73, 82, 57, 99,210, + 13, 95,245,237,151, 26,173,201, 6, 97, 99, 14, 65, 76,102,192, 68,209, 96, 0,200,173,121,232,212,107, 25,242,245, 29,113,104, +235, 10, 53,109,208,142,122, 43,135,214, 27,156, 12,195, 48, 14, 14, 14,127, 56, 7,151, 47, 95, 70,216,208,143, 16, 58,120, 16, +236,220, 60, 96,223,171, 15, 66, 39, 76,198,214,173, 91, 65,146, 36,108,109,109,223,238,120,171, 56,247,196,128,115,224, 41,136, + 3, 79, 65,252, 18, 13, 54,128,240,125,251,246,125,231,231,231,119,245,214,173, 91,107, 1, 12,175,254, 91,213,176,248, 45,107, + 86, 77,215,104,254,244,233,211, 53, 9, 9, 9, 16,139,197, 48,153, 76,184,117,235, 22,182,108,217,130,239,191,255, 30,209,209, +209,176,177,177, 65,243,230,205,161,211,233,240,224,193, 3, 13,128,249,117,112,210, 5, 5,166,143, 54,108, 88, 93,212,175, 95, + 23,236,218,181, 9,142,142, 29,193, 97, 59,130,205,177,131, 88,226,141, 29, 63,127,135, 15, 63, 12,192,169,147,135,139, 11,139, + 76, 31, 1, 48,153,113, 47,105,239,221,187,135,173, 91,183, 98,232,208,161, 89, 97, 97, 97, 84, 89, 89, 89,149, 69,139, 97, 24, + 48, 12,131,197, 21, 62,102, 58,157,142, 95, 27,231,196,217,177, 89,179, 86, 60, 91,154,151,155,213, 33,234,234,157,143, 35, 47, + 92, 70,114, 66, 36, 34, 47, 92,198,141,200,219,115,242,114,179, 58, 4,180,111,201, 29, 50, 97,202, 55,123,142, 31, 99, 73, 44, +156,176,231,248, 49,214,200,169, 95,174,104, 23,218, 99,126,125,247,124,197,117,100,148,249,121,115, 87,174,221,168, 52, 25,180, +228,191,126,220,156,173, 41,200,153, 95,237,190,100,234,187, 63, 53, 26,205, 54,173, 86, 43,215,106,181,114,157, 78, 55, 63, 53, + 53,181,235, 87, 95,125, 85, 64, 81, 84,149,181,180,224,249,169, 59,241, 55,127, 89,105,111, 43, 19,118, 12,108,227,181,110,219, +209,107,233, 25,121,191, 86,203,161, 85, 83, 57,181, 74,141,246,163, 65, 67, 70,171, 74, 75,116, 8,254,114, 14,104,129, 4, 58, + 10, 48, 50, 44,152, 8, 50,219, 13, 77, 0, 0, 32, 0, 73, 68, 65, 84, 54,158, 46, 95, 7,161,181, 20,251, 83, 30,169,203,140, +134,143,240,102, 14,173,186,234,254,103,208,200,217,200,217,200,249,207,228,252,111,134, 19,222, 92,235,208,233, 13,139, 86,125, + 33,149,206,206,206, 93, 7, 14,232,133,238,253, 22,128, 97, 24,196, 63, 90,131,146,130, 23,112,118,228, 35, 41, 93, 17, 12, 32, +170, 1,133, 73, 79,205,200,232, 48,125,254,130,227, 97,189,123,182,242,113,115,227, 55,107,214, 20, 98,123,123, 20, 22, 22,224, +230,221,231,198, 21, 7,142,196, 86,136, 44,179, 38, 38,105,154,126,237,228, 14,160,231,244,217, 32, 88, 44,160, 34,141, 67,101, +199,232, 22,216, 17, 4,155, 13,138,161,161,211,233,204,137,150,203,124,245,234,213, 71,163, 70,141,186, 18, 17, 17, 65,134,134, +134,250,159, 56,113,226,207,172,153, 7, 85,126,194, 85, 0,253, 86,204,157,116,168, 67,143, 65, 22,158,109,218,113,219, 53, 99, +193, 96, 36,144,157,149,134,136,227,247, 13,207,239, 93, 80, 48, 38,237,112,117, 97,194,213,186,184, 12, 6, 67,122,139, 22, 45, + 28,182,110,221, 90,229, 12, 79, 81, 20, 10, 11, 11,113,231,206, 29,248, 6, 6,161,213,184, 79, 80, 80, 80,128, 13, 27, 54,160, + 73,147, 38,232,223,191, 63,138,139,139, 97, 50,153,204,157,240,165, 0, 92,168,216,240,150,200, 34, 42,150, 0,170,115,218,208, +195,195,131,167,213,106,253, 25,134, 97, 17, 4,241,131, 94,175, 31, 59,119,238, 92,167,149, 43, 87,194,203,203, 11,133,133,133, + 16,139,197,240,244,244, 68, 65, 65, 1,238,223,191, 79,169,213,234,173,120,189,144,117, 65, 61,229, 75,188,127, 63,165,195,180, +105,159, 31,255,110,245, 36, 79,173,174, 59,207,218,186, 51, 24,198,132,130,130, 84,148, 43,110, 25,150, 45,221,253, 42, 47,223, + 56, 4, 64,130,153,117, 94, 52,101,202, 20, 0, 16, 0, 88,144,148,148, 20,211,170, 85, 43,207,218, 44, 90,230, 96,253,209, 44, + 45,128, 3, 31,133,202,103, 40, 10,159,120, 90,179, 83, 83, 58,248,208, 27,214, 31,205,210, 90,200, 85,203, 11, 83,163, 94,230, +168, 46,108,221,115,252, 24,107,204,224,143, 40, 23, 73,194, 28,129, 61,115,212, 12,106,198,207,207,207,149, 32,138,221,243,139, + 94, 60, 28, 63, 97,210, 48, 75,174,230,172,159, 75, 81,115,178, 73,128, 32, 58, 58, 58, 5, 13,140, 12,173,192,203,172,172,172, +174,115,231,206,189,192, 48,204, 27,190, 9,249,133,197,145,193,253,166, 48,165,165,101, 49, 5,113,167,204,201,165,118,255,254, +163,232,158, 62,190, 1,199,190, 91,185,218,161,251,244,175,216, 47,175, 94, 3, 40, 35,210,162,174,129,226,235,233,117,183, 47, +229,149, 25, 12,131,209,152, 21,190, 17,141,248,159,183,102,213,165, 69,254,225,232,139, 90,156,225,205,174,140,135,187,243, 5, + 47,207,102,189,155,184,216, 1, 0,146, 82,178,145,148,146,117, 49, 41, 57, 43,180, 30,197, 91, 91,120,101,213,162,210, 68, 69, + 10, 7,198,188, 69,165,223,224,180,177,177,121,200,102,179, 93, 26,114, 54, 40,138,202, 46, 44, 44, 12, 48,179,156, 35,221,220, +220, 86,167,165,165, 29,167,105,122, 70, 3,213,126,141,156,149,139, 74,147,108, 94, 47,198,164,247, 5, 0,130,205, 51,103, 81, +233,234,156,190, 18,137,100, 27,135,195,105, 82,121, 29, 43,125,176, 40,138, 98, 25, 12, 6, 1, 69, 81, 44, 0, 4, 73,146, 38, + 14,135,163, 37, 8,194,100, 50,153,210,117, 58,221, 36,252,158,112,180,174,186,215,219,209, 87, 8, 45,212, 96,209,186, 12, 0, + 9, 9, 9, 45,101, 50,217,112,130, 32,134, 50, 12,227, 93, 94, 94,174, 91,184,112, 97,244,145, 35, 71, 20,110,110,110, 31,244, +237,219,151,120,242,228, 9, 98, 99, 99,153,162,162,162,163, 21, 86,172,164, 6,222, 75, 36,159,207, 26, 97,109, 77,246,101, 24, +248,129, 1, 65,144,120, 90, 86, 70,159, 85,171,169, 95, 43, 4, 99, 67,239,207, 74,124,220,172, 89,179,221, 41, 41, 41,156,218, + 44,169,181,213,253,109,172,153,223,102, 65,112,151, 46, 31,221,185,113,227,196,172, 21,207,150, 86,255,110,234, 32,217,248,145, + 95, 76, 95,115, 96,243,143,179, 54,254, 86,178,203,156,114,250,251,251,123, 16, 4, 49, 28,128, 15,195, 48, 45, 24,134, 16, 16, + 4, 83, 66, 16,196, 51, 0, 79,244,122,125,196,243,231,207, 51,255, 68,221,223,101,132, 91, 27,103,213,162,210,160,168,182, 20, +192,152,185,168,244,191,187,156,141,156,141,156,141,156,255, 57,206,255,102,124, 90,195,103,230,101,134,175, 68, 82,114, 86,104, + 82,114, 22, 90,180,104,193, 36, 38, 38, 54, 72,164,213,214, 73, 83, 20,117, 80,173, 86, 31,252, 51, 36, 69, 69, 69,237,254,230, +147,119, 32, 37, 37,229,192, 95, 73, 88, 33,164,150, 86,108,239,138,167, 74,165, 50,200,220,157, 13, 6,195,223,113,110,136, 10, +107,214,146,218,118,232,221,187,119,154,193, 96,184, 12, 32,131, 32, 8, 43, 0,197, 6,131,225,130,201,100,202, 75, 76, 76,108, +183,110,221,186,202,204,247,203, 0, 60,124,199,114,208, 58, 29,181, 63, 59,155,218,255, 55,212,113,191, 94,175,159,105, 99, 99, +211, 92,171,213,242,180, 90, 45,183,122,240,129, 80, 40, 44,168,203, 33,190, 58,172,164,196, 47, 92,118,137,141,149,148,120, 91, + 72,193,218, 25,199, 52,170, 88, 47,107,103, 28, 51,183, 96, 49, 49, 49, 73,126,126,126,251, 72,146,116, 99, 24,198, 1, 96, 44, + 25, 6, 5, 12,195, 20,178,217,236,172,231,207,159,103,253,131, 26, 33,173,137,166,215,154,244,250,223,253, 14, 27,163, 11, 27, +209,136, 70,252,255, 65,173, 62, 90,236,134, 50, 37, 38, 38, 18,141,231,179, 17,213,197, 86, 93, 95,166,165,165,233, 0,220,174, +216,222,198, 67, 0,253,255,233, 21,204,201,201, 9,168,237, 59,115, 69, 22,240,218,103, 11,136,173, 49, 59,251,226,141, 37,229, +216,120,252,155,134,150,237,241,227,199,233, 48,115,138,189, 17,141,104, 68, 35, 26,241,183,225,207, 91,180, 26,209,136, 70, 52, +162, 17,141,104, 68, 35, 26, 81, 35,182, 87, 19, 92,111, 88,183, 8,212, 30, 57,208,144,185,215,119,137, 62,184,220,200,217,200, +217,200,217,200,217,200,217,200,217,200,249, 63,199,249,255, 21,127, 16, 89,255, 14, 52,134,190, 54,114, 54,114, 54,114, 54,114, + 54,114, 54,114, 54,114,254, 47,136,172,183, 55, 0,141, 83,135,141,104, 68, 35,254,135,113,228,200, 17,179, 22, 21, 29, 49,107, + 71, 63,137, 68,182, 80,169, 40, 91,125,112,237,248, 19,149,159,135,133,133, 81,141,103,177, 17,141,104, 4,222,197, 25,222,221, +221,165, 53, 73,209,157, 24,134,100, 49, 36, 99, 36, 20,154, 67, 73, 37, 37,111,164, 29,112,117,117,181,226,144,232, 79, 48,140, +152, 32,104,138,102,145,183,146,147, 51,159, 55,160, 96, 60,153, 76, 54,133,203,229,246,210,235,245, 46, 36, 73,102,234,116,186, +203,106,181,122, 19,254,152,184,240, 63,134,150, 45, 91,142,188,118,237,154, 85,231,206,157,117, 66,161,208,164,209,104,216,231, +207,159,231,127,248,225,135,165,175, 94,189,122,167,136, 68,185, 92,222, 99,199,142, 29,238,161,161,161,104,209,162,133,106,248, +240,225,220,224,224, 96,238,132, 9, 19,146,179,179,179, 35, 27, 72,215,154, 32,136,189, 4, 65,176,104,154, 14,199,239,169, 27, +254,106,144, 36, 73, 78, 34, 8, 98, 48,195, 48, 30, 4, 65, 36, 49, 12,115,130,166,233,186, 18,183,214,133,143, 0,244, 33, 73, + 50, 0, 0,104,154,142, 6,112, 22, 48, 63,242,238,223,201, 41, 18,137,252, 1, 64,173, 86,199,252, 85,156, 4, 65,248, 3, 0, +195, 48,239,202, 57, 78, 40, 20, 78, 4, 0,141, 70,243, 51,204, 88, 14,234,109, 48, 91,189,153,128, 37,241, 0,128,232, 69,222, + 0,128,134,188, 39, 38,199, 19, 13,249,173,154,248, 26,194, 81, 3,250,140, 26, 53,106,229,175,191,254,186, 8,192,201,191,227, +198,119,116,116,221,244,253,143,219,229, 95, 78,249,100, 53, 94,175, 8, 81,247, 3, 9,188,207, 99,177, 6,232, 41,234,198,115, +224, 8, 0,182,181,181,245, 72, 30,143,215, 85,175,215, 59,177,217,236, 28,189, 94,127,189,172,172,236, 0,234, 88, 1,193,236, +243, 26, 7,153, 65, 13, 71,130,254,125,157, 55,134,132,142, 43, 66, 46,209, 10, 37,255,128,102,148, 4, 48,189,162,174, 59, 81, +123, 58,143,186, 26,159, 47,229,114,249, 96,133, 66,161,102,177, 88, 12, 94, 71, 61,191,254,243,250,123,130,166,233,252,226,226, +226,240,250,184,196, 77,224,197, 19, 19,123, 41, 35, 52, 38, 29,243,153, 42, 3,241, 18, 87,116,100,128,112, 6,112, 35, 89,164, + 29, 77,211, 57, 0, 34, 73, 19, 78, 43,179,145,248, 15,237,220,155, 86,156,215,102, 21,239, 57, 0, 28, 0, 60, 1,240, 37, 0, +101,163,254,249,183,225,109,103,248, 51, 0,114,170,132, 86,181,116,247,221,251,245,235, 23,229,238,238,210,122,232,160, 33, 43, + 39, 79,250,140, 96,177, 72,196, 62,123,198,254, 56,124, 92,111,153, 76,230, 44,209,233, 90,129, 32,104,181, 64, 16,171, 80,148, +101, 29, 57,240,171,212,219,203,139,162, 40, 26, 91,183,253,244,225,209,223,142,207, 51, 83,108,181,116,116,116,220, 59,103,206, + 28,199, 1, 3, 6,176, 28, 29, 29,145,154,154,106,117,240,224, 65,175,141, 27, 55, 14, 43, 41, 41, 9, 7,240,242, 29, 42,219, +197,209,154,236, 45, 21, 18, 61, 81, 78,161,220,136, 43,185, 26, 92, 4,112,227, 93,207,158, 90,173,158,170, 86,171,131, 2, 3, + 3,153,157, 59,119, 18, 99,199,142,101, 8,130, 32, 52, 26,205, 47, 0,222, 73,104,137,197,226,205,161,161,161,158,158,158,158, + 73,175, 94,189,234,115,248,240,225,179, 99,198,140,241, 16,139,197, 9, 0, 90, 54,144,110,119, 81, 81,145,159, 70,163,129,139, +139,203, 78, 0,239,253, 13, 55, 17,193, 98,177, 78, 56, 59, 59, 51,107,214,172, 57,233,231,231,231, 80, 92, 92,108,250,230,155, +111,122,221,189,123,247, 67,138,162, 6, 52, 64,108,201, 8,130,216,230,224,224, 96,187,122,245,234,196,118,237,218, 61,225,243, +249,188,132,132, 4,209,204,153, 51,103,188,124,249,114, 24,195, 48,147,128, 6,117, 16, 50,130, 32,182,201,229,114,219,149, 43, + 87,166, 6, 4, 4,196,114,185, 92,110, 66, 66,130,120,246,236,217, 95,198,199,199,191, 19, 39, 73,146, 91,131,130,130,100,139, + 22, 45,138,243,242,242,186,205, 98,177,120,153,153,153,228,226,197,139,167, 92,186,116, 41,140,166,233,201,239, 82, 78,123,123, +123,217,226,197,139,227,130,131,131,239,114,185, 92,238,139, 23, 47,200, 57,115,230, 76, 73, 76, 76, 52,187,156,214,214,214, 33, + 4, 65,108,207,205,205,101, 3,128,147,147, 83,123, 11, 11,139,141,213,215,180,172, 76, 69, 97, 52, 26,203,181, 90,237,168,226, +226,226, 26, 19,225,142,157,187,161, 63, 0,108, 52, 84,190,127,253, 90,223,123, 96,235,105,115, 42,237,239,248, 58, 47,222,247, +170,241,131, 0, 96,100,197, 82,225,223,171, 0, 54,155, 77,251, 59,126,201,196,228, 54, 40,101,204,192, 30, 61,122, 44,142,140, +140,252,169,123,247,238,179,247,237,219,103,159,145,145,241,221,141, 27, 55, 92, 71,140, 24, 49,246,202,149, 43,171, 10, 11, 11, +143,254, 85, 55, 63,143,203,231, 19, 36, 1,161, 64,100, 97,206,254, 28,146,236,119,123,224,192,137, 63,191,120, 17,176, 49, 62, +222, 93,229,228, 20, 52,109,218, 52,135, 33, 67,134,144,174,174,174, 72, 76, 76,180,217,183,111, 95,171,159,127,254,121,112,105, +105,233,116, 0,105,127, 70,100,169, 74,225,171,211, 35,128, 97, 96, 85,245,192, 18, 40,229, 27, 16,205,196,225,233, 63, 64,108, +125,187,123,247,238, 69,137,137,137, 88,181,106, 21, 0,108,106,224,241, 51, 7, 14, 28,216,247,248,241,227,194, 35, 71,142, 8, + 3, 3, 3,225,232,232,136,138,193, 84, 85, 98,106,119,119,119,243,206, 25,141,239,127, 56, 59,254,189,216,226,115,216, 60, 36, +119,149,208, 5,166,142, 3, 61, 7,247, 27, 27, 0, 75, 59, 17, 4, 18, 54, 74,139, 20, 62, 47,162, 51, 66,175, 30, 78,252, 46, +241, 81,193,106, 85, 58,190, 69,237, 57,249,254, 35,176,177,177,217,153,156,156, 28, 34, 22,139,223,248, 60, 41, 41,201,223,211, +211,179, 12,192, 87, 13, 21,110,118,118,118,251,105,154,214, 21, 21, 21,125, 2, 0, 82,169,244, 87,177, 88, 44,203,201,201,153, +247,119, 13,100, 42,241,182, 22,249, 47,183,104, 85,249,107,213,180,214, 33, 65, 82,116,167,201,147, 62, 35,134,143, 28,145,155, +152,148, 76,179, 57,188,145,231, 47, 92, 16,181,110,221,154,212,109,218, 4, 83, 65, 1,140, 51,102,116,188,124,249,178, 49,108, +228,104, 13,135, 69,236,246,112,119, 19, 29, 58,112,208,241,248,177,163,157, 0,212, 39,180,120,142,142,142,123,175, 93,187,230, +236,238,238,142,210,210, 82,164,166,166, 66,165, 82, 97,216,176, 97,156, 78,157, 58, 57, 15, 29, 58,116,111, 89, 89, 89,231, 6, + 88,182, 28, 90,184,176, 35, 38,141, 27,210,242,195,222,157,196,206,174,205,193,228,106,145,241, 42, 62, 48,226,218,221,105,187, +143,157,125,153, 88,198,244, 67,205,107, 35,213,137,194,194,194, 89,131, 7, 15, 62, 22, 18, 18, 98,199,231,243, 33,151,203,137, + 1, 3, 6,228,103,103,103, 47,121,103,213, 82,177,132, 13, 73,146, 84,245,215, 26,150, 7, 50, 7, 46, 50,153, 12, 50,153, 12, + 0,156,255,236,200,211,202,202,106,147, 84, 42, 29,170, 80, 40, 52, 36, 73, 50, 4, 65, 48,122,189, 94, 40,147,201, 30,199,197, +191,148,235,116,186, 22,107,127,248,249,199, 30, 93,252, 44, 46, 93,186,132, 33, 67,134, 48, 23, 47, 94,156,100,238, 58,117, 4, + 65,108, 27, 60,120,176,122,225,194,133,218,196,164, 84,231,184,151, 73,132, 88,192,163,109,109,109, 57,247,239,223,103,175, 95, +191, 94,176,120,241,226,109, 12,195, 12,109,192,249,220, 54, 98,196, 8,195,215, 95,127,157,243, 34, 49,217,254,105, 92, 34, 35, + 17,112, 76,182,182, 54,172,187,119,239,210,239,194, 73,146,228,214, 89,179,102, 41, 38, 77,154, 84, 82, 84, 92,230, 88,162, 80, + 50,124, 14,203,232,232,232,200, 62,121,242,164,110,255,254,253,228,196,137, 19,183,210, 52, 29,214,128,243,187,117,192,128, 1, +229,115,230,204, 41, 77, 72, 74,113,124,250,252, 37, 68,124,142,209,193,193,158,245,224,193, 3,195,218,181,107,201,229,203,151, +155, 85, 78,177, 88,188,231,240,225,195,236,147, 39, 95,183,125,119,238,220, 33, 61, 60, 60, 68,213,247,209,104,117, 32, 9,160, +176,176, 80, 20, 28, 28,188, 7,192, 31,146,251, 6, 44,137,199,216,185,192,212,169, 83,115, 26,122,179, 4, 56, 77,171,119, 31, +234, 39,111,102,189,122,252, 32, 54,155, 77, 79,156, 56, 49,247,237,239,181, 90, 45, 1, 96, 0,190, 51, 95,108,245,233,211,103, +254,153, 51,103,154,239,219,183,111,221,254,253,251,245, 0, 32, 16, 8,108, 15, 30, 60,184,106,216,176, 97, 24, 54,108,216,194, +163, 71,143,254,101, 66,139, 98, 40, 3, 0,240, 5,124,126,124,124, 60,225,237,237, 93,103,198,125, 3, 77, 63,252,249,197,139, +118,159,123,123, 7, 22,211,116, 11,238,135, 31, 42,103,206,156, 89,168, 80, 40,144,154,154, 10,131,193,128,177, 99,199,178,186, +119,239, 46, 31, 54,108,216,134,242,242,242,143, 0, 24,204,184, 39,215, 58, 59, 59,127, 90, 86, 86,166,172,180,234,116, 14,167, +216, 93,253, 77,252,182, 45,140, 60, 46,203,196,237, 63,131, 38, 46,110, 34, 84,222,238,184, 9, 0, 92, 53, 10, 26, 56, 24,168, + 17, 22, 46,112,167, 56, 88,110,231, 34,236, 81,144,166, 89,170, 74,175, 83, 44,125, 36, 22,139, 7,169, 84,170,163, 21,157,115, +203,126,253,250,225,238,221,187, 0,208,169, 66,104,245, 32, 73,242, 99,154,166,119, 0,168,107, 41,183,105, 3, 7, 14,124,255, +248,241,227, 82, 0, 56,122,244, 40,140, 70, 35, 60, 60, 60,192,229,114,193,227,241,192,225,112,170, 86, 7, 49, 19, 78,118,118, +182,176,181,228, 64,102, 45,254,112,246,150,129,236, 38,173, 45,144, 79, 61, 67, 49, 83, 10, 19,163, 3,215, 70, 12,175, 80, 43, + 4,244,238, 65,158,222, 26, 59,239,244,230,184,118,106, 18,253,145, 6,221, 63,165,103, 39, 73,146,255,228,201, 19,200,229,242, + 55, 62,103,177, 88, 0,208,245, 29, 40, 23, 38, 37, 37, 5, 63,122,244, 8, 33, 33, 33, 11,125,125,125, 63,136,138,138,114, 44, + 42, 42, 66, 72, 72,200,134,204,204,204,147,127,119,157,170,107,145,255, 47,166, 46,242, 45, 37,217,253,245, 40,152,100,177, 88, + 36,146,147, 82,141, 33, 33, 61,199,164,167,167, 75,130,130,130, 72, 14,135, 3, 85,100, 36,180, 15, 30, 64, 34,145, 96,240,224, +193,156,235,215,175, 91, 88, 72, 44, 38,164, 36,167,148,179, 88, 36, 24,134,172,215,231, 65, 38,147, 77,153, 55,111,158,163,167, +167, 39, 76, 38, 83, 85, 70,115,147,201,132,140,140, 12, 72, 36, 18,132,135,135,219,139, 68,162, 41,102,214,163, 89, 75, 15,251, +232,107,103,183,189, 55,115,114, 31,113, 75,209, 37,136, 51,166, 67,114,244,115,180,202, 62,143, 57,131,130,196, 23, 55, 47, 12, +104, 46,183,142,174,102, 98, 53, 27, 58,157,238,102,108,108,236,132,168,168, 40, 26, 0,174, 94,189,202,196,197,197, 77,250, 51, +163, 80,154,166, 81, 90, 90, 10,154,166, 89, 21,239, 43, 95,255,163,247,131,133,133,197,214, 15, 62,248, 96, 68, 90, 90,154,240, +220,185,115, 54,233,233,233,182, 41, 41, 41,118, 45, 91,182,100,175, 90,181,234,140, 86,103, 96, 25, 41, 70,111,162,140,229, 57, +207,158, 37,149,228,229, 69,239,218,181, 75, 67, 16,196, 96, 51,127,227, 35, 39, 39, 39,155,185,115,231,130,224,136,218,123,181, +242,245,100,113,132,150, 36,135,103,169,209,104,169,228,228,228,140,185,115,231,186,249,249,249,201,241,122,122,205, 44, 78,185, + 92,110,251,245,215, 95,131,205,151,250,183,245, 11,104,206,227,139,165, 44,142, 80, 26, 20, 20,212, 61, 41, 41, 41,123,206,156, + 57, 78,129,129,129, 13,226, 12, 12, 12,148, 77,156, 56,209, 36, 16, 74,131,221,221, 61, 90,181,109,211,170,111,203,150, 45, 7, +177,217,108, 83, 65, 65, 65, 90,120,120,184, 83,255,254,253, 29, 26,194,105,111,111, 47,155, 51,103,142,201,181,169, 71,104,232, +251,189, 59,112,133, 82, 75, 54, 79,108,165, 86,107,169, 23, 47, 94,164, 45, 88,176,192,201,223,223,223,222, 28, 78,181, 90,205, +177,181,181,133,143,143, 15, 90,123,120,160,172,172, 12,199,143, 31,199,238,221,187,177, 99,199, 14, 28, 56,112, 0,237, 58,247, +134, 84, 42, 69,118,118, 54, 20, 10, 5,231,223,125, 67, 81, 63,121, 51, 27,245,159, 14,248,236,179,207,178, 39, 78,156,152, 43, + 20, 10,233,183, 55,107,107,107,106,212,168, 81,121,225,179,127, 24, 80, 57,181, 88,143, 37,235,201,217,179,103, 95,237,219,183, + 15,173, 91,183, 70,104,104, 40, 15, 0,166, 76,153,194, 27, 54,108, 24, 14, 31, 62,140,163, 71,143, 62,247,244,244,188, 5, 96, +160, 57,229, 12, 15, 15,239, 28, 22, 22,118, 35, 44, 44, 44,102,248,240,225,219, 39, 77,154,244, 70,207,149,147,157,249, 80,175, +215,195, 47, 32, 80,180,108,231,189, 81,245,241,197, 1,251,182,199,199,239, 94,253,236, 89,218,194,214,173,173,154,166,164, 88, +255,178,118,173,109,229, 34,221, 70,163, 17, 25, 25, 25,144,201,100, 24, 53,106,148, 45,159,207, 15, 55,163,152,235, 7, 14, 28, + 56, 46, 61, 61, 93,242,243,207, 63, 59,197,196,196,200,115,114,114,156,174, 92,190, 96,247,205, 87, 83,164,150, 18, 30, 47,187, +128, 33, 0, 32, 37, 27,226,248,100,116,102, 24, 88, 85,159, 78,124, 39, 56, 65, 40,116,193,198,230,157,173, 94,126,125,216,127, +248,156,136, 0, 91,153, 19,127,110, 29, 71,180, 93,179,102,205,145,211,167, 79,143,236,220,185,243, 49, 0,194, 26,246, 17,180, +107,215,238,248,225,195,135,199,117,233,210,229, 38, 0,159, 90, 71,145, 46, 46,131,127,251,237, 55,155,202,247,182,182,182, 16, + 8, 4,127, 16, 89, 92, 46, 23, 36, 73, 54,184,122, 43, 14,142,100, 91,183,210, 33,182,228, 44, 14,175,121,130, 53, 31,190,160, + 87,118, 76,209,109, 10,143,199,197,195, 79,144,143, 39,232,243,121,115,140, 92,224,215, 75, 68, 97,249, 63,169, 3, 47, 40, 40, +248,184,107,215,174, 71,250,244,233,163,123,244,232, 17, 10, 10, 10,224,236, 92, 53,214,206,125, 7, 74,107,145, 72, 4, 87, 87, + 87,120,122,122,142,188,126,253,186,163,209,104, 68, 74, 74, 10,242,243,243,163,255, 29,117,170,174, 69,254,203,240,182, 35,252, +153, 63, 8,173,138,181,133,174, 1, 0, 67, 16,170, 39,177,177, 28, 22,143, 55,250,215,253,251,249, 92, 46, 23,105,105,105,120, +254,252, 57,212, 87,174, 64,115,251, 54,242,242,242,160, 84, 42,225,224,224,128,109, 59,119,138,245, 20, 51,254,197,203,151, 44, +134,100,170,251, 27,212, 24,226,201,231,243,123, 13, 25, 50,164, 86, 65,150,157,157,141, 62,125,250,112, 88, 44, 86, 77, 81, 13, +111,115, 18,114, 59,226,244,149, 99,203,156,156,120,207,129,196,153, 64,121, 52,192,232, 0,147, 30,200,122, 10,156, 89,130,166, +202,120,226,194,178, 49,142,206, 34,246,233, 26,148,114,125,161,168, 30,222,222,222, 59, 70,143, 30, 77, 2, 64,143, 30, 61, 8, +111,111,239,237, 0, 60,234, 56,230,114, 61,157,228,221,146,146, 18, 12, 27, 54,204,166,121,243,230,151,135, 13, 27,102, 83,249, +249,187,114, 86, 90,147, 91,183,110, 93, 36, 16, 8, 14, 0,102, 53,176, 85,156, 86, 86, 86,155,250,244,233, 51,116,255,254,253, + 92, 0,184,118,237, 26, 78,159, 62,141,103,207,158, 33, 33, 33,129, 14, 8, 8,176,251, 97,199,145,173,155,126,218,179,126, 80, + 39, 63,121,247,246, 1,173, 36,202, 18,165,131,131, 67, 39,134, 97, 60,204, 44,103,159, 37, 75,150, 60,143,123,149,102, 73,178, + 57,108, 46,135,205,183,176, 16, 59,200,164, 98, 23,107,145,192,153, 79, 18, 18,181, 90,157,123,224,192, 1, 26, 64, 31,115, 57, +151, 45, 91,150, 28,151,152,102, 69,144,108, 54,135,205,225, 74, 36, 34,171, 15, 67, 67, 2, 1,128, 11,134,171, 80, 40,242,118, +239,222,109,104, 8,231,162, 69,139, 98,139, 75,149, 50, 54,135,195, 97,179, 89, 85,231, 82, 44, 20,218,137,248,124,158, 78,167, +203,250,241,199, 31, 53, 13,225, 92,178,100,201,243, 23,175,210,173, 73,130, 96, 17, 4,201,182,144,138,109,108, 44, 69,118,118, + 18,161,173,136,205,226, 41, 20,138,172,189,123,247,154,197,105, 48, 24,184,121,121,121,136,139,139,131,107, 96, 32, 46, 93,186, +132, 38, 77,154, 96,216,176, 97, 24, 49, 98, 4,132, 66, 33,122, 4,251, 98,238,220,185,120,245,234, 21, 12, 6, 3,191, 38,206, + 74, 63,169,183, 33,151,203, 31,213,119,243,188,117,236, 27,229,244,119, 4,179, 81,255,233,128,234, 2,171, 54,126,107,107,107, +170, 38,107,215,219,156,125,250,244,153,127,229,202,149,230,123,247,238, 29, 16, 30, 30,126,115,239,222,189,232,208,161, 3,226, +226,226,224,230,230,134, 95,126,249, 5, 35, 70,140,184,185, 97,195,134, 1,143, 30, 61,242,115,119,119,159, 87, 31,231,240,225, +195,191,240,247,247,143,204,205,205, 13, 46, 46, 46,246, 57,126,252,248,248,193,131, 7, 39,143, 28, 57,178,103,149, 96, 52, 26, +247,159, 57,117, 12,125, 7, 12,129, 87, 27,159,173, 99,231,237,243,173,231,217,100,158, 1,219,119,231,228, 20,236,215,106,213, +195, 56, 28,145,232,222, 61,235,163, 63,253,100, 91,125,101,129,172,172, 44,244,239,223,159,195,229,114,187,212, 83,206, 53,131, + 6, 13, 26,118,252,248,113, 89,165, 85,231,246,237,219,120,250,244, 41, 82, 83, 83, 81, 90, 90,138,158,147,148,248,108,213,107, +238,207, 86, 49,232, 61,133, 17,191, 99, 27, 82, 5, 97, 19, 56,218, 88,176,111,141,255,209,107,202,167, 91, 91,179, 37,214, 28, +252, 58, 59, 1,133, 41,186,163,181,112, 18,193,193,193,251,194,194,194, 8,189, 94, 15,189, 94,175, 7, 80, 99, 86, 95,103,103, +103, 65,219,182,109, 49,105,210, 36,210,194,194, 98, 67,109,229, 84,169, 84,186,179,103,207, 34, 60, 60, 28,211,167, 79, 71,139, + 22, 45, 32,147,201,192,225,112,176,103,223, 33,219, 17,227, 39,183,124,175,115, 87,191,214,239,117,104, 91,174, 99, 5,114,132, +178,137,181, 88, 67,106,172,187,210,254, 17, 98, 83,238, 96,227,128, 76,250,254, 47,106,229, 55, 31,255, 43,254, 69, 84,222,179, +121, 97,219, 99,153, 59, 29, 11,247,125,153,142, 60, 99, 28,186, 12,107, 10,119,127,217, 12,177, 43,188,223,245,124,154,137, 6, +113,250,250,250,118,190,127,255, 62,191,107,215,174, 72, 75, 75, 3,135, 83, 53,158,162,254, 76, 57,151, 44, 89,194,215,106,181, +120,252,248, 49,198,140, 25,147,101, 48, 24,102,252,153,114, 54,196,162, 85,169, 69,254,203,176,253,173, 45,167, 54,139,214, 18, + 0, 48,210, 56, 61,122,204,120,117, 68, 68,132,136,199,227, 33, 45, 45, 13, 57, 57, 57,216,179,123, 55,213,195,222,190, 60,212, +217, 89,177,103,247,110, 70,175,215,131, 97, 24,120,123,123, 99,232,208,161,194,143,134,141,204, 39, 20,154, 67,102, 76,243, 56, + 85,206,175,143, 31, 63,254, 15,223,127,243,205, 55,176,176,176, 0, 65, 16,142,102, 84, 46,108,218,146, 65, 46, 50,119,171, 60, + 38,119, 79, 49, 88, 2,128, 45, 5,216, 22,128,192, 18,224, 75, 1,158, 8,186, 71,145,197, 36, 19,154, 58,164,203, 39,206, 0, + 26, 50,213, 3,185, 92,190, 48, 50, 50,210,238,209,163, 71,140, 66,161, 64, 78, 78, 14,179,114,229, 74, 59,185, 92,190,240, 93, +175, 72,118,118,246,178,190,125,251,230,141, 25, 51,198,242,252,249,243,174, 99,198,140,177,236,219,183,111, 94,118,118,246,178, + 63,115,165,185, 92, 46,235,217,179,103,214,203,151, 47, 31, 1,224, 97,155, 54,109,138,156,157,157, 31,226,181,211,100,157,144, + 74,165, 85, 34,171,210,186,198,102,179,193,225,112, 32,151,203,245,197,197,197, 84,151,247, 60,132,222,150,164, 81,206,231, 10, +173,133, 2, 23,169,133,101, 80, 81, 81,209, 19,130, 32,146,204,156,226,243,111,223,190, 61,135, 98, 56,244,103,163,123,200,167, +140, 11,177,223,178,124, 98,147, 31,151,125,234,188,102,241, 4,239,101,179, 70,133,144, 52,173,117,115,115,115,172,116,104, 55, +195,124, 30,208,174, 93, 59, 54, 13, 14,226, 94,166,230,165,101,102,149,191,223, 61,184,202,114,217,218, 63, 32,212,206,206,174, +171,183,183,119, 59,130, 32,204, 10, 73, 22, 10,133,254, 94, 94, 94,108,146,197, 33,108,100, 82, 87,169, 68,232, 80, 53,133, 98, +101,213,209,218,206, 46,140,100,152, 50, 39, 39, 39,123,161, 80,232,223,128,186,179,105,112,225, 96,111,109,105,103,107, 37, 9, + 13,233,212, 34,184, 99,112, 75,223,160, 14,193,109,222,107,247, 17, 97, 50, 41, 60, 60, 60,236, 43,157,228,235,177,180, 10,246, +239,223,143,229,203,151,163,109,211,166,112,118,118,134,189,189, 61,110,223,190,141,251,247,239, 67, 38,147, 33, 63, 63, 31,107, +215,174,197,137, 19, 39, 96, 48, 24,164, 13,189,159,204, 17, 91,117,193,100, 50,145,111, 11,172,218,248,133, 66, 33, 93,233, 36, + 95, 27,206,158, 61,187,175,210,146,245,229,151, 95,118,254,225,135, 31,110,198,199,199, 67, 34,145,224,254,253,251, 24, 63,126, +252,205, 13, 27, 54,116,158, 60,121, 50,118,239,222,141,228,228,228,157,117,241, 13, 31, 62,124,241,132, 9, 19,126,140,138,138, + 34, 29, 28, 28, 32,147,201, 48,104,208, 32,236,220,185,147,109, 50,153,118,133,133,133,197,132,133,133,197, 80, 25, 23,231, 31, +217,177,242,118,236,147, 24,124, 49,237,107,158,222,100,156, 99, 70,245, 25,141, 68, 82,110,234,218,181,248,176,209,168, 30,206, +229,138, 44, 99, 98,172, 79,239,218, 85, 37,182,230,206,157, 11, 75, 75, 75,224,181, 3, 51,234,176,234,124,122,226,196,137,170, +246,208,198,198, 6, 60, 30, 15, 92, 46, 23, 28, 14, 7, 44, 22, 11,151,183,138,241,211,220,215,250,226,167,185, 4, 46,110, 34, + 84,127,230,218,137,156,225, 35,115,224,197,124,254, 75, 27, 63,159,158, 54,184,125, 48, 23, 43,251, 62,202,188,127,184, 96,166, + 54, 31,223,215,114,216,123,223,124,243, 77,235,252,252,124, 60,120,240, 0, 15, 30, 60,168,205, 2,164, 61,117,234,212,119, 74, +165, 18,238,238,238, 24, 56,112, 96, 87, 0,129,181, 60, 55,104,215,174, 29,250,247,239,143,144,144, 16,180,109,219, 22,122,131, +137, 19, 54,250, 83,175,103,201, 5,206, 43,215,174, 20, 69, 94, 61, 78,222,188, 25,197,218,119,236,162,101,112, 72,239, 31,185, + 82,167,187, 16,218, 56,153, 83, 79, 53, 85, 4,127,167, 15,177,253,202, 52,114,227,181, 49,146, 61,167, 55,122, 72,165, 82, 34, +250, 65,140,113,207,230,195,233, 62,226,129,249,119, 15, 22, 65, 77,228,162,231, 56,119,146, 6,134,254, 83,122,118,129, 64,240, + 67, 84, 84,148,163,193, 96, 64,108,108, 44,166, 79,159,174,253,147,148, 85, 6, 16, 87, 87, 87, 92,187,118, 13,163, 70,141,210, +230,229,229,221,249,119,213,169,186, 22,249,255, 2,118, 53, 5, 89,133,140,140,140, 82,153, 76,230,236,229,229, 69,234,245,250, +215, 83, 18, 71,143, 82, 59,118,237, 58,163,213,106,167, 1,224,110,218,178,101,171,179,139, 75,200,232,240,112,194,104, 52,162, +111,223,190,188,136,136, 8,155,164,252,252,114, 51, 58,156, 55,126,111,236,216,177,248,225,135, 31, 0, 0, 83,167, 78,173, 50, +173, 19,102, 56, 44, 73, 44,209, 39,180, 95, 59,139, 12,241, 70, 11, 67, 71,163,178,217, 43,233, 93,177, 82,216, 14, 36,143, 13, + 1, 11,180,193,104, 74,200, 31,252,240, 85, 66,171,214,194,226, 34,183, 94,109,186, 97,199,165,189,125,212,148,246,176,217, 13, +142, 72,212, 94, 34,145,224,225,195,135,197,237,218,181, 43,101, 24,198,114,217,178,101,182, 34,145,168,253,159, 56,247, 41, 47, + 95,190,236,218,169, 83,167, 41, 36, 73,246,162,105,250,114, 94, 94,222, 38, 0, 41,102, 30,255, 25,128, 69, 0,170, 70,150,122, +189, 30, 36, 73,130, 97, 24, 12, 31, 62, 28,115,231,206,109,253,244,233, 83, 68, 70, 70, 90,247,234,213,235, 46,128, 82, 0,159, + 0,168,209,106,166, 80, 40, 52,247,239,223, 23, 70, 70, 70,130,166,105, 88, 91, 91,195,194,194, 2,124, 62, 31,131, 6, 13,146, +204,153, 51,167,231,133, 11, 23,242, 21,205,154,176, 4, 57, 89, 42,190, 68, 34,133,163,115,151,201, 35, 63,142,103, 24,230, 68, + 3, 26, 7,158,144,109,210, 18,148,142, 92,243,237, 6, 82,196,229, 18, 2, 46, 27,124, 90,141,249,223,173, 32,184, 12,197, 70, + 3,231,231,185, 92, 46, 87,202,135,158,197, 99, 25, 69, 4,152,191,226,225, 96,177, 88, 60, 1,183,118,127, 12, 14, 73,146, 36, + 73,114, 1,152,189,104, 31,159,207,231, 74,249, 76,173,156, 66, 22,193, 34, 8,130,135, 90, 34,209,252, 29,193, 84, 90,145,120, +211,146,116,213, 69,113,151, 46, 93,112, 38,242, 33,142,158,190,140,194,180, 39, 88, 48,251, 75, 4, 6, 6, 34, 34, 34,162,206, + 50, 85,250,104,213,102, 93,150,203,229,143,178,179,179,223,171,237,216,186,166, 12,107,177, 82,253,145,255, 91, 75, 4, 44,137, + 71, 61, 62, 90, 3,187,116,233,242,197,254,253,251,245, 31,124,240, 1,111,248,240,225,240,241,241,233, 60,110,220, 56, 0, 64, +175, 94,189,240,195, 15, 63,116, 30, 55,110, 28, 14, 29, 58,132,227,199,143,235,186,119,239, 62,251,218,181,107, 89,120, 29,209, +249, 7,208, 52,221,127,219,182,109,111, 91, 10, 97, 50,153, 96, 52, 26,157, 76, 38,147, 83, 69, 91,132, 31,127,220, 80,120,241, + 66, 4,102,207, 91, 2,123, 59, 71,127, 51,239, 33, 98,236,215, 95, 23,254,178,118, 45,214, 30, 58,132,175,221,220, 68,123,159, + 63,199, 69,173, 22,135, 35, 35, 11, 43,126,167, 94,223, 76,149, 74,165, 57,123,246,172,197,225,195,135, 97,101,101,133, 22, 45, + 90,192,218,218, 26, 28, 14, 7, 36, 75, 8, 22, 87, 6,175, 54,237, 1,220, 7, 0,184,201,161,242,118,199, 77,130, 64, 41, 67, + 54,220,167,136,223, 4,205,108, 93, 4, 81, 95,236,246,177,178,176,231,226,252,166,116, 92,216,152,113, 66, 91,136,117, 48,225, + 5,106,247,249,106,231,238,238,142,252,252,124,156, 61,123, 86, 5,212, 42,200, 64,211,244,119, 91,182,108,249,102,222,188,121, +124,111,111,111, 0,240, 7,240,160,166,125,197, 98, 49,156,157,157,171,132,229,240, 49,147, 61, 38,205,156, 44, 28,220, 59, 4, +108,182, 45, 74, 85, 70, 20,149, 27, 33,179,149, 96,246,204, 48,193,229,118,206,129,219, 54,252,122, 74,163, 65, 32,240,199,246, +128, 32,240,224,222,147,155,190, 2,111,128, 32,129, 12,242, 42, 8, 16, 80, 18, 70, 16, 44, 22, 67, 81, 20,210,211,211,193, 48, + 12, 70, 13, 30,159,241,233,202,227,246,157, 71, 41,224,234, 37, 7,193,160,219, 63, 69, 8,216,216,216,248, 23, 21, 21, 33, 37, + 37, 5, 99,198,140,201, 42, 44, 44,188,164, 82,169,198,103,103,103, 3, 64,241, 59, 80, 86,137,121,127,127,127,180,111,223, 30, +195,134, 13, 19,168,213,234, 48, 15, 15, 15,231,130,130,130,142,127,103,125,222,214, 34,255,175,132, 86,141, 15,154,209,232,165, +219,186, 21,170,203,151,193,187,120, 17,135,229,114,165, 86,171,253, 10, 64, 70,197,131,255,229,238, 95,126,185, 53,224,206, 29, + 11,125,124, 60, 60,158, 62, 5,199,202,202,191,161, 5,216,181,107, 23, 20, 10, 5,202,202,202, 0, 0, 27, 55,110,132, 66,161, +128,201,204, 5,103,217, 92,116,118,180,119, 67, 46, 18, 64,179, 73, 73,170,151,186,131, 68, 43,205,118, 78,119, 80,149,145,206, +136, 79, 11, 18,107,138,244, 29, 8,150, 30,218, 66, 53,156, 59,181, 0, 27,236,206, 13, 41, 99,229,188, 63,155,205, 46,126,249, +242,101,255,150, 45, 91,158, 6, 96,251, 46,254, 0,111, 33, 49, 47, 47,111,218,187, 28,200, 98,177, 22, 37, 39, 39,219,239,220, +185,115,202,178,101,203,152,234, 66,171,242,127, 54,155, 13,134, 97, 96,105,105, 9, 14,135,227,112,251,246,109,135,160,160,160, +205, 52, 77,251,215, 82, 79,198,199,199, 7,201,201,201, 96,179,217,176,180,180, 4,109, 50, 96,201,204,201,160, 88,124,246,172, + 89,179,252,135, 12, 25, 18,187,115,231, 78,163, 69,112,167,142, 69, 69, 69,207,190, 24, 53, 58,246,228,201,147,250,138, 20, 15, +245, 15,241, 25, 38, 38, 33, 33,129,229, 34,119, 96, 49, 38, 53, 45,230, 2,130, 39, 63, 50, 60,137, 35, 4,108, 22,195, 37, 72, +240, 5, 66,203,148,204,204, 34,154,166,227,204,225,164,105, 58, 58, 57, 57, 89,232, 96,111,195, 86,107,244, 74, 33,135,225,165, + 70, 63, 76,106, 22,208,206, 3, 0,180,209,247,175,241,189, 90, 9, 83,243, 10,196,110,110,110,102,113,106, 52,154,152,172,172, + 44,150,131,131, 3, 59, 45, 35,243,148,149, 68,108,103, 97,101,213, 1, 0, 12,229,101,247, 73,157,174,128,197, 97, 59, 20, 20, + 21, 21,107, 52,154,100,115,235,254,234,213, 43,182,147,147, 61,235,252,197, 43,167, 29, 68,124,123, 41,143,109,193, 39, 8, 66, +196, 34, 20, 92, 19, 93, 40, 16,137,236, 83, 50, 51,139, 25,134,169,213, 66,184,186,116,244,224,215,215,107,201,161,106,220,120, +242,228, 9,206,221,140,131,152,209,131,208,150,225,226,238,159, 49,106,214,188, 63,237,247, 87,159,216,122, 39,107,214,182, 86, +143,222,226, 71, 78, 61,142,240,163, 70,141, 90,178,111,223,190, 42, 7,148,184,184, 56,244,232,209,163,114,154, 3,161,161,161, + 8, 10, 10, 66, 92, 92, 28, 60, 61, 61, 17, 25, 25,201,103,177, 88,252,209,163, 71,175,252,245,215, 95,207,214,107,247,223,190, + 29,227,199,143,175,201,177,250, 21, 0, 45, 33,243, 86,206, 93,189,199,182,184,168, 16,249, 5,185, 49,230,158, 7,130, 32, 48, +246,235,175, 11,183,233,245,216,127,239, 30,194,197, 98,209, 47,137,137,232, 27, 20, 4,223, 30, 61, 10,205,105,235, 42,173, 58, + 90,173, 22, 28, 14, 7, 22, 22, 22,176,177,177, 1,151,203, 5,139, 35, 7,155,231, 7,146,203, 69, 64, 23, 63,172,253, 74,172, + 30,243, 33, 54, 16, 4, 74,249, 60, 68,115, 69,181,250,234, 16,226, 38, 24,196, 48, 80,168, 51,112,181, 82,144, 88, 54,133, 37, + 71,202,185, 56, 97,179,183,149,133, 61, 23,231, 54,164,225,226,230,204, 99,218, 92, 44,168, 56, 23,116, 29, 3, 9, 95, 43, 43, + 43,100,100,100, 32, 61, 61,253, 57,234,118,240, 87,199,197,197, 37,241,249,252,214,118,118,118, 0,224, 94,219,192,156,166,233, + 42, 63,172,189,251,143,216,250,119,245, 16,188,223,185, 53,246,156, 94,129,207,195, 54,128,195, 34, 64, 81, 6,172,251,161, 31, + 40,157, 18, 97, 3, 62, 37,186,245,242,244,187,124, 90, 63,193,168, 41,249,249, 15, 3, 1, 54,150,255,107,196,109, 43,190,132, +244, 5, 77, 88,217,218,218,139,185, 92, 46,108, 44,156,244,243, 38,205,158,147,240,216, 0, 0, 32, 0, 73, 68, 65, 84,200, 97, + 24,166,234,185,225,176,184, 70,178,220, 90, 83,148,171, 20, 90,113, 52, 0, 67, 54,123,183,108, 54,127, 61, 50, 51, 51,167,117, +237,218,117,101,121,121,121,137, 74,165, 26, 5, 0,238,238,238, 77, 73,146,228, 3,168,107,118,164, 41,106, 78, 11,193,125,250, +244, 41,164, 82, 41,178,178,178,170, 27, 95, 64,211,244, 63, 38, 8,224, 31,138, 0, 0,209, 0,156, 0,244, 69,181,244, 14,100, +133,169,174, 91, 68, 68, 4, 19, 17, 17,209,173,170,243, 98, 24,218, 84, 92, 12, 70,247,250,220,114, 56, 28, 6, 64,245,136, 38, +145,149,149, 21,193,113,113, 1,193,127,237,250,193,252,133,161,175, 70,163,121,169,101,104, 10, 44, 16, 6, 48,213, 6, 45, 42, + 1,129, 21,182, 61, 49,141,183, 16,185, 60,171,234, 61, 29, 96, 98, 64,129,102, 53,176, 56,140, 74,165,130,201,100,146, 53,111, +222,252,140,201,100,146, 85,116,110,204,127,234,138, 82, 20,149,196, 98,177, 48,101,202, 20, 84, 90,127,244,122, 61,114,115,115, +161,211,233,160,215,235,145,156,156,140,178,178, 50,232,245,122, 60,123,246, 12,238,238,238, 96,177, 88, 78,117, 52,230, 12,195, + 48,112,117,117, 69,179,102,205,192, 34, 24,236, 88,179, 24,243,167, 79,198, 8,119, 26,187, 54,173, 67,247,238,221, 91,185,185, +185, 5,179,217,108,202,209,209,145,123,252,248,241, 83, 20, 69, 13,130,249, 45,207,217,185,115,231, 54,107,211,166,141,189,149, +133,212,200,231,177,192, 51,170, 24,190,174,136, 97,171, 11,225,234,218,212, 4,161,200, 51, 60, 60,156,170,205, 10, 81, 19,231, + 87, 95,125,229,228,237,237,109, 41,179,146,170,120, 28, 86, 62, 23, 76, 97,217,147, 7,119, 1,128,103,103,175,133, 64,212,122, +204,152, 49,166,134,112, 46, 92,184,208,221,206,206,206,138, 4, 83, 78, 25, 12,191,207,183,235,244, 69, 4,135,163, 1,151,215, +110,234,212,169, 68, 67, 56,191,249,230, 27,183,214,173, 91, 91, 89, 89,136,149,108, 14, 43,135, 75,211, 57, 2,208,185, 28,189, +161, 68, 96,103,171,134, 72, 18, 16, 30, 30, 94, 43,103,165, 53,107,206,156, 57, 25,111, 9,111, 20, 23, 23, 67,155, 27, 11,110, + 86, 60,252, 36, 28, 4,218,201,192,231,243,171, 66,223,107,187, 93,107,243,209,170, 73,108,153,123,108,187,165,117, 76, 1,110, +107,245,232,237,188, 89,217,217,217,112,114,114,170,243,121,250,245,215, 95,231,133,132,132,228,135,134,134,234,207,156, 57, 3, +130, 32, 16, 25, 25,137,172,172, 44,132,134,134,130, 97,152,202,168, 54,196,196,196,160, 87,175, 94,250,174, 93,187,102, 85,228, +215,170, 23,227,199,143,135,209,104,132, 82,169, 68,113,113, 49, 34, 34, 34,224,231,231,199,136, 68,162, 33, 44,215,222, 43,194, + 38,204,235,232,211,214, 31,155, 55,172,213,243,216,156,213, 13,121, 94, 9,130,192,152,175,190, 42, 44, 11, 8, 40,222,171, 82, +169,199, 90, 88,136,154,103,100, 88, 63,188,112,193,214, 96, 48,152,197, 81,105,213,113,113,113,169, 18, 89, 92, 46, 23,108,158, + 29, 88, 98, 95,240,108, 66, 33,114, 28,130,171,209,124,157,165, 24, 39,164, 18,156, 23, 91,213,158,218, 65,228,138, 21, 29,135, + 59, 29,239, 52,194,233,138,168, 9,118, 86,244, 7, 36,195, 38,142,143, 91,215,178,185, 93, 51, 33,238, 28,201,197,197,205,153, +191,105,115,177, 24, 64, 98,125,207,185,193, 96,208, 82, 20, 5,146, 36,193,102,179,171,251, 4,222,250,237,183,223,240,240,225, + 67,160, 90,218,158,242,242,114,138,197, 98, 65, 32, 16, 0,128,164,142,246, 14, 28, 14, 7, 28, 14, 7,215,238, 94,183, 25,241, + 81, 63,226,246,227, 75,232,228, 55, 18, 69, 74, 3,242,202, 12, 40, 85, 3,109, 2, 23,192,167,215, 9, 60, 73, 46,135,127, 91, + 31, 22,139, 39, 30, 83, 19,159, 54, 5, 25,170,116, 12, 45,122, 78,183,208,103, 10,207,221, 57, 25,247,252,250,209, 39,207, 14, +110, 57,157,216, 49,176,171,170,194,152, 0,165, 82,201, 16, 4,193,204,152, 56, 47,105,239,248, 18,106,195,168, 39, 52, 91, 39, +120,245,111,108,234,155,218,217,217,221,182,177,177,137,172, 16, 71, 77,165, 82,233, 45, 39, 39,167,120,188, 14,244, 56,153,147, +147,227,173, 82,169, 58,225,117,112, 86, 90, 81, 81, 81,143, 10,203, 83, 90, 29,150,176,157, 10,133,226, 75,138,162, 6, 84,108, + 31, 82, 20,229,159,144,144,208,218,223,223,255,185,135,135, 71,140,135,135,199, 57, 15, 15,143, 83, 30, 30, 30,167, 66, 66, 66, +126,168, 76,247,240, 55, 79, 27,254, 65,139,252,151, 9, 45, 84,136,172,237, 21,175,168, 18, 90, 0,174,189,237,128,102,226,243, +159,153,190,248, 2, 86,167, 78,129,147,144,128,113, 99,198, 88,136, 68,162, 13,120,157,163,169,147, 68, 34,217,188,120,241, 98, +169,237,170, 85,144, 95,191,142,212,136, 8, 24, 57,156, 7,239, 82, 58,141, 70, 3, 54,155, 93,101,137, 17,139,197,160, 40, 10, + 53,153,124,255,240, 0,154,112, 39, 43, 47, 30, 60, 52, 3, 13, 70,121, 94,209,245,222,200,164, 5,246, 17, 10,119,207, 68, 21, +215,115,169, 93, 7,251, 13, 77, 59,223, 83, 17,108, 37,207, 74,128,244,244, 12, 80,160, 27, 52,223,172,213,106,203, 84, 42, 21, +252,253,253,109, 30, 62,124,216,220,207,207,207,186,226,243,251,127,242,194, 4,203,229,242, 35,206,206,206, 41,114,185,252, 8, +128,224, 6, 28,187,243,198,141, 27, 96,177, 88, 88,188,120, 49,202,203,203, 97, 48, 24, 80, 84, 84,132,244,244,116,232,245,122, +100,102,102,226,197,139, 23,208,235,245, 72, 77, 77,133, 78, 87,255,128,132,166,105, 88, 88, 88, 64,171, 81,226,167, 21,243,177, +112,206, 76,148,189,122,132,204,236, 60, 88, 89,138, 49,109,218, 52,150, 76, 38,163,105,154,110, 70, 81, 84, 47,154,166,183,154, +115,157,170,221,111, 55, 93, 93, 93,125,214,172, 89,211,122,254,138,173, 92, 11,182,146,225, 75, 5, 52, 79,202,103,120,173, 58, + 96,252,130, 13,220, 31,215,127,255,242,206,157, 59, 89, 48, 47,121, 39, 9,224,102, 64, 64, 64,203,172,172, 44, 63,111,111,111, + 47,219,166,110,124,190,147,115, 41,215,169,137,130,209,105,239, 17,206, 77,186,108,221,186, 53,246,214,173, 91,217, 13,225, 20, +139,197,173,246,236,217,227,227,224,224,224,195, 17, 10, 5,234,178,178,195, 38,181,234, 8,203, 74, 38, 32, 45,172, 62, 60,113, +226,196,163, 99,199,142,229, 54,132,211,211,211,211,123,197,138, 21,109,124,125,125,219, 56,186, 55,231, 11,157, 93,139, 4, 46, + 77,139,132,190,126,124,184, 52,251, 96,243,230,205, 49,119,238,220, 49,139,147,197, 98,153, 72,146, 4,135,195,129, 72, 36,194, +249,243,231,241,197,132,145,112,117,182,129,151,183, 55,122,126,254, 37,142, 29, 59, 86,229,195,195, 98,177,106,237,209,127, 89, + 53,237,116,128, 19,241, 8,219, 90, 61,194,182, 86,143, 2,156,136, 71,181,138,173,138,239,107,218,199,172,214,168,150,233, 70, + 51,196,214,217,107,215,174,125, 55,118,236, 88, 94,159, 62,125,112,239,222, 61,140, 31, 63,254,230,241,227,199, 1, 0,247,238, +221,195,140, 25, 51,110, 94,185,114, 5,147, 39, 79, 70,143, 30, 61,120, 55,110,220,216, 12, 51,114,255,152, 76, 38,236,218,181, + 11, 38,147, 9, 18,137, 4,214,214,214,232,215,175, 31, 98, 99, 99, 39,239,222,189, 59,158,197,225,124,220,119,192, 71, 56,115, +234, 56, 94, 60,139,157,252,203,202,209, 13, 78, 10, 76,146, 36,250,140, 25, 83, 88,216,166, 77,241, 47, 10,133,250, 19,153, 76, +228,157,155,107,125,245,200, 17, 91, 51,132, 26, 65, 81, 84,149,184,170, 20, 29,149, 27,155,103, 7,182,216, 7,108,105, 32,158, + 36,114,141,220, 32, 68,243, 2, 17, 87, 87,254, 44, 14,143, 28, 63,100,190, 59,134,204,119,199,192, 89,110,227, 68, 77,176, 67, +220, 4,159,245,153,222, 44,196, 35,208, 18,138,124, 3, 34,214,165,166,105,139,176, 10,192, 11,115,158,115,154,166,159,103,101, +101,129,199,227,161, 73,147, 38, 45, 1, 84,250, 5,238,156, 56,113,226,212,165, 75,151,206, 4,176,180,226, 51, 73, 72, 72, 72, + 27,165, 82,137,132,132, 4, 0,120, 88,135, 53,184, 42,202,176, 88,145,202,119,147,251,194,175,213, 36,200,100,109,145, 85,172, + 71,118,177, 30, 59,126, 26,132, 71, 55,150,227,225,197,112,164,229,230, 66,232, 56, 24,148, 73,231, 99,198,160, 94,254,248,241, + 99,226,198,141, 27, 4, 77,211, 48, 26,141, 76,185, 66,193, 68,223,188, 9, 77, 84, 20, 97, 97, 97, 65,116,110,223, 85,249,203, +242, 51,247, 79,108,186,249,208,160,110,240, 64,253,207, 96, 97, 82, 82, 82,240,145, 35, 71, 66, 0, 44,244,245,245,189,147,158, +158,222,241,250,245,235, 94, 46, 46, 46, 27,222,149,180, 50, 45, 68,106,106,234, 27, 91, 69, 90, 8,125,133,104,232, 83, 33,230, + 6, 2,152,129, 63, 17,101,223, 0, 92,251, 47,118,134, 63,131,183,162, 13,223, 22, 90,213, 19,133,193, 67, 38,147, 26,141,134, +204, 75,151, 46, 25, 72,146,132, 72, 36,194,216,241,227,201,159,182,108,233, 50, 50, 56, 56,242,211,247,223, 63, 23,121,229, 74, + 64, 80, 80, 16, 24,134, 1, 73,146, 56,116,232,144, 70,171,213, 20,185,186,186, 90,153,211,104, 84,127,128, 20, 10, 69,149,208, + 42, 43, 43,131,131,131,131,217, 83,135, 42, 5, 46, 95, 57,255,168,132,161, 62, 79,239,147,184,222,176, 58,119, 80, 80, 41, 77, +177,203, 40, 35,202, 52, 12,202,181, 96,223, 35,173,131,198,122, 14, 54, 36,247, 10,122, 17, 21,127,187, 72, 75,105, 27, 20, 45, +145,159,159, 63, 63, 44, 44,172,200,201,201,137,176,176,176,128,179,179, 51, 57,112,224,192,194,140,140,140,165,239,122, 69,108, +108,108, 70,132,132,132,156,206,202,202, 26, 26, 21, 21,213,236,250,245,235, 67, 67, 66, 66, 78,219,216,216,140, 48,147,226,240, +188,121,243, 84, 60, 30, 15, 29, 58,116, 64,121,121, 57, 42,162,124,234,220,204,153, 34,229,114,185,216,182,102, 17, 22,206,153, +137,226,248,123,120,114,243, 18,174,229, 18, 88,176,226,123,112,185,220,119,202,245,213,194, 78,228,235, 43,151,198,205, 24, 63, + 60,123,238,156, 57,210,152,152, 24,206,212,233, 51,152,212,156, 98,240,250,172,101,161,219,124,242,177,202, 14,125, 63,236,137, +197, 11,191,246,173, 72,218, 89, 39, 90,217,137,124,125,228,210,231, 95,127, 58, 50,105,250,244,233,194,213,171, 87,107,131,131, +131, 53,121,121,121, 66,177,204,218,155,109,105,229,147,154,147, 43, 9, 14, 14, 78,254,252,243,207, 75, 27,202,185, 96,193, 2, +209,133, 11, 23,216, 97, 97, 97,166,146,146, 18, 9, 71, 40,244, 39,248,130,246, 5, 37, 37,150, 67,195,194, 18,135, 14, 29,170, +174, 72, 88,106, 54,231,183,223,126, 43,122,241,226, 5, 59, 56, 56,216,152,155,155, 43, 21,219,216,250,177,172,172, 3, 83,114, +242, 44,218, 7, 5,189,154, 58,117,170,170,174,114, 86, 23, 41, 82,169, 52,171, 83,167, 78, 88,183,110, 29,126,252,241, 71,124, +240,193, 7,136,125, 22,139,190, 83,103,162,245,103, 51,112,234,246, 93,100,101,101, 97,217,178,101,240,243,243, 3,151,203,125, + 81,227,243, 56, 57,158,136,201, 5, 17,147, 11,130,152, 28, 79, 84,190,175,213,178,181,180, 12,213,247,175,105,191,135,223,214, +108,233, 10,112, 34, 30,213,229,135, 85,159,216, 26, 58,116,232, 23,149, 41, 28, 62,249,228,147,155, 27, 54,108,232,252,201, 39, +175, 7,218, 29, 58,116,192,242,229,203, 59, 47, 88,176,224,230,138, 21, 43,208,179,103, 79,120,120,120,212, 27,248, 66, 81, 20, + 76, 38, 19, 70,142, 28, 9,147,201,132,130,130, 2,188,124,249, 18,219,183,111, 7,195, 48, 2, 0,112,146,187,180,227,241,120, +120, 28,253, 64,189,240,147,160, 95, 27, 96,201, 34,170, 15, 98,148, 74, 37,134,126,246, 89, 97,102,139, 22,197, 91, 11, 11,213, + 19,100, 50,145, 91, 90,154,181, 84,175,119, 70, 29,126,137, 4, 65,128,166,233, 42, 97, 85, 41,184,222,222, 42, 58, 74,179, 96, + 80,211,103,175,239,203, 6, 0,116, 29, 45,199,192, 89,110,227,156, 60, 69, 27,187,140,122,109,244, 62,182, 60,137, 41,207,166, + 86,195,136,231, 13,176, 88,223,187,119,239, 30,172,172,172, 16, 22, 22,198, 39, 73,114, 85,229,120, 21,175,115,103,173,175,228, +226,243,249,107,195,195,195,201,210,210, 82, 60,121,242, 4, 0,174,212,214, 46, 49, 12, 83, 85,119,101, 49, 1,138,230,225, 86, +244,121, 92,188,126, 20, 41, 89, 5, 72,203,215, 2,108, 75,104, 85,153, 48,104,178,160, 47,141,134, 66, 39, 50,171,192, 92, 46, +183,192,215,215,151, 9, 12, 12,100, 24,134,193,171, 87,175, 76,169,105,105,166, 7, 63,252,192, 60,157, 52,137,144,190,124,201, + 21, 10,133,132,187,187, 59, 4, 2, 1, 45, 16, 8,138,254,141,157,247,223,146,110,225,111, 72, 11,241, 87, 90,181, 24,252,119, + 34, 7,111, 70, 27, 86, 37, 48,173, 41, 97, 41, 24, 11,225,240,163,155,127,178, 12, 27, 57, 90,229,231,231, 39,115,118,118, 6, + 65, 16, 24, 52,120, 48, 17, 18, 21, 37,229,200,229,176,121,239,189,170,233,136,203,151, 46,225,252,249,243,170, 51,191,157,112, + 30, 63, 97, 66,127, 0,123,234, 40, 12,155,207,231, 87,253,110, 78, 78, 14,248,124,126,149, 79,132, 66,161,128,157,157, 29,114, +114,114, 96,230,204,220,222,185,115,238,206,201, 15,154,239, 30, 36,229, 16,231, 84,185,160, 24, 6, 28,130, 2, 52, 12,140, 20, +160, 51, 50,104,231,198,178,190,168, 49,201, 34,238, 29, 79, 6,176,183, 33,103, 79,167,211, 93,141,137,137,153, 68,211,244, 81, + 0,100, 84, 84, 20,253,252,249,243, 47, 96,190,227,250, 31,205,246, 34,209,172,200,200, 72,235, 89,179,102,149, 68, 68, 68,148, +245,235,215,207,114,251,246,237,214, 61,122,244,152, 85, 84, 84,116,208, 28, 67, 96,122,122,250,158,140,140,140, 47, 2, 3, 3, + 81, 92, 92, 12,131,193,128, 71,143, 30,193,211,211, 19, 15, 31, 62, 68,203,150, 45,241,224,193, 3,120,121,121,129,162, 40,104, +181, 90,208, 52, 77,213,215,152, 23, 23, 22, 0, 69,233,200,190,119, 14, 47,159, 62, 66,100, 54,129, 77, 7, 79,163, 73, 51,247, +119,202, 83,211,210, 94,212,198,201,206,230,226,234, 37,223,218,167, 94, 61,132,227,187, 54,209,215,206,157,107,205,147, 98, 82, +183,145, 95,126,164, 55,162, 41, 0, 94,199,160, 64,244,145,189,160, 68,205,144, 27,249,188,238, 4,139, 45,237, 69,109, 28,108, +109, 46,252,107,213, 82,233,171,243,191,224,240,182,117,204,177,125, 7,252,180, 64, 80,155, 54,109,250,144, 36,105, 5, 64, 91, +225,231,101,214,210, 54, 53,113, 94, 62,125, 58, 64, 11, 4,157, 60,121,178,143, 72, 36,114, 4, 96, 84,171,213, 73,127,134,243, + 74, 68, 68, 64,101, 57, 9,130,176, 7, 96, 96, 24,230, 21, 26,184, 4,207,176, 97,195,150,207,152, 49, 99, 14, 69, 81,118,213, + 70,231,172,181,107,215,178,105,154,102, 49, 12, 99, 32, 73,210,112,225,194, 5,202,100, 50,101,107,181,218,207,254, 76, 43,242, +209, 71, 31,225,238,221,187, 75,240, 58, 8,195, 92,107,245, 27,126, 90, 21, 75,246,188, 51,127, 84, 84,212,178,143, 63,254,120, +238,193,131, 7, 95,110,216,176, 97,192,228,201,147,113,232,208, 33,180,104,209, 2,143, 31, 63,198,252,249,243, 1,160,243,130, + 5, 11, 78,237,220,185,211, 35, 53, 53,117,173, 25, 22, 13,152, 76, 38, 28, 56,112, 0,131, 6, 13,130,157,157, 29,228,114, 57, + 8,130,184, 58, 97,194,132, 45, 0,192, 34, 88, 92, 0,208,105,117, 58,111,239, 64,179, 45,184, 92, 46,183,170,173,203,205,205, +173,138, 20,236,253,241,199,133, 59, 86,175,198,175, 26, 13, 38,200,100,162, 76, 23, 23,167, 83,175, 94,125,250,236,117,227,204, +212,101,213,169, 79,100,153,235,210,160,201,193,188,223, 86,166, 56, 2,248,160,235,104, 57,186,142,150, 35,112,160, 61, 65,178, + 8, 60,189, 88,132,216,203,197,199,140, 10, 92, 69,195,150,203,121,190,106,213,170, 83,221,186,117, 27,208,170, 85, 43, 76,156, + 56,241,243, 93,187,118,113,141, 70,227,116,252,158,230,193,146, 36,201,165,219,182,109,251,212,218,218, 26, 55,110,220,192,245, +235,215,175, 2, 72,175,173, 93, 2, 80,149, 51,171,137,107, 75,237,139, 84,165, 40, 63,235, 22,110,222,248, 13, 45,252,190,132, +208,177, 63,172,189, 87,192, 16,255, 35,244, 69, 23, 97,237,218, 15,153,169,175,192, 98,243, 99,235,115, 66, 97, 24,230, 89,102, +102,166,135,135,135, 7,145,146,146, 98, 2,192, 80, 20,197, 24,186,116, 49,182, 94,189,154, 19,251,249,231, 68,199, 23, 47, 88, + 12, 65,208,143, 30, 61, 2,128,184,255, 68, 47, 94,153,110, 33, 54, 54,182,182,116, 11, 13,130,175,175,111,231,235,215,175,243, +181, 90, 45,174, 93,187,134,246,237,171, 98,187,254,163,217,239,171,107,145,255, 50,124, 90,195,103,219,223,176,104,189,113, 99, +211, 4,199,171,101, 75,138, 75, 98,247,160,254,253,213, 49, 49, 49, 85,163, 62,237,253,251, 80,157, 63, 15,138,162,192, 48, 12, +174, 71, 69, 33,124,244,104, 37,135, 69,236,112,115,107,198, 16,204, 27,185, 91,122,213, 48,122, 8, 11, 11, 11,171,106,124, 50, + 50, 50, 32, 22,139,193,227,241, 64,211, 52, 76, 38, 19, 88, 44, 22, 44, 45, 45, 97, 50,153,106, 50,193,188,205,105,164,138, 85, + 67,119,246, 29,149, 35, 87, 26,152, 73, 86,110,104,202, 21, 86, 61,156,142, 22, 4, 6,248,113, 96,203,206,103,174,172,125, 63, +155,214, 21, 13,197, 31, 35,186,234, 11,249,111,217,182,109,219, 45,225,225,225, 36, 0,244,234,213,139,108,219,182,237, 70,212, +189, 84, 78,157,156, 2,129,128, 15, 0,167, 79,159, 46,126,249,242,229, 7,167, 79,159, 46,174,254,185,153,156,219,215,172, 89, + 3,145, 72, 4,147,201, 4,189, 94, 95,229,159, 85,253,213, 96, 48,192,214,214, 22,103,206,156, 1, 69, 81,103,234, 43,167,107, +211,102, 32,236,154, 99,207,233, 72, 92, 47,228,190,139,200,170,226,108,238, 40,246,114,180,181,185,244,175,149,203,236, 74, 18, + 31, 33, 51, 51,147,185,112,254,204, 29, 45,144, 85, 86,142,133,165, 42,120,105,244, 16,180,247, 64,250,165,109,179,153, 5, 93, + 97, 68,205, 81,131, 85,156,173, 29,197, 94,206,118, 54, 23,190,255,215, 74,105,105,226, 35,228,228,230,226,236,153,211, 49, 90, +160,114,186,113, 28, 77,211, 62, 52, 77,251, 0, 24, 87,135,120,105, 16,167, 90,173,246, 85,171,213,190,127, 37, 39,195, 48,190, + 12,195,152,205, 89,221, 39,106,253,250,245,241, 57, 57, 57,225,249,249,249,161,149, 91, 73, 73, 73, 47,165, 82,217, 93,173, 86, +119,209,172,111,102,169, 86,171,237,149, 74,165,147, 86,171,109, 7,224, 81, 3,238,249, 42, 84,207, 58,157,147,147,179, 56,231, +255,216,187,242,240, 38,170,246,123,102, 38,251,210,180, 77,219,164, 41, 45,101, 45, 91,203, 82,144,125, 21, 20,164, 40,202,250, + 67, 16, 16, 44, 32,138,128,130,168,168,236, 8,226,135, 11,178, 20, 80, 22, 17, 89,101,119, 1,100,151, 29, 4, 74,161, 44, 45, +221,151, 52, 75,155, 52,205, 54, 51,191, 63,154,196,180,116, 73, 74, 81,248,190,156,231,153, 39,153,100,114,114,231,206,204,189, +231,190,247,189,239,155,157, 77, 84, 87, 78,106, 82, 18,177,229,139,247,126, 94,179,102,141,234, 17,249,203,148, 83,173, 86,239, +216,186,117,107,155, 6, 13, 26, 52, 28, 59,118, 44, 86,175, 94,141,175,191,254,218, 12, 0,235,215,175, 55,187, 89,178, 34, 82, + 83, 83,159,169,100,218,176,143,155,181,100,211,243,207, 63,207,158, 56,113, 2, 47,191,252,178, 43,144,232,218,181,107, 97,183, +219, 11,123,247,238,205, 0,128,169,164,184,144,101, 88, 88,172,149,206,191, 63, 84,159,124, 62,255, 5,247,120,129,206, 96,204, +124, 62, 31, 44,203,162,105,215,174,106, 93,235,214,154,239,244,250,226, 57, 45, 91,202,226,155, 53, 27,219, 28, 24, 85, 17, 39, + 65, 16,101,172, 58,229, 55, 47, 44, 89,238,229,204, 51,101,225,141,159, 23,165,252,226,180,108, 9,165, 28,148, 20,217,177,251, +179,148,252,146,124,172,173, 76,252, 84,117,238, 26,141,230,237,207, 62,251,204, 28, 24, 24,136,193,131, 7, 99,225,194,133,227, +187,118,237,170, 87, 40, 20,103, 27, 55,110,124,109,248,240,225,217,151, 46, 93,122,187, 87,175, 94, 72, 78, 78,198, 23, 95,124, +161,211,106,181, 35,171,226, 36, 8,194,101,201, 27, 24,215, 71,179,234,155,255, 48,189,123, 76,134, 88, 36,131,141, 27, 1,141, +193, 6,173,145,133, 69,208, 1,124,158, 0,125, 59, 69,227,236,175, 27,138,105,139,113, 99,117,247,188,193, 96,216, 57,102,204, +152, 66, 30,143, 7,139,197,194,114,185, 92, 8, 74,253,142, 25,110,191,126,214,206,137,137,118,154,101, 25,130, 32,240,238,187, +239, 26,181, 90,237,214,154, 60, 71, 94,192,157,179,182,194, 45,244, 41,215,255,212, 70, 88,136,199,113,238, 79, 51, 18, 42,216, +254,182,104, 57,151, 84, 58, 95, 9,130,161,105,154, 65,253, 6,245,253, 82, 83,210, 86, 12, 27, 54,116, 92,255,254,113,226,184, +184, 56, 97,116, 82,233,104,116,223,190,125,216,181,107, 87,241,111,191,253, 86, 40,224, 82,235, 35,234, 70, 40,105,154, 1, 65, + 48, 85,170, 97, 63, 63,191,119, 62,252,240, 67,145, 94,175,199,215, 95,127,205,180,105,211,134,148, 72, 36,176, 90,173, 88,191, +126,189, 45, 58, 58,154, 75,146, 36,244,122, 61, 72,146,188,229,225, 9,254,165, 79,203,236,187,178,215,160, 93,207,188,245,122, + 80,139, 94,157, 3,123, 70,212,129,173, 45,139,172,244, 20,220, 62,242,155,246,198,175, 95, 22,160, 36,119, 16,170, 79, 15, 84, + 81, 71,240,233,111,191,253,166,120,251,237,183,217,146,146, 18, 34, 45, 45,141, 93,180,104,145,226,141, 55,222,248, 52, 43, 43, +235,255,106,120, 81, 8,157, 78, 7,130, 32, 24, 71, 67,226, 28,245,123, 51, 47,119,125,227,198,141,123, 94,121,229,149,129,189, +123,247, 70, 82, 82,146,107,138,208, 93,104, 57, 87, 31, 46, 94,188, 88, 7,224,131,234, 72,185, 92, 46,190,222,184, 3, 58,173, + 26, 74,101, 24,132, 34, 17,106,186,194,146, 79,146,115,150,204,255, 68,161,190,121,150,184,254,231, 81,102,251, 95,185,121,118, +154,173, 56,226,127, 81, 22,235, 80,255, 85,143,102, 72,106,206,146, 69,243,252,157,211,154, 91, 47,103, 23, 18, 52,251,246, 35, + 61, 34, 79, 11,231, 63,140,176,176, 48,100,103,103, 19, 97, 97, 97,172,195, 71,139,173, 66,104,149,189,193, 75,167,203,136,170, +166, 13,107,202,127,255,254,253, 69,109,219,182,125, 47, 57, 57,121,123,139, 22, 45, 38, 2,168,107, 54,155,117,179,103,207,254, +124,253,250,245,227, 60,177,100, 1,192, 79, 63,253,244,229,235,175,191,254,203,139, 47,190,248, 62,195, 48,173,220, 58,246,251, + 10,133,194, 53,133,155,159,155, 51,107,194,184, 17,179, 12, 6,173,199,113,238,164, 82,105,252,236,217,179,133, 70,163, 17,223, +126,251, 45, 19, 29, 29, 77, 58, 7, 69,155, 55,111,182, 55,105,210,132, 51,116,242,100,245,242,156, 28, 44, 56,121,210, 56, 43, + 38,166,205,119,183,111,183, 3,195,108,170,204,170, 83,145, 37,203,233,118, 81, 67,100, 57,196,214, 90, 0,253, 58, 15, 11,197, +158,165, 41,208,166, 90, 62,135, 29,119,225, 65, 90,160, 10,144,177,115,231,206,190,185,185,185,123, 62,249,228, 19,255,118,237, +218, 33, 38, 38,134, 43,149, 74, 59, 56,195,197,232,245,122, 28, 62,124, 24,171, 87,175,182,220,184,113,227,149,170,166,171,104, +154,206,107,210,164,137,179, 30, 88,130, 32, 10, 10,205,132,255,182,230, 29,164, 99, 39,108, 39, 78, 93, 56,131, 44, 43, 3,179, +141, 65,253, 6,177,232,217,111, 57,246, 30,186, 70,103,165, 38, 38,218, 76,218,117, 30,148,247,238,157, 59,119,118,207,159, 63, +127,216,251,239,191, 47, 82,171,213,180,217,108,102,118,236,216, 65,141, 29, 59,150,102, 57, 28,134,199,225,224,157,119,222, 49, +233,116,186,159,129,127, 52,193,244, 99, 9,183,240, 24,194, 66,212,154, 53,203,253,245,191, 5, 21, 62,161, 12, 69,158, 94,189, +102,213, 11, 63,253,184, 53,148,162,200,208,187,247,238, 93,120,105,208,144,204,223,127,255, 93,206,243,247,111, 15,128,177, 76, +156,248,167,213,108,210,236,223,179, 39,178,126,253,122,173, 29, 73,165, 89,134, 34, 79, 87,245,135, 6,131,193,120,242,228,201, +226, 15, 62,248,128, 72, 79, 79,223,162, 84, 42,135, 31, 58,116, 72, 58,104,208, 32, 83, 82, 82,210,206,208,208,208,129,189,122, +245,242,123,239,189,247,204, 6,131,193,155,196,163,137,108,190,182,249,249, 79,150,189,122,126,233,170,231,192,161,186,192,204, + 5, 24,219,105, 88,139,126, 7,176, 5, 94,196, 59,114,135, 68, 34,105, 45, 22,139,113,229,202, 21,109,135, 14, 29, 44, 37, 37, + 37,188,133, 11, 23, 6, 73, 36,146,214, 53,173,120,150,101, 89,173, 86, 11,134, 97, 56, 0, 8,199, 43, 24,239,215,226,255,223, + 75, 47,189,180,103,219,182,109,207,199,197,197,161, 97,195,134,176,217,108,104,210,164, 9, 44, 22, 11,162,162,162, 96, 54,155, + 49,119,238, 92,232,245,250,233,168, 34,231, 25, 65, 16,176,219,237, 46,103,219, 58,225,145,165,113,122, 30, 33,140,133,132, 75, + 54,188,181,255, 59,228, 21,168,153,109, 87,115,115,139,173,116,223, 59,249,197, 55,202, 31, 87, 76,195,216,107,236,148, 76, 0, + 48, 51, 85,103,156,151,240,209,240,246,129,181,200,205, 83,227,167,203,217, 58,163,149,233,119,187, 2, 78,175,202,249,148,112, +198,206, 77,194,144, 41,158, 31,251, 40,240, 84, 80, 85,134, 43, 57, 32, 46,138,191, 99,177,230,187, 10, 99,100, 61, 34,255,158, +228,228,228, 61, 0,144,152,152,152, 62, 98,196,136, 89, 41, 41, 41,243, 1, 28, 76, 77, 77, 93,227, 13,209,119,223,125,151, 12, +224,245,170,142,217,186,236,245,221, 0,118,123,195, 91, 84, 84, 84,114,233,210,165,146,247,222,123,143, 72, 79, 79, 63, 20, 26, + 26,250,252, 47,191,252, 34, 30, 52,104,144,249,250,245,235, 71,194,194,194,186,247,233,211, 71,122,240,220,185,204,226,187,119, +247,239, 79, 73, 9,183, 49,204,254,170,158,207, 90, 22, 89,101,196,214,238, 5, 41, 75,246, 44, 73,233,195,152,177,211,162,197, +159, 0, 50, 30,129,243,196,233,211,167, 91,140, 26, 53,106,219,128, 1, 3, 58,183,104,209, 2,117,235,214,197,237,219,183,145, +159,159,143,191,254,250, 11,251,246,237,219, 87, 82, 82, 82,109, 66,109,141, 70,243,112,122, 34,161, 60,108,195,183,115,246, 93, + 56,213,190, 73,183,184, 49,162,152, 48, 6, 22, 43,139,244, 7,119, 49,247,227,117,197,217, 15,146, 19,173,118,235, 43,240,112, +161,142,201,100, 74,248,234,171,175,184,251,247,239,143, 91,177, 98,133, 95,100,100, 36,197,227,241, 72, 0,236,197,139, 23,217, + 41, 83,166, 24,213,106,245,129,194,194,194,132,127,184,143, 62,113,239,222,189, 88,138,162,106, 53,220,194, 35,132,133,240,161, + 54,209,160, 65,120,139, 70,145, 97, 19, 27,214, 13,159,220, 32, 50, 98,116, 69, 78,238, 13, 3, 3,253, 26,212,171, 19,223,176, +110,248,228, 70,145, 97, 19, 27, 52, 8,111,225,129,105,177,161, 76, 38, 59,164, 82,169,218, 0,128,191,191,255,192,128,128,128, + 27,254,254,254, 3, 29,163,192,129, 82,169,244,102,116,116,244, 27,255,160,185,178, 74,206, 38, 77,154,140, 48, 24, 12,111, 54, +105,210,100,132,115,255,238,221,187,174,253,154,112, 70, 68, 68,244,190,120,241,226,255, 45, 91,182,108,112,227,198,141, 7, 46, + 90,180,104,240,207, 63,255,252,127,225,225,225,237,106,192, 41, 0,240, 3,151,203,205,229,243,249,121, 92, 46, 55,215,185,113, + 56,156, 92,138,162,114, 1,172,169,196, 90,214,199,109,148,115, 74,169, 84,166, 42,149,202,212,208,208,208,212,208,208,208, 84, +149, 74,245,208, 22, 28, 28,124,202,211,250,108, 22, 42,237,218,161,174,223,233,150, 42,233,169,230, 74, 73,179,218,184, 70,205, + 66,165, 93,219,215,245, 63,221, 82,229,119,242,127,141,179, 77, 40, 88,118,117, 51,150, 93,221,140,109, 19, 10,182,186,253,218, + 52,251,171, 84, 42, 86,165, 82,205,121, 92, 83, 9,149,240,255,227,207,123, 45,114, 54,244,243,243,219, 90,183,110, 93,103, 91, +247,162, 76, 38,251, 67, 42,149,190,232,104,235, 94,148, 72, 36,199,163,163,163,199, 84,199, 41,151,203, 47, 42, 20,138, 28,199, +150,173, 84, 42,179,149, 74,101,182, 66,161,200, 82, 40, 20, 89, 33, 33, 33,153,206, 45, 32, 32,224,108, 13,207, 93, 1,160, 35, +128,118, 0,100,181, 88,159, 13, 0, 76,112,180, 65,159, 1,120, 3, 64,171, 90,184, 70, 4, 87, 36,159, 36, 8,136, 56,205,149, +134, 20,113,165, 33, 69, 2,255,240,211, 85,164,224,241,132,179,169, 92, 46, 95, 40,147,201,126,246,243,243, 59,233,231,231,183, + 39, 56, 56,120, 17,128,166,255,210,189, 36, 5,176, 30,165,241,153, 14,162,116, 42,124, 15, 74, 23, 21, 68, 62,129,247,252,255, + 50,226,255,173, 63,238,227,227,244,113,250, 56,125,156, 62, 78, 31,231, 83,200, 73,250,234,211, 39,180,188, 20, 90,229, 55, 0, + 85, 68,134,247,193, 7, 31,124,240,193,135,255, 97, 48,190, 42,240,193, 75, 84, 56,181, 76, 84,161, 74,189,137, 53, 85, 19,101, +123,216,199,233,227,244,113,250, 56,125,156, 62, 78, 31,231,255, 28,167, 15,181, 8,159, 89,213,199,233,227,244,113,250, 56,125, +156, 62, 78, 31,231,127, 59,124, 83,135, 62,248,224,131, 15, 62,248,224,131, 15,143, 9, 9,110,130,171,204, 20,162, 79,104,121, + 15, 18,192,155, 0,134, 0,104,132,210,108,246, 59, 0,172, 68,205,230,244,101, 0,102, 1,232,130,210,213, 57,247, 1,156, 68, +233,234, 28,131,175,186, 43, 70,112,112,240,135, 92, 46, 55, 0, 40, 77,109,226,124,117,127, 79,211,180,174,176,176,112,209, 99, + 42, 2, 5, 15, 35, 40, 59,203,234, 94, 54,247, 87,155,205,246, 56,203,233,195,147,137, 38,114,185,252, 7,141, 70, 51, 18,110, + 73,150,125,240,225,191, 1, 33, 33, 33, 19,173, 86,235,108, 30,143,183, 48, 63, 63,127,213,255,208,169, 63, 36,178,202, 8,173, +253,251,247, 31, 7,128, 1, 3, 6,244, 0,128,128,128,128, 51, 36, 73, 54,240,230, 31, 24,134,185,175,211,233, 42, 13,160, 22, + 16, 16,112,134,162,168,135, 56,109, 54,155, 31,135,195, 41,170,232, 55,118,187, 61,163,176,176,176,221, 19, 82,137, 4,128,253, +129,129,129, 37,243,231,207, 95,217,179,103,207,136,172,172, 44,251,204,153, 51,187, 95,189,122, 53, 14,192, 11, 94,138,173, 78, + 4, 65,108,104,211,166,205,238,209,163, 71,111,235,208,161, 3,191,160,160,192,111,199,142, 29,117, 54,110,220,120,137, 97,152, +145,168, 34,209,234,255, 50,184, 92,110, 64, 70, 70,134, 31, 80,154,154,196, 33,172, 96,179,217, 96,179,217, 96, 52, 26,209,186, +117,235, 90,255,223,208,208,208, 88,130, 32, 86, 72,165,210,118, 6,131,225, 2,128,201,217,217,217, 87,189, 41,171,221,110, 7, +203,178,174,114,182,104,209,194,119, 65,189,195,120, 62,159,223, 47, 42, 42,170,189,217,108,214,222,191,127,255, 60, 77,211,159, +160,246,114,180,249, 3,248, 68, 32, 16,116,104,212,168, 81, 68,114,114,114,186,213,106, 61,135,210,100,200,250,218, 16, 89, 61, +122,244, 56,245,237,183,223, 6, 77,154, 52,233,212,201,147, 39,187,250,196,150, 15,255, 22, 34, 34, 34, 2,140, 70,227, 58, 0, +177, 92, 46, 55, 84, 40, 20, 66, 36, 18,229, 8, 4,130, 43, 34,145,104,220,233,211,167,117,222,114,210, 52,253, 73,106,106,106, +104,199,142, 29,151, 42, 20,138,185,106,181,186,196,106,181, 30,209,106,181,211, 1, 20, 86,245,219,242, 90,228, 41, 19, 89,238, +175,112,138, 46,142,227,196, 88, 0, 61,203, 40, 48, 14, 39,252,193,131, 7, 10,161, 80, 8,134, 97, 92,157, 89,249,205,249,185, +197, 98, 65, 76, 76,140,181,154, 14, 39, 34, 61, 61, 93,193,231,243, 93,159, 89, 44, 22,212,169, 83,135,201,200,200, 80, 56,210, + 30,184, 96, 54,155, 17, 30, 30,254, 36,229, 60,122, 83, 46,151,235,211,210,210, 91,151,152,173,243,222,120,251,131, 15, 71, 14, +121, 46,240,204,153, 51,204, 11, 47,188, 96, 62,126,252,248,155, 40, 77,156,234, 81, 99, 78, 16,196,198,153, 51,103,206, 21,138, +101, 65, 71,207, 36,154, 55,238, 56,144,217,166, 73,125, 98,250,244,233,212,148, 41, 83, 78,196,198,198,254,192, 48, 76, 91,120, + 97,217, 10, 12, 12,252, 69, 32, 16,212,115,212, 95,154, 86,171,125,254, 9,188, 33, 57,120, 56,120,108, 69,159, 85,139,130,130, + 2,152, 76,166,135,182, 22, 45, 90,120,154, 43,211,171,114,115,185,220, 61,139, 23, 47,174,147,147,157,141,255, 44, 95,222, 17, +165,150,204,142,158,252, 56, 47, 47,239,161,114, 54,107,214, 12, 62,120,133, 89,115,231,206, 93,252,234,171,175,130,166,105,152, + 76,166,176, 59,119,238, 68,207,158, 61,251,149,187,119,239,182, 7,112,239, 81, 7,227, 81, 81, 81, 73, 83,167, 78,149,183,111, +223, 30,142, 44, 21, 97, 39, 79,158,236,184,126,253,250,215,210,210,210,154, 1,200,127,148, 63,144,203,229, 63,172, 93,187, 54, + 72, 44, 22, 99,239,222,189, 65,189,123,247, 62,121,249,242,229,110,143, 32,182,200,160,160,160, 41, 0,158,101, 24,134, 15,224, +156, 86,171, 93, 0,239,163,186,171,164, 82,233, 78,146, 36,235, 3,127, 71,163, 39, 73, 50,152, 32, 8,181,243, 51,130, 32, 20, + 12,195,252,169,209,104, 58,251,110,199,167, 27, 65, 65, 65,227,115,115,115,191, 21, 8, 4,188,192,192, 64,136,197, 98,112, 56, + 28,112, 56,156,186, 2,129,160,174, 64, 32,232,223,171, 87,175,201,127,252,241, 71,149, 17,246, 59,181, 81,142, 5, 73,204,163, + 8,146, 2, 0,146, 43,145,249,251,251, 99,222,188,121,146,129, 3, 7, 74, 0,224,212,169, 83,163,199,140, 25,211, 59, 35, 35, + 35,166, 50,177, 85,145, 22,121,138,144, 80, 85,135, 7,135,122, 60, 94,230,201, 37, 73,240,249,124,156, 61,123, 22,158, 4, 43, +119,166, 72,168,178, 53,112, 68, 24,191,122,245,111, 3,128,179,163,225,243,249, 56,125,186,108, 80,249, 78,157, 58,185, 30,246, +127, 10, 67, 90,148, 6,121,220,254, 86,105,185,134,174, 40,141,174,189,253,173,102,232,254,197, 3, 12,153, 50,103,120,113,137, +245, 25, 0, 70,157, 86,171,189,176,107, 87, 86,155, 38, 77,120, 63,252,240, 67,251, 58,117,234, 12,241, 66,104,205,106,219,182, +237, 78, 74,228, 31, 60,122,204,216,209,227, 56,164,245,181, 9,239, 45, 76,207, 86, 27,227,227,227,119,237,221,187,119,244,146, + 37, 75,110,206,152, 49, 99, 22,128,143, 60, 45,191, 80, 40,172,119,235,214,173, 40,154,166,209,162, 69,139, 39, 49,141, 65, 27, +148, 6,223,123, 21,192,143,142,207, 70,160, 52,114,127, 44,128, 43,222,144, 57, 45, 88, 21,109,181,141, 58,117,234, 52, 27, 53, +106, 84,176, 70,173,198,127,150, 47,119,126,220, 14,213, 76, 35, 58,159, 31,139,197,130,193,131, 7,143,162,105,154,227, 20,129, +102,179,217,162,215,235, 75,240,183, 99,105, 62,128,231, 60, 40, 78, 3,137, 68,242, 57,128, 88,147,201, 84, 7, 0, 36, 18, 73, + 38,195, 48,187,141, 70,227, 71,248, 59,129,175,215, 3, 92, 0,209,168, 60, 21, 20,187,120,241,226,228, 15, 62,248,224,222,191, +192, 89, 79,169, 84, 46, 26, 58,116, 40, 14, 28, 56,128,131, 7, 15,218, 68, 34, 17,103,204,152, 49,196,228,201,147, 3,167, 78, +157,218, 31,192, 87,143,120,153,251,207,157, 59, 87,222,188,121,115,236,216,177, 3,127,253,245,151, 41, 42, 42, 74,212,179,103, + 79,112, 56, 28,249,135, 31,126,248, 2,128, 13,143,242, 7, 26,141,102,193,123,239,189,183,241,199, 31,127,244,187,127,255, 62, + 86,172, 88, 17, 60,124,248,240,227,105,105,105, 61,188, 16, 91, 2, 0, 83, 0,244,162, 40,170,219,152, 49, 99,236,111,191,253, + 54,151, 36, 73,219,242,229,203, 67,214,175, 95, 63,156,203,229,198, 22, 20, 20,120, 50, 72, 35, 1,204, 27, 55,110,220,235,127, +252,241, 71,224,249,243,231,249, 65, 65, 65,160,105,218,101, 41,102, 24, 70,225,188,103,237,118, 59,154, 53,107, 22,238,246,123, +209,211, 42, 52, 72,146,180, 50, 12,195, 5, 32, 4, 96,174,110,255,191, 73,100,201,229,242, 73, 26,141,102,101,104,104, 40,148, + 74,229, 67,125,173,217,108,134, 80, 40,228,133,134,134,174, 29, 56,112, 32,119,207,158, 61,149, 78, 1, 18, 20,241,201,222,173, +243,235,200, 3,253, 0, 0, 95,174,254,181, 24, 0,126,254,249,103,100,101,101, 33, 48, 48, 16, 49, 49, 49,212,252,249,243, 85, +211,167, 79,255,143, 86,171, 29, 87, 25, 87,121, 45,242,148, 89,180, 18, 42,218,175,210, 71,139,101, 89, 87,158, 60, 15,111,218, +242, 31, 29, 46,199, 71, 88, 44, 22,148,183,104, 57, 31, 94, 46,151, 91,222,252, 8,130, 32,216,170, 56, 43,192, 24,137,101, 26, +113, 91, 0, 0, 32, 0, 73, 68, 65, 84, 68,210,218,104, 52,126,227,197,232,214,197,185,253,173,102,216, 40,152, 57,194,153,137, +180,255,123,165,175, 27, 1,156, 73, 25,183,226,219, 30, 61,234, 76,249,248,235, 57,166,130, 44,245,135,163, 94,172, 23, 21, 26, + 36,146,232,242,244,242,166, 77,251,150,179,200, 84, 87,206,238,163, 71,143,222,244,219,217, 84, 66, 40,228,241, 56, 20,197,237, +218,178, 73, 80,132, 63,229,239, 7,248,167,223, 75, 62, 51,118,236,216,150, 51,102,204,232,230, 5, 39, 28, 29, 46, 54,111,222, + 12,130, 32, 72,111,206,189, 22,113,184, 42,145,197,178, 44, 8,130,216,226,214,169,108,113,124,118,217, 77,108,113,170,170, 79, +167, 53,213, 41,170,198,140, 25, 51,202,110,183,115,220, 26,137,242, 2,166, 34, 17,227,209,185,171, 84,170,223, 0, 60, 71, 16, + 4, 44, 37, 37,150,207,191,248,194,253,235,139,229, 68,214,225,202,158, 37,155,205, 6,154,166, 57,151, 47, 95,230,186,221,235, + 92, 0, 18, 0,193, 44,203,130, 36,201,107, 30,212,103, 51,177, 88,124,102,223,190,125,178,118,237,218, 17,124, 62, 31,118,187, + 29,215,175, 95,143, 88,178,100,201,132,195,135, 15,191, 96, 52, 26, 91,224,225,228,233,158, 92,163,232,147, 39, 79, 26, 27, 54, +108, 88,161,112, 44, 44, 44,228, 52,105,210,164, 71, 37,162,232,113,115,102,228,230,230,190,252,220,115,207, 77,204,201,201, 73, +178,219,237,239, 3,136, 9, 14, 14,190, 60,104,208, 32,136, 68,162, 94, 38,147,233,171, 71,185,231, 21, 10,197,192,206,157, 59, + 99,197,138, 21, 88,178,100, 73, 31, 0, 71, 0,244, 46, 44, 44, 60,252,210, 75, 47, 33, 32, 32,224,101,157, 78,183,225, 17,158, +163, 38,221,187,119, 95, 59,111,222, 60,191, 3, 7, 14, 32, 42, 42, 10, 69, 69, 69,120,247,221,119, 21,159,126,250,233, 49,157, + 78,215,211,237,185,168,140,179,133, 64, 32,216,240,227,143, 63, 74, 27, 54,108,216,144,199,227,145, 13, 27, 54,132, 70,163, 65, + 73, 73,137, 96,225,194,133, 45, 69, 34,209,213,175,190,250,106, 3,128, 65,213,148,147, 4,176, 96,205,154, 53, 19,227,227,227, + 3, 70,141, 26, 69, 91, 44, 22,108,219,182, 13, 20, 69,129,203,229, 66, 44, 22,187,146, 87,243,120, 60, 52,109,250, 80,144,244, +189, 85,156,175, 30,165,126,168, 1,240,110,218,245,112, 21,124,174,169, 15, 46,151, 11,161, 80, 8,161, 80, 8,129, 64,128, 91, +183,110,125, 44, 20, 10,151, 19, 4, 97,247,132,147,248, 91, 93,180, 6,112,190,186,125, 60,236, 26,242, 79,182,159, 78,132, 19, + 4,241, 37,128, 94,165,221, 46,121, 60, 56, 56,248,157,220,220,220, 7,158,114,170, 84,170,160,130,130,130,175, 84, 42, 21,148, + 74,165,171,255,174, 83,167, 14,108, 54, 27,114,115,115,193,178, 44,116, 58, 29,196, 98, 49,194,194,194,190,138,143,143,223,145, +144,144, 80, 80, 33, 39,131, 37, 47, 13,159,253, 9, 69, 81, 36, 0, 80, 28,169,116,234, 7, 64,189,122,245,208,181,107, 87,148, +148,148, 64,175,215, 35, 58, 58,154, 67, 16,196,104,130, 32,100, 44,203,174, 2,112,244,191,208, 80, 88,169, 51,252,220,242,243, +162,206,108,241, 60, 30,207, 35,161,229, 56,190, 58, 11, 10,105,179,217,192,227,241,202, 88, 36, 8,130, 0, 77,211,101, 62,119, + 10,173,154, 8,245,201,147, 39, 51,107,215,174,157,168,213,106, 87,163,134, 83, 9,163, 71,143,126,200,223, 99,250,244,233, 25, +121,121,121,236,224,190,173, 37, 73,135,178,178, 27, 5, 74, 69, 33,126,126,245,133,129,242,128,130,130,130, 63, 29,141,137,167, +104,220,182,109, 91,209,198, 93, 39, 51,222,152,182,120,126,187,134, 65,178, 86,225,193,129,161,254, 34,190,148, 36,140, 66,187, + 45, 67, 46,151, 71,121, 91,110,103,187, 32, 22,139, 65,146,228,147,100,209,226, 56, 69,150, 70,163,193,129, 3, 7, 16, 23, 23, +119,217, 41, 66, 10, 11, 11,145,157,157, 13,149, 74,117,217, 97,249,168,118, 26,145, 97, 24, 88,173, 86, 88,173, 86,151,128,113, +187,135, 92, 2,198,121, 44, 69, 81,215,106, 88,246,249,129,129,129,221,123,245,234,197,223,186,109, 27,159,101, 89, 35, 74,115, +168, 25, 88,182,146, 4,217,229, 96,183,219, 93, 86, 54, 46,151,139,180,180, 52, 87,199,229,204, 45, 41, 20, 10, 61, 51,101, 8, + 4,239,253,244,211, 79,178,246,237,219, 19, 5, 5, 5, 96, 24,198,213, 72,174, 92,185, 82, 56,100,200,144, 58,151, 46, 93,250, +208,108, 54,207,173,193,185, 18,149, 9, 34, 0,144,201,100,118,120, 22, 49,187, 90, 78,187,221, 78,116,233,210,101,134, 90,173, +110,105, 50,153, 22,122, 82,141, 0,246,102,100,100,184,119,236, 87,147,146,146, 76,195,134, 13, 19,213,175, 95,191, 67, 98, 98, +226, 35,221,164, 77,154, 52,233,196,229,114,113,238,220, 57, 51, 0,231,200,250,248, 95,127,253,101, 30, 52,104,144, 32, 34, 34, +162,147, 78,231,177,203, 74,147,102,205,154,253,174, 80, 40, 68,206, 54, 52, 36, 36,132,155,144,144,224,151,153,153, 9,171,213, +138, 89,179,102, 97,192,128, 1, 8, 14, 14,198,244,233,211,149, 75,151, 46,253,193, 96, 48,180,173,202,104,205,231,243, 55,221, +185,115, 39, 74,165, 82,137,206,158, 61,139, 86,173, 90, 65,173, 86, 35, 39, 39, 7, 6,131, 1, 57, 57, 57, 24, 55,110,156,226, + 63,255,249, 79,152, 7,150, 44,151,200, 74, 72, 72,208,237,220,185,147, 90,183,110,157, 31,151,203,117, 9, 45, 14,135,227, 18, + 90,206,220,138, 53,152,105,208, 57, 68, 91,128, 94,175,127, 20, 63, 55, 1, 0,190,187,200, 18, 8, 4, 16, 8, 4, 16, 10,133, +143,148,151,245, 41, 65, 29,130, 32, 18,121, 60,158, 64, 44, 22,243, 72,146,132, 64, 32,232, 43,151,203,111,196,196,196,196,252, +254,251,239,169,158,144,148,148,148,108, 18, 8, 4, 92,133, 66, 1, 0,136,138,138, 66,171, 86,173, 96, 52, 26, 25,189, 94,143, +128,128, 0,242,193,131, 7, 48,153, 76,200,206,206, 70,100,100, 36,151, 36,201, 77, 40,245, 67,126, 8,103, 46,231,172, 6,176, +218,185, 31, 28, 28,156,235,110,233, 20, 10,133,168, 83,167, 14, 50, 51, 51,225,231,231, 71,125,250,233,167,131,182,109,219,246, +202,153, 51,103, 70, 3,216,236, 70, 53,247, 41,246,209,114,138, 44,247,215,191,133,214,128, 1, 3,230,236,223,191,191, 71, 69, +163,112, 46,151, 91,107,190, 46, 78, 65, 37,147,201,202, 91,173,192, 48, 76,101, 22, 45,175,255, 71, 40, 20,138, 38, 77,154, 84, +180,106,213, 42,175,197,214,208, 21, 73, 46, 43,214, 67,195,200, 22, 45,206,124,248,225,135, 3,255,248,227,143,204,118, 13,235, +115, 36, 89, 15, 12, 66, 89, 64, 0,194,235,198,141,121,121,208, 95, 40, 93,125,232, 41,238, 20, 21, 21,137, 26,133,139, 45, 36, + 89, 66,212, 21,112,252, 84, 18,158, 32, 52, 48,176, 14,207, 98,206,147, 5, 6,242,205,102,179, 14, 85, 36,129, 6, 0,165, 82, +249,171, 72, 36,138,116,238, 7, 6, 6,250,179, 44, 11,177, 88, 12,149, 74, 37,165, 40,234,182,219,195,245, 32, 55, 55,183,111, +117, 5, 11, 8, 8,248, 85, 32, 16, 68,146, 36, 9,130, 32, 64, 81, 20, 72,146, 4, 73,146,174,247, 20, 69,129, 32, 8, 20, 23, + 23, 63, 72, 77, 77,237,235,193,249,218, 1,196, 18, 4,113,249,192,129, 3,232,208,161, 3, 14, 29, 58,132,126,253,250, 65,175, +215,227,250,245,235,232,222,189, 59, 80, 58,165,232, 17,220,157,223,157,131,130, 91,183,110,185,132,139,251,230,231,231,247, 40, + 38,246, 83, 67,135, 14,197,218,181,107, 89,199, 96, 66, 66, 16, 68, 43,127,127,255, 91, 55,111,222,244,200, 15,134,101, 89, 88, +173,127, 31,234,236,188, 28,254, 16, 94, 37, 7,166, 40,170,111,219,182,109, 9,189, 94,239, 20,144,224,112, 56,160, 40, 10, 20, + 69,225,219,111,191, 21,181,111,223,126,182, 64, 32,152,193,227,241, 10,109, 54,219,214,146,146,146,133, 0,116, 79, 82,139,212, +173, 91,183,105,233,233,233, 3, 34, 35, 35,247, 61, 2, 13,107,179,217, 44, 0, 68, 20, 69,113,107,161,141,162, 28,247, 86,137, +155,216,183, 59,246, 5, 40,157, 38,246, 8,193,193,193, 63, 28, 60,120, 48, 60, 50, 50, 18, 54,155, 13,118,187, 29, 6,131, 1, +199,143, 31,135,217,108,134,221,110, 71, 84, 84, 20, 62,249,228,147,146,119,222,121, 71,184,102,205,154, 60,131,193, 48,178, 26, +218,119,118,236,216, 33, 81,169, 84, 34,147,201,132,123,247,238,161,109,219,182, 40, 42, 42,130,209,104, 68,113,113, 49,172, 86, + 43, 10, 11, 11, 3,104,154,182, 84,195,245,177,187,200,154, 48, 97,194, 53, 62,159,223,246,237,183,223, 70, 70, 70,134,235,153, +127,227,141, 55,160, 84, 42, 93,207,146,163, 77,246,170, 97,230,112, 56, 16, 8, 4,224,241,120,186,186,117,235,130, 32, 8,225, +131, 7, 15,106, 50, 21, 39, 3, 80,200,229,114,249,238, 2, 75, 32, 16,224,220,185,115, 31,242,249,252,202,172, 89,149, 61,151, +172, 55,251,255, 54, 8,130,248,146,199,227, 9,228,114, 57,207,109,192,201,147, 74,165, 80, 40, 20, 43, 0,244,247,240,188,219, +200,229,114, 87,251,222,186,117,107,164,167,167,239,214,235,245,175,229,229,229,129, 36,201, 77, 36, 73,190,226, 28,164,106,181, + 90, 68, 68, 68,180,169,140,175,115,108,232, 68, 16,108, 25,139, 86,185, 1, 26,100, 50, 25, 82, 82, 82, 96, 52, 26,217,228,228, +100, 98,210,164, 73,132,197, 98,249,254,210,165, 75,127,162,116,181,125,165, 90,228, 41,129,247, 62, 90, 78,139,150,167, 29, 0, + 65, 16,213,142, 38,108, 54,155, 52, 58, 58,186, 34,135, 47,162, 34,161,229,152, 78,170,209,141,206,229,114,253,106, 42,182,202, + 99,223,206, 31,149, 75, 62,153,245,137, 60,172,126,163, 25, 51, 62,230,188,248,226,139,103, 55,110,220, 72,203,155,247,239,125, +244,215,205,202,175,222,157,121,232,224,193,131, 64,169, 99,180,167, 56,181,127,255,254,208,233, 83, 38,227,147,247,222,249, 69, + 22, 21,204,151, 18,114,137,208,108,204,151,130, 53, 9, 26, 55, 27,176,107,223,190,108, 0,151,170, 34, 17,139,197,145,137,137, +137, 81,238, 11, 9, 44, 22, 11,196, 98, 49,142, 30, 61, 26, 34, 18,137, 66, 0,192,100, 50, 33, 38, 38,198, 83,139, 73,228,237, +219,183,163,252,252,252, 80, 92, 92, 12,179,217, 12,155,205, 6,134, 97, 64, 16, 4,184, 92, 46,248,124, 62, 36, 18,137,183, 43, +251,174, 0,120, 53, 46, 46,110,203,161, 67,135, 16, 29, 29, 13,173, 86,139,164,164, 36,167,200,242,202, 71,203,105, 37,114,247, +199,226,112, 56,248,161, 97, 67,188,145,149,229, 18, 48, 95,250,251,227, 19,166,102,217, 52, 98, 98, 98,216, 83,167, 78,225,151, + 95,126,193, 75, 47,189, 68,236,217,179,199, 74,211, 52, 47, 43, 43,235, 90, 86, 86,150, 71, 28, 12,195,184,202,234,108,183,221, + 5,150,183, 66,203,110,183,251,241,249,124,148,148,148,192,105,121,112,223, 26, 52,104, 0,141, 70,195, 41, 44, 44,228,100,101, +101,137, 23, 44, 88,240,246,177, 99,199, 84, 69, 69, 69, 35,254,205, 86,104,213,170, 85,145,111,188,241, 70, 26,135,195, 97,251, +245,235, 55,234,193,131, 7, 47,171, 84,170, 35,127,252,241,199, 23, 0,154,120,203, 23, 28, 28,124,145,195,225,132, 23, 22, 22, +242,182,111,223,110, 43, 42, 42,226,133,132,132,228, 58,219, 14,103, 93,219,108, 54,143, 86, 46, 7, 7, 7, 95, 84,171,213,188, +111,190,249,198, 86, 80, 80,192, 83, 42,149,185, 78, 30,157, 78,199,219,190,125,187,173,176,176,144,231,239,239,127, 81,175,215, + 87,203,167, 86,171, 71,142, 30, 61,250,228,145, 35, 71,130, 41,138,194,131, 7, 15, 80, 80, 80,128,128,128, 0,108,218,180, 9, +145,145,145,216,177, 99,135, 70,163,209,140,255,252,243,207,103, 59, 68, 86,117, 62, 90,221, 59,116,232, 16,169,211,233, 16, 16, + 16, 0,163,209,136,139, 23, 47,162, 69,139, 22,200,202,202, 2, 73,146, 8, 8, 8,192,202,149, 43,139, 9,130,208, 84, 69, 36, + 18,137, 94,142,143,143, 15, 0,128,248,248,248,128,248,248,248, 10, 59,184, 78,157, 58, 97,197,138, 21,229,133,150, 55, 3, 3, +151,213,201, 77, 28,149,116,236,216, 17,199,142, 29,155,233,165, 56,178, 56, 69, 91,121,107,150, 64, 32,240,122, 49, 13,195, 48, + 60,148,186, 52, 16,158,236, 63, 1,232, 33, 18,137,120,229, 63, 44, 46, 46,230,169, 84,170,110, 94, 8,223, 32,145,168,212,224, + 20, 25, 25, 9,189, 94, 79, 91, 44,150,225,155, 55,111,182, 1, 64,108,108,236,112,154,166, 75,236,118, 59,197,231,243, 97, 52, + 26,161, 80, 40,130,170,176,141,190,191,119,235,130,208,242, 62, 90, 42,149, 10,177,177,177, 48,155,205,200,206,206,198,241,227, +199,109, 52, 77,111, 89,181,106, 21, 19, 18, 18,242,250,224,193,131,169, 75,151, 46,189, 5, 96, 90,101, 90,228, 41,179,102, 37, + 84, 42,180, 28, 10,242, 24,128,158,229, 79,178,188,248,169, 74,104, 85, 55,117,200,231,243,117,105,105,105, 18,247, 78,197,110, +183, 35, 44, 44,140, 97, 89,150,168, 72,104, 61,138, 41,152,203,229,250,125,240,193, 7,186, 85,171, 86,141, 76, 73, 73,153,227, +201,111,182,191,213, 12, 27,203,137,172,213, 75,230,173,248,102,201, 2,249,221, 95,190,199,186,175,151,209, 52,141, 75, 45, 91, +182,236,102, 48, 24, 56,254, 18, 27,212, 58, 28,114,136, 44, 79, 69, 33, 9,224,187,243,231,207, 95,234,223,191,255,233,239,126, +218, 37,207,186,119,239, 79, 65,161, 58, 91,214, 56,138,195,171, 19,249, 74, 81, 73, 9,111,248,240,225, 33, 0, 6, 87,215,136, +233,116, 58,228,228,228,148, 23, 96,184,117,235,214, 67,199,122, 84, 56,146, 4, 77,211,216,185,115, 39,196, 98, 49, 36, 18, 73, +153,205, 41,178,106,184, 80,225, 54, 0,244,235,215, 15, 26,141, 6, 82,169,212,227,114,149, 23, 47, 44,203,194, 98,177,192, 98, +177,192,106,181,210, 0,184, 28, 14, 7,227, 50, 50, 92, 86, 30,111, 4, 76,121,180,108,217,146, 61,115,230, 12, 78,159, 62, 13, +163,209,136,111,190,249, 6, 42,149,234, 89, 0, 31,123,203,229,230,164, 79, 23, 22, 22,114, 11, 11, 11, 93,214, 65, 46,151,235, +178, 30,120,104,201,227,113, 56, 28,215,104,212,185,185, 91,181, 40,138,130, 82,169, 68,104,104, 40, 86,175, 94,205,171, 95,191, +254,128,127,179, 5, 90,186,116,105,227, 47,191,252,114,253,198,141, 27, 15,141, 28, 57,114,219,245,235,215,199,250,251,251, 95, + 59,122,244,232, 2,129, 64,192,212,240,249, 14,207,202,202, 82,184,127,196, 48,140,216,110,183,187,132,109,113,113,177,199, 3, + 12, 46,151, 27,158,152,152, 40, 6,128, 5, 11, 22,112, 1,136,157,206,224, 78,206,226,226, 98,110,139, 22, 45,194, 61,189,215, + 79,158, 60,217,173, 79,159, 62,103,126,255,253,247,192,200,200, 72,100,102,102, 34, 51, 51, 19,141, 27, 55,198,162, 69,139,140, +133,133,133, 93, 0,220, 54, 24, 12,123, 60,228, 12, 11, 12, 12,228,166,165,165,193,110,183,163, 77,155, 54, 88,185,114, 37,134, + 15, 31,142,152,152, 24, 20, 22, 22, 34, 49, 49, 17, 27, 54,108, 8,228,241,120, 85,182, 29, 38,147,105, 79, 66, 66, 66, 68,121, +139,214,168, 81,163, 36,185,185,185,174,123,114,222,188,121,101,166, 16,189,105,147, 29, 83, 91,149,110, 53,129,221,110,151, 9, +133,194, 66,129, 64,192,119,250,103, 29, 63,126,220,107,107, 86,185, 1,160, 55,251,255, 26,156,162,181,130,190, 21,161,161,161, + 30,243, 8, 4, 2,194,217, 54,218,237,118,232,245,122, 90,165, 82,185,166,247, 47, 95,190, 76,215,171, 87,143,166, 40,138,226, +243,249, 32, 8, 2, 98,177,184,210, 6,159,165,217,121, 47, 14,255,184,204,170,195,169, 31, 0, 86,171, 21,151, 47, 95,134,213, +106,197,241,227,199,109,159,127,254,121,150, 78,167,155, 10,128,243,235,175,191,142,158, 57,115, 38,165, 80, 40,250,228,229,229, +161, 58, 45,242, 20,137,173,135,172, 92,206, 94,232,216,128, 1, 3, 8,199,210, 74,194, 41,156,188, 17, 90,142,135,175,218,158, +151, 32, 8,100,103,103,187,246, 21, 10,133,215,255,229, 41,130,130,130,140,157, 58,117,242, 83,171,213,123,150, 46, 93, 90, 35, + 75,214,234, 37,243, 86, 44,158,255,169, 92,115,243, 44, 50,178,178,161,201,179, 93, 58,117, 45,101, 55,128,221, 0,128, 53,205, +143, 17, 19,147,190,245,148,179, 89,176,168, 53,151,199,217,253, 92,255, 1, 17,195,226,167,145,111,190,249,102,215,209,163, 71, +235, 71,142, 28, 57, 69, 42,149, 54,177, 90,173,218, 93, 7, 14,164, 14, 27, 54,172, 62, 77,211,163, 81, 77,204, 17,147,201,244, +160,103,207,158,238,245, 41, 59,124,248,176, 50, 53, 53, 21,147, 39, 79,206,207,204,204,212,185, 31,235, 73, 25,173, 86,235,131, +214,173, 91, 87, 58, 93,232,156, 82, 4,128,162,162,162, 7, 94, 84,233, 8, 56, 28,223, 11, 10, 10,112,235,214, 45,112, 56, 28, +116,236,216, 17,167, 78,157, 66,215,174, 93, 47,123, 99,213, 42, 41, 41, 65,100,100, 36, 74, 74, 74, 96, 52, 26,139, 1, 8, 54, +213,175, 15, 0,120,171,160, 0, 23, 63,255, 28,103, 23, 47,134,251,253,236, 41, 90,181,106,197,158, 61,123, 22,215,174, 93,131, +217,108,198,248,241,227, 1,128,112,220,187,222,132,204,104, 72, 81, 84,191,254,253,251,135, 1,128,209,104, 36,206,159, 63, 15, +161, 80,232,122, 22,246,237,219,135,204,204, 76, 16, 4,129,192,192,192,112,173, 86, 91, 31, 64, 74, 21,102,127, 34, 37, 37, 5, +159,125,246, 25, 24,134,193,204,153, 51, 17, 21, 21,229, 18, 88, 15, 30, 60,192,130, 5, 11, 64,211, 52, 62,253,244, 83, 52,110, +220, 24, 54,155, 77,136, 26,134,208,168, 13, 76,159, 62,253,238,238,221,187, 15,165,167,167,191,176,100,201,146, 30, 4, 65, 48, + 51,102,204,248, 76, 38,147,209,143,194,171,213, 23,225,214,157, 7, 46, 33, 84,126, 11, 9,150,123,205,151,124, 47,221,245,123, +154,118,231,163, 17, 36, 15,244,182,136,197, 54,155,205,248,202, 43,175, 4,236,220,185,147,104,220,184, 49,238,223,191,239,180, + 12, 21,195,251,144, 14,153, 26,141, 38,138,162, 40,222,157, 59,119, 80,175, 94, 61,116,232,208, 1, 11, 23, 46,132, 90,173,134, +221,110,135, 66,161, 96,108, 54,219,101,171,213,122,162, 26,174,121, 19, 38, 76,224, 1,152,232,176,108,181,156, 58,117, 42,179, +108,217, 50, 92,190,124,217,101,193,114,119,134,247,118,234,208,221,234,228,190, 29, 63,126,124, 38,159,207,103, 1,156,131,247, +129,158, 45,229, 45, 90, 53,177,102, 61, 46, 60,206,149,140, 42,149,234,184,159,159,223, 0,173, 86, 91,198,170,213,165, 75, 23, +171, 82,169, 60,233, 41,143, 84, 42,213, 82, 20, 21, 4, 0,153,153,153,144, 72, 36,188,123,247,238, 45, 70,105,240,108,212,175, + 95,127,177, 70,163,225,213,119,180,167,161,161,161,176, 88, 44,149,186,177,252,121, 37,247,123, 0,223, 59,247,229,114,121,182, + 94,175, 23, 45, 91,182,204,176,120,241, 98, 19, 77,211,102, 0, 71,117, 58,157, 43,142, 86, 78, 78,142,158,203,229,202, 3, 2, + 2,234, 56,133, 86, 69, 90,228, 41, 67,229, 22, 45,135,146,100,203, 11, 34,130, 32, 30,114, 80,175, 70,104, 85, 43,178,104,154, + 46, 99,101,112, 58,188, 87,244, 95,142, 78,189, 70, 83,135, 14,145, 37,220,181,107,215,166,165, 75,151,158,243,244,119,238, 62, + 90,107,190,152,191,196, 41,178,254, 58,253, 59,246, 36,233,213, 51, 23, 47,255,178,166, 87,160,121,176,184,149, 82, 25,116,236, +243, 69,243,100,119,127,217,128,109,107,254,195,254,117,225, 66,251, 11, 23, 46,188, 54,121,242,228,186,142, 27, 75, 3,224, 42, +128, 97,240, 96,149, 78,102,102,102,223,114,157,240,109, 30,143,167, 20,139,197,200,204,204, 52, 36, 39, 39,123, 61, 37,163, 86, +171,251, 62,134, 27,144,227, 20, 89,106,181, 26,137,137,137,232,213,171, 23, 0,224,212,169, 83,232,210,165, 11, 46, 93,186,132, +182,109,219, 94, 6,240, 12,170, 9,212,106,179,217,116,205,155, 55,119, 89,183,244,122, 61, 3, 0,241,217,217, 72, 80,169,192, +225,112,112,118,241, 98,124,100,179, 97,161,151, 2,190,117,235,214,236,249,243,231,145,154,154, 10,187,221,142,129, 3, 7,162, +134, 15,125, 76,179,102,205, 14, 31, 61,122, 52, 68, 42,149,194,104, 52,194, 96, 48, 96,204,152, 49, 24, 62,124, 56,204,102, 51, +182,111,223,142,189,123,247,194,207,207, 15, 70,163, 17, 70,163, 49, 48, 46, 46,238,204,237,219,183,187, 3,184, 83,137,208, 98, +251,246,237,139,147, 39, 79,130,162, 40,180,111,223, 30, 5, 5,127, 47, 6, 82, 42,149, 21,125, 71,253,155, 66,139,195,225,176, +199,143, 31, 95,210,163, 71, 15,164,167,167,191,208,182,109,219,111,198,142, 29,155,249,168,188,129,254,126,104,221,162, 33,204, +102, 51,204,102, 51,194,194,194, 80, 84, 84,132,187,119,239,194,108, 54, 67,169, 8,240,154, 47, 54,166,177,139, 79,161, 80,192, +104, 52, 34, 37, 37, 5, 22,139, 5,193,193, 94, 9,173,136,190,125,251,254,177,101,203,150,160, 13, 27, 54, 88,122,246,236,201, +255,230,155,111, 8,153, 76, 6,183,142,197, 91, 28, 63,117,234, 84,100,159, 62,125,154,222,188,121, 19,199,143, 31,135,197, 98, + 65,108,108, 44,146,147,147,209,169, 83, 39, 24, 12,134,115, 23, 46, 92,216,235,137, 97, 24,192,236, 9, 19, 38,192, 41,182, 78, +158, 60,137,236,236,108,248,249,249, 61, 36,180,156,190,143,142, 85,227, 97,158, 20,214, 41,136,220, 44, 79, 31, 5, 4, 4, 88, + 1,124, 89, 67,235, 19, 0, 32, 61, 61, 93,208,178,101, 75,179, 80, 40,228, 59, 68,219,242, 71,225,171, 77,212,194, 74,198, 74, + 17, 26, 26, 58, 53, 56, 56,184, 79,131, 6, 13,144,155,155,203,227,243,249,232,210,165,139,245,153,103,158,177,134,134,134,190, +229, 41,143, 64, 32,184,201,227,241,186,151, 14, 38,104,164,165,165,129,101,217,153, 49, 49, 49,239, 20, 21, 21,161,160,160,128, + 47,147,201, 92,131,234,166, 77,155,194,108, 54,223,244,194,242, 54,175, 94,189,122,179,121, 60,222, 66,181, 90, 93, 81, 88, 8, +126, 64, 64,128,140,199,227,193,106,181,150, 17,155,229,181,200,211, 46,178,202, 8, 45, 55, 21, 89, 70,232,120, 99,209,242,196, +106,224,116,176,119,223,119,138,186,242,255, 85,211, 24, 90,254,254,254,102,167,200, 90,184,112,225,185,154,112,236,216,178, 89, +229,207, 20, 71,100,157, 59,136,219,215, 46, 97,119,162, 78, 61,115,241,242, 41, 47, 14, 30,145, 91, 94,152,121,130,168, 16,113, +140, 82, 17,116,236,139,165,139,101,154,155,103,145,157,147,131,131,231, 46, 92,178, 2,137, 0,102,214,166,105, 25, 40,157, 58, +164, 40,234, 73,186, 97, 93,206,240,217,217,217, 78,145, 21, 11, 0, 93,187,118,189,236, 16, 89,240,212,162,165,211,233,202,167, +172,233, 3, 32,216,121,254, 28, 14, 7, 93,102,207,246, 90,100, 1, 96, 47, 93,186, 4,141, 70,227, 28, 41,214, 84,100, 33, 52, + 52,244,189,163, 71,143,134,124,247,221,119,133, 27, 55,110, 44, 96, 24,134,219,186,117,235,240,118,237,218, 17,155, 54,109, 2, + 0, 12, 27, 54, 12, 51,103,206,196,141, 27, 55, 32,145, 72,208,181,107, 87,122,206,156, 57,138,169, 83,167,190,149,155,155, 59, +165,194,222,145, 97,120, 66,161,240, 8,128,103,111,222,188, 9, 0,103, 80,154,194,201,105, 69,168,244, 59, 79, 58,223,162,162, + 34,174,159,159, 95,133,161, 33,120,165,163, 33,111, 45, 16, 46,206,211,167, 79,127,246,197, 23, 95,236,126,247,221,119,239, 60, + 34,103,133, 22,173, 1, 3, 6,192,100,182, 34, 35, 87, 15,154,182,195,100,205,243,154,207,221,162, 53, 96,192, 0, 20,151, 88, +144,150,173,129,221, 78,163,200,228,113, 95, 46,126,238,185,231,126,221,186,117,107,232,159,127,254, 9,154,166,153,228,228,228, +148, 87, 94,121, 69, 54, 99,198,140,160, 71, 88,100,244,245,136, 17, 35,134,156, 62,125, 90,211,180,105, 83,249,185,115,231,144, +151,151, 7,187,221,142,103,159,125, 22,124, 62, 63,109,241,226,197, 60, 0, 95,123,122,109, 28, 98,203,122,225,194,133, 55,206, +158, 61, 43,151,203,229,124,166, 89, 51,100,255,254, 59,118,238,220,249,208, 15,214,172, 89, 3,120, 24,133,223,105,113, 58,127, +254,124,173, 8,172, 50, 61, 53,159, 95,227,233,199,167, 21,231,207,159,207,124,243,205, 55, 91,200,100,178, 47,187,117,235,214, + 43, 40, 40,136, 12, 12, 12, 60, 94,167, 78,157,119, 90,183,110,237,241,236, 2,151,203, 29, 43,145, 72,238,218,237,118,202, 96, + 48,192,104, 52,150, 54,210,118, 59,159, 36, 73,212,175, 95,223,213,151,180,111,223, 30,161,161,161,116, 82, 82,210, 88, 79,249, +243,243,243,203,172, 66,172, 0, 19,186,116,233,194, 49,155,205, 72, 77, 77, 61,229,254, 69, 69, 90,228, 41, 65,124,149,226,203, +121, 82,238, 39, 87,167, 78,157,116,155,205,198, 38, 2,236,213,171, 87,217,248,248,248, 42,183,146,146, 18, 86,161, 80,100, 87, +208,249,193,157,211,108, 54,151,249,157,217,108,102,149, 74, 37,109, 50,153, 30,226, 52,153, 76,108,120,120,120,102, 85,156, 21, + 96,204,149, 43, 87, 86,125,244,209, 71, 29,188,168, 32, 23, 39,187,186, 25,187, 97,195,134,255, 99, 89,182, 71,183, 22,145,215, +134,182, 86,178, 93,162, 20, 89,123,119,108, 25,206,178,108,143,242,155, 51,192,105, 85,156,205,148,146,230,189,163,235,106,255, +250,229, 71,246,232,178,183,217, 47, 6, 70,177,109,195,253,116,205,130, 69,222,230,136,169, 54, 91,122,116,116,244,109,134, 97, + 88,139,197,194, 70, 71, 71, 39,215, 6,103, 13, 80, 21,103, 27,148,250,178,141,168,224,179, 54,143, 80,206,191, 88,150,101, 53, + 26, 13,107, 48, 24, 88,179,217,204,210, 52,205,186, 3,192, 95, 30,112,178, 86,171,149,213,106,181, 44, 60,247,185,171,144, 83, +165, 82,165,220,187,119,143,109,212,168, 81,186,195, 28, 63,213,104, 52,178,229, 97, 52, 26,217, 94,189,122,177,201,201,201,108, +189,122,245, 74,146,147,147, 89,149, 74,117,171,154,114, 54,136,136,136, 56, 18, 28, 28,124, 28, 64,148, 23,223, 85, 89,159,219, +183,111,111,200,178,236,120,150,101,227, 43,217,198,179, 44,219,236,223,230,116,212,111, 46,203,178,108,113,113, 49,171,209,104, +216,172,172, 44,182,184,184,152, 53, 24, 12,236,149, 43, 87,216, 63,255,252,147,189,118,237, 26, 43,151,203,115, 61,225,116,242, + 89, 44, 22,182,176,176,144,205,203,203, 99, 77, 38, 19,107, 52, 26,217,235,215,175,179, 23, 47, 94,100,111,222,188, 89, 17,223, + 67,156, 65, 65, 65,107,114,114,114, 12,103,206,156, 41, 94,189,122,117,113,104,104,232, 77, 0,145, 0,154, 4, 6, 6,230,188, +253,246,219,172, 84, 42,125, 80,195,231,168, 5,151,203,189,178,100,201,146,243,251,247,239,207,221,187,119,175,101,253,250,245, + 25,147, 39, 79, 62,193,225,112,174, 0,104, 81,195,231, 72, 17, 16, 16,112,230,220,185,115,118,173, 86,203,234,116, 58,182,176, +176,144, 53, 26,141,172,201,100, 98, 45, 22, 11,107,179,217,216, 19, 39, 78,176, 74,165,210,125, 90,242,253, 42, 6,214,211, 88, +150,125,143,101, 89, 78,109,183,117,110,220,221,106,139,179, 54,218, 58,146, 36,173,142,182,163, 99,233,110,213,251,255, 86, 57, +123,247,238,253,233,240,225,195,217,126,253,250,177,177,177,177, 15,109,109,219,182,101, 39, 77,154,196,238,223,191,159,253,252, +243,207, 63,173,133,114,114, 80,186,232,101, 81,239,222,189,109, 39, 79,158,100,135, 13, 27,198, 2,232, 91,149, 22,249,111, 16, + 92,206,240, 14,132,251, 43, 0, 88,173,214,244,219,183,111,171,154,218,237, 20, 0,124,251,237,183, 15, 89,166,220,113,242,228, + 73, 59, 65, 16,119,171,250,119,171,213,154,126,244,232, 81,229,138, 21, 43,184,110, 38, 96,216,237,118, 38, 43, 43,139,252,230, +155,111,202, 28,127,236,216, 49,187,221,110, 79,243,242, 36, 55,180,105,211,102, 67,109,212,214,137, 27,169,239,252,122,240,231, +224,142, 29,186,233,100,114,121,133,163,176,237,111, 53, 3, 49,177,106,171, 22,193, 33, 23, 46, 89, 52, 47,192, 57, 5,249,211, +229, 28, 93,137,153,238,149,164, 54,253, 85,219, 87,216, 96, 48,164, 58, 87, 2, 26,141,198,180, 39,240, 38,188,130,210, 24, 87, +246,114,159, 61,131, 71,116, 58,101, 24, 6,254,254,254, 46,107,104, 13, 44,162,172,211,194,234,188,116,143, 82, 30,150,101, 79, + 95,191,126,189,222,152, 49, 99,252, 54,110,220,120,143,166,105,238,184,113,227,172,161,161,161,188, 83,167, 78,217, 0, 16, 61, +122,244,224,228,228,228,176,153,153,153,154,151, 94,122,169,232,141, 55,222, 8,186,122,245, 42,159, 97,152,234,130, 22,222, 79, + 79, 79,239, 93,131,239,170,196,208,161, 67,239,225,209,211,216, 60,118, 78, 39, 52,186, 66,220, 75,205,116, 68, 48,103, 64, 63, +200,117,249, 85,217,108,118,104, 10, 11,188,182,104,221, 77,201,116,164, 24,163, 65,211, 89, 14,190, 82,135,120, 86, 91, 92,125, +111,194,225,116,157, 51,103, 78,127,146, 36,201,179,103,207,154,151, 46, 93,154,158,159,159, 63, 16, 64, 26, 0,104,181,218,158, + 27, 54,108,248,193,131, 80, 14,149, 33,209,102,179,117,122,255,253,247,167, 0,232, 10,160,174,131,251,148,195,146, 85,211, 8, +230,121, 58,157,238,249,254,253,251,255, 78, 81, 84,125,183,231, 40, 24,128,218,249, 92,176, 44,171,200,205,205,125,193, 19, 66, +130, 32,150, 63,174,134,228,113,114, 63, 98, 59,244, 84,172,100, 60,114,228,200,220,129, 3, 7,114, 34, 35, 35, 63,140,140,140, + 36,181, 90, 45, 12, 6, 3, 72,146, 68,104,104, 40,162,163,163, 17, 26, 26,202,220,188,121,115,209,172, 89,179,170,141,201,215, +188,121,243,134, 54,155,173, 17, 73,146, 13, 1, 52,100, 89,182, 33, 65, 16, 13, 1,200, 1, 64, 38,147,201,234,213,171,199,233, +216,177, 35, 58,116,232,128, 99,199,142, 97,199,142, 29,223, 3,248,213,221,154, 85, 94,139, 60, 9, 72,108, 3,182,197, 21, 16, + 55,218,162, 7,193,224, 24, 75,162,103,244, 37, 87,156,189,242, 34,171,242,164,210, 21,152,254,250, 62,251,236,179,174, 7,206, +131, 78, 37,181,186,135, 47, 63, 63,191,239,216,177, 99,203,112,210, 52,109, 46, 40, 40,120,179,115,231,206, 43, 41,138, 18,148, +187, 97, 31,228,229,229,253,163,185,250,202,199,209,234,219,255,101,245,163,114, 74,121,100,163,219, 7,214, 34, 55, 79,141,159, + 46,231,104,139, 44,116,207,100,117,241,245,199, 81,254, 7, 15, 30,244,123, 10, 20,127, 69,162,245, 81,147,103,231,123, 16,144, +180,186, 28,117,132, 35,156, 72,173, 60,228, 57, 57, 57,203,102,207,158,253,252,162, 69,139, 66, 14, 29, 58, 36,115, 14, 80, 6, + 13, 26,148,119,253,250,245,110, 0, 4, 37, 37, 37,135, 23, 45, 90, 20, 50,111,222,188, 32, 0, 65, 0, 16, 23, 23,151,155,155, +155,187, 2, 62, 84, 9,155,205,150, 17,221,188,169,107,224,231, 30,210,193,253,189,221,110,207,240,134,175, 34, 30,247,125,154, +166,171,228,163, 40,234,221, 14, 29, 58, 80,239,190,251,110,238,161, 67,135,156,137,116,221, 21,218,237,106,130,146,122, 2, 51, +128,165,142,173, 54, 97,212,104, 52,157,188,252, 13,237,187, 27, 43, 28, 80,122,179,255,175, 96,207,158, 61, 31, 15, 27, 54,108, +131, 92, 46,223,220,176, 97,195,166, 74,165, 82, 38, 18,137, 96, 54,155,139, 44, 22,203,173,219,183,111,143,252,248,227,143,239, +123,100,225,216,176,129, 2,192, 99, 24, 70, 72,146,164, 4,128,140, 32,136, 64,167,208, 34, 8, 2, 86,171, 21,169,169,169,248, +232,163,143,232, 35, 71,142,124, 14,224, 83, 47, 6,174,207, 0, 8,113,107,199, 67, 0, 88, 80, 26,192, 54,159, 32,136, 11,143, +187,190, 8, 6,199, 90, 92, 1,145,216, 6, 21,245, 19, 85, 39,149,174,236,129,203,207,207,239, 84,219, 15,113,101,156,249,249, +249,145, 79,202, 19, 50,218,188,244, 71,172, 89, 90, 38,207,161, 83,132, 85,180, 95, 29,244, 38,251,228,175,127,189,177,204,108, +103, 25,171,157,121, 61, 57,191, 56,209,215, 14,213, 58,158,171,173,103,169, 22,203,116, 61, 41, 41,169,243,228,201,147, 63, 22, +139,197,237, 1,160,184,184,248,108, 86, 86,214,124, 56, 86, 21, 86,247,189, 15,149, 67,173, 86,183,123, 18,249, 44, 22,203, 59, +157, 59,119,254,138,166,233, 47,236,118,251,169,255,129, 75, 81,226,187, 27,159, 94,108,219,182,237, 62,128, 78, 0, 48,100,200, + 16, 10, 0,118,236,216,225,181,120, 30, 51,102, 12,205,178,172,213,113, 63, 24, 81,186,186, 80,235,108, 83,141, 70,163, 54, 43, + 43,235, 38, 77,211, 55, 1,252, 0,239, 87,220,134, 16, 4,177,159,101,217, 1, 14,225,182,159,101,217, 1,238,159, 61,110,171, + 86, 53,135, 84,239, 12,239, 67, 41,118, 36,130, 40, 63, 21, 88,221,126,117,184,157,107, 60, 14,160,173,175,118,255, 39,113, 47, + 43, 43,107,244, 35,124,239,195,211,135, 52,139,197, 50,240,127,232,124,245,190, 75,254, 95,210,255,213, 64, 96, 57,113,243,230, +205,199,230, 34,240,111,163,197,149,178, 3,240,242,251,110,136,175, 72,120,249,132,150, 15, 62,248,224,131, 15,143, 2,157,175, + 10,124,248,111,134,211, 55,203,185, 95,137,143, 86,121,255, 44,215, 62,129,202, 87, 14,120,147,149,188, 38,171, 36, 14,251, 56, +125,156, 62, 78, 31,167,143,243, 95,231, 12, 0, 80, 15,192,146,106,142, 43,191,186, 48, 23,128, 26,128,205, 87,159, 62,206, 71, +208, 15, 30,129,101,217,184,170,166, 14, 9,130, 56,240,184,132,150,203, 25,190, 13,230, 68, 95,193, 28,231,190,167, 66,235,113, +163,143,143,211,199,233,227,244,113,250, 56,125,156, 62, 78, 31,231, 35, 10,173, 94,179,102,205,250, 0,165,161, 49,216, 89,179, +102,125,192,178,108, 92,233, 87,108,220,227,252,239, 27,109,209, 35,177, 13, 88,231,118,163, 45,122, 84,114,104,188,219,230,130, +111,234,208, 7, 31,124,240,193, 7, 31,124,120,210,113,102,241,226,197,197,139, 23, 47,118, 58,190,231, 3, 32, 28, 22,174,252, +199,249,199,142,105, 66, 79, 22, 74, 85,157,130,231, 95, 64, 24,201,225,141,226,242, 4,189,192, 50,209, 0, 0,146,186, 65, 91, + 74,254,176,219,173,155, 1,100,213,148,184, 25,208,188,113,128,104,175,153,166,121,233, 69,150, 33, 73,165,105, 14,188,198, 16, +160,139,128,207,255, 77, 16, 16, 32,170,232,123,179, 78,103, 50, 91, 44,207,239, 0, 78,251,158, 1, 31,124,240,193, 7, 31,158, + 18, 72, 2, 3, 3,143,144, 36, 25,233,252,192, 61,238, 96,249, 24,132, 52, 77,103,107, 52,154,231, 81, 58, 85,252, 79,114,186, +255,222,130, 26,246,229,181, 13,111,167, 14, 57, 64,153, 40,172,255, 72,198,108,138, 43,120,195,207, 63, 96,225,255,141,125, 39, + 40,170, 73, 83, 34, 34,162, 14,192, 2,105,233, 25,202,187,119,146,123,111,219,248,245,244, 66,189,230, 35,155,217,188,214, 91, +238,230,128,164,174, 84,112,106,237,172, 87, 3, 56,176, 99,196,130, 45,191, 16, 6,107,196,205,210,229,166, 94,137,172,128,160, +160, 95, 23, 31, 62, 44, 10,108,213,170,204,119, 44,203,150,230,215,251,235, 47,209,135,207, 63,255,235, 16,141,166,175, 79,108, +253, 87, 34, 84, 38,147, 77,229,114,185, 61,173, 86,107, 36,159,207, 79,167,105,250,184, 86,171,253, 18, 64,166,175,122,254,187, +209, 52, 84,210,173,105,195,200, 45, 89, 57,185,151, 11, 75, 44,227,110,103, 25, 52,190, 90,241, 26, 85,229,215,252,215,114,111, + 2,128, 84, 42,189, 72,146,100,184,187, 8,112,230,236,117,238,151,127,101, 24,230,190, 70,163,233, 92, 5,109, 67,185, 92,190, + 18,192, 51,213, 5, 76,118,196,102,187,160,209,104,222, 68,229,171,245,252, 2, 3, 3,231, 18, 4, 49,148, 36, 73,170,186,115, + 98, 24,134,102, 89,118,187, 86,171,253, 20, 64, 81,101,199, 5, 6, 6, 30, 78, 74, 74,122, 70,161, 80, 84,107,165,177,219,237, + 72, 75, 75, 11,105,223,190,253, 9,141, 70,211,236,113,114,254,211, 90,164,166,168, 98,213, 97,165, 55, 58,128, 50,249,133, 30, +107, 68, 86,158, 80,186,183, 83,247,190,189, 38, 77,121, 87,114,229,250, 45,252,118,236, 79, 20, 26,205,160, 72, 18, 1,126, 98, + 52,105,210,136, 88,158,176, 51,248,251,213,203,191, 56,123,242,247,184, 18,163,254, 37,175,100,186,152,243,209,204, 87,218, 75, +130,228, 52,192,208,120,175,127,107,201,135,251, 47,127,132, 98,251, 7, 94,139,172, 35, 71,196,121,185,185,152, 23, 22, 6,142, +221, 14, 33, 73, 66, 72, 16, 16,146, 36, 36, 66, 33,250,173, 95,143,249,135, 14,137, 63,126,225, 5,159,216,250, 47,131, 84, 42, + 29, 27, 22, 22,182,116,221,186,117, 65, 13, 26, 52,128, 68, 34,129, 70,163, 9,190,125,251,118,155,105,211,166,141,206,206,206, +158, 93, 88, 88,184,198, 87, 83,255,189, 96, 24,140,250,110,225,155,117,178, 31,220,169, 51, 97,209,143, 77,136, 32,186,231,173, + 2, 83,142,175,102, 60, 70, 27, 0,151,248,250,153, 97, 0, 0, 32, 0, 73, 68, 65, 84, 81,113,254,210,170,190,171, 20, 66,161, + 48,183,164,164, 68, 81,213, 49,124, 62, 63,207, 98,177, 40,171,227, 34, 73, 50, 60, 51, 51, 83, 33, 22,139, 65,211,180, 35, 27, + 0,227, 26, 72,187,103, 63,113, 4,170, 69,179,102,205,172, 85,113,250,249,249,125,155,151,151,215,199,153, 39,208, 77, 80, 85, +136,204,204,204, 62, 45, 90,180,248,182,168,168,232,249, 74,196,203,220, 41, 83,166, 76,141,137,137,113, 90,129, 28, 89, 16, 74, + 95,213,106, 53, 38, 79,158,236,250, 15,134, 97,240,251,239,191, 79, 25, 59,118, 44,180, 90,237,180, 42,206, 61, 82,161, 80, 16, +142,132,226,149, 98,206,156, 57,152, 51,103, 14,190,254,250,107,130,203,229, 6, 84, 83,159,181,194,249, 79,105,145,154, 88,176, +170,137, 12,127, 0,101,125,179, 14, 60, 36,180,254, 9, 80, 92,193,235,207,116,238,211,115,242,212,153,146, 31,127, 62,138,219, + 55,255, 66,210,169,173,101,142,105,247,252, 88,228,168,139, 48,118,210,123, 82,130,226,244, 60,121,120,207,235, 54,179,233, 59, + 15,173, 89,202, 72, 1,255,237,142,237,163,185,153,162,219, 8, 13, 20,161,107,219,198,220,136, 95,175,189,109,132,253,171,155, +165,171,100,188, 18, 89,235, 94,125, 21,221,108, 54, 40, 40, 10, 20, 65,128, 2, 64, 18, 4, 74,204,102, 92, 24, 53, 10,237, 55, +109,194,167,251,246,137,231,190,248,162, 87, 98, 75, 34,145, 92, 33, 8, 34,208, 96, 48,196,161, 52,177,244,211,128, 22, 82,169, +244, 0,203,178, 90,163,209,216,230, 9, 42,151, 10,165,115,244,229, 71,199, 60,148,174,168,242, 42,179,176, 64, 32,120, 99,200, +144, 33,203, 87,172, 88, 33,206,205,205, 69, 86, 86, 22,104,154,134, 80, 40, 68, 84, 84, 20,113,248,240,225,160,153, 51,103, 46, + 59,112,224,128,160,168,168,232, 43,111, 6, 54, 92, 46, 55, 65, 46,151,191,160, 84, 42, 37,121,121,121,197, 58,157,238,119,179, +217,252, 6,106,158, 54,133,228,114,185, 35,235,213,171,247,114, 88, 88,152, 50, 51, 51, 83,157,145,145,177,215,108, 54,127,143, + 26, 38,106,118,171,211, 86,112, 68,171, 7,144, 93,175, 94,189, 27,169,169,169,121,181,200,153, 85,175, 94,189,196, 26,112, 74, + 0,108, 3, 16, 86,205,113, 89, 0,134,193, 75,107,182,171, 98, 89,230,224,130, 47,215,141,155, 55,166, 43,241,221,180, 62, 81, + 19,191, 62,252, 39,201, 99,187,223,204, 46, 73,247,105, 40,207, 68,150, 35,165, 85,121, 65, 85,213,119, 85,194,108, 54,135, 88, +173, 86,112, 43, 73, 22,111, 52, 26,225,231,231, 23,226,105, 33, 69, 34, 17,182,110,221, 10, 46,151, 11, 46,151, 11,173, 86,139, +240,240,112,215, 62,143,199,115,189,175, 91,183,110,181,124, 52, 77,183,167, 40, 10, 6,131, 1, 52, 77,187, 54,157, 78, 7,150, +101, 33, 16, 8, 64,211,165,233,156,220,190,111, 95, 25, 31, 65, 16, 67,195,194,194,240,227,143, 63,194, 98,177, 60,244,189, 76, + 38,195,245,235,127, 39, 25,161, 40, 10, 29, 58,116, 32, 9,130, 24, 10, 96, 90, 21,188, 44, 0,196,199,199,131,162, 40, 80, 20, + 5,146, 36, 93,239,157, 27, 77,211,152, 51,103, 14,202,165, 38,251,199, 56,159, 52, 84, 19, 25, 62, 27,149,248,104,145,143,185, + 92,238, 75, 60,195,196, 18,217,103,111,190,243,158,244,192,137,107, 72, 75, 79,123, 72,100, 1,192,197,223,190, 71,118, 86, 38, + 46, 39,101, 96,228,235,111, 73,101,178,128,207,202, 53,168,149, 46, 27,245,247,227,125, 62,107, 88, 87,161,193,150,133,162, 64, +128,106,200, 7, 87,108,196,204, 1,173, 4, 50, 63,222, 82, 79,202, 41,224,243,127, 91,124,248,176, 75,100,117, 49,155, 33,160, +105,216,105,218, 37,178, 44,118, 59, 76, 22, 11, 84, 6, 3,238,142, 29, 11,214,102,195,236,221,187,197, 2, 62,255, 55, 79,202, + 9, 0, 60, 30, 79,181,119,239,222,186, 45, 91,182, 60, 6,207,131,153, 30,126,204,215,168, 42,180,109,221,186,245,241, 77,155, + 54,213,229,241,120,170,218,224, 20, 10,133,131, 37, 18, 73,190, 80, 40, 28, 92,195,114,146, 0, 22,140, 27, 55,238, 82,163, 70, +141,142, 58,132,149, 75,212, 52,106,212,232,240,184,113,227,174, 0,152, 83,201,189, 94, 17,103,157,176,176,176,133, 43, 86,172, + 16, 39, 39, 39, 35, 51, 51, 19, 54,155, 13, 35, 70,140, 0, 77,211, 48,153, 76,176, 88, 44, 88,178,100,137, 36, 40, 40,232, 35, +148, 38, 10,246,228,220,121,254,254,254,201, 27, 55,110, 28,146,146,146, 34, 61,122,244, 40,113,253,250,117,201,178,101,203, 6, + 6, 5, 5,221, 6, 32,168, 65,125,146, 42,149,234,187, 61,123,246,188,121,253,250,245,240, 93,187,118,113,207,158, 61,171, 90, +189,122,245,120,149, 74,181, 9, 0, 85,195,107,212, 70, 44, 22,247,158, 49, 99, 6,115,230,204,153,204, 51,103,206,100, 46, 95, +190, 28,221,186,117,235, 50,111,222,188,216, 26,114,182,245,243,243,123,118,198,140, 25,204,201,147, 39,179,206,157, 59,151,177, +108,217, 50,242,217,103,159,237,186,112,225,194, 86, 94,114,110, 59,115,230, 76,143,244,244,244, 6, 25, 25, 25,245, 51, 50, 50, +234,101,100,100,212,203,204,204,140,204,206,206,174,155,147,147, 19,145,151,151, 23,113,252,248,241,174, 0,182,120,194,217, 84, + 41,121,115,218,136, 62,197, 31,189,222,159,253,224,181,231,216,153, 35,122,176, 47,116,111,249, 51,197,225, 16,231, 18,211, 16, +238, 15,124, 63,249,153,200,136, 96,201,245,104,185,180,201, 19,246,108, 62,105,156, 28,167,144,210,104, 52, 56,112,224, 0, 28, +214,171, 54,238, 34,171,176,176, 16,217,217,217,206,239, 56,158,148, 83, 38,147, 29, 89,183,110, 29, 91, 82, 82, 2,189, 94,143, +188,188, 60,164,167,167,227,238,221,187, 40, 40, 40,192,173, 91,183, 32, 22,139,143,120, 82, 78,130, 32, 64,211,180, 75, 72,253, +254,251,239, 24, 55,110, 28, 52, 26,141,235, 51, 14,135,227,122,239,252, 77,117,156, 78,203, 19, 77,211, 56,119,238, 28, 38, 76, +152,128,229,203,151, 99,203,150, 45,216,191,127, 63, 52, 26,141, 75,108,217,237,246,106, 57,213,106, 53, 24,198,179, 49, 19,203, +178,208,235,245, 30, 95,119,119, 1,196,225,112, 30, 18, 69,206,205,155,123,233, 17, 57,159, 88,120, 16, 25,190,242, 17,182,243, +141,195, 84,215,243,113, 21,146,228,240, 70, 14, 29, 51, 37, 40, 35,175, 16,153,185,122, 80,228,223,253, 94,108,159, 49,224, 80, + 36,206,255, 90,106,184, 34, 41, 10,122,163, 25, 58,131, 21, 67,198, 76,149,175, 93,254,201, 72,187,181,164,202, 24, 47, 49, 64, + 84,180, 84,250, 74,139, 22,117,201,155,130, 36,196,190,112, 10, 52, 3,176, 39, 95, 68, 27,173,130,106,246, 27,255, 21, 99,145, +117,225,117, 32,185, 74,107, 70, 64,128, 40,176, 85, 43,204, 11, 11, 67,119,155, 13, 60,150,197,115,185,185,248,107,234, 84,152, +119,238, 4, 9,128, 55,120, 48,122,125,249, 37, 78,132,133, 33,212,100,130,110,250,116,132,252,242, 11,120, 50,153, 8,249,158, + 45,126, 32, 8, 2, 61,123,246,196,225,195,135,131,250,245,235,247,235,181,107,215, 6,217,237,246, 19, 53,169, 91,127,127,255, +139, 28, 14, 39,188,186,227,236,118,123,134, 94,175,247, 58,205, 8,135,195,233,222,161, 67,135,221,187,118,237, 10,180, 90,173, +181, 50, 10,225,243,249,253, 6, 14, 28,184,110,213,170, 85,178,241,227,199,175,219,191,127,127,177,197, 98,249,197,155, 91, 10, +192,130, 53,107,214, 76,140,143,143, 15, 24, 63,126, 60,123,247,238, 93,119,235, 85, 72,183,110,221, 26,173, 91,183, 46,244,153, +103,158,153, 50, 97,194, 4, 30,128,217,213, 89,121,164, 82,233,164,117,235,214, 5,171,213,106, 24, 12, 6, 87, 35,155,145,145, + 1,145, 72, 4,146, 36, 65,146, 36,184, 92, 46, 62,251,236,179,160, 73,147, 38, 77,213,104, 52, 83, 61,176,146, 37,172, 92,185, + 50,228,249,231,159, 39, 83, 82, 82, 64,146, 36,132, 66, 33, 94,125,245, 85,210,100, 50, 5,206,155, 55,111,131,209,104, 28,238, + 77, 29,114,185,220,145, 9, 9, 9, 77,186,116,233,194, 73, 74, 74, 66,167, 78,157,112,254,252,121, 12, 30, 60,152, 91, 84, 84, + 84,127,230,204,153,227,204,102,179,183,113, 92, 84, 98,177, 56,230,143, 63,254, 72,143,136,136,112, 53, 44,245,235,215,167,227, +226,226, 52, 73, 73, 73, 77,207,156, 57, 83,208,185,115,103,111, 18,150,215, 17,139,197,205, 14, 30, 60,152, 61,111,222,188,222, +107,214,172, 25, 8, 0,237,219,183,223, 59,127,254,252,163, 26,141, 38,250,196,137, 19,154,238,221,187,103,120,200, 23,166, 82, +169,232,201,147, 39, 75,171, 58,104,253,250,245, 58,148, 38, 92,110, 0,160,202,124,109, 77,235,133,126,180,116,234, 80, 17,104, + 43, 88,155, 9,176, 22, 3, 86, 3, 24, 75, 49, 8,158, 8,176,153, 16, 34,208, 96,219,164,166,178,247,127,188,119,147,190, 69, +196, 37,169,139,126,129, 15, 21, 54, 53, 0, 98, 9,130,184,124,224,192, 1,116,232,208, 1, 7, 14, 28, 64, 92, 92,220,101,119, + 49,112,253,250,117,116,239,222, 29, 14,139,150, 71,190, 90,122,189,126,214,156, 57,115, 78,142, 28, 57, 82, 92,166, 49, 32, 73, + 4, 4, 4,160,127,255,254, 37, 70,163,113,150,167, 5,165,105, 26, 28, 14, 7, 25, 25, 25, 88,191,126, 61, 22, 45, 90,132,168, +168, 40,216,108,182,135,196,150,163,221,243,168,241,179,219,237,184,112,225, 2, 54,111,218,132,217, 31,125, 4, 63, 63, 63, 0, +128,213,106,133, 70,171,133, 80, 40,116,137,177,106,132,211,246, 59,119,238, 76, 13, 15, 15, 47, 51,101,232,124,117,180, 89, 96, + 24, 6,118,187, 29, 37, 37, 37, 88,190,124,185,157,101,217,237,213,245, 63, 78, 81, 52,117,234, 84,152,205,127, 27,212, 91, 57, +124,146,235,213,171,135,214,173, 91,187,246, 73,146,100, 61,229, 92,219, 57, 6, 38,183,163,155,206, 89, 6, 0, 8, 15, 15, 71, +211,166, 77,161, 82,169, 42,229,124,220, 90,164, 38,240, 34, 50,124,229, 66,235,159,200,148,205,229, 9,123, 53,108,220,132, 72, +203,214,128,195,225, 64,226, 31,140,206, 47, 79, 3, 69,145,144, 6, 4,131,160, 77,127, 43, 98,146, 2,135,226, 64, 83,100, 66, +189, 6,141, 73,129, 80,212,203, 88,141,208,146,249,115, 87,206, 24,222, 89, 88, 96,207,128,168,174, 16,180,179, 59, 13,227,131, + 12, 42,194,187,253,162, 68,241,123,175,173,132,222,246,172, 39,229,165,236,118, 40, 40, 10, 86,150,197, 95, 83,167, 34, 54, 33, + 1,151,157,194, 48, 33, 1,151,227,227, 33,231,114, 33, 32, 73,176, 54,219, 67,115,250,158, 8, 45, 0, 72, 79, 79,199,206,157, + 59,229, 67,135, 14,221,125,253,250,245,145, 94,138, 13, 39, 87,240,185,115,231, 20, 13, 26, 52,168,244,152,251,247,239,163, 93, +187,118, 94, 79, 79,241,249,252,126,207, 62,251,236,143, 59,119,238,244, 79, 76, 76,132, 66,161,120,100,161, 37, 16, 8,186,247, +233,211,231,199,141, 27, 55,202,242,243,243,145,144,144, 32,123,241,197, 23,183, 92,186,116,233,101,179,217,236,137,216, 44, 35, +178, 18, 18, 18,116,235,215,175, 95,139,178, 83,132,217,235,215,175,255,238,153,103,158,121, 51, 62, 62, 62, 0,192, 68,135,239, + 64,149, 98, 75, 32, 16,244,108,216,176, 97,153, 81,173, 64, 80,106,108,146, 72, 36,240,247,247, 7,143,199,131,217,108, 70,108, +108, 44,193,231,243,187,122,114,206,126,126,126,125, 94,121,229, 21,242,212,169, 83,200,201,201, 65, 64, 64, 0,164, 82, 41,104, +154,198,248,241,227,169,229,203,151,247, 52, 26,189,155,225,138,136,136, 24,216,187,119,111,206,141, 27, 55,144,146,146, 2,179, +217,140,219,183,111, 67, 38,147,225,181,215, 94,227, 45, 93,186,244,197,204,204, 76,111,133, 86, 76,124,124,124,174,187,200,114, + 66, 34,145, 16, 77,154, 52,209, 4, 5, 5,181, 5,224,141,208,138,121,235,173,183,242, 22, 47, 94,220,253,240,225,195,174,160, +151,135, 15, 31,158, 9, 0, 95,125,245,213,201,144,144,144,182, 0, 60, 21, 90, 96, 89,150,249,191,255,251,191, 7,124, 62, 31, + 92, 46, 23,124, 62,191,204,198,227,241, 64,146,164,159,243,113,174,142,239,102, 74,206,146,241, 51,151, 45,147, 8, 41,238, 59, + 47,183, 68,221, 0, 30, 32,146,131,215,253,125, 16, 1,165, 70, 75, 86,115, 31,248,237,125,124,241,138,134,140,255,161,228,103, + 43, 29, 24,114, 79,171, 45,250,151,251,128,103, 0,252, 7,165,201,117, 63, 2,112,238, 9,233,155,174, 0,136,141,139,139,115, +137,173, 67,135, 14,161, 95,191,126,208,233,116,184,113,227,134,187,200,242, 38,193,242, 21,155,205,118,117,235,214,173,157,135, + 14, 29, 74,184, 61, 95, 72, 76, 76,196,173, 91,183, 46,123,202, 71,146, 36, 24,134, 1,151,203,197,178,101,203, 96,181, 90,241, +195, 15, 63, 96,199,142, 29, 32, 73, 18, 4, 65,128, 32, 8,200,100, 50,124,253,245,215, 94,181,123, 52, 77, 99,195,134, 13,120, +127,230, 76,151,200,114,204,100, 32, 84,169, 68, 80,112, 48,238,221,187, 87,173,208,210,106,181,159,238,219,183, 15, 85, 57,195, +239,219,183,207,245,190,156, 51,124,245,253, 28, 69,193,108, 54,227,185,231,254, 78, 21,251,214, 91,111,185,222,107, 52, 26, 80, + 20,229,172, 11,194, 83, 78, 19, 11,188, 44,252,251,179,254,239,190, 91,198, 66, 87, 25,231, 63,161, 69,106,203,186, 85,129,216, +138,117, 88,103, 85, 0,226, 80,234,163,149, 13,252,131, 62, 90, 44,203, 52, 11,175, 19,134,171,119,175,131, 67, 81,224,251, 7, +195, 95,174, 4, 99,183, 64,159,151,130, 99,187,190, 5, 0,172,217,176, 29, 36, 73,130,195,161, 96,182,208,136,170, 27, 6,134, + 97,154, 85,197,221, 28,232,220, 83, 25,220, 33, 34, 50,128,184, 17,152,130, 38,138,160,114, 19, 33, 2, 68,101, 73,137, 78, 82, + 81,123,173,190,176,243, 77,224, 76,181, 98,128, 36, 65, 18, 4,196, 60, 30,204, 59,119,150,122,109, 38,148,246, 89,151,227,227, + 65,254,252, 51,252, 4, 2, 80, 4, 1,142,195, 4, 93, 19, 20, 22, 22,130, 32, 8,108,222,188, 57,240,181,215, 94,219,114,227, +198,141,248,146,146,146,157,222,112,232,116,186,184, 46, 93,186, 28,221,176, 97, 67, 72,104,104,232, 67,223,231,228,228, 96,204, +152, 49,249, 58,157,206,171,160,110, 66,161,112,240,192,129, 3,215,125,255,253,247,178, 59,119,238,192, 96, 48, 32, 36, 36,228, + 81,111,133,182, 29, 59,118,220,189,115,231, 78,255,156,156, 28,232,245,122,152,205,102,108,222,188, 57,160,127,255,254, 59,147, +146,146,250, 1,184, 84, 13,199,199,238, 34,107,194,132, 9,215, 0, 40, 0,172, 44,175, 65, 29,223,181,116, 19, 91,122, 0, 75, +171, 24,137, 70, 74, 36, 18,228,229,229, 97,204,152, 49, 72, 78,254,219, 0, 26, 22, 22,230, 26,233,221,187,119, 15, 33, 33, 33, + 32, 8, 66,225,201, 73,135,132,132, 72, 45, 22, 11,198,141, 27,135,244,244,244, 50,156, 25, 25, 25, 32, 8, 66,236,109, 69, 42, +149, 74,165,201,100, 66,183,110,221, 80, 82, 82,154,215,119,216,176, 97,224,114,185,200,203,203, 3,151,203, 13,174,193,245, 9, +142,139,139,171, 52,180,138, 76, 38,179, 6, 6, 6, 54,247,146, 51,232,197, 23, 95,204, 76, 72, 72,120,104, 97,203,249,243,231, + 95,146,203,229,135,229,114,121, 19, 47, 57, 25,119, 81,197,227,241,202, 8, 45, 46,151, 11,146, 36, 61,246, 81, 75,206, 51,174, +224, 16,217,173, 23, 79,126,126, 76, 93,133, 63, 88, 67, 46,120,207,126,138,171,249, 34, 44, 91,126, 16, 0,240,222,171,237,208, +170,207, 2, 88,190,127, 30, 83, 59, 81,252, 81, 25,230, 25, 0, 62,254,151,219,252,207, 1, 56, 87,193,173, 2,208,250, 9,234, +143, 92, 98,235,208,161, 67,136,142,142,134, 86,171, 69, 82, 82, 82, 77, 69,150,179,189,123,127,238,220,185,191, 13, 26, 52, 72, +226, 28,180,138, 68, 34, 76,159, 62,221,100, 48, 24,222,247,234, 38, 98, 24,112, 56, 28,215, 32, 89, 40, 20, 34, 54, 54,214, 37, +178, 8,130, 64,113,113, 49, 56, 28,142,115, 69, 34,225, 97, 25,161, 10, 13,133,159,159, 31, 26, 71, 69,225,142,163, 29,113,190, + 23, 8, 4, 32, 8, 2,118,123,181,134,188, 34,135, 83,251,180,218,238,146,157,162,168, 74,211,113, 88, 24, 24,134,113,138, 76, +182, 54, 56,131,131,131, 97, 48, 24, 60,229,124, 34, 81,137, 69,203, 41,180,226, 80,234,171,245, 80,120,135, 30, 0,142,225, 49, + 46,169, 36,192, 18, 12,203,130, 67,145,142,185, 91, 10, 20, 69, 66,147,159,141, 47, 63,157,232, 16, 89, 59,112,224,100, 18,194, + 27, 70,255, 61,143, 75, 16, 0, 91,245,205, 29,226,207, 75,152, 52,168,163, 40,151,200, 70, 64,152, 24, 66, 97, 57,253, 24,200, + 3, 81,143,196,228,158,225,226, 11,251, 74, 18,110,234,173,213,118, 20, 66,146, 44,117,126, 39,136, 10,157,123, 72,199,119, 20, + 65,128,101, 89,176,140,119,126,199, 78, 33, 47, 18,137, 96,181, 90, 65, 81, 20,190,249,230,155,128, 62,125,250,172,244, 86,104, + 1, 72,204,205,205,237, 63,126,252,248, 67,219,183,111, 15, 14, 14, 14, 46, 51,122, 24, 63,126,188, 58, 55, 55,183, 63,188,116, +186,231,114,185, 43, 87,173, 90, 37, 75, 77, 77, 69,113,113, 49, 68, 34,145,171,241,169,233,253,217,190,125,251, 95,127,249,229, +151, 64,189, 94, 15,171,213, 10,145, 72, 4,150,101, 65, 81, 20,126,250,233,167,160, 1, 3, 6, 28, 76, 75, 75,123,182,170,178, +138, 68,162,151, 29,194, 9,241,241,241, 1,241,241,241, 61,128, 74, 35,245,186, 16, 31, 31, 31, 48,109,218,180, 23, 77, 38,211, +210, 42,206, 57, 93,163,209,132,138, 68, 34,236,218,181, 11, 82,169, 20, 98,177, 24, 97, 97, 97,208,104, 52, 16,139,197, 96, 89, + 22, 54,155,205,217, 88, 20,120,114,226,249,249,249, 6,187,221,238,127,232,208, 33, 20, 20,252,253,147,186,117,235, 66,167,211, +129, 97,152, 98,111, 43, 51, 43, 43, 43,151, 32,136,136,171, 87,175, 34, 53, 53, 21,253,250,245,195,207, 63,255,140,118,237, 74, +103,135, 45, 22, 75, 77,130,248,209, 20, 69,177, 85,220,183, 4,128,192,218,228,116,116, 94, 94,113, 50, 12,195, 56, 69,150,251, +171,187,248,170,230, 63,203, 60,206,205,149,210,245,139, 39,245, 30,243,124,116, 48, 76,249, 41, 16,250, 5,131, 8,168,135,101, +203, 15,226,198,253,210,235,181,108,203, 69,252, 56,175, 63, 32,146,163,169,191, 26,161,126,156, 87,110,229,253,235, 66,203,223, +125,156,240,164,118, 76,253,250,245,131, 70,163,129, 84, 42,173, 13,255,156, 63, 77, 38,211,237, 61,123,246,180,141,139,139, 3, +159,207,199,237,219,183,113,233,210,165, 36, 0,127,122, 43,180,184, 92, 46,230,206,157,139,137, 19, 39, 66,169, 84,226,253,247, +223, 7,135,195,113,109, 4, 65,184, 44, 92,222, 64,161,172,122,225,163,211, 33,190, 58, 99,184,191,191,255, 92,146, 36,135, 82, + 30, 84, 28, 77,211, 52,195, 48,219,245,122,125,149,225, 29,156,142,235,158, 92, 11,247, 58,168,166, 79,123,100,206,127, 66,139, +212, 4,229, 87, 27, 86, 98,209,114,174, 58,124, 40, 21,144,243, 44,143, 57, 76,118,199, 30, 87, 65, 9,146,186,149,145,153,133, +160, 64,169, 67,100, 57, 54,146, 68,171,232,210,193,236,129,147, 73, 8,111, 16, 13, 14, 69,129, 67, 81,144,138, 4,200,205,201, + 6,135, 67,222,170,140, 55,134,194,160, 65, 77, 34,234, 5, 6,113,161, 14,177, 64,165,172,196, 48,208,214, 15,225, 42, 62,250, + 6, 9, 35, 99, 40, 12,170,218,250,198,186,132,150,213,110, 7,111,240, 96,215,116,225,229,248,120,196, 38, 36,128, 30, 56, 16, + 70,171,181,140,169,184,166, 66, 75, 36, 18,161,168,168, 8, 35, 71,142,212,216,108,182, 55,107, 88,197,151, 10, 10, 10,134,140, + 26, 53,170,192, 41, 96,172, 86, 43, 70,141, 26, 85, 80, 80, 80, 48,196, 3, 43,209, 67,176,217,108,111,182,107,215, 78,163, 86, +171, 93,229,172, 73,131,227,132, 92, 46, 63,176,126,253,122,185,217,108,134,221,110,119,113,138, 68, 34, 80, 20,133,144,144, 16, +252,248,227,143, 33,114,185,188,202,156, 85, 38,147,105, 79, 66, 66,130, 14, 0, 18, 18, 18,116, 4, 65, 28, 39, 8, 98, 53, 65, + 16,171,202,109,171, 9,130, 56,238,126,172,201,100,218, 93, 21,183,197, 98, 57,158,148,148,196,138,197, 98, 80, 20, 5,171,213, + 10,161, 80,232, 50,137, 23, 22, 22,194,100, 42,157,230,190,116,233, 18,108, 54,219, 41, 79,206,189,168,168,232,200,134, 13, 27, +152,186,117,235, 34, 58, 58, 26,177,177,177,232,216,177, 35, 34, 35, 35, 49,127,254,124,218,104, 52,122,253,236,101,101,101, 29, +216,182,109,155, 45, 34, 34, 2,109,219,182,133, 64, 32, 64,171, 86,173, 16, 22, 22,134, 69,139, 22, 89,244,122,253,161, 26, 92, +166,180,235,215,175, 83, 85,136, 92, 25, 60, 88,189, 91, 14,233, 23, 46, 92,160, 58,118,236,184,183,252, 23,237,219,183,223, 43, +149, 74,253,157, 38,118,111, 70,228,238,226, 74, 32, 16,184, 54,231,231, 28, 14,199,147,209, 15,217, 92, 41, 93,255,217,196, 94, + 99,158,143, 14,196,222, 35,231,192,179,234, 0, 75, 21, 51,130,180, 13, 4, 79, 2,165, 63, 55,252, 9,232, 3,166, 2,184,134, +210, 56, 76,239,227,201,130,203,241,189,160,160, 0, 73, 73, 73,184,116,233, 18, 58,118,236,136, 83,167, 78, 1,127, 59,200,123, + 13,189, 94,255,254,188,121,243,140,206,149,124, 31,125,244,145,169,168,168,232,125,111,219, 96,150,101,193,229,114,209,180,105, + 83, 76,155, 54, 13, 7, 15, 30,196,237,219,183, 97,179,217, 92, 66,200,233,147,233,141, 69,139,199,227, 65,169, 84,194,102,179, +185,172, 89, 0,112, 39, 57, 25, 28, 14, 7, 12,195,192, 98,177, 84,107,209,242,247,247,159,187,110,221,186, 41,106,181, 90,149, +159,159,175,112,223,114,115,115, 21,217,217,217,138,204,204, 76, 69,122,122,186,226,193,131, 7,138,148,148, 20,213,146, 37, 75, +166,248,251,251,207,245,164,156, 20, 69,161, 85,171, 86,120,235,173,183, 92,219,138, 21, 43, 92,219,177, 99,199,188,118, 94,167, + 40, 10, 77,231, 44, 67,255,124,214,181, 29, 12, 33, 92,219,141,247, 38, 84,197,249,216,181, 72,141,244,139, 99,181,161,123, 98, +233, 10,224, 92,117,232,108,203, 92,110, 27,229,157,225, 31, 27,236,150,146,163,247,239, 38,247,106, 26,243, 12,153,163, 54,148, + 89,254, 25,219,115, 8, 8,130, 64,157, 6,209,160, 56, 28, 80, 20, 9, 14, 69, 33, 64, 38, 68,210,213,171,140,217,100, 58, 90, + 17,103, 15,128,195, 23,241, 87,188,218,183,149, 48,139,159,135, 16,149, 4, 60,110,169,118,100,239, 15, 41,215, 67,112,128, 24, + 63,140,205, 12, 18, 29,205, 45, 89, 17,104,180,238, 61, 94,201, 8,144, 97, 24, 72, 5, 2,148,152,205, 48,217,237,232,249,229, +151,174,233, 66,146, 32,112, 5, 64,203, 47,191,196,153,157, 59, 33,227,243, 1,129,192,227, 85, 33, 21, 9, 45,181, 90,141,209, +163, 71, 23,100,103,103,191, 86, 19, 31, 45, 39,204,102,243,137,156,156,156,215,134, 12, 25,178,121,215,174, 93,242, 33, 67,134, +104,114,114,114, 94,243,208,239,233, 33,148,148,148,236, 76, 79, 79, 47, 30, 61,122,244,166, 45, 91,182, 4, 5, 7, 7,187, 70, + 34, 53,186, 89, 9, 66,221,187,119,111,129, 39,199, 85,115,200, 60,135,115,251, 68,135,101,171,229,132, 9, 19,206,160,212,255, +202, 29,115,214,172, 89, 51,204,109,138,113, 53,128, 47,171, 34, 46, 44, 44, 92, 53,109,218,180,215, 79,156, 56, 17, 44, 20, 10, + 65, 16, 4,120, 60, 30, 26, 55,110,236, 90, 69,195,229,114,193,178, 44,222,125,247, 93,117, 94, 94,222, 87, 30, 94,155, 9,243, +230,205,235, 94, 82, 82, 18, 56,122,244,104, 74, 40, 20, 34, 55, 55, 23,203,151, 47,167,191,255,254,123,157,209,104, 28, 83, 3, + 33,188,225,147, 79, 62,233,105, 48, 24, 26,140, 31, 63,158,167,215,235, 97, 50,153, 48, 99,198, 12,203,119,223,125,151, 97, 50, +153,188, 14,248,219,169, 83,167,187, 15, 30, 60,232, 90, 92, 92,172, 21,139,197,229,173,125,132, 68, 34,121, 6,192, 38,111, 56, + 99, 99, 99,239,165,165,165,117, 92,176, 96,193,113,155,205,198, 61,127,254,188,203, 25,254,155,111,190, 57, 38, 20, 10,123,195, +203,228,171, 4, 65, 48, 2,129,160,140, 5,171,252,123, 14,135, 83,109,155,214, 44, 84,188,224,179, 55,186,143,121,174,185, 63, +246, 28,185,136,121,187,239,223,138, 26, 19,210,180, 81, 96, 62,152,252, 36,188,247,106, 59, 44,219,114, 17, 64,233,212, 33,147, +119, 3,172,246, 30, 88,191, 8,164,104,212, 89, 79, 64, 31,112, 12,165, 33, 51,158, 52,148, 17, 89, 55,110,220, 64,175, 94,189, + 0, 0,167, 78,157, 66,151, 46, 93,112,234,212, 41,116,237,218,213,235, 88, 90, 14,252, 81, 88, 88,248,224,216,177, 99, 45, 34, + 34, 34,240,231,159,127,166, 0,248,195,219, 66, 58,133, 22,135,195,193,136, 17, 35,208,167, 79, 31,212,173, 91,183,204,106, 67, +231,123,111,196,134,221,110, 71, 76, 76, 12,204, 22, 11,120, 60,158,107,106,146,195,225, 32, 68,161,192,221,187,119, 61,178,104, +145, 36, 57,244,229,151, 95, 38, 19, 19, 19, 49,124,248,112,108,222,188,185,210, 99, 71,141, 26,133,173, 91,183,226,229,151, 95, + 38, 63,248,224,131, 42,195, 59, 56,157,208, 61, 57, 39,103, 63, 93, 93,187, 95, 91,156,143, 91,139, 60, 10,220, 66, 59, 84, 56, +105, 82,193,103, 9,101,132,150, 91,144,176,199, 35,180,236,214,205, 63,255,240,237,180,142, 43,187,134,168, 20,254,208,232, 77, + 46,177,117,249,216, 14, 0,192,160, 9, 11,193,161, 74,167, 20,101, 82, 33, 68, 60, 10, 59, 55,126,165,182, 90, 75, 42,188,187, +138,184,228,196, 15, 58, 55,246,231, 75,108, 40, 12,101, 17, 29,242,119,166, 28,162,193,142,135, 5, 87,155, 64, 4,223,208,226, +213, 70, 82,217, 87,137,186,137,176, 49, 43, 30,234, 16,117, 58,147,238,234, 85, 81,191,117,235,112,254,181,215, 80,135,166,113, + 60, 44, 12,114, 46, 23,254, 2, 1, 72,130,128,105,255,126,156,217,181, 11, 74,129, 0,240,243,131,125,254,124,152,147,146, 96, + 43, 42, 50,213, 96,100,134, 97,195,134,169,213,106,245, 16,139,197,114,226, 81,235,217,100, 50,253,146,158,158, 62,177, 83,167, + 78, 43,109, 54,219,155, 38,147,233,145, 86, 70, 89, 44,150, 95,114,114,114, 6, 15, 27, 54,108,199,238,221,187,131, 3, 2, 2, +106,204, 85, 80, 80,208,174,150,110, 39, 6,192,108,135,115,251,255,183,119,245, 65, 81, 93, 87,252,247,222,219, 15, 88, 62,205, +194,146,240, 17, 37,208, 20,218,105,163, 65, 76,211,194, 8,109,136, 38,109,167,116,172, 17, 71,193,182,160, 41, 67,167,181,244, +143,142,211,152, 80,181,227,180, 83, 2, 54, 99, 70,173, 24, 99, 90,199,113,162, 77,169, 14, 96,204, 4,153,132,182,124,164, 90, + 80, 19,151, 12, 24, 2, 11,187, 32,187,203,178,236, 46,239,237,235, 31,187, 15,215,101, 23,246,193,125,176,144, 61, 51,111,100, + 21,127,156,123,207,185,188,223, 61,231,222,115,126,182,103,207,158, 85,109,109,109, 63,173,171,171,123,221, 99, 55,145, 80, 90, + 90,186,219,139,100,205,121,235, 16,192,221,225,225,225,131,149,149,149,191,175,174,174,142, 18, 14,190, 95,191,126, 29, 44,203, + 66, 46,151,131,227, 56,148,150,150,142,143,140,140,252, 9,254, 43, 58,207,112, 45,147,201,244,248,161, 67,135,234,106,107,107, + 11, 24,134,137,228, 56,206, 50, 49, 49,209, 60, 57, 57,249, 99,204,175,142,150, 83,175,215,239,218,191,127,255,174,154,154,154, + 31,210, 52,157,192,178,172,193,108, 54,215, 91,173,214, 83,152, 71, 42,169,181,181, 85,191, 99,199,142, 79,245,122,253, 87, 82, + 82, 82,140, 81, 81, 81,118,187,221,206,168, 84,170,152,200,200,200, 44, 0,173, 20, 69,221, 20,131,217,217,217,169, 43, 43, 43, +235,181,217,108,153,199,142, 29,107,137,137,137,185, 74, 81, 20,165, 80, 40, 30, 82,169, 84,223, 6,208, 76, 81,212, 29, 49,152, + 52, 77, 59, 61,163, 87,222,231,179,148, 74,101, 64,103,180,210, 52, 17, 63, 41,120, 92,134,119,222,107,199,129,119,238,158,230, +120,254,194,133,206,123,255,252, 77, 14,224, 56,191, 3,107,183,158,113,165, 11, 1, 56,135,187,224, 56, 95, 12, 42, 34, 30, 45, +159,203, 97,180, 58, 46, 33, 36,190,100,186,188,131,193, 96, 64,119,119,183, 64,178,178, 0, 32, 55, 55,183, 83, 32, 91, 29, 29, + 29, 88,191,126,125, 39, 0,185, 88,127, 53,153, 76,149, 59,119,238,108,112,111,142, 43,231,177,241,155, 38, 90, 2,161, 90,189, +122,245,244,103,207,199,227,140, 86, 64,194,113, 28, 20, 10, 5,100, 50, 25, 18,147,146,166,127, 22,207,243,208,106,181, 24, 29, + 29, 13,136,104, 49, 12,195, 80, 20,133,162,162,192, 46, 36,111,223,190, 29,205,205,205, 96, 2,100,133, 12,195, 32, 53, 53,117, +206,239, 17,120,105,160,152, 41, 41, 41,243,198,148,154,139,204,151, 96,249,250,218, 23,169,242,183, 32, 22, 75, 6,198,199,141, + 47,189,121,242,181,234,210,242, 95, 71,117,245, 12,193, 56,110, 3,195,208,158,191, 60, 33,147, 49,136,137, 12,199,163,143,196, +226,111,127,121,213,108, 54,141,237,135,159,190,135,171,163, 21, 47, 62,179,225, 75, 97,138, 68, 11, 50,159,216, 6, 38,252, 62, + 9,224,117,126,178,131, 57, 77,120,254,174, 37,252,239,119, 45, 47,126,116,207, 62,147,104,217,237,155,126,187,121,115,227,129, +203,151, 35,158, 58,125, 26, 61,165,165, 72,178, 90, 17,230, 78, 37,210, 20,133, 40,133, 2, 81, 10,133,139,100,213,212,192,202, +178,168, 45, 41,153,176,217,237,155,197, 44,242,145,145, 17, 20, 22, 22,234, 7, 6, 6,190,139,121,164,246,252,137,197, 98,121, + 27,192,219,164,240,108, 54,219,181,254,254,254,231, 11, 11, 11, 47, 55, 52, 52,104,130,164,200,156, 64,182, 28,109,109,109,187, + 91, 90, 90,122,240, 96, 99,209,177,150,150,150,158,178,178, 50,170,174,174,238, 20,128,151, 17, 96, 1, 79,139,197,242,218,149, + 43, 87,176,113,227,198,151, 15, 31, 62, 28,151,157,157,141,132,132, 4,152,205,102,116,116,116, 96,239,222,189,163, 38,147,233, +240,216,216, 88,181, 72,157, 29, 54,155,173,216,243, 42, 53,137,121,176,217,108,111, 12, 14, 14,190, 65, 10,176,162,162,226,186, + 86,171, 29,209,104, 52,223, 80, 40, 20, 79,192,117, 14, 72, 7,224,148, 88, 66, 36, 72,121,121,249,127,181, 90,173, 33, 57, 57, +249,105, 55,230, 42,184,218, 24,157,156, 7,230, 64,123,123,123,202,134, 13, 27,104,185, 92,206, 51, 12, 3,185, 92,206,203,100, + 50,222,125,174,134, 7,128,250,250,250, 48, 0,179,182,205,233, 25,182, 30, 42,126,245,131,125, 55,117,147, 23,110, 13, 77,252, + 10, 0,127,190, 43,162,105,173,134,217,180, 41,163, 31,182, 19,185,160, 98, 92,133, 42,249,241, 65, 80,145, 15,163,223,153,140, +170,127,220,214,177,160,254, 24,226, 84,190,247,213,112,151,119, 24, 28, 28,244, 36, 89, 66,212, 42, 43, 55, 55,183,211, 77,178, +132,127,155,207,249,178,119,157, 78,231,130,222, 97, 60,207,227,192,129, 3, 56,126,252, 56,230,170,104,238,190,221, 71,205,133, + 39, 68,180, 56,142,131,195,225, 64, 87, 87,215,116,205, 46, 33, 93, 40,148,118, 96, 89,118,214,219,234, 28,199,113,118,187, 29, +231,206,157, 11,136,108,157, 61,123, 22,147,147,147,224,230, 96,112,158,165, 24,214,173, 91,135,209,209,209,233,203, 62, 89, 89, +247, 75,229, 57, 28, 14, 81,196, 85,192,204,204,204,132,193, 96,128,112, 94,248,209,146,251,193, 30,214, 98, 89,169,126,239, 55, +162,181,232,111,204,176,136,152,134,236,111, 21,228,148,236,222, 27, 57,110,227,208,219,219, 7,253,240, 32,104,138, 70, 98,114, + 10,214,172, 73,133, 74, 73,227,173, 19,213,150,206, 15,175,126, 48,110,190,247,156, 63,172,239,197, 42, 62,172,249, 81,206,211, +233,233,209, 20,216, 41,128,155, 2,216, 41,192,233,254, 83,248, 59,231,131, 62,215,221, 61,198,239,251,104,244, 95,151,140, 14, +159, 61,171,182, 2, 57,171,212,234,198,170,250,250, 8,167,195,129,145,202, 74, 68,176, 44,194,221,187, 18,215, 64,194,192, 30, + 60,232, 34, 89,197,197, 19,198,177, 49, 81, 45,120,226,227,227,219, 41,138,138,215,235,245,203,170, 50,188, 70,163,185,196,243, +188,193, 96, 48,100, 7,145, 94, 9, 0,198, 0, 56,124,108, 36, 52, 16,127,254, 71,144, 84,141, 70,179,143,166,233,111,242, 60, + 31, 71,211,244, 61,167,211,217, 58, 60, 60,252, 7, 0,218,208,251,116,201, 68,168, 12,255,216, 28,223, 55, 12,224,151,112, 29, + 10,238, 13, 20,124,109,108,108,172, 77, 57,117,241, 7, 95, 11,203,127, 33, 43, 22,105,143, 68, 67,174, 8,199,128,137,197,187, + 55, 77, 56,249,190,238, 51,235, 20,247,253, 79,244, 19,255, 11,153, 98, 86, 33,222,130,135,164,168,213,234,127, 55, 54, 54,102, +167,165,165,209,158, 7,222,133, 90,121, 66,122, 75, 38,115,113,185,107,215,174,177, 69, 69, 69,173, 67, 67, 67, 27,253, 97, 70, + 71, 71, 55,221,184,113,227, 89,163,209, 56,131, 80,121, 86,138, 23, 62, 91, 44, 22,148,151,151, 95,241,215,130, 39, 54, 54,182, +166,186,186,250, 23, 91,182,108,161,133,114, 20,158,143,208, 46, 72,120, 28, 14, 7,206,156, 57,227, 60,114,228,200,159,141, 70, +163,223,212, 97, 98, 98,226,103, 3, 3, 3, 41, 66,169,133, 64,138,138,166,166,166, 14,246,245,245, 37, 45, 38,230, 50, 38, 92, + 15, 68,183,150, 36, 52, 33, 87,169, 42,162,163, 30,122,101,203,206,159,199,165,166,127,153,122, 56, 49, 25, 20,104, 12,233, 62, + 71,223,167,159,240, 23,255,122,116,196, 98, 26,253,157,213,106, 57, 58, 27,206, 87,129,244,199, 98, 20,231,149, 28, 50, 32, 16, + 32,175,254, 84, 51,118, 28, 0, 28,114,250,118,175,121,106,219,205, 89,210, 62, 2,217,122,233,226,197, 8,101, 70,198,140, 66, +113, 78,167, 19,182, 91,183, 80, 91, 82, 34,154,100,133, 36, 36, 33, 33, 34,105,152,187, 70,214, 20, 92,245,185,196, 70, 76,168, +204,132,200,109, 60,240, 2, 13,231,215,105,138, 82,178, 60, 62, 6,143,166, 8,217,196,235,157,131,176,134,166, 63, 32, 9,218, +166,210, 0, 34,213,106,245, 85,134, 97,214, 8, 17, 25,207,104,189,143,134,210,189, 67, 67, 67,207, 0,152,237,134,112,122,116, +116,244, 81,142,227,158, 10,164,169, 52,195, 48,255, 49,155,205, 21,152,165,169,180, 20,183, 14,227,226,226,180,125,125,125,233, +194, 45,106,207,119,165,175,155,229,119,238,220, 65, 94, 94, 94,159, 78,167, 75, 93, 76,204, 96, 21, 63,183, 14,131, 39,162,229, + 33, 73,138,176,168, 93, 74, 85,248,119,156, 83,108, 38, 40, 64, 38,151,223,182, 79, 90,223,179, 89,199,223,132,159,116,225, 98, +202, 86, 32, 39, 76,169,108, 82,196,196,168,124,145,182, 41,179,217,106,179,219, 55,133, 72, 86, 72, 66, 18,146,144,132,100, 25, + 73,134, 90,173,110,148,203,229, 97,158,100,210,251,107, 65, 88,150,157,212,235,245,207, 1,248,120,145, 49,191,152, 34,242,144, + 90, 65,160,152,238, 39, 47,216, 49, 37, 28, 59, 79, 16, 51,207,141, 89,181, 76,244,204, 11, 86, 76, 97,188, 34,112, 11,196,248, + 17,169,249,244,208,147, 39,173,167, 84,152,164,214,145, 15, 61,121, 9,236, 94,181, 76,244,204, 11, 54, 76,111,255, 9, 16, 87, + 20,102,128, 62, 37, 86, 79,158,180,158, 82, 97, 46,116, 29,205,162, 39,191, 80, 95,242, 99,251, 42, 44, 67,233,126, 18,124,247, +147,224,187,214,251,172,219,184,199,223,255, 19,117,144, 80,170,155, 0, 66,217,125, 55, 62, 21,172,152,158,243, 64,178, 85,128, + 4,109, 7,222, 39,141,233, 53,159,164,164,202,125,195,164, 25, 1, 20, 28, 21, 51,118, 18,118,247, 26, 43, 17,220,121,144, 44, + 81,152,164,252, 94,106, 76, 82,107,201, 27,147,132,223,251,178,187,132, 54, 34,165, 39,145,181, 36,133,207,251,240,159, 5,227, +122, 99,146, 88, 75,222,152, 36,252,126, 49, 48, 73,172, 37, 95,152, 36,252,222,159,237,151,107,160, 73, 72, 23,186, 75, 60, 80, + 1,144,173, 19, 0, 64,207,103,210, 36,140,148,229,147,198, 36,173,179, 20,100, 83, 68, 4,102,201, 49, 9,219,168,202,141, 73, +114,119,147, 79,202, 70, 82,248,187, 39, 38, 41,124,111, 28, 18,118,242,133,185, 80,125,253,232, 73,124,236, 11,245,251,197,194, + 36,108, 35, 34,107,201, 11, 51,159,240,102, 32,223,227,115, 21, 73, 76, 82,107,201,135,158, 11,182,147, 47,204,133,234,235, 71, + 79,226, 99, 39,241, 14,145, 10,119, 41, 35, 90, 60,237,215, 39, 78,120, 61,139, 66, 52,150, 44, 37, 39, 18,123, 69, 97,138, 76, +207, 20, 72, 96,251, 37,213,147, 36,166,183,142, 36,211, 61, 82,234, 73, 18, 83,132,174, 43, 14,115,185,217, 61, 24,231,211, 31, +222, 66,210, 82,254,162,163, 82,232, 73, 18, 51, 64,236, 21,129,185, 0,219,175, 56,145, 5,139, 34,194,196, 19,222,153,128,112, + 4, 70,178,113, 19,214, 51, 95,138, 8,161, 4, 66, 92, 79,247, 78,249, 21, 9,198,190, 89, 87, 78,217, 0, 0, 0, 46, 73, 68, + 65, 84, 92,230, 52,180,150, 66,107, 41,232,214,146,151, 79,230, 19,140, 20, 17,141, 60,123, 99,146,248, 25,158, 24,164,124, 84, +234,177,147, 92, 75, 82,216,126,185,201,255, 1, 22, 74, 86,152, 88,239,214,181, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, 0}; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 64da61f8f55..081d604819d 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -693,6 +693,7 @@ void draw_gpencil_2dimage (bContext *C, ImBuf *ibuf) /* calculate rect */ switch (sa->spacetype) { case SPACE_IMAGE: /* image */ + case SPACE_CLIP: /* clip */ { /* just draw using standard scaling (settings here are currently ignored anyways) */ @@ -766,7 +767,7 @@ void draw_gpencil_view2d (bContext *C, short onlyv2d) /* special hack for Image Editor */ // FIXME: the opengl poly-strokes don't draw at right thickness when done this way, so disabled - if (sa->spacetype == SPACE_IMAGE) + if (ELEM(sa->spacetype, SPACE_IMAGE, SPACE_CLIP)) dflag |= GP_DRAWDATA_IEDITHACK; /* draw it! */ diff --git a/source/blender/editors/gpencil/editaction_gpencil.c b/source/blender/editors/gpencil/editaction_gpencil.c index 56210864593..81a5f6777e7 100644 --- a/source/blender/editors/gpencil/editaction_gpencil.c +++ b/source/blender/editors/gpencil/editaction_gpencil.c @@ -422,6 +422,7 @@ void paste_gpdata (Scene *scene) case SPACE_NODE: /* Nodes Editor: either screen-aligned or view-aligned */ case SPACE_IMAGE: /* Image Editor: either screen-aligned or view\image-aligned */ + case SPACE_CLIP: /* Image Editor: either screen-aligned or view\image-aligned */ if ((gps->flag == 0) || (gps->flag & GP_STROKE_2DSPACE)) stroke_ok= 1; break; diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 7b79384fbb4..65db5e27ed7 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -69,6 +69,7 @@ #include "ED_gpencil.h" #include "ED_view3d.h" +#include "ED_clip.h" #include "gpencil_intern.h" @@ -137,6 +138,19 @@ bGPdata **gpencil_data_get_pointers (bContext *C, PointerRNA *ptr) } break; + case SPACE_CLIP: /* Nodes Editor */ + { + SpaceClip *sc= (SpaceClip *)CTX_wm_space_data(C); + MovieClip *clip= ED_space_clip(sc); + + if(clip) { + /* for now, as long as there's a clip, default to using that in Clip Editor */ + if (ptr) RNA_id_pointer_create(&clip->id, ptr); + return &clip->gpd; + } + } + break; + default: /* unsupported space */ return NULL; } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 12f03f7341c..b89b0cda451 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -103,6 +103,11 @@ typedef struct tGPsdata { short radius; /* radius of influence for eraser */ short flags; /* flags that can get set during runtime */ + + float imat[4][4]; /* inverted transformation matrix applying when converting coords from screen-space + to region space */ + + float custom_color[3]; /* custom color for */ } tGPsdata; /* values for tGPsdata->status */ @@ -277,6 +282,7 @@ static void gp_stroke_convertcoords (tGPsdata *p, const int mval[2], float out[3 /* 2d - on 'canvas' (assume that p->v2d is set) */ else if ((gpd->sbuffer_sflag & GP_STROKE_2DSPACE) && (p->v2d)) { UI_view2d_region_to_view(p->v2d, mval[0], mval[1], &out[0], &out[1]); + mul_v3_m4v3(out, p->imat, out); } #if 0 @@ -997,6 +1003,8 @@ static int gp_session_initdata (bContext *C, tGPsdata *p) /* pass on current scene and window */ p->scene= CTX_data_scene(C); p->win= CTX_wm_window(C); + + unit_m4(p->imat); switch (curarea->spacetype) { /* supported views first */ @@ -1097,6 +1105,33 @@ static int gp_session_initdata (bContext *C, tGPsdata *p) #endif } break; + case SPACE_CLIP: + { + SpaceClip *sc= curarea->spacedata.first; + + /* set the current area */ + p->sa= curarea; + p->ar= ar; + p->v2d= &ar->v2d; + //p->ibuf= BKE_image_get_ibuf(sima->image, &sima->iuser); + + invert_m4_m4(p->imat, sc->unistabmat); + + /* custom color for new layer */ + p->custom_color[0]= 1.0f; + p->custom_color[1]= 0.0f; + p->custom_color[2]= 0.5f; + p->custom_color[3]= 0.9f; + + /* check that gpencil data is allowed to be drawn */ + if ((sc->flag & SC_SHOW_GPENCIL)==0) { + p->status= GP_STATUS_ERROR; + if (G.f & G_DEBUG) + printf("Error: In active view, Grease Pencil not shown \n"); + return 0; + } + } + break; /* unsupported views */ default: @@ -1182,8 +1217,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) { /* get active layer (or add a new one if non-existent) */ p->gpl= gpencil_layer_getactive(p->gpd); - if (p->gpl == NULL) + if (p->gpl == NULL) { p->gpl= gpencil_layer_addnew(p->gpd); + + if(p->custom_color[3]) + copy_v3_v3(p->gpl->color, p->custom_color); + } if (p->gpl->flag & GP_LAYER_LOCKED) { p->status= GP_STATUS_ERROR; if (G.f & G_DEBUG) @@ -1299,6 +1338,12 @@ static void gp_paint_initstroke (tGPsdata *p, short paintmode) p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; } break; + + case SPACE_CLIP: + { + p->gpd->sbuffer_sflag |= GP_STROKE_2DSPACE; + } + break; } } } @@ -1336,9 +1381,12 @@ static void gp_paint_strokeend (tGPsdata *p) /* finish off stroke painting operation */ static void gp_paint_cleanup (tGPsdata *p) { - /* finish off a stroke */ - if(p->gpd) + /* p->gpd==NULL happens when stroke failed to initialize, + for example. when GP is hidden in current space (sergey) */ + if (p->gpd) { + /* finish off a stroke */ gp_paint_strokeend(p); + } /* "unlock" frame */ if (p->gpf) diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h new file mode 100644 index 00000000000..7d36159f47e --- /dev/null +++ b/source/blender/editors/include/ED_clip.h @@ -0,0 +1,64 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file ED_clip.h + * \ingroup editors + */ + +#ifndef ED_MOVIECLIP_H +#define ED_MOVIECLIP_H + +struct ARegion; +struct bContext; +struct ImBuf; +struct Main; +struct MovieClip; +struct SpaceClip; +struct wmEvent; + +/* clip_editor.c */ +int ED_space_clip_poll(struct bContext *C); + +void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip); +struct MovieClip *ED_space_clip(struct SpaceClip *sc); +void ED_space_clip_size(struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_zoom(struct SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy); +void ED_space_clip_aspect(struct SpaceClip *sc, float *aspx, float *aspy); + +struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc); +struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle); + +void ED_clip_update_frame(const struct Main *mainp, int cfra); +int ED_clip_view_selection(struct SpaceClip *sc, struct ARegion *ar, int fit); + +void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]); +void ED_clip_point_stable_pos(struct bContext *C, float x, float y, float *xr, float *yr); +void ED_clip_mouse_pos(struct bContext *C, struct wmEvent *event, float co[2]); + +/* clip_ops.c */ +void ED_operatormacros_clip(void); + +#endif /* ED_TEXT_H */ diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h index 8e445ab1cee..b5a1ca193db 100644 --- a/source/blender/editors/include/ED_space_api.h +++ b/source/blender/editors/include/ED_space_api.h @@ -54,6 +54,7 @@ void ED_spacetype_sequencer(void); void ED_spacetype_logic(void); void ED_spacetype_console(void); void ED_spacetype_userpref(void); +void ED_spacetype_clip(void); /* calls for instancing and freeing spacetype static data called in WM_init_exit */ diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 3a6cbc556d1..37f647abfd9 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -94,6 +94,7 @@ enum { #define CTX_AUTOCONFIRM 32 #define CTX_BMESH 64 #define CTX_NDOF 128 +#define CTX_MOVIECLIP 256 /* Standalone call to get the transformation center corresponding to the current situation * returns 1 if successful, 0 otherwise (usually means there's no selection) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index e43ad964c9c..82a1e6f1f00 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -290,4 +290,6 @@ void ED_view3d_camera_lock_init(struct View3D *v3d, struct RegionView3D *rv3d); /* copy the view to the camera, return TRUE if */ int ED_view3d_camera_lock_sync(struct View3D *v3d, struct RegionView3D *rv3d); +struct BGpic *ED_view3D_background_image_add(struct View3D *v3d); + #endif /* ED_VIEW3D_H */ diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 8cb37ab337d..c7afe2fb28f 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -173,6 +173,7 @@ DEF_ICON(NODETREE) DEF_ICON(LOGIC) DEF_ICON(CONSOLE) DEF_ICON(PREFERENCES) +DEF_ICON(CLIP) DEF_ICON(ASSET_MANAGER) #ifndef DEF_ICON_BLANK_SKIP DEF_ICON(BLANK057) @@ -180,7 +181,6 @@ DEF_ICON(ASSET_MANAGER) DEF_ICON(BLANK059) DEF_ICON(BLANK060) DEF_ICON(BLANK061) - DEF_ICON(BLANK061b) #endif /* MODES */ @@ -642,6 +642,8 @@ DEF_ICON(DRIVER) /* ANIMATION */ DEF_ICON(SOLO_OFF) DEF_ICON(SOLO_ON) +DEF_ICON(FRAME_PREV) +DEF_ICON(FRAME_NEXT) #ifndef DEF_ICON_BLANK_SKIP /* available */ DEF_ICON(BLANK186) @@ -666,8 +668,6 @@ DEF_ICON(SOLO_ON) DEF_ICON(BLANK205) DEF_ICON(BLANK206) DEF_ICON(BLANK207) - DEF_ICON(BLANK208) - DEF_ICON(BLANK208b) #endif /* EDITING */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7a556eddd2b..942252bc00f 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -222,18 +222,19 @@ typedef struct uiLayout uiLayout; #define TOGBUT (37<<9) #define OPTION (38<<9) #define OPTIONN (39<<9) +#define TRACKPREVIEW (40<<9) /* buttons with value >= SEARCH_MENU don't get undo pushes */ -#define SEARCH_MENU (40<<9) -#define BUT_EXTRA (41<<9) -#define HSVCIRCLE (42<<9) -#define LISTBOX (43<<9) -#define LISTROW (44<<9) -#define HOTKEYEVT (45<<9) -#define BUT_IMAGE (46<<9) -#define HISTOGRAM (47<<9) -#define WAVEFORM (48<<9) -#define VECTORSCOPE (49<<9) -#define PROGRESSBAR (50<<9) +#define SEARCH_MENU (41<<9) +#define BUT_EXTRA (42<<9) +#define HSVCIRCLE (43<<9) +#define LISTBOX (44<<9) +#define LISTROW (45<<9) +#define HOTKEYEVT (46<<9) +#define BUT_IMAGE (47<<9) +#define HISTOGRAM (48<<9) +#define WAVEFORM (49<<9) +#define VECTORSCOPE (50<<9) +#define PROGRESSBAR (51<<9) #define BUTTYPE (63<<9) @@ -749,6 +750,10 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr); void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type); +void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact); +void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname); +void uiTemplateMarker(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int cmpact); + /* items */ void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname); void uiItemEnumO(uiLayout *layout, const char *opname, const char *name, int icon, const char *propname, int value); diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 9c46a5d28de..4b1371c532c 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -247,7 +247,18 @@ enum { TH_DRAWEXTRA_FACEAREA, TH_DRAWEXTRA_FACEANG, - TH_NODE_CURVING + TH_NODE_CURVING, + + TH_MARKER_OUTLINE, + TH_MARKER, + TH_ACT_MARKER, + TH_SEL_MARKER, + TH_BUNDLE_SOLID, + TH_DIS_MARKER, + TH_PATH_BEFORE, + TH_PATH_AFTER, + TH_CAMERA_PATH, + TH_LOCK_MARKER }; /* XXX WARNING: previous is saved in file, so do not change order! */ diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 3d08e761090..4bc0963aad4 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -34,6 +34,7 @@ #include "DNA_color_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "DNA_movieclip_types.h" #include "BLI_math.h" #include "BLI_rect.h" @@ -1501,6 +1502,114 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax); } +static ImBuf *scale_trackpreview_ibuf(ImBuf *ibuf, float zoomx, float zoomy) +{ + ImBuf *scaleibuf; + int x, y, w= ibuf->x*zoomx, h= ibuf->y*zoomy; + scaleibuf= IMB_allocImBuf(w, h, 32, IB_rect); + + for(y= 0; yy; y++) { + for (x= 0; xx; x++) { + int pixel= scaleibuf->x*y + x; + int orig_pixel= ibuf->x*(int)(((float)y)/zoomy) + (int)(((float)x)/zoomx); + char *rrgb= (char*)scaleibuf->rect + pixel*4; + char *orig_rrgb= (char*)ibuf->rect + orig_pixel*4; + rrgb[0]= orig_rrgb[0]; + rrgb[1]= orig_rrgb[1]; + rrgb[2]= orig_rrgb[2]; + rrgb[3]= orig_rrgb[3]; + } + } + + return scaleibuf; +} + +void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti) +{ + rctf rect; + int ok= 0; + GLint scissor[4]; + MovieClipScopes *scopes = (MovieClipScopes *)but->poin; + + rect.xmin = (float)recti->xmin+1; + rect.xmax = (float)recti->xmax-1; + rect.ymin = (float)recti->ymin+SCOPE_RESIZE_PAD+2; + rect.ymax = (float)recti->ymax-1; + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + /* need scissor test, preview image can draw outside of boundary */ + glGetIntegerv(GL_VIEWPORT, scissor); + glScissor(ar->winrct.xmin + (rect.xmin-1), ar->winrct.ymin+(rect.ymin-1), (rect.xmax+1)-(rect.xmin-1), (rect.ymax+1)-(rect.ymin-1)); + + if(scopes->track_disabled) { + glColor4f(0.7f, 0.3f, 0.3f, 0.3f); + uiSetRoundBox(15); + uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); + + ok= 1; + } + else if(scopes->track_preview) { + int a, off_x, off_y; + float zoomx, zoomy; + ImBuf *drawibuf; + + glPushMatrix(); + + /* draw content of pattern area */ + glScissor(ar->winrct.xmin+rect.xmin, ar->winrct.ymin+rect.ymin, scissor[2], scissor[3]); + + zoomx= (rect.xmax-rect.xmin) / (scopes->track_preview->x-2.f); + zoomy= (rect.ymax-rect.ymin) / (scopes->track_preview->y-2.f); + + off_x= ((int)scopes->track_pos[0]-scopes->track_pos[0]-0.5)*zoomx; + off_y= ((int)scopes->track_pos[1]-scopes->track_pos[1]-0.5)*zoomy; + + drawibuf= scale_trackpreview_ibuf(scopes->track_preview, zoomx, zoomy); + glaDrawPixelsSafe(off_x+rect.xmin, off_y+rect.ymin, rect.xmax-rect.xmin+1.f-off_x, rect.ymax-rect.ymin+1.f-off_y, drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect); + + IMB_freeImBuf(drawibuf); + + /* draw cross for pizel position */ + glTranslatef(off_x+rect.xmin+scopes->track_pos[0]*zoomx, off_y+rect.ymin+scopes->track_pos[1]*zoomy, 0.f); + glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin+rect.ymin, rect.xmax-rect.xmin, rect.ymax-rect.ymin); + + for(a= 0; a< 2; a++) { + if(a==1) { + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + UI_ThemeColor(TH_SEL_MARKER); + } + else { + UI_ThemeColor(TH_MARKER_OUTLINE); + } + + glBegin(GL_LINES); + glVertex2f(-10.0f, 0.0f); + glVertex2f(10.0f, 0.0f); + glVertex2f(0.0f, -10.0f); + glVertex2f(0.0f, 10.0f); + glEnd(); + } + + glDisable(GL_LINE_STIPPLE); + glPopMatrix(); + + ok= 1; + } + + if(!ok) { + glColor4f(0.f, 0.f, 0.f, 0.3f); + uiSetRoundBox(15); + uiDrawBox(GL_POLYGON, rect.xmin-1, rect.ymin-1, rect.xmax+1, rect.ymax+1, 3.0f); + } + + /* outline, scale gripper */ + draw_scope_end(&rect, scissor); + + glDisable(GL_BLEND); +} /* ****************************************************** */ diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index c34c10bf1a7..c871c87983c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -56,6 +56,7 @@ #include "BKE_idprop.h" #include "BKE_report.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "BKE_unit.h" #include "ED_screen.h" @@ -259,7 +260,7 @@ static uiBut *ui_but_last(uiBlock *block) static int ui_is_a_warp_but(uiBut *but) { if(U.uiflag & USER_CONTINUOUS_MOUSE) - if(ELEM3(but->type, NUM, NUMABS, HSVCIRCLE)) + if(ELEM4(but->type, NUM, NUMABS, HSVCIRCLE, TRACKPREVIEW)) return TRUE; return FALSE; @@ -922,6 +923,13 @@ static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *d data->applied= 1; } +static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data) +{ + ui_apply_but_func(C, but); + data->retval= but->retval; + data->applied= 1; +} + static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive) { @@ -1051,6 +1059,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut case WAVEFORM: ui_apply_but_WAVEFORM(C, but, data); break; + case TRACKPREVIEW: + ui_apply_but_TRACKPREVIEW(C, but, data); + break; default: break; } @@ -4254,6 +4265,88 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, wmE return WM_UI_HANDLER_CONTINUE; } +static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, int mx, int my, int shift) +{ + MovieClipScopes *scopes = (MovieClipScopes *)but->poin; + int changed= 1; + float dx, dy; + + dx = mx - data->draglastx; + dy = my - data->draglasty; + + if(shift) { + dx /= 5.0f; + dy /= 5.0f; + } + + if (in_scope_resize_zone(but, data->dragstartx, data->dragstarty)) { + /* resize preview widget itself */ + scopes->track_preview_height = (but->y2 - but->y1) + (data->dragstarty - my); + } else { + if(scopes->marker) { + if(scopes->marker->framenr!=scopes->framenr) + scopes->marker= BKE_tracking_ensure_marker(scopes->track, scopes->framenr); + + scopes->marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED); + scopes->marker->pos[0]+= -dx*scopes->slide_scale[0] / (but->block->maxx-but->block->minx); + scopes->marker->pos[1]+= -dy*scopes->slide_scale[1] / (but->block->maxy-but->block->miny); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL); + } + + scopes->ok= 0; + } + + data->draglastx= mx; + data->draglasty= my; + + return changed; +} + +static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + int mx, my; + + mx= event->x; + my= event->y; + ui_window_to_block(data->region, block, &mx, &my); + + if(data->state == BUTTON_STATE_HIGHLIGHT) { + if(event->type==LEFTMOUSE && event->val==KM_PRESS) { + data->dragstartx= mx; + data->dragstarty= my; + data->draglastx= mx; + data->draglasty= my; + button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); + + /* also do drag the first time */ + if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift)) + ui_numedit_apply(C, block, but, data); + + return WM_UI_HANDLER_BREAK; + } + } + else if(data->state == BUTTON_STATE_NUM_EDITING) { + if(event->type == ESCKEY) { + data->cancel= 1; + data->escapecancel= 1; + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + else if(event->type == MOUSEMOVE) { + if(mx!=data->draglastx || my!=data->draglasty) { + if(ui_numedit_but_TRACKPREVIEW(C, but, data, mx, my, event->shift)) + ui_numedit_apply(C, block, but, data); + } + } + else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) { + button_activate_state(C, but, BUTTON_STATE_EXIT); + } + return WM_UI_HANDLER_BREAK; + } + + return WM_UI_HANDLER_CONTINUE; +} + static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) { uiBut *but = (uiBut *)arg1; @@ -4791,6 +4884,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case INLINK: retval= ui_do_but_LINK(C, but, data, event); break; + case TRACKPREVIEW: + retval= ui_do_but_TRACKPREVIEW(C, block, but, data, event); + break; } return retval; diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 9c5fafaf167..29447d492c5 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -454,6 +454,7 @@ void ui_draw_but_COLORBAND(uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_NORMAL(uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_CURVE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); void ui_draw_but_IMAGE(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); +void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, struct uiWidgetColors *wcol, rcti *rect); /* interface_handlers.c */ extern void ui_button_activate_do(struct bContext *C, struct ARegion *ar, uiBut *but); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 19d22a432dc..7c745c3cfef 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2455,6 +2455,7 @@ void uiTemplateOperatorSearch(uiLayout *layout) #define B_STOPANIM 3 #define B_STOPCOMPO 4 #define B_STOPSEQ 5 +#define B_STOPCLIP 6 static void do_running_jobs(bContext *C, void *UNUSED(arg), int event) { @@ -2474,6 +2475,9 @@ static void do_running_jobs(bContext *C, void *UNUSED(arg), int event) case B_STOPSEQ: WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL); break; + case B_STOPCLIP: + WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL); + break; } } @@ -2499,6 +2503,10 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C) if(WM_jobs_test(wm, sa)) owner = sa; handle_event = B_STOPSEQ; + } else if(sa->spacetype==SPACE_CLIP) { + if(WM_jobs_test(wm, sa)) + owner = sa; + handle_event= B_STOPCLIP; } else { Scene *scene; /* another scene can be rendering too, for example via compositor */ diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 878d1bc36a4..8ab48ac8ffa 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -3078,6 +3078,10 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct wt= widget_type(UI_WTYPE_SCROLL); break; + case TRACKPREVIEW: + ui_draw_but_TRACKPREVIEW(ar, but, &tui->wcol_regular, rect); + break; + default: wt= widget_type(UI_WTYPE_REGULAR); } diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 921a1879bb7..5f392daeec6 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -153,6 +153,9 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case SPACE_LOGIC: ts= &btheme->tlogic; break; + case SPACE_CLIP: + ts= &btheme->tclip; + break; default: ts= &btheme->tv3d; break; @@ -409,6 +412,27 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo case TH_PREVIEW_BACK: cp= ts->preview_back; break; + + case TH_MARKER_OUTLINE: + cp= ts->marker_outline; break; + case TH_MARKER: + cp= ts->marker; break; + case TH_ACT_MARKER: + cp= ts->act_marker; break; + case TH_SEL_MARKER: + cp= ts->sel_marker; break; + case TH_BUNDLE_SOLID: + cp= ts->bundle_solid; break; + case TH_DIS_MARKER: + cp= ts->dis_marker; break; + case TH_PATH_BEFORE: + cp= ts->path_before; break; + case TH_PATH_AFTER: + cp= ts->path_after; break; + case TH_CAMERA_PATH: + cp= ts->camera_path; break; + case TH_LOCK_MARKER: + cp= ts->lock_marker; break; } } } @@ -533,6 +557,7 @@ static void ui_theme_init_new(bTheme *btheme) ui_theme_init_new_do(&btheme->tlogic); ui_theme_init_new_do(&btheme->tuserpref); ui_theme_init_new_do(&btheme->tconsole); + ui_theme_init_new_do(&btheme->tclip); } @@ -639,7 +664,9 @@ void ui_theme_init_default(void) SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255); SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80); // alpha 80 is not meant editable, used for wire+action draw - + + SETCOL(btheme->tv3d.bundle_solid, 200, 200, 200, 255); + SETCOL(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255); /* space buttons */ /* to have something initialized */ @@ -777,6 +804,23 @@ void ui_theme_init_default(void) /* space logic */ btheme->tlogic= btheme->tv3d; SETCOL(btheme->tlogic.back, 100, 100, 100, 255); + + /* space clip */ + btheme->tclip= btheme->tv3d; + + SETCOL(btheme->tclip.marker_outline, 0x00, 0x00, 0x00, 255); + SETCOL(btheme->tclip.marker, 0x7f, 0x7f, 0x00, 255); + SETCOL(btheme->tclip.act_marker, 0xff, 0xff, 0xff, 255); + SETCOL(btheme->tclip.sel_marker, 0xff, 0xff, 0x00, 255); + SETCOL(btheme->tclip.dis_marker, 0x7f, 0x00, 0x00, 255); + SETCOL(btheme->tclip.lock_marker, 0x7f, 0x7f, 0x7f, 255); + SETCOL(btheme->tclip.path_before, 0xff, 0x00, 0x00, 255); + SETCOL(btheme->tclip.path_after, 0x00, 0x00, 0xff, 255); + SETCOL(btheme->tclip.grid, 0x5e, 0x5e, 0x5e, 255); + SETCOL(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255); + SETCOL(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff); + SETCOL(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff); + btheme->tclip.handle_vertex_size= 4; } @@ -1590,6 +1634,35 @@ void init_userdef_do_versions(void) } } + { + bTheme *btheme; + for(btheme= U.themes.first; btheme; btheme= btheme->next) { + if(btheme->tv3d.bundle_solid[3] == 0) + SETCOL(btheme->tv3d.bundle_solid, 200, 200, 200, 255); + + if(btheme->tv3d.camera_path[3] == 0) + SETCOL(btheme->tv3d.camera_path, 0x00, 0x00, 0x00, 255); + + if((btheme->tclip.back[3]) == 0) { + btheme->tclip= btheme->tv3d; + + SETCOL(btheme->tclip.marker_outline, 0x00, 0x00, 0x00, 255); + SETCOL(btheme->tclip.marker, 0x7f, 0x7f, 0x00, 255); + SETCOL(btheme->tclip.act_marker, 0xff, 0xff, 0xff, 255); + SETCOL(btheme->tclip.sel_marker, 0xff, 0xff, 0x00, 255); + SETCOL(btheme->tclip.dis_marker, 0x7f, 0x00, 0x00, 255); + SETCOL(btheme->tclip.lock_marker, 0x7f, 0x7f, 0x7f, 255); + SETCOL(btheme->tclip.path_before, 0xff, 0x00, 0x00, 255); + SETCOL(btheme->tclip.path_after, 0x00, 0x00, 0xff, 255); + SETCOL(btheme->tclip.grid, 0x5e, 0x5e, 0x5e, 255); + SETCOL(btheme->tclip.cframe, 0x60, 0xc0, 0x40, 255); + SETCOL(btheme->tclip.handle_vertex, 0x00, 0x00, 0x00, 0xff); + SETCOL(btheme->tclip.handle_vertex_select, 0xff, 0xff, 0, 0xff); + btheme->tclip.handle_vertex_size= 4; + } + } + } + /* GL Texture Garbage Collection (variable abused above!) */ if (U.textimeout == 0) { U.texcollectrate = 60; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 50b798c5bea..b36416151a9 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -55,6 +55,7 @@ #include "BKE_main.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_tracking.h" #include "BIK_api.h" #ifdef WITH_PYTHON @@ -402,6 +403,23 @@ static void test_constraints (Object *owner, bPoseChannel *pchan) data->flag &= ~CONSTRAINT_SPLINEIK_BOUND; } } + else if (curcon->type == CONSTRAINT_TYPE_FOLLOWTRACK) { + bFollowTrackConstraint *data = curcon->data; + + if((data->flag&CAMERASOLVER_ACTIVECLIP)==0) { + if(data->clip != NULL && data->track[0]) { + if (!BKE_tracking_named_track(&data->clip->tracking, data->track)) + curcon->flag |= CONSTRAINT_DISABLE; + } + else curcon->flag |= CONSTRAINT_DISABLE; + } + } + else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) { + bCameraSolverConstraint *data = curcon->data; + + if((data->flag&CAMERASOLVER_ACTIVECLIP)==0 && data->clip == NULL) + curcon->flag |= CONSTRAINT_DISABLE; + } /* Check targets for constraints */ if (cti && cti->get_constraint_targets) { @@ -1368,7 +1386,9 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase BPY_pyconstraint_update(ob, con); } #endif + break; } + default: break; } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 9d6d663df5c..e6ae8698b14 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1366,6 +1366,7 @@ static const char *editortype_pup(void) "|UV/Image Editor %x6" "|Video Sequence Editor %x8" + "|Movie Clip Editor %x20" "|Text Editor %x9" "|Node Editor %x16" "|Logic Editor %x17" diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 72fb0a019b6..a76be0c3c42 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -58,6 +58,7 @@ #include "ED_screen.h" #include "ED_screen_types.h" #include "ED_fileselect.h" +#include "ED_clip.h" #include "UI_interface.h" @@ -1809,6 +1810,8 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, bScreen *screen, int UNUS * call before scene_update_for_newframe so modifiers with textuers dont lag 1 frame */ ED_image_update_frame(bmain, scene->r.cfra); + ED_clip_update_frame(bmain, scene->r.cfra); + /* this function applies the changes too */ /* XXX future: do all windows */ scene_update_for_newframe(bmain, scene, BKE_screen_visible_layers(screen, scene)); /* BKE_scene.h */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index e86dd8dbde3..007a8f7e4d7 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2783,10 +2783,23 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) if(redraws & TIME_ALL_IMAGE_WIN) return 1; break; + case SPACE_CLIP: + if(redraws & TIME_CLIPS) + return 1; + break; } } else if(regiontype==RGN_TYPE_UI) { + if(spacetype==SPACE_CLIP) { + /* Track Preview button is on Properties Editor in SpaceClip, + and it's very common case when users want it be refreshing + during playback, so asking people to enable special option + for this is a bit ticky, so add exception here for refreshing + Properties Editor for SpaceClip always */ + return 1; + } + if(redraws & TIME_ALL_BUTS_WIN) return 1; } @@ -2800,6 +2813,8 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws) if(redraws & (TIME_SEQ|TIME_ALL_ANIM_WIN)) return 1; break; + case SPACE_CLIP: + return 1; } } return 0; diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 905f7bc80b6..fbf8af514b6 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -61,6 +61,7 @@ #include "ED_uvedit.h" #include "ED_mball.h" #include "ED_logic.h" +#include "ED_clip.h" /* only call once on startup, storage is global in BKE kernel listbase */ void ED_spacetypes_init(void) @@ -89,6 +90,7 @@ void ED_spacetypes_init(void) ED_spacetype_logic(); ED_spacetype_console(); ED_spacetype_userpref(); + ED_spacetype_clip(); // ... /* register operator types for screen and all spaces */ @@ -129,6 +131,7 @@ void ED_spacetypes_init(void) ED_operatormacros_file(); ED_operatormacros_graph(); ED_operatormacros_action(); + ED_operatormacros_clip(); /* register dropboxes (can use macros) */ spacetypes = BKE_spacetypes_list(); diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt new file mode 100644 index 00000000000..4f9819e8e77 --- /dev/null +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -0,0 +1,56 @@ +# ***** 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. +# +# The Original Code is Copyright (C) 2011 Blender Foundation. +# +# Contributor(s): Blender Foundation, +# Sergey Sharybin +# +# ***** END GPL LICENSE BLOCK ***** + +set(INC + ../include + ../../blenkernel + ../../blenloader + ../../blenfont + ../../blenlib + ../../imbuf + ../../makesdna + ../../makesrna + ../../windowmanager + ../../../../intern/guardedalloc + ${GLEW_INCLUDE_PATH} +) + +set(INC_SYS +) + +set(SRC + space_clip.c + clip_draw.c + clip_toolbar.c + clip_ops.c + clip_graph_ops.c + clip_graph_draw.c + clip_editor.c + clip_buttons.c + clip_utils.c + tracking_ops.c + + clip_intern.h +) + +blender_add_lib(bf_editor_space_clip "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript new file mode 100644 index 00000000000..70331b0ec4a --- /dev/null +++ b/source/blender/editors/space_clip/SConscript @@ -0,0 +1,9 @@ +#!/usr/bin/python +Import ('env') + +sources = env.Glob('*.c') +defs = [] +incs = '../include ../../blenkernel ../../blenloader ../../blenfont ../../blenlib ../../imbuf ../../makesdna' +incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew/include' + +env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] ) diff --git a/source/blender/editors/space_clip/clip_buttons.c b/source/blender/editors/space_clip/clip_buttons.c new file mode 100644 index 00000000000..149aa9106b0 --- /dev/null +++ b/source/blender/editors/space_clip/clip_buttons.c @@ -0,0 +1,436 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_buttons.c + * \ingroup spclip + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" +#include "DNA_space_types.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" +#include "BLI_listbase.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_screen.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "ED_clip.h" +#include "ED_gpencil.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "clip_intern.h" // own include + +/* Panels */ + +void ED_clip_buttons_register(ARegionType *art) +{ + PanelType *pt; + + pt= MEM_callocN(sizeof(PanelType), "spacetype clip panel gpencil"); + strcpy(pt->idname, "CLIP_PT_gpencil"); + strcpy(pt->label, "Grease Pencil"); + pt->draw= gpencil_panel_standard; + pt->flag|= PNL_DEFAULT_CLOSED; + BLI_addtail(&art->paneltypes, pt); +} + +/********************* MovieClip Template ************************/ + +void uiTemplateMovieClip(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, int compact) +{ + PropertyRNA *prop; + PointerRNA clipptr; + MovieClip *clip; + uiLayout *row, *split; + uiBlock *block; + + if(!ptr->data) + return; + + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { + printf("uiTemplateMovieClip: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + if(RNA_property_type(prop) != PROP_POINTER) { + printf("uiTemplateMovieClip: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + clipptr= RNA_property_pointer_get(ptr, prop); + clip= clipptr.data; + + uiLayoutSetContextPointer(layout, "edit_movieclip", &clipptr); + + if(!compact) + uiTemplateID(layout, C, ptr, propname, NULL, "CLIP_OT_open", NULL); + + if(clip) { + row= uiLayoutRow(layout, 0); + block= uiLayoutGetBlock(row); + uiDefBut(block, LABEL, 0, "File Path:", 0, 19, 145, 19, NULL, 0, 0, 0, 0, ""); + + row= uiLayoutRow(layout, 0); + split = uiLayoutSplit(row, 0.0, 0); + row= uiLayoutRow(split, 1); + + uiItemR(row, &clipptr, "filepath", 0, "", ICON_NONE); + uiItemO(row, "", ICON_FILE_REFRESH, "clip.reload"); + } +} + +/********************* Track Template ************************/ + +void uiTemplateTrack(uiLayout *layout, PointerRNA *ptr, const char *propname) +{ + PropertyRNA *prop; + PointerRNA scopesptr; + uiBlock *block; + rctf rect; + MovieClipScopes *scopes; + + if(!ptr->data) + return; + + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { + printf("uiTemplateTrack: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + if(RNA_property_type(prop) != PROP_POINTER) { + printf("uiTemplateTrack: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + scopesptr= RNA_property_pointer_get(ptr, prop); + scopes= (MovieClipScopes *)scopesptr.data; + + rect.xmin= 0; rect.xmax= 200; + rect.ymin= 0; rect.ymax= 120; + + block= uiLayoutAbsoluteBlock(layout); + + scopes->track_preview_height= (scopes->track_preview_height<=UI_UNIT_Y)?UI_UNIT_Y:scopes->track_preview_height; + + uiDefBut(block, TRACKPREVIEW, 0, "", rect.xmin, rect.ymin, rect.xmax-rect.xmin, scopes->track_preview_height, scopes, 0, 0, 0, 0, ""); +} + +/********************* Marker Template ************************/ + +#define B_MARKER_POS 3 +#define B_MARKER_OFFSET 4 +#define B_MARKER_PAT_DIM 5 +#define B_MARKER_SEARCH_POS 6 +#define B_MARKER_SEARCH_DIM 7 +#define B_MARKER_FLAG 8 + +typedef struct { + int compact; /* compact mode */ + + MovieClip *clip; + MovieClipUser *user; /* user of clip */ + MovieTrackingTrack *track; + + int framenr; /* current frame number */ + float marker_pos[2]; /* position of marker in pixel coords */ + float track_pat[2]; /* position and dimensions of marker pattern in pixel coords */ + float track_offset[2]; /* offset of "parenting" point */ + float track_search_pos[2], track_search[2]; /* position and dimensions of marker search in pixel coords */ + int marker_flag; /* marker's flags */ +} MarkerUpdateCb; + +static void to_pixel_space(float r[2], float a[2], int width, int height) +{ + copy_v2_v2(r, a); + r[0]*= width; + r[1]*= height; +} + +static void marker_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg)) +{ + MarkerUpdateCb *cb= (MarkerUpdateCb*) arg_cb; + MovieTrackingMarker *marker; + + if(!cb->compact) + return; + + marker= BKE_tracking_ensure_marker(cb->track, cb->framenr); + + marker->flag= cb->marker_flag; + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL); +} + +static void marker_block_handler(bContext *C, void *arg_cb, int event) +{ + MarkerUpdateCb *cb= (MarkerUpdateCb*) arg_cb; + MovieTrackingMarker *marker; + int width, height, ok= 0; + + BKE_movieclip_get_size(cb->clip, cb->user, &width, &height); + + marker= BKE_tracking_ensure_marker(cb->track, cb->framenr); + + if(event==B_MARKER_POS) { + marker->pos[0]= cb->marker_pos[0]/width; + marker->pos[1]= cb->marker_pos[1]/height; + + /* to update position of "parented" objects */ + DAG_id_tag_update(&cb->clip->id, 0); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL); + + ok= 1; + } + else if(event==B_MARKER_PAT_DIM) { + float dim[2], pat_dim[2]; + + sub_v2_v2v2(pat_dim, cb->track->pat_max, cb->track->pat_min); + + dim[0]= cb->track_pat[0]/width; + dim[1]= cb->track_pat[1]/height; + + sub_v2_v2(dim, pat_dim); + mul_v2_fl(dim, 0.5f); + + cb->track->pat_min[0]-= dim[0]; + cb->track->pat_min[1]-= dim[1]; + + cb->track->pat_max[0]+= dim[0]; + cb->track->pat_max[1]+= dim[1]; + + BKE_tracking_clamp_track(cb->track, CLAMP_PAT_DIM); + + ok= 1; + } + else if(event==B_MARKER_SEARCH_POS) { + float delta[2], side[2]; + + sub_v2_v2v2(side, cb->track->search_max, cb->track->search_min); + mul_v2_fl(side, 0.5f); + + delta[0]= cb->track_search_pos[0]/width; + delta[1]= cb->track_search_pos[1]/height; + + sub_v2_v2v2(cb->track->search_min, delta, side); + add_v2_v2v2(cb->track->search_max, delta, side); + + BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_POS); + + ok= 1; + } + else if(event==B_MARKER_SEARCH_DIM) { + float dim[2], search_dim[2]; + + sub_v2_v2v2(search_dim, cb->track->search_max, cb->track->search_min); + + dim[0]= cb->track_search[0]/width; + dim[1]= cb->track_search[1]/height; + + sub_v2_v2(dim, search_dim); + mul_v2_fl(dim, 0.5f); + + cb->track->search_min[0]-= dim[0]; + cb->track->search_min[1]-= dim[1]; + + cb->track->search_max[0]+= dim[0]; + cb->track->search_max[1]+= dim[1]; + + BKE_tracking_clamp_track(cb->track, CLAMP_SEARCH_DIM); + + ok= 1; + } else if(event==B_MARKER_FLAG) { + marker->flag= cb->marker_flag; + + ok= 1; + } else if(event==B_MARKER_OFFSET) { + float offset[2], delta[2]; + int i; + + offset[0]= cb->track_offset[0]/width; + offset[1]= cb->track_offset[1]/height; + + sub_v2_v2v2(delta, offset, cb->track->offset); + copy_v2_v2(cb->track->offset, offset); + + for(i=0; itrack->markersnr; i++) + sub_v2_v2(cb->track->markers[i].pos, delta); + + /* to update position of "parented" objects */ + DAG_id_tag_update(&cb->clip->id, 0); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL); + + ok= 1; + } + + if(ok) + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, cb->clip); +} + +void uiTemplateMarker(uiLayout *layout, PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact) +{ + PropertyRNA *prop; + uiBlock *block; + uiBut *bt; + PointerRNA clipptr; + MovieClip *clip; + MovieClipUser *user; + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + MarkerUpdateCb *cb; + + if(!ptr->data) + return; + + prop= RNA_struct_find_property(ptr, propname); + if(!prop) { + printf("uiTemplateMarker: property not found: %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + if(RNA_property_type(prop) != PROP_POINTER) { + printf("uiTemplateMarker: expected pointer property for %s.%s\n", RNA_struct_identifier(ptr->type), propname); + return; + } + + clipptr= RNA_property_pointer_get(ptr, prop); + clip= (MovieClip *)clipptr.data; + user= userptr->data; + track= trackptr->data; + + marker= BKE_tracking_get_marker(track, user->framenr); + + cb= MEM_callocN(sizeof(MarkerUpdateCb), "uiTemplateMarker update_cb"); + cb->compact= compact; + cb->clip= clip; + cb->user= user; + cb->track= track; + cb->marker_flag= marker->flag; + cb->framenr= user->framenr; + + if(compact) { + block= uiLayoutGetBlock(layout); + + bt= uiDefIconButBitI(block, TOGN, MARKER_DISABLED, 0, ICON_RESTRICT_VIEW_OFF, 0, 0, 20, 20, &cb->marker_flag, 0, 0, 1, 0, "Marker is disabled for current frame."); + uiButSetNFunc(bt, marker_update_cb, cb, NULL); + } else { + int width, height, step, digits; + float pat_dim[2], pat_pos[2], search_dim[2], search_pos[2]; + uiLayout *col; + + BKE_movieclip_get_size(clip, user, &width, &height); + + if(track->flag&TRACK_LOCKED) { + uiLayoutSetActive(layout, 0); + block= uiLayoutAbsoluteBlock(layout); + uiDefBut(block, LABEL, 0, "Track is locked", 0, 0, 300, 19, NULL, 0, 0, 0, 0, ""); + + return; + } + + step= 100; + digits= 2; + + sub_v2_v2v2(pat_dim, track->pat_max, track->pat_min); + sub_v2_v2v2(search_dim, track->search_max, track->search_min); + + add_v2_v2v2(search_pos, track->search_max, track->search_min); + mul_v2_fl(search_pos, 0.5); + + add_v2_v2v2(pat_pos, track->pat_max, track->pat_min); + mul_v2_fl(pat_pos, 0.5); + + to_pixel_space(cb->marker_pos, marker->pos, width, height); + to_pixel_space(cb->track_pat, pat_dim, width, height); + to_pixel_space(cb->track_search, search_dim, width, height); + to_pixel_space(cb->track_search_pos, search_pos, width, height); + to_pixel_space(cb->track_offset, track->offset, width, height); + + cb->marker_flag= marker->flag; + + block= uiLayoutAbsoluteBlock(layout); + uiBlockSetHandleFunc(block, marker_block_handler, cb); + uiBlockSetNFunc(block, marker_update_cb, cb, NULL); + + uiDefButBitI(block, OPTIONN, MARKER_DISABLED, B_MARKER_FLAG, "Enabled", 10, 190, 145, 19, &cb->marker_flag, + 0, 0, 0, 0, "Marker is disabled for current frame."); + + col= uiLayoutColumn(layout, 1); + uiLayoutSetActive(col, (cb->marker_flag&MARKER_DISABLED)==0); + + block= uiLayoutAbsoluteBlock(col); + uiBlockBeginAlign(block); + + uiDefBut(block, LABEL, 0, "Position:", 0, 190, 300, 19, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_MARKER_POS, "X:", 10, 171, 145, 19, &cb->marker_pos[0], + -10*width, 10.0*width, step, digits, "X-position of marker at frame in screen coordinates."); + uiDefButF(block, NUM, B_MARKER_POS, "Y:", 165, 171, 145, 19, &cb->marker_pos[1], + -10*height, 10.0*height, step, digits, "Y-position of marker at frame in screen coordinates."); + + uiDefBut(block, LABEL, 0, "Offset:", 0, 152, 300, 19, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_MARKER_OFFSET, "X:", 10, 133, 145, 19, &cb->track_offset[0], + -10*width, 10.0*width, step, digits, "X-offset to parenting point."); + uiDefButF(block, NUM, B_MARKER_OFFSET, "Y:", 165, 133, 145, 19, &cb->track_offset[1], + -10*height, 10.0*height, step, digits, "Y-offset to parenting point."); + + uiDefBut(block, LABEL, 0, "Pattern Area:", 0, 114, 300, 19, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Width:", 10, 95, 300, 19, &cb->track_pat[0], 3.0f, + 10.0*width, step, digits, "Width of marker's pattern in screen soordinates."); + uiDefButF(block, NUM, B_MARKER_PAT_DIM, "Height:", 10, 76, 300, 19, &cb->track_pat[1], 3.0f, + 10.0*height, step, digits, "Height of marker's pattern in screen soordinates."); + + uiDefBut(block, LABEL, 0, "Search Area:", 0, 57, 300, 19, NULL, 0, 0, 0, 0, ""); + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "X:", 10, 38, 145, 19, &cb->track_search_pos[0], + -width, width, step, digits, "X-position of search at frame relative to marker's position"); + uiDefButF(block, NUM, B_MARKER_SEARCH_POS, "Y:", 165, 38, 145, 19, &cb->track_search_pos[1], + -height, height, step, digits, "X-position of search at frame relative to marker's position"); + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Width:", 10, 19, 300, 19, &cb->track_search[0], 3.0f, + 10.0*width, step, digits, "Width of marker's search in screen soordinates."); + uiDefButF(block, NUM, B_MARKER_SEARCH_DIM, "Height:", 10, 0, 300, 19, &cb->track_search[1], 3.0f, + 10.0*height, step, digits, "Height of marker's search in screen soordinates."); + + uiBlockEndAlign(block); + } +} diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c new file mode 100644 index 00000000000..0da68953593 --- /dev/null +++ b/source/blender/editors/space_clip/clip_draw.c @@ -0,0 +1,1325 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_draw.c + * \ingroup spclip + */ + +#include "DNA_gpencil_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "MEM_guardedalloc.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_string.h" +#include "BLI_rect.h" +#include "BLI_math_base.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_gpencil.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" + +#include "BLF_api.h" + +#include "clip_intern.h" // own include + +/*********************** main area drawing *************************/ + +void clip_draw_curfra_label(SpaceClip *sc, float x, float y) +{ + uiStyle *style= UI_GetStyle(); + int fontid= style->widget.uifont_id; + char str[32]; + float fontsize, fontwidth; + + /* frame number */ + BLF_size(fontid, 11.0f, U.dpi); + BLI_snprintf(str, sizeof(str), "%d", sc->user.framenr); + fontsize= BLF_height(fontid, str); + fontwidth= BLF_width(fontid, str); + + glRecti(x, y, x+fontwidth+6, y+fontsize+4); + + UI_ThemeColor(TH_TEXT); + BLF_position(fontid, x+2.0f, y+2.0f, 0.0f); + BLF_draw(fontid, str, strlen(str)); +} + +static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene) +{ + float x; + int *points, totseg, i, a; + float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1); + + glEnable(GL_BLEND); + + /* cache background */ + glColor4ub(128, 128, 255, 64); + glRecti(0, 0, ar->winx, 8); + + /* cached segments -- could be usefu lto debug caching strategies */ + BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points); + if(totseg) { + glColor4ub(128, 128, 255, 128); + + for(a= 0; awinx; + x2= (points[a*2+1]-sfra+1)/(efra-sfra+1)*ar->winx; + + glRecti(x1, 0, x2, 8); + } + } + + /* track */ + if(clip->tracking.act_track) { + MovieTrackingTrack *track= clip->tracking.act_track; + + for(i= sfra, a= 0; i <= efra; i++) { + int framenr; + MovieTrackingMarker *marker; + + while(amarkersnr) { + if(track->markers[a].framenr>=i) + break; + + if(amarkersnr-1 && track->markers[a+1].framenr>i) + break; + + a++; + } + + if(amarkersnr) marker= &track->markers[a]; + else marker= &track->markers[track->markersnr-1]; + + if((marker->flag&MARKER_DISABLED)==0) { + framenr= marker->framenr; + + if(framenr!=i) glColor4ub(128, 128, 0, 96); + else if((marker->flag&MARKER_TRACKED)==0) glColor4ub(255, 255, 0, 196); + else glColor4ub(255, 255, 0, 96); + + glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 4); + } + } + } + + /* failed frames */ + if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) { + int n= clip->tracking.reconstruction.camnr; + MovieReconstructedCamera *cameras= clip->tracking.reconstruction.cameras; + + glColor4ub(255, 0, 0, 96); + + for(i= sfra, a= 0; i <= efra; i++) { + int ok= 0; + + while(ai) { + break; + } + + a++; + } + + if(!ok) + glRecti((i-sfra)*framelen, 0, (i-sfra+1)*framelen, 8); + } + } + + glDisable(GL_BLEND); + + /* current frame */ + x= (sc->user.framenr-sfra)/(efra-sfra+1)*ar->winx; + + UI_ThemeColor(TH_CFRAME); + glRecti(x, 0, x+framelen, 8); + + clip_draw_curfra_label(sc, x, 8.0f); +} + +static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) +{ + char str[256]= {0}; + + if(sc->flag&SC_LOCK_SELECTION) + strcpy(str, "Locked"); + + if(str[0]) { + uiStyle *style= UI_GetStyle(); + int fontsize, fontwidth; + int fontid= style->widget.uifont_id; + + BLF_size(fontid, 11.0f, U.dpi); + fontsize= BLF_height(fontid, str); + fontwidth= BLF_width(fontid, str); + + glEnable(GL_BLEND); + + glColor4f(0.0f, 0.0f, 0.0f, 0.6f); + glRecti(0, ar->winy-fontsize-9, fontwidth+12, ar->winy); + + glColor3f(1.0f, 1.0f, 1.0f); + BLF_position(fontid, 6.0f, ar->winy-fontsize-5.0f, 0.0f); + BLF_draw(fontid, str, strlen(str)); + + glDisable(GL_BLEND); + } +} + +static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf, + int width, int height, float zoomx, float zoomy) +{ + int x, y; + MovieClip *clip= ED_space_clip(sc); + + /* set zoom */ + glPixelZoom(zoomx*width/ibuf->x, zoomy*height/ibuf->y); + + /* find window pixel coordinates of origin */ + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y); + + if(sc->flag&SC_MUTE_FOOTAGE) { + glColor3f(0.0f, 0.0f, 0.0f); + glRectf(x, y, x+zoomx*width, y+zoomy*height); + } else { + if(ibuf->rect_float && !ibuf->rect) { + IMB_rect_from_float(ibuf); + } + + if(ibuf->rect) + glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + } + + /* draw boundary border for frame if stabilization is enabled */ + if(sc->flag&SC_SHOW_STABLE && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) { + glColor3f(0.0f, 0.0f, 0.0f); + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_NOR); + + glPushMatrix(); + glTranslatef(x, y, 0); + + glScalef(zoomx, zoomy, 0); + glMultMatrixf(sc->stabmat); + + glBegin(GL_LINE_LOOP); + glVertex2f(0.0f, 0.0f); + glVertex2f(ibuf->x, 0.0f); + glVertex2f(ibuf->x, ibuf->y); + glVertex2f(0.0f, ibuf->y); + glEnd(); + + glPopMatrix(); + + glDisable(GL_COLOR_LOGIC_OP); + glDisable(GL_LINE_STIPPLE); + } + + + /* reset zoom */ + glPixelZoom(1.0f, 1.0f); +} + +static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track) +{ + int count= sc->path_length; + int i, a, b, curindex= -1; + float path[102][2]; + int tiny= sc->flag&SC_SHOW_TINY_MARKER, framenr; + MovieTrackingMarker *marker; + + if(count==0) + return; + + marker= BKE_tracking_get_marker(track, sc->user.framenr); + if(marker->framenr!=sc->user.framenr || marker->flag&MARKER_DISABLED) + return; + + framenr= marker->framenr; + + a= count; + i= framenr-1; + while(i>=framenr-count) { + marker= BKE_tracking_get_marker(track, i); + + if(!marker || marker->flag&MARKER_DISABLED) + break; + + if(marker->framenr==i) { + add_v2_v2v2(path[--a], marker->pos, track->offset); + ED_clip_point_undistorted_pos(sc, path[a], path[a]); + + if(marker->framenr==sc->user.framenr) + curindex= a; + } else + break; + + i--; + } + + b= count; + i= framenr; + while(i<=framenr+count) { + marker= BKE_tracking_get_marker(track, i); + + if(!marker || marker->flag&MARKER_DISABLED) + break; + + if(marker->framenr==i) { + if(marker->framenr==sc->user.framenr) + curindex= b; + + add_v2_v2v2(path[b++], marker->pos, track->offset); + ED_clip_point_undistorted_pos(sc, path[b-1], path[b-1]); + } else + break; + + i++; + } + + if(!tiny) { + UI_ThemeColor(TH_MARKER_OUTLINE); + + if(TRACK_VIEW_SELECTED(sc, track)) { + glPointSize(5.0f); + glBegin(GL_POINTS); + for(i= a; iflag&SC_SHOW_TINY_MARKER; + int show_search= 0; + float px[2]; + + UI_ThemeColor(TH_MARKER_OUTLINE); + + px[0]= 1.0f/width/sc->zoom; + px[1]= 1.0f/height/sc->zoom; + + if((marker->flag&MARKER_DISABLED)==0) { + float pos[2]; + rctf r; + + BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); + add_v2_v2v2(pos, marker->pos, track->offset); + + ED_clip_point_undistorted_pos(sc, pos, pos); + + if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) { + if(tiny) glPointSize(3.0f); + else glPointSize(4.0f); + glBegin(GL_POINTS); + glVertex2f(pos[0], pos[1]); + glEnd(); + glPointSize(1.0f); + } else { + if(!tiny) glLineWidth(3.0f); + glBegin(GL_LINES); + glVertex2f(pos[0] + px[0]*2, pos[1]); + glVertex2f(pos[0] + px[0]*8, pos[1]); + + glVertex2f(pos[0] - px[0]*2, pos[1]); + glVertex2f(pos[0] - px[0]*8, pos[1]); + + glVertex2f(pos[0], pos[1] - px[1]*2); + glVertex2f(pos[0], pos[1] - px[1]*8); + + glVertex2f(pos[0], pos[1] + px[1]*2); + glVertex2f(pos[0], pos[1] + px[1]*8); + glEnd(); + if(!tiny) glLineWidth(1.0f); + } + } + + /* pattern and search outline */ + glPushMatrix(); + glTranslatef(marker_pos[0], marker_pos[1], 0); + + if(!tiny) glLineWidth(3.0f); + + if(sc->flag&SC_SHOW_MARKER_PATTERN) { + glBegin(GL_LINE_LOOP); + glVertex2f(track->pat_min[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_max[1]); + glVertex2f(track->pat_min[0], track->pat_max[1]); + glEnd(); + } + + show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0); + if(sc->flag&SC_SHOW_MARKER_SEARCH && show_search) { + glBegin(GL_LINE_LOOP); + glVertex2f(track->search_min[0], track->search_min[1]); + glVertex2f(track->search_max[0], track->search_min[1]); + glVertex2f(track->search_max[0], track->search_max[1]); + glVertex2f(track->search_min[0], track->search_max[1]); + glEnd(); + } + glPopMatrix(); + + if(!tiny) glLineWidth(1.0f); +} + +static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3]) +{ + if(track->flag&TRACK_CUSTOMCOLOR) { + if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol); + else copy_v3_v3(scol, track->color); + + mul_v3_v3fl(col, track->color, 0.5f); + } else { + UI_GetThemeColor3fv(TH_MARKER, col); + + if(act) UI_GetThemeColor3fv(TH_ACT_MARKER, scol); + else UI_GetThemeColor3fv(TH_SEL_MARKER, scol); + } +} + +static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int width, int height, int act, int sel) +{ + int tiny= sc->flag&SC_SHOW_TINY_MARKER; + int show_search= 0; + float col[3], scol[3], px[2]; + + track_colors(track, act, col, scol); + + px[0]= 1.0f/width/sc->zoom; + px[1]= 1.0f/height/sc->zoom; + + /* marker position and offset position */ + if((track->flag&SELECT)==sel && (marker->flag&MARKER_DISABLED)==0) { + float pos[2]; + rctf r; + + if(track->flag&TRACK_LOCKED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); + else UI_ThemeColor(TH_LOCK_MARKER); + } else { + if(track->flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + BLI_init_rctf(&r, track->pat_min[0], track->pat_max[0], track->pat_min[1], track->pat_max[1]); + add_v2_v2v2(pos, marker->pos, track->offset); + ED_clip_point_undistorted_pos(sc, pos, pos); + + if(BLI_in_rctf(&r, pos[0]-marker_pos[0], pos[1]-marker_pos[1])) { + if(!tiny) glPointSize(2.0f); + glBegin(GL_POINTS); + glVertex2f(pos[0], pos[1]); + glEnd(); + if(!tiny) glPointSize(1.0f); + } else { + glBegin(GL_LINES); + glVertex2f(pos[0] + px[0]*3, pos[1]); + glVertex2f(pos[0] + px[0]*7, pos[1]); + + glVertex2f(pos[0] - px[0]*3, pos[1]); + glVertex2f(pos[0] - px[0]*7, pos[1]); + + glVertex2f(pos[0], pos[1] - px[1]*3); + glVertex2f(pos[0], pos[1] - px[1]*7); + + glVertex2f(pos[0], pos[1] + px[1]*3); + glVertex2f(pos[0], pos[1] + px[1]*7); + glEnd(); + + glColor3f(0.0f, 0.0f, 0.0f); + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + glEnable(GL_COLOR_LOGIC_OP); + glLogicOp(GL_NOR); + + glBegin(GL_LINES); + glVertex2fv(pos); + glVertex2fv(marker_pos); + glEnd(); + + glDisable(GL_COLOR_LOGIC_OP); + glDisable(GL_LINE_STIPPLE); + } + } + + /* pattern */ + glPushMatrix(); + glTranslatef(marker_pos[0], marker_pos[1], 0); + + if(tiny) { + glLineStipple(3, 0xaaaa); + glEnable(GL_LINE_STIPPLE); + } + + if((track->pat_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_PATTERN)) { + if(track->flag&TRACK_LOCKED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); + else UI_ThemeColor(TH_LOCK_MARKER); + } + else if(marker->flag&MARKER_DISABLED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128); + else UI_ThemeColor(TH_DIS_MARKER); + } else { + if(track->pat_flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + glBegin(GL_LINE_LOOP); + glVertex2f(track->pat_min[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_max[1]); + glVertex2f(track->pat_min[0], track->pat_max[1]); + glEnd(); + } + + /* search */ + show_search= TRACK_VIEW_SELECTED(sc, track) && ((marker->flag&MARKER_DISABLED)==0 || (sc->flag&SC_SHOW_MARKER_PATTERN)==0); + if((track->search_flag&SELECT)==sel && (sc->flag&SC_SHOW_MARKER_SEARCH) && show_search) { + if(track->flag&TRACK_LOCKED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); + else UI_ThemeColor(TH_LOCK_MARKER); + } + else if(marker->flag&MARKER_DISABLED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->search_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128); + else UI_ThemeColor(TH_DIS_MARKER); + } else { + if(track->search_flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + glBegin(GL_LINE_LOOP); + glVertex2f(track->search_min[0], track->search_min[1]); + glVertex2f(track->search_max[0], track->search_min[1]); + glVertex2f(track->search_max[0], track->search_max[1]); + glVertex2f(track->search_min[0], track->search_max[1]); + glEnd(); + } + + /* pyramid */ + if((sel == TRACK_SELECTED(track) && sel && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (track->tracker==TRACKER_KLT))) { + if(track->flag&TRACK_LOCKED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); + else UI_ThemeColor(TH_LOCK_MARKER); + } + else if(marker->flag&MARKER_DISABLED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_DIS_MARKER, 128); + else UI_ThemeColor(TH_DIS_MARKER); + } else { + if(track->pat_flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + { + int i = 0; + glPushMatrix(); + glEnable(GL_LINE_STIPPLE); + for (i = 1; i < track->pyramid_levels; ++i) { + glScalef(2.0f, 2.0f, 1.0); + } + /* only draw a pattern for the coarsest level */ + glBegin(GL_LINE_LOOP); + glVertex2f(track->pat_min[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_min[1]); + glVertex2f(track->pat_max[0], track->pat_max[1]); + glVertex2f(track->pat_min[0], track->pat_max[1]); + glEnd(); + glDisable(GL_LINE_STIPPLE); + glPopMatrix(); + } + } + + if(tiny) + glDisable(GL_LINE_STIPPLE); + + glPopMatrix(); +} + +static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, + float marker_pos[2], int outline, int sel, int act, int width, int height) +{ + float x, y, dx, dy, patdx, patdy, searchdx, searchdy, tdx, tdy; + int tiny= sc->flag&SC_SHOW_TINY_MARKER; + float col[3], scol[3], px[2]; + + if((tiny && outline) || (marker->flag&MARKER_DISABLED)) + return; + + if(!TRACK_VIEW_SELECTED(sc, track) || track->flag&TRACK_LOCKED) + return; + + track_colors(track, act, col, scol); + + if(outline) { + glLineWidth(3.0f); + UI_ThemeColor(TH_MARKER_OUTLINE); + } + + glPushMatrix(); + glTranslatef(marker_pos[0], marker_pos[1], 0); + + dx= 6.0f/width/sc->zoom; + dy= 6.0f/height/sc->zoom; + + patdx= MIN2(dx*2.0f/3.0f, (track->pat_max[0]-track->pat_min[0])/6.0f); + patdy= MIN2(dy*2.0f/3.0f, (track->pat_max[1]-track->pat_min[1])/6.0f); + + searchdx= MIN2(dx, (track->search_max[0]-track->search_min[0])/6.0f); + searchdy= MIN2(dy, (track->search_max[1]-track->search_min[1])/6.0f); + + px[0]= 1.0f/sc->zoom/width/sc->scale; + px[1]= 1.0f/sc->zoom/height/sc->scale; + + if((sc->flag&SC_SHOW_MARKER_SEARCH) && ((track->search_flag&SELECT)==sel || outline)) { + if(!outline) { + if(track->search_flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + /* search offset square */ + x= track->search_min[0]; + y= track->search_max[1]; + + tdx= searchdx; + tdy= searchdy; + + if(outline) { + tdx+= px[0]; + tdy+= px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x-tdx, y+tdy, 0); + glVertex3f(x+tdx, y+tdy, 0); + glVertex3f(x+tdx, y-tdy, 0); + glVertex3f(x-tdx, y-tdy, 0); + glEnd(); + + /* search resizing triangle */ + x= track->search_max[0]; + y= track->search_min[1]; + + tdx= searchdx*2.0f; + tdy= searchdy*2.0f; + + if(outline) { + tdx+= px[0]; + tdy+= px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0); + glVertex3f(x-tdx, y, 0); + glVertex3f(x, y+tdy, 0); + glEnd(); + } + + if((sc->flag&SC_SHOW_MARKER_PATTERN) && ((track->pat_flag&SELECT)==sel || outline)) { + if(!outline) { + if(track->pat_flag&SELECT) glColor3fv(scol); + else glColor3fv(col); + } + + /* pattern offset square */ + x= track->pat_min[0]; + y= track->pat_max[1]; + + tdx= patdx; + tdy= patdy; + + if(outline) { + tdx+= px[0]; + tdy+= px[1]; + } + + glBegin(GL_QUADS); + glVertex3f(x-tdx, y+tdy, 0); + glVertex3f(x+tdx, y+tdy, 0); + glVertex3f(x+tdx, y-tdy, 0); + glVertex3f(x-tdx, y-tdy, 0); + glEnd(); + + /* pattern resizing triangle */ + x= track->pat_max[0]; + y= track->pat_min[1]; + + tdx= patdx*2.0f; + tdy= patdy*2.0f; + + if(outline) { + tdx+= px[0]; + tdy+= px[1]; + } + + glBegin(GL_TRIANGLES); + glVertex3f(x, y, 0); + glVertex3f(x-tdx, y, 0); + glVertex3f(x, y+tdy, 0); + glEnd(); + } + + glPopMatrix(); + + if(outline) + glLineWidth(1.0f); +} + +static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, float marker_pos[2], int act, + int width, int height, float zoomx, float zoomy) +{ + char str[128]= {0}, state[64]= {0}; + float dx= 0.0f, dy= 0.0f, fontsize, pos[3]; + uiStyle *style= U.uistyles.first; + int fontid= style->widget.uifont_id; + + if(!TRACK_VIEW_SELECTED(sc, track)) + return; + + BLF_size(fontid, 11.0f, U.dpi); + fontsize= BLF_height_max(fontid); + + if(marker->flag&MARKER_DISABLED) { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else UI_ThemeColorShade(TH_DIS_MARKER, 128); + } else { + if(act) UI_ThemeColor(TH_ACT_MARKER); + else UI_ThemeColor(TH_SEL_MARKER); + } + + if(sc->flag&SC_SHOW_MARKER_SEARCH) { + dx= track->search_min[0]; + dy= track->search_min[1]; + } else if(sc->flag&SC_SHOW_MARKER_PATTERN) { + dx= track->pat_min[0]; + dy= track->pat_min[1]; + } + + pos[0]= (marker_pos[0]+dx)*width; + pos[1]= (marker_pos[1]+dy)*height; + pos[2]= 0.0f; + + mul_m4_v3(sc->stabmat, pos); + + pos[0]= pos[0]*zoomx; + pos[1]= pos[1]*zoomy - fontsize; + + if(marker->flag&MARKER_DISABLED) strcpy(state, "disabled"); + else if(marker->framenr!=sc->user.framenr) strcpy(state, "estimated"); + else if(marker->flag&MARKER_TRACKED) strcpy(state, "tracked"); + else strcpy(state, "keyframed"); + + if(state[0]) + BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state); + else + BLI_snprintf(str, sizeof(str), "%s", track->name); + + BLF_position(fontid, pos[0], pos[1], 0.0f); + BLF_draw(fontid, str, strlen(str)); + pos[1]-= fontsize; + + if(track->flag&TRACK_HAS_BUNDLE) { + BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error); + BLF_position(fontid, pos[0], pos[1], 0.0f); + BLF_draw(fontid, str, strlen(str)); + pos[1]-= fontsize; + } + + if(track->flag&TRACK_LOCKED) { + BLF_position(fontid, pos[0], pos[1], 0.0f); + BLF_draw(fontid, "locked", 6); + } +} + +static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony) +{ + /* express given coordinates as proportional values */ + x= -v2d->cur.xmin / (v2d->cur.xmax-v2d->cur.xmin); + y= -v2d->cur.ymin / (v2d->cur.ymax-v2d->cur.ymin); + + /* convert proportional distances to screen coordinates */ + *regionx= v2d->mask.xmin + x*(v2d->mask.xmax-v2d->mask.xmin); + *regiony= v2d->mask.ymin + y*(v2d->mask.ymax-v2d->mask.ymin); +} + +static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip, + int width, int height, float zoomx, float zoomy) +{ + float x, y; + MovieTracking* tracking= &clip->tracking; + MovieTrackingMarker *marker; + MovieTrackingTrack *track, *act_track; + int framenr= sc->user.framenr; + int undistort= sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT; + float *marker_pos= NULL, *fp, *active_pos= NULL, cur_pos[2]; + + /* ** find window pixel coordinates of origin ** */ + + /* UI_view2d_to_region_no_clip return integer values, this could + lead to 1px flickering when view is locked to selection during playbeck. + to avoid this flickering, calclate base point in the same way as it happens + in UI_view2d_to_region_no_clip, but do it in floats here */ + + view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y); + + glPushMatrix(); + glTranslatef(x, y, 0); + + glPushMatrix(); + glScalef(zoomx, zoomy, 0); + glMultMatrixf(sc->stabmat); + glScalef(width, height, 0); + + act_track= clip->tracking.act_track; + + if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) { + int count= 0; + + /* count */ + track= tracking->tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) + count++; + } + + track= track->next; + } + + /* undistort */ + if(count) { + marker_pos= MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos"); + + track= tracking->tracks.first; + fp= marker_pos; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + ED_clip_point_undistorted_pos(sc, marker->pos, fp); + + if(track==act_track) + active_pos= fp; + + fp+= 2; + } + } + + track= track->next; + } + } + } + + if(sc->flag&SC_SHOW_TRACK_PATH) { + track= tracking->tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) + draw_track_path(sc, clip, track); + + track= track->next; + } + } + + /* markers outline and non-selected areas */ + track= tracking->tracks.first; + fp= marker_pos; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + copy_v2_v2(cur_pos, fp ? fp : marker->pos); + + draw_marker_outline(sc, track, marker, cur_pos, width, height); + draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0); + draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height); + draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height); + + if(fp) fp+= 2; + } + } + + track= track->next; + } + + /* selected areas only, so selection wouldn't be overlapped by + non-selected areas */ + track= tracking->tracks.first; + fp= marker_pos; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + int act= track==act_track; + + if(!act) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + copy_v2_v2(cur_pos, fp ? fp : marker->pos); + + draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1); + draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height); + } + } + + if(MARKER_VISIBLE(sc, marker) && fp) + fp+= 2; + } + + track= track->next; + } + + /* active marker would be displayed on top of everything else */ + if(act_track) { + if((act_track->flag&TRACK_HIDDEN)==0) { + marker= BKE_tracking_get_marker(act_track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos); + + draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1); + draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height); + } + } + } + + if(sc->flag&SC_SHOW_BUNDLES) { + float pos[4], vec[4], mat[4][4], aspy; + + glEnable(GL_POINT_SMOOTH); + glPointSize(3.0f); + + aspy= 1.0f/clip->tracking.camera.pixel_aspect; + BKE_tracking_projection_matrix(tracking, framenr, width, height, mat); + + track= tracking->tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0 && track->flag&TRACK_HAS_BUNDLE) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + float npos[2]; + copy_v4_v4(vec, track->bundle_pos); + vec[3]=1; + + mul_v4_m4v4(pos, mat, vec); + + pos[0]= (pos[0]/(pos[3]*2.0f)+0.5f)*width; + pos[1]= (pos[1]/(pos[3]*2.0f)+0.5f)*height*aspy; + + BKE_tracking_apply_intrinsics(tracking, pos, npos); + + if(npos[0]>=0.0f && npos[1]>=0.0f && npos[0]<=width && npos[1]<=height*aspy) { + vec[0]= (marker->pos[0]+track->offset[0])*width; + vec[1]= (marker->pos[1]+track->offset[1])*height*aspy; + + sub_v2_v2(vec, npos); + + if(len_v2(vec)<3) glColor3f(0.0f, 1.0f, 0.0f); + else glColor3f(1.0f, 0.0f, 0.0f); + + glBegin(GL_POINTS); + if(undistort) glVertex3f(pos[0]/width, pos[1]/(height*aspy), 0); + else glVertex3f(npos[0]/width, npos[1]/(height*aspy), 0); + glEnd(); + } + } + } + + track= track->next; + } + + glPointSize(1.0f); + glDisable(GL_POINT_SMOOTH); + } + + glPopMatrix(); + + if(sc->flag&SC_SHOW_NAMES) { + /* scaling should be cleared before drawing texts, otherwise font would also be scaled */ + track= tracking->tracks.first; + fp= marker_pos; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + if(MARKER_VISIBLE(sc, marker)) { + int act= track==act_track; + + copy_v2_v2(cur_pos, fp ? fp : marker->pos); + + draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy); + + if(fp) fp+= 2; + } + } + + track= track->next; + } + } + + glPopMatrix(); + + if(marker_pos) + MEM_freeN(marker_pos); +} + +static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip, int width, int height, float zoomx, float zoomy) +{ + float x, y; + const int n= 10; + int i, j, a; + float pos[2], tpos[2], grid[11][11][2]; + MovieTracking *tracking= &clip->tracking; + float aspy= 1.0f/tracking->camera.pixel_aspect; + float dx= (float)width/n, dy= (float)height/n*aspy; + + if(sc->mode!=SC_MODE_DISTORTION) + return; + + if(!tracking->camera.focal) + return; + + if((sc->flag&SC_SHOW_GRID)==0 && (sc->flag&SC_MANUAL_CALIBRATION)==0) + return; + + view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y); + + glPushMatrix(); + glTranslatef(x, y, 0); + glScalef(zoomx, zoomy, 0); + glMultMatrixf(sc->stabmat); + glScalef(width, height, 0); + + /* grid */ + if(sc->flag&SC_SHOW_GRID) { + float val[4][2], idx[4][2]; + float min[2], max[2]; + + for(a=0; a<4; a++) { + if(a<2) val[a][a%2]= FLT_MAX; + else val[a][a%2]= -FLT_MAX; + } + + zero_v2(pos); + for(i= 0; i<=n; i++) { + for(j= 0; j<=n; j++) { + if(i==0 || j==0 || i==n || j==n) { + BKE_tracking_apply_intrinsics(tracking, pos, tpos); + + for(a=0; a<4; a++) { + int ok; + + if(a<2) ok= tpos[a%2] < val[a][a%2]; + else ok= tpos[a%2] > val[a][a%2]; + + if(ok) { + copy_v2_v2(val[a], tpos); + idx[a][0]= j; + idx[a][1]= i; + } + } + } + + pos[0]+= dx; + } + + pos[0]= 0.0f; + pos[1]+= dy; + } + + INIT_MINMAX2(min, max); + + for(a= 0; a<4; a++) { + pos[0]= idx[a][0]*dx; + pos[1]= idx[a][1]*dy; + + BKE_tracking_invert_intrinsics(tracking, pos, tpos); + + DO_MINMAX2(tpos, min, max); + } + + copy_v2_v2(pos, min); + dx= (max[0]-min[0])/n; + dy= (max[1]-min[1])/n; + + for(i= 0; i<=n; i++) { + for(j= 0; j<=n; j++) { + BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]); + + grid[i][j][0]/= width; + grid[i][j][1]/= height*aspy; + + pos[0]+= dx; + } + + pos[0]= min[0]; + pos[1]+= dy; + } + + glColor3f(1.0f, 0.0f, 0.0f); + + for(i= 0; i<=n; i++) { + glBegin(GL_LINE_STRIP); + for(j= 0; j<=n; j++) { + glVertex2fv(grid[i][j]); + } + glEnd(); + } + + for(j= 0; j<=n; j++) { + glBegin(GL_LINE_STRIP); + for(i= 0; i<=n; i++) { + glVertex2fv(grid[i][j]); + } + glEnd(); + } + } + + if(sc->flag&SC_MANUAL_CALIBRATION && clip->gpd) { + bGPDlayer *layer= clip->gpd->layers.first; + + while(layer) { + bGPDframe *frame= layer->frames.first; + + glColor4fv(layer->color); + glLineWidth(layer->thickness); + glPointSize((float)(layer->thickness + 2)); + + while(frame) { + bGPDstroke *stroke= frame->strokes.first; + + while(stroke) { + if(stroke->flag&GP_STROKE_2DSPACE) { + if(stroke->totpoints>1) { + glBegin(GL_LINE_STRIP); + for(i= 0; itotpoints-1; i++) { + float npos[2], dpos[2], len; + int steps; + + pos[0]= stroke->points[i].x*width; + pos[1]= stroke->points[i].y*height*aspy; + + npos[0]= stroke->points[i+1].x*width; + npos[1]= stroke->points[i+1].y*height*aspy; + + len= len_v2v2(pos, npos); + steps= ceil(len/5.0f); + + /* we want to distort only long straight lines */ + if(stroke->totpoints==2) { + BKE_tracking_invert_intrinsics(tracking, pos, pos); + BKE_tracking_invert_intrinsics(tracking, npos, npos); + } + + sub_v2_v2v2(dpos, npos, pos); + mul_v2_fl(dpos, 1.0f/steps); + + for(j= 0; j<=steps; j++) { + BKE_tracking_apply_intrinsics(tracking, pos, tpos); + glVertex2f(tpos[0]/width, tpos[1]/(height*aspy)); + + add_v2_v2(pos, dpos); + } + } + glEnd(); + } + else if(stroke->totpoints==1) { + glBegin(GL_POINTS); + glVertex2f(stroke->points[0].x, stroke->points[0].y); + glEnd(); + } + } + + stroke= stroke->next; + } + + frame= frame->next; + } + + layer= layer->next; + } + + glLineWidth(1.0f); + glPointSize(1.0f); + } + + glPopMatrix(); +} + +void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene) +{ + MovieClip *clip= ED_space_clip(sc); + ImBuf *ibuf; + int width, height; + float zoomx, zoomy; + + /* if no clip, nothing to do */ + if(!clip) + return; + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + + if(sc->flag&SC_SHOW_STABLE) { + float smat[4][4], ismat[4][4]; + + ibuf= ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle); + BKE_tracking_stabdata_to_mat4(width, height, sc->loc, sc->scale, sc->angle, sc->stabmat); + + unit_m4(smat); + smat[0][0]= 1.0f/width; + smat[1][1]= 1.0f/height; + invert_m4_m4(ismat, smat); + + mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL); + } else { + ibuf= ED_space_clip_get_buffer(sc); + + zero_v2(sc->loc); + sc->scale= 1.0f; + unit_m4(sc->stabmat); + unit_m4(sc->unistabmat); + } + + if(ibuf) { + draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy); + IMB_freeImBuf(ibuf); + + draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy); + draw_distortion(sc, ar, clip, width, height, zoomx, zoomy); + } + + draw_movieclip_cache(sc, ar, clip, scene); + draw_movieclip_notes(sc, ar); +} + +/* draw grease pencil */ +void clip_draw_grease_pencil(bContext *C, int onlyv2d) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + ImBuf *ibuf; + + if((sc->flag&SC_SHOW_GPENCIL)==0 || !clip) + return; + + if(onlyv2d) { + /* if manual calibration is used then grase pencil data is already + drawed in draw_distortion */ + if((sc->flag&SC_MANUAL_CALIBRATION)==0 || sc->mode!=SC_MODE_DISTORTION) { + ibuf= ED_space_clip_get_buffer(sc); + + if(ibuf) { + glPushMatrix(); + glMultMatrixf(sc->unistabmat); + draw_gpencil_2dimage(C, ibuf); + + IMB_freeImBuf(ibuf); + glPopMatrix(); + } + } + } else { + draw_gpencil_view2d(C, 0); + } +} diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c new file mode 100644 index 00000000000..0de7fed1f1a --- /dev/null +++ b/source/blender/editors/space_clip/clip_editor.c @@ -0,0 +1,302 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_editor.c + * \ingroup spclip + */ + +#include + +#include "BKE_main.h" +#include "BKE_movieclip.h" +#include "BKE_context.h" +#include "BKE_tracking.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +int ED_space_clip_poll(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + if(sc && sc->clip) + return 1; + + return 0; +} + +void ED_space_clip_set(bContext *C, SpaceClip *sc, MovieClip *clip) +{ + sc->clip= clip; + + if(sc->clip && sc->clip->id.us==0) + sc->clip->id.us= 1; + + if(C) + WM_event_add_notifier(C, NC_MOVIECLIP|NA_SELECTED, sc->clip); +} + +MovieClip *ED_space_clip(SpaceClip *sc) +{ + return sc->clip; +} + +ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) +{ + if(sc->clip) { + ImBuf *ibuf; + + ibuf= BKE_movieclip_get_ibuf(sc->clip, &sc->user); + + if(ibuf && (ibuf->rect || ibuf->rect_float)) + return ibuf; + + if(ibuf) + IMB_freeImBuf(ibuf); + } + + return NULL; +} + +ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle) +{ + if(sc->clip) { + ImBuf *ibuf; + + ibuf= BKE_movieclip_get_stable_ibuf(sc->clip, &sc->user, loc, scale, angle); + + if(ibuf && (ibuf->rect || ibuf->rect_float)) + return ibuf; + + if(ibuf) + IMB_freeImBuf(ibuf); + } + + return NULL; +} + +void ED_space_clip_size(SpaceClip *sc, int *width, int *height) +{ + if(!sc->clip) { + *width= 0; + *height= 0; + } else + BKE_movieclip_get_size(sc->clip, &sc->user, width, height); +} + +void ED_space_clip_zoom(SpaceClip *sc, ARegion *ar, float *zoomx, float *zoomy) +{ + int width, height; + + ED_space_clip_size(sc, &width, &height); + + *zoomx= (float)(ar->winrct.xmax - ar->winrct.xmin + 1)/(float)((ar->v2d.cur.xmax - ar->v2d.cur.xmin)*width); + *zoomy= (float)(ar->winrct.ymax - ar->winrct.ymin + 1)/(float)((ar->v2d.cur.ymax - ar->v2d.cur.ymin)*height); +} + +void ED_space_clip_aspect(SpaceClip *sc, float *aspx, float *aspy) +{ + MovieClip *clip= ED_space_clip(sc); + + if(clip) + BKE_movieclip_aspect(clip, aspx, aspy); + else + *aspx= *aspy= 1.0f; +} + +void ED_clip_update_frame(const Main *mainp, int cfra) +{ + wmWindowManager *wm; + wmWindow *win; + + /* image window, compo node users */ + for(wm=mainp->wm.first; wm; wm= wm->id.next) { /* only 1 wm */ + for(win= wm->windows.first; win; win= win->next) { + ScrArea *sa; + for(sa= win->screen->areabase.first; sa; sa= sa->next) { + if(sa->spacetype==SPACE_CLIP) { + SpaceClip *sc= sa->spacedata.first; + + sc->scopes.ok= 0; + + BKE_movieclip_user_set_frame(&sc->user, cfra); + } + } + } + } +} + +static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int width, height, ok= 0; + + INIT_MINMAX2(min, max); + + ED_space_clip_size(sc, &width, &height); + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); + + if(marker) { + float pos[3]; + + pos[0]= (marker->pos[0]+track->offset[0])*width; + pos[1]= (marker->pos[1]+track->offset[1])*height; + pos[2]= 0.0f; + + mul_v3_m4v3(pos, sc->stabmat, pos); + + DO_MINMAX2(pos, min, max); + + ok= 1; + } + } + + track= track->next; + } + + return ok; +} + +int ED_clip_view_selection(SpaceClip *sc, ARegion *ar, int fit) +{ + int w, h, frame_width, frame_height; + float min[2], max[2]; + + ED_space_clip_size(sc, &frame_width, &frame_height); + + if(frame_width==0 || frame_height==0) return 0; + + if(!selected_boundbox(sc, min, max)) + return 0; + + /* center view */ + clip_view_center_to_point(sc, (max[0]+min[0])/(2*frame_width), (max[1]+min[1])/(2*frame_height)); + + w= max[0]-min[0]; + h= max[1]-min[1]; + + /* set zoom to see all selection */ + if(w>0 && h>0) { + int width, height; + float zoomx, zoomy, newzoom, aspx, aspy; + + ED_space_clip_aspect(sc, &aspx, &aspy); + + width= ar->winrct.xmax - ar->winrct.xmin + 1; + height= ar->winrct.ymax - ar->winrct.ymin + 1; + + zoomx= (float)width/w/aspx; + zoomy= (float)height/h/aspy; + + newzoom= 1.0f/power_of_2(1/MIN2(zoomx, zoomy)); + + if(fit || sc->zoom>newzoom) + sc->zoom= newzoom; + } + + return 1; +} + +void ED_clip_point_undistorted_pos(SpaceClip *sc, float co[2], float nco[2]) +{ + copy_v2_v2(nco, co); + + if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) { + MovieClip *clip= ED_space_clip(sc); + float aspy= 1.0f/clip->tracking.camera.pixel_aspect; + int width, height; + + ED_space_clip_size(sc, &width, &height); + + nco[0]*= width; + nco[1]*= height*aspy; + + BKE_tracking_invert_intrinsics(&clip->tracking, nco, nco); + nco[0]/= width; + nco[1]/= height*aspy; + } +} + +void ED_clip_point_stable_pos(bContext *C, float x, float y, float *xr, float *yr) +{ + ARegion *ar= CTX_wm_region(C); + SpaceClip *sc= CTX_wm_space_clip(C); + int sx, sy, width, height; + float zoomx, zoomy, pos[3]={0.0f, 0.0f, 0.0f}, imat[4][4]; + + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + ED_space_clip_size(sc, &width, &height); + + UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); + + pos[0]= (x-sx)/zoomx; + pos[1]= (y-sy)/zoomy; + + invert_m4_m4(imat, sc->stabmat); + mul_v3_m4v3(pos, imat, pos); + + *xr= pos[0]/width; + *yr= pos[1]/height; + + if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) { + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + float aspy= 1.0f/tracking->camera.pixel_aspect; + float tmp[2]= {*xr*width, *yr*height*aspy}; + + BKE_tracking_apply_intrinsics(tracking, tmp, tmp); + + *xr= tmp[0]/width; + *yr= tmp[1]/(height*aspy); + } +} + +void ED_clip_mouse_pos(bContext *C, wmEvent *event, float co[2]) +{ + ED_clip_point_stable_pos(C, event->mval[0], event->mval[1], &co[0], &co[1]); +} diff --git a/source/blender/editors/space_clip/clip_graph_draw.c b/source/blender/editors/space_clip/clip_graph_draw.c new file mode 100644 index 00000000000..7b14783d4ca --- /dev/null +++ b/source/blender/editors/space_clip/clip_graph_draw.c @@ -0,0 +1,255 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_graph_draw.c + * \ingroup spclip + */ + +#include "DNA_movieclip_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" /* SELECT */ + +#include "MEM_guardedalloc.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_string.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "BIF_gl.h" + +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "BLF_api.h" + +#include "clip_intern.h" // own include + +static void draw_curve_knot(float x, float y, float xscale, float yscale, float hsize) +{ + static GLuint displist=0; + + /* initialise round circle shape */ + if (displist == 0) { + GLUquadricObj *qobj; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE); + + qobj= gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluDisk(qobj, 0, 0.7, 8, 1); + gluDeleteQuadric(qobj); + + glEndList(); + } + + glPushMatrix(); + + glTranslatef(x, y, 0.0f); + glScalef(1.0f/xscale*hsize, 1.0f/yscale*hsize, 1.0f); + glCallList(displist); + + glPopMatrix(); +} + +static void draw_graph_cfra(SpaceClip *sc, ARegion *ar, Scene *scene) +{ + View2D *v2d= &ar->v2d; + float xscale, yscale; + float vec[2]; + + /* Draw a light green line to indicate current frame */ + vec[0]= (float)(sc->user.framenr * scene->r.framelen); + + UI_ThemeColor(TH_CFRAME); + glLineWidth(2.0); + + glBegin(GL_LINE_STRIP); + vec[1]= v2d->cur.ymin; + glVertex2fv(vec); + + vec[1]= v2d->cur.ymax; + glVertex2fv(vec); + glEnd(); + + glLineWidth(1.0); + + UI_view2d_view_orthoSpecial(ar, v2d, 1); + + /* because the frame number text is subject to the same scaling as the contents of the view */ + UI_view2d_getscale(v2d, &xscale, &yscale); + glScalef(1.0f/xscale, 1.0f, 1.0f); + + clip_draw_curfra_label(sc, (float)sc->user.framenr * xscale, 18); + + /* restore view transform */ + glScalef(xscale, 1.0, 1.0); +} + +static void tracking_segment_point_cb(void *UNUSED(userdata), MovieTrackingTrack *UNUSED(track), + MovieTrackingMarker *marker, int UNUSED(coord), float val) +{ + glVertex2f(marker->framenr, val); +} + +void tracking_segment_start_cb(void *userdata, MovieTrackingTrack *track, int coord) +{ + static float colors[2][3] = {{1.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f}}; + float col[4]; + + copy_v3_v3(col, colors[coord]); + + if(track==userdata) { + col[3]= 1.0f; + glLineWidth(2.0f); + } else { + col[3]= 0.5f; + glLineWidth(1.0f); + } + + glColor4fv(col); + + glBegin(GL_LINE_STRIP); +} + +void tracking_segment_end_cb(void *UNUSED(userdata)) +{ + glEnd(); + + glLineWidth(1.0f); +} + +static void tracking_segment_knot_cb(void *userdata, MovieTrackingTrack *track, + MovieTrackingMarker *marker, int UNUSED(coord), float val) +{ + struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } *data = userdata; + int sel= 0; + + if(track!=data->act_track) + return; + + sel= (marker->flag&MARKER_GRAPH_SEL) ? 1 : 0; + + if(sel == data->sel) { + if(sel) UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); + else UI_ThemeColor(TH_HANDLE_VERTEX); + + draw_curve_knot(marker->framenr, val, data->xscale, data->yscale, data->hsize); + } +} + +static void draw_tracks_curves(View2D *v2d, SpaceClip *sc) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + int width, height; + struct { MovieTrackingTrack *act_track; int sel; float xscale, yscale, hsize; } userdata; + + BKE_movieclip_get_size(clip, &sc->user, &width, &height); + + if(!width || !height) + return; + + /* non-selected knot handles */ + userdata.hsize= UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); + userdata.sel= 0; + userdata.act_track= clip->tracking.act_track; + UI_view2d_getscale(v2d, &userdata.xscale, &userdata.yscale); + clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); + + /* draw graph lines */ + glEnable(GL_BLEND); + clip_graph_tracking_values_iterate(sc, tracking->act_track, tracking_segment_point_cb, tracking_segment_start_cb, tracking_segment_end_cb); + glDisable(GL_BLEND); + + /* selected knot handles on top of curves */ + userdata.sel= 1; + clip_graph_tracking_values_iterate(sc, &userdata, tracking_segment_knot_cb, NULL, NULL); +} + +static void draw_frame_curves(SpaceClip *sc) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + int i, lines= 0, prevfra= 0; + + glColor3f(0.0f, 0.0f, 1.0f); + + for(i= 0; icamnr; i++) { + MovieReconstructedCamera *camera= &reconstruction->cameras[i]; + + if(lines && camera->framenr!=prevfra+1) { + glEnd(); + lines= 0; + } + + if(!lines) { + glBegin(GL_LINE_STRIP); + lines= 1; + } + + glVertex2f(camera->framenr, camera->error); + + prevfra= camera->framenr; + } + + if(lines) + glEnd(); +} + +void clip_draw_graph(SpaceClip *sc, ARegion *ar, Scene *scene) +{ + View2D *v2d= &ar->v2d; + View2DGrid *grid; + short unitx= V2D_UNIT_FRAMESCALE, unity= V2D_UNIT_VALUES; + + /* grid */ + grid= UI_view2d_grid_calc(scene, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP, ar->winx, ar->winy); + UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL); + UI_view2d_grid_free(grid); + + if(sc->flag&SC_SHOW_GRAPH_TRACKS) + draw_tracks_curves(v2d, sc); + + if(sc->flag&SC_SHOW_GRAPH_FRAMES) + draw_frame_curves(sc); + + /* current frame */ + draw_graph_cfra(sc, ar, scene); +} diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c new file mode 100644 index 00000000000..831b225386a --- /dev/null +++ b/source/blender/editors/space_clip/clip_graph_ops.c @@ -0,0 +1,356 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_graph_ops.c + * \ingroup spclip + */ + +#include "DNA_object_types.h" /* SELECT */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +/******************** common graph-editing utilities ********************/ + +typedef struct { + int action; +} SelectUserData; + +static void toggle_selection_cb(void *userdata, MovieTrackingMarker *marker) +{ + SelectUserData *data= (SelectUserData *)userdata; + + switch(data->action) { + case SEL_SELECT: + marker->flag|= MARKER_GRAPH_SEL; + break; + case SEL_DESELECT: + marker->flag&= ~MARKER_GRAPH_SEL; + break; + case SEL_INVERT: + marker->flag^= MARKER_GRAPH_SEL; + break; + } +} + +/******************** mouse select operator ********************/ + +typedef struct { + int coord, /* coordinate index of found entuty (0 = X-axis, 1 = Y-axis) */ + has_prev; /* if there's valid coordinate of previous point of curve segment */ + + float min_dist, /* minimal distance between mouse and currently found entuty */ + mouse_co[2], /* mouse coordinate */ + prev_co[2], /* coordinate of previeous point of segment */ + min_co[2]; /* coordinate of entity with minimal distance */ + + MovieTrackingTrack *track; /* nearest found track */ + MovieTrackingMarker *marker; /* nearest found marker */ +} MouseSelectUserData; + +static void find_nearest_tracking_segment_cb(void *userdata, MovieTrackingTrack *track, + MovieTrackingMarker *marker, int coord, float val) +{ + MouseSelectUserData *data= userdata; + float co[2]= {marker->framenr, val}; + + if(data->has_prev) { + float d= dist_to_line_segment_v2(data->mouse_co, data->prev_co, co); + + if(data->track==NULL || dmin_dist) { + data->track= track; + data->min_dist= d; + data->coord= coord; + copy_v2_v2(data->min_co, co); + } + } + + data->has_prev= 1; + copy_v2_v2(data->prev_co, co); +} + +void find_nearest_tracking_segment_end_cb(void *userdata) +{ + MouseSelectUserData *data= userdata; + + data->has_prev= 0; +} + +static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track, + MovieTrackingMarker *marker, int coord, float val) +{ + MouseSelectUserData *data= userdata; + float dx= marker->framenr-data->mouse_co[0], dy= val-data->mouse_co[1]; + float d= dx*dx+dy*dy; + + if(data->marker==NULL || dmin_dist) { + float co[2]= {marker->framenr, val}; + + data->track= track; + data->marker= marker; + data->min_dist= d; + data->coord= coord; + copy_v2_v2(data->min_co, co); + } + +} + +static void mouse_select_init_data(MouseSelectUserData *userdata, float *co) +{ + memset(userdata, 0, sizeof(MouseSelectUserData)); + userdata->min_dist= FLT_MAX; + copy_v2_v2(userdata->mouse_co, co); +} + +static int mouse_select_knot(bContext *C, float co[2], int extend) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + ARegion *ar= CTX_wm_region(C); + View2D *v2d= &ar->v2d; + MovieTracking *tracking= &clip->tracking; + static const int delta= 6; + + if(tracking->act_track) { + MouseSelectUserData userdata; + + mouse_select_init_data(&userdata, co); + clip_graph_tracking_values_iterate_track(sc, tracking->act_track, + &userdata, find_nearest_tracking_knot_cb, NULL, NULL); + + if(userdata.marker) { + int x1, y1, x2, y2; + + UI_view2d_view_to_region(v2d, co[0], co[1], &x1, &y1); + UI_view2d_view_to_region(v2d, userdata.min_co[0], userdata.min_co[1], &x2, &y2); + + if(abs(x2-x1)<=delta && abs(y2-y1)<=delta) { + if(!extend) { + SelectUserData selectdata = {SEL_DESELECT}; + clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); + } + + userdata.marker->flag|= MARKER_GRAPH_SEL; + + return 1; + } + } + } + + return 0; +} + +static int mouse_select_curve(bContext *C, float co[2], int extend) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MouseSelectUserData userdata; + + mouse_select_init_data(&userdata, co); + clip_graph_tracking_values_iterate(sc, &userdata, find_nearest_tracking_segment_cb, NULL, find_nearest_tracking_segment_end_cb); + + if(userdata.track) { + if(extend) { + if(tracking->act_track==userdata.track) { + /* currently only single curve can be selected (selected curve represents active track) */ + tracking->act_track= NULL; + } + } + else if(tracking->act_track!=userdata.track) { + MovieTrackingMarker *marker; + SelectUserData selectdata = {SEL_DESELECT}; + + tracking->act_track= userdata.track; + + /* make active track be centered to screen */ + marker= BKE_tracking_get_marker(userdata.track, sc->user.framenr); + + clip_view_center_to_point(sc, marker->pos[0], marker->pos[1]); + + /* deselect all knots on newly selected curve */ + clip_graph_tracking_iterate(sc, &selectdata, toggle_selection_cb); + } + + return 1; + } + + return 0; +} + +static int mouse_select(bContext *C, float co[2], int extend) +{ + int sel= 0; + + /* first try to select knot on selected curves */ + sel= mouse_select_knot(C, co, extend); + + if(!sel) { + /* if there's no close enough knot to mouse osition, select nearest curve */ + sel= mouse_select_curve(C, co, extend); + } + + if(sel) + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +static int select_exec(bContext *C, wmOperator *op) +{ + float co[2]; + int extend= RNA_boolean_get(op->ptr, "extend"); + + RNA_float_get_array(op->ptr, "location", co); + + return mouse_select(C, co, extend); +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + float co[2]; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void CLIP_OT_graph_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select"; + ot->description= "Select graph curves"; + ot->idname= "CLIP_OT_graph_select"; + + /* api callbacks */ + ot->exec= select_exec; + ot->invoke= select_invoke; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, + "Location", "Mouse location to select nearest entity closest to", -100.0f, 100.0f); + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); +} + +/******************** delete curve operator ********************/ + +static int delete_curve_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + + if(tracking->act_track) + clip_delete_track(C, clip, tracking->act_track); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_graph_delete_curve(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Curve"; + ot->description= "Delete selected curves"; + ot->idname= "CLIP_OT_graph_delete_curve"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= delete_curve_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/******************** delete knot operator ********************/ + +static int delete_knot_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + + if(tracking->act_track) { + int a= 0; + MovieTrackingTrack *track= tracking->act_track; + + while(amarkersnr) { + MovieTrackingMarker *marker= &track->markers[a]; + + if(marker->flag&MARKER_GRAPH_SEL) + clip_delete_marker(C, clip, track, marker); + else + a++; + } + } + + return OPERATOR_FINISHED; +} + +void CLIP_OT_graph_delete_knot(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Knot"; + ot->description= "Delete curve knots"; + ot->idname= "CLIP_OT_graph_delete_knot"; + + /* api callbacks */ + ot->exec= delete_knot_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h new file mode 100644 index 00000000000..da0b589652e --- /dev/null +++ b/source/blender/editors/space_clip/clip_intern.h @@ -0,0 +1,144 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_intern.h + * \ingroup spclip + */ + +#ifndef ED_CLIP_INTERN_H +#define ED_CLIP_INTERN_H + +struct bContext; +struct ARegion; +struct MovieClip; +struct MovieTrackingMarker; +struct MovieTrackingTrack; +struct Scene; +struct SpaceClip; +struct wmOperatorType; + +/* internal exports only */ + +/* clip_buttons.c */ +void ED_clip_buttons_register(struct ARegionType *art); + +/* clip_draw.c */ +void clip_draw_main(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); +void clip_draw_grease_pencil(struct bContext *C, int onlyv2d); +void clip_draw_curfra_label(struct SpaceClip *sc, float x, float y); + +/* clip_graph_draw.c */ +void clip_draw_graph(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scene); + +/* clip_graph_ops.c */ +void CLIP_OT_graph_select(struct wmOperatorType *ot); +void CLIP_OT_graph_delete_curve(struct wmOperatorType *ot); +void CLIP_OT_graph_delete_knot(struct wmOperatorType *ot); + +/* clip_ops.c */ +void CLIP_OT_open(struct wmOperatorType *ot); +void CLIP_OT_reload(struct wmOperatorType *ot); +void CLIP_OT_view_pan(struct wmOperatorType *ot); +void CLIP_OT_view_zoom(wmOperatorType *ot); +void CLIP_OT_view_zoom_in(struct wmOperatorType *ot); +void CLIP_OT_view_zoom_out(struct wmOperatorType *ot); +void CLIP_OT_view_zoom_ratio(struct wmOperatorType *ot); +void CLIP_OT_view_all(struct wmOperatorType *ot); +void CLIP_OT_view_selected(struct wmOperatorType *ot); +void CLIP_OT_change_frame(wmOperatorType *ot); +void CLIP_OT_rebuild_proxy(struct wmOperatorType *ot); +void CLIP_OT_mode_set(struct wmOperatorType *ot); + +/* clip_toolbar.c */ +void CLIP_OT_tools(struct wmOperatorType *ot); +void CLIP_OT_properties(struct wmOperatorType *ot); +void ED_clip_tool_props_register(struct ARegionType *art); + +/* clip_utils.c */ +void clip_graph_tracking_values_iterate_track(struct SpaceClip *sc, struct MovieTrackingTrack *track, void *userdata, + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), + void (*segment_end) (void *userdata)); + +void clip_graph_tracking_values_iterate(struct SpaceClip *sc, void *userdata, + void (*func) (void *userdata, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker, int coord, float val), + void (*segment_start) (void *userdata, struct MovieTrackingTrack *track, int coord), + void (*segment_end) (void *userdata)); + +void clip_graph_tracking_iterate(struct SpaceClip *sc, void *userdata, + void (*func) (void *userdata, struct MovieTrackingMarker *marker)); + +void clip_delete_track(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track); +void clip_delete_marker(struct bContext *C, struct MovieClip *clip, struct MovieTrackingTrack *track, struct MovieTrackingMarker *marker); + +void clip_view_center_to_point(struct SpaceClip *sc, float x, float y); + +/* tracking_ops.c */ +void CLIP_OT_select(struct wmOperatorType *ot); +void CLIP_OT_select_all(struct wmOperatorType *ot); +void CLIP_OT_select_border(struct wmOperatorType *ot); +void CLIP_OT_select_circle(struct wmOperatorType *ot); +void CLIP_OT_select_grouped(struct wmOperatorType *ot); + +void CLIP_OT_add_marker(struct wmOperatorType *ot); +void CLIP_OT_delete_track(struct wmOperatorType *ot); +void CLIP_OT_delete_marker(struct wmOperatorType *ot); + +void CLIP_OT_track_markers(struct wmOperatorType *ot); +void CLIP_OT_solve_camera(struct wmOperatorType *ot); +void CLIP_OT_clear_solution(struct wmOperatorType *ot); + +void CLIP_OT_clear_track_path(struct wmOperatorType *ot); +void CLIP_OT_join_tracks(struct wmOperatorType *ot); + +void CLIP_OT_disable_markers(struct wmOperatorType *ot); +void CLIP_OT_hide_tracks(struct wmOperatorType *ot); +void CLIP_OT_hide_tracks_clear(struct wmOperatorType *ot); +void CLIP_OT_lock_tracks(struct wmOperatorType *ot); + +void CLIP_OT_set_origin(struct wmOperatorType *ot); +void CLIP_OT_set_floor(struct wmOperatorType *ot); +void CLIP_OT_set_axis(struct wmOperatorType *ot); +void CLIP_OT_set_scale(struct wmOperatorType *ot); + +void CLIP_OT_set_center_principal(struct wmOperatorType *ot); + +void CLIP_OT_slide_marker(struct wmOperatorType *ot); + +void CLIP_OT_frame_jump(struct wmOperatorType *ot); +void CLIP_OT_track_copy_color(struct wmOperatorType *ot); + +void CLIP_OT_detect_features(struct wmOperatorType *ot); + +void CLIP_OT_stabilize_2d_add(struct wmOperatorType *ot); +void CLIP_OT_stabilize_2d_remove(struct wmOperatorType *ot); +void CLIP_OT_stabilize_2d_select(struct wmOperatorType *ot); +void CLIP_OT_stabilize_2d_set_rotation(struct wmOperatorType *ot); + +void CLIP_OT_clean_tracks(wmOperatorType *ot); + +#endif /* ED_CLIP_INTERN_H */ diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c new file mode 100644 index 00000000000..c52346fd4b6 --- /dev/null +++ b/source/blender/editors/space_clip/clip_ops.c @@ -0,0 +1,1004 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_ops.c + * \ingroup spclip + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_userdef_types.h" +#include "DNA_scene_types.h" /* min/max frames */ + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_report.h" +#include "BKE_main.h" +#include "BKE_library.h" +#include "BKE_movieclip.h" +#include "BKE_sound.h" +#include "BKE_tracking.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +/******************** view navigation utilities *********************/ + +static void sclip_zoom_set(SpaceClip *sc, ARegion *ar, float zoom) +{ + float oldzoom= sc->zoom; + int width, height; + + sc->zoom= zoom; + + if (sc->zoom > 0.1f && sc->zoom < 4.0f) + return; + + /* check zoom limits */ + ED_space_clip_size(sc, &width, &height); + + width*= sc->zoom; + height*= sc->zoom; + + if((width < 4) && (height < 4)) + sc->zoom= oldzoom; + else if((ar->winrct.xmax - ar->winrct.xmin) <= sc->zoom) + sc->zoom= oldzoom; + else if((ar->winrct.ymax - ar->winrct.ymin) <= sc->zoom) + sc->zoom= oldzoom; +} + +static void sclip_zoom_set_factor(SpaceClip *sc, ARegion *ar, float zoomfac) +{ + sclip_zoom_set(sc, ar, sc->zoom*zoomfac); +} + + +/******************** open clip operator ********************/ + +static void clip_filesel(bContext *C, wmOperator *op, const char *path) +{ + RNA_string_set(op->ptr, "filepath", path); + WM_event_add_fileselect(C, op); +} + +static void open_init(bContext *C, wmOperator *op) +{ + PropertyPointerRNA *pprop; + + op->customdata= pprop= MEM_callocN(sizeof(PropertyPointerRNA), "OpenPropertyPointerRNA"); + uiIDContextProperty(C, &pprop->ptr, &pprop->prop); +} + +static int open_cancel(bContext *UNUSED(C), wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + +static int open_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + PropertyPointerRNA *pprop; + PointerRNA idptr; + MovieClip *clip= NULL; + char str[FILE_MAX]; + + RNA_string_get(op->ptr, "filepath", str); + /* default to frame 1 if there's no scene in context */ + + errno= 0; + + clip= BKE_add_movieclip_file(str); + + if(!clip) { + if(op->customdata) + MEM_freeN(op->customdata); + + BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, errno ? strerror(errno) : "Unsupported movie clip format"); + + return OPERATOR_CANCELLED; + } + + if(!op->customdata) + open_init(C, op); + + /* hook into UI */ + pprop= op->customdata; + + if(pprop->prop) { + /* when creating new ID blocks, use is already 1, but RNA + * pointer se also increases user, so this compensates it */ + clip->id.us--; + + RNA_id_pointer_create(&clip->id, &idptr); + RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr); + RNA_property_update(C, &pprop->ptr, pprop->prop); + } + else if(sc) { + ED_space_clip_set(C, sc, clip); + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_ADDED, clip); + + MEM_freeN(op->customdata); + + return OPERATOR_FINISHED; +} + +static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + char *path= U.textudir; + MovieClip *clip= NULL; + + if(sc) + clip= ED_space_clip(sc); + + if(clip) + path= clip->name; + + if(!RNA_property_is_set(op->ptr, "relative_path")) + RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS); + + if(RNA_property_is_set(op->ptr, "filepath")) + return open_exec(C, op); + + open_init(C, op); + + clip_filesel(C, op, path); + + return OPERATOR_RUNNING_MODAL; +} + +void CLIP_OT_open(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Open Clip"; + ot->description= "Open clip"; + ot->idname= "CLIP_OT_open"; + + /* api callbacks */ + ot->exec= open_exec; + ot->invoke= open_invoke; + ot->cancel= open_cancel; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_filesel(ot, FOLDERFILE|IMAGEFILE|MOVIEFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH|WM_FILESEL_RELPATH); +} + +/******************* reload clip operator *********************/ + +static int reload_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= CTX_data_edit_movieclip(C); + + if(!clip) + return OPERATOR_CANCELLED; + + sc->scopes.ok= 0; + + BKE_movieclip_reload(clip); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_reload(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Reload Clip"; + ot->description= "Reload clip"; + ot->idname= "CLIP_OT_reload"; + + /* api callbacks */ + ot->exec= reload_exec; +} + +/********************** view pan operator *********************/ + +typedef struct ViewPanData { + float x, y; + float xof, yof, xorig, yorig; + int event_type; + float *vec; +} ViewPanData; + +static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewPanData *vpd; + + op->customdata= vpd= MEM_callocN(sizeof(ViewPanData), "ClipViewPanData"); + WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); + + vpd->x= event->x; + vpd->y= event->y; + + if(sc->flag&SC_LOCK_SELECTION) vpd->vec= &sc->xlockof; + else vpd->vec= &sc->xof; + + copy_v2_v2(&vpd->xof, vpd->vec); + copy_v2_v2(&vpd->xorig, &vpd->xof); + + vpd->event_type= event->type; + + WM_event_add_modal_handler(C, op); +} + +static void view_pan_exit(bContext *C, wmOperator *op, int cancel) +{ + ViewPanData *vpd= op->customdata; + + if(cancel) { + copy_v2_v2(vpd->vec, &vpd->xorig); + + ED_region_tag_redraw(CTX_wm_region(C)); + } + + WM_cursor_restore(CTX_wm_window(C)); + MEM_freeN(op->customdata); +} + +static int view_pan_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + float offset[2]; + + RNA_float_get_array(op->ptr, "offset", offset); + + if(sc->flag&SC_LOCK_SELECTION) { + sc->xlockof+= offset[0]; + sc->ylockof+= offset[1]; + } else { + sc->xof+= offset[0]; + sc->yof+= offset[1]; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (event->type==MOUSEPAN) { + SpaceClip *sc= CTX_wm_space_clip(C); + float offset[2]; + + offset[0]= (event->x - event->prevx)/sc->zoom; + offset[1]= (event->y - event->prevy)/sc->zoom; + + RNA_float_set_array(op->ptr, "offset", offset); + + view_pan_exec(C, op); + return OPERATOR_FINISHED; + } + else { + view_pan_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } +} + +static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewPanData *vpd= op->customdata; + float offset[2]; + + switch(event->type) { + case MOUSEMOVE: + copy_v2_v2(vpd->vec, &vpd->xorig); + offset[0]= (vpd->x - event->x)/sc->zoom; + offset[1]= (vpd->y - event->y)/sc->zoom; + RNA_float_set_array(op->ptr, "offset", offset); + view_pan_exec(C, op); + break; + case ESCKEY: + view_pan_exit(C, op, 1); + return OPERATOR_CANCELLED; + case SPACEKEY: + view_pan_exit(C, op, 0); + return OPERATOR_FINISHED; + default: + if(event->type==vpd->event_type && event->val==KM_RELEASE) { + view_pan_exit(C, op, 0); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int view_pan_cancel(bContext *C, wmOperator *op) +{ + view_pan_exit(C, op, 1); + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_view_pan(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Pan"; + ot->idname= "CLIP_OT_view_pan"; + + /* api callbacks */ + ot->exec= view_pan_exec; + ot->invoke= view_pan_invoke; + ot->modal= view_pan_modal; + ot->cancel= view_pan_cancel; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING; + + /* properties */ + RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX, + "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); +} + +/********************** view zoom operator *********************/ + +typedef struct ViewZoomData { + float x, y; + float zoom; + int event_type; +} ViewZoomData; + +static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewZoomData *vpd; + + op->customdata= vpd= MEM_callocN(sizeof(ViewZoomData), "ClipViewZoomData"); + WM_cursor_modal(CTX_wm_window(C), BC_NSEW_SCROLLCURSOR); + + vpd->x= event->x; + vpd->y= event->y; + vpd->zoom= sc->zoom; + vpd->event_type= event->type; + + WM_event_add_modal_handler(C, op); +} + +static void view_zoom_exit(bContext *C, wmOperator *op, int cancel) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ViewZoomData *vpd= op->customdata; + + if(cancel) { + sc->zoom= vpd->zoom; + ED_region_tag_redraw(CTX_wm_region(C)); + } + + WM_cursor_restore(CTX_wm_window(C)); + MEM_freeN(op->customdata); +} + +static int view_zoom_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, RNA_float_get(op->ptr, "factor")); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if (event->type==MOUSEZOOM) { + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + float factor; + + factor= 1.0f + (event->x-event->prevx+event->y-event->prevy)/300.0f; + RNA_float_set(op->ptr, "factor", factor); + sclip_zoom_set(sc, ar, sc->zoom*factor); + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; + } + else { + view_zoom_init(C, op, event); + return OPERATOR_RUNNING_MODAL; + } +} + +static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + ViewZoomData *vpd= op->customdata; + float factor; + + switch(event->type) { + case MOUSEMOVE: + factor= 1.0f + (vpd->x-event->x+vpd->y-event->y)/300.0f; + RNA_float_set(op->ptr, "factor", factor); + sclip_zoom_set(sc, ar, vpd->zoom*factor); + ED_region_tag_redraw(CTX_wm_region(C)); + break; + default: + if(event->type==vpd->event_type && event->val==KM_RELEASE) { + view_zoom_exit(C, op, 0); + return OPERATOR_FINISHED; + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +static int view_zoom_cancel(bContext *C, wmOperator *op) +{ + view_zoom_exit(C, op, 1); + return OPERATOR_CANCELLED; +} + +void CLIP_OT_view_zoom(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom"; + ot->idname= "CLIP_OT_view_zoom"; + + /* api callbacks */ + ot->exec= view_zoom_exec; + ot->invoke= view_zoom_invoke; + ot->modal= view_zoom_modal; + ot->cancel= view_zoom_cancel; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; + + /* properties */ + RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); +} + +/********************** view zoom in/out operator *********************/ + +static int view_zoom_in_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, 1.25f); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_out_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set_factor(sc, ar, 0.8f); + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +static int view_zoom_inout_invoke(bContext *C, wmOperator *op, wmEvent *event, int out) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + float co[2], oldzoom= sc->zoom; + + ED_clip_mouse_pos(C, event, co); + + if(out) + view_zoom_out_exec(C, op); + else + view_zoom_in_exec(C, op); + + if(U.uiflag&USER_ZOOM_TO_MOUSEPOS) { + int width, height; + + ED_space_clip_size(sc, &width, &height); + + sc->xof+= ((co[0]-0.5)*width-sc->xof)*(sc->zoom-oldzoom)/sc->zoom; + sc->yof+= ((co[1]-0.5)*height-sc->yof)*(sc->zoom-oldzoom)/sc->zoom; + } + + return OPERATOR_FINISHED; +} + +static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return view_zoom_inout_invoke(C, op, event, 0); +} + +void CLIP_OT_view_zoom_in(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom In"; + ot->idname= "CLIP_OT_view_zoom_in"; + + /* api callbacks */ + ot->exec= view_zoom_in_exec; + ot->invoke= view_zoom_in_invoke; + ot->poll= ED_space_clip_poll; +} + +static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return view_zoom_inout_invoke(C, op, event, 1); +} + +void CLIP_OT_view_zoom_out(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom Out"; + ot->idname= "CLIP_OT_view_zoom_out"; + + /* api callbacks */ + ot->exec= view_zoom_out_exec; + ot->invoke= view_zoom_out_invoke; + ot->poll= ED_space_clip_poll; +} + +/********************** view zoom ratio operator *********************/ + +static int view_zoom_ratio_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sclip_zoom_set(sc, ar, RNA_float_get(op->ptr, "ratio")); + + /* ensure pixel exact locations for draw */ + sc->xof= (int)sc->xof; + sc->yof= (int)sc->yof; + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_zoom_ratio(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Zoom Ratio"; + ot->idname= "CLIP_OT_view_zoom_ratio"; + + /* api callbacks */ + ot->exec= view_zoom_ratio_exec; + ot->poll= ED_space_clip_poll; + + /* properties */ + RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); +} + +/********************** view all operator *********************/ + +static int view_all_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc; + ARegion *ar; + int w, h, width, height; + float aspx, aspy; + + /* retrieve state */ + sc= CTX_wm_space_clip(C); + ar= CTX_wm_region(C); + + ED_space_clip_size(sc, &w, &h); + ED_space_clip_aspect(sc, &aspx, &aspy); + + w= w*aspx; + h= h*aspy; + + /* check if the image will fit in the image with zoom==1 */ + width= ar->winrct.xmax - ar->winrct.xmin + 1; + height= ar->winrct.ymax - ar->winrct.ymin + 1; + + if((w >= width || h >= height) && (width > 0 && height > 0)) { + float zoomx, zoomy; + + /* find the zoom value that will fit the image in the image space */ + zoomx= (float)width/w; + zoomy= (float)height/h; + sclip_zoom_set(sc, ar, 1.0f/power_of_2(1/MIN2(zoomx, zoomy))); + } + else + sclip_zoom_set(sc, ar, 1.0f); + + sc->xof= sc->yof= 0.0f; + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View All"; + ot->idname= "CLIP_OT_view_all"; + + /* api callbacks */ + ot->exec= view_all_exec; + ot->poll= ED_space_clip_poll; +} + +/********************** view selected operator *********************/ + +static int view_selected_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + ARegion *ar= CTX_wm_region(C); + + sc->xlockof= 0.0f; + sc->ylockof= 0.0f; + + ED_clip_view_selection(sc, ar, 1); + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_view_selected(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "View Selected"; + ot->idname= "CLIP_OT_view_selected"; + + /* api callbacks */ + ot->exec= view_selected_exec; + ot->poll= ED_space_clip_poll; +} + +/********************** change frame operator *********************/ + +static int change_frame_poll(bContext *C) +{ + /* prevent changes during render */ + if(G.rendering) + return 0; + + return ED_space_clip_poll(C); +} + +static void change_frame_apply(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + + /* set the new frame number */ + CFRA= RNA_int_get(op->ptr, "frame"); + FRAMENUMBER_MIN_CLAMP(CFRA); + SUBFRA = 0.0f; + + /* do updates */ + sound_seek_scene(CTX_data_main(C), CTX_data_scene(C)); + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); +} + +static int change_frame_exec(bContext *C, wmOperator *op) +{ + change_frame_apply(C, op); + + return OPERATOR_FINISHED; +} + +static int frame_from_event(bContext *C, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + Scene *scene= CTX_data_scene(C); + int framenr= 0; + + if(ar->regiontype == RGN_TYPE_WINDOW) { + float sfra= SFRA, efra= EFRA, framelen= ar->winx/(efra-sfra+1); + + framenr= sfra+event->mval[0]/framelen; + } else { + float viewx, viewy; + + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &viewx, &viewy); + + framenr= (int)floor(viewx+0.5f); + } + + return framenr; +} + +static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + ARegion *ar= CTX_wm_region(C); + + if(ar->regiontype == RGN_TYPE_WINDOW) { + if(event->mval[1]>16) + return OPERATOR_PASS_THROUGH; + } + + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + + change_frame_apply(C, op); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + switch (event->type) { + case ESCKEY: + return OPERATOR_FINISHED; + + case MOUSEMOVE: + RNA_int_set(op->ptr, "frame", frame_from_event(C, event)); + change_frame_apply(C, op); + break; + + case LEFTMOUSE: + case RIGHTMOUSE: + if (event->val==KM_RELEASE) + return OPERATOR_FINISHED; + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void CLIP_OT_change_frame(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change frame"; + ot->idname= "CLIP_OT_change_frame"; + ot->description= "Interactively change the current frame number"; + + /* api callbacks */ + ot->exec= change_frame_exec; + ot->invoke= change_frame_invoke; + ot->modal= change_frame_modal; + ot->poll= change_frame_poll; + + /* flags */ + ot->flag= OPTYPE_BLOCKING|OPTYPE_UNDO; + + /* rna */ + RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); +} + +/********************** rebuild proxies operator *********************/ + +typedef struct ProxyBuildJob { + Scene *scene; + struct Main *main; + MovieClip *clip; +} ProxyJob; + +static void proxy_freejob(void *pjv) +{ + ProxyJob *pj= pjv; + + MEM_freeN(pj); +} + +/* only this runs inside thread */ +static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress) +{ + ProxyJob *pj= pjv; + Scene *scene=pj->scene; + MovieClip *clip= pj->clip; + struct MovieDistortion *distortion= NULL; + int cfra, undistort; + short tc_flag, size_flag, quality, build_flag; + int sfra= SFRA, efra= EFRA; + int build_sizes[4], build_count= 0; + + tc_flag= clip->proxy.build_tc_flag; + size_flag= clip->proxy.build_size_flag; + quality= clip->proxy.quality; + build_flag= clip->proxy.build_flag; + undistort= build_flag&MCLIP_PROXY_RENDER_UNDISTORT; + + if(clip->source == MCLIP_SRC_MOVIE) { + if(clip->anim) + IMB_anim_index_rebuild(clip->anim, tc_flag, size_flag, quality, stop, do_update, progress); + + if(!undistort) { + return; + } + else { + sfra= 1; + efra= IMB_anim_get_duration(clip->anim, IMB_TC_NONE); + } + } + + if(size_flag&IMB_PROXY_25) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_25; + if(size_flag&IMB_PROXY_50) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_50; + if(size_flag&IMB_PROXY_75) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_75; + if(size_flag&IMB_PROXY_100) build_sizes[build_count++]= MCLIP_PROXY_RENDER_SIZE_100; + + if(undistort) + distortion= BKE_tracking_distortion_create(); + + for(cfra= sfra; cfra<=efra; cfra++) { + if(clip->source != MCLIP_SRC_MOVIE) + BKE_movieclip_build_proxy_frame(clip, NULL, cfra, build_sizes, build_count, 0); + + if(undistort) + BKE_movieclip_build_proxy_frame(clip, distortion, cfra, build_sizes, build_count, 1); + + if(*stop || G.afbreek) + break; + + *do_update= 1; + *progress= ((float)cfra)/(efra-sfra); + } + + if(distortion) + BKE_tracking_distortion_destroy(distortion); +} + +static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) +{ + wmJob * steve; + ProxyJob *pj; + Scene *scene= CTX_data_scene(C); + ScrArea *sa= CTX_wm_area(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + + if((clip->flag&MCLIP_USE_PROXY)==0) + return OPERATOR_CANCELLED; + + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Building Proxies", WM_JOB_PROGRESS); + + pj= MEM_callocN(sizeof(ProxyJob), "proxy rebuild job"); + pj->scene= scene; + pj->main= CTX_data_main(C); + pj->clip= clip; + + WM_jobs_customdata(steve, pj, proxy_freejob); + WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|ND_DISPLAY, 0); + WM_jobs_callbacks(steve, proxy_startjob, NULL, NULL, NULL); + + G.afbreek= 0; + WM_jobs_start(CTX_wm_manager(C), steve); + + ED_area_tag_redraw(CTX_wm_area(C)); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_rebuild_proxy(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Rebuild Proxy and Timecode Indices"; + ot->idname= "CLIP_OT_rebuild_proxy"; + ot->description="Rebuild all selected proxies and timecode indeces using the job system"; + + /* api callbacks */ + ot->exec= sequencer_rebuild_proxy_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER; +} + +/********************** mode set operator *********************/ + +static int mode_set_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + int mode= RNA_enum_get(op->ptr, "mode"); + int toggle= RNA_boolean_get(op->ptr, "toggle"); + + if(sc->mode==mode) { + if(toggle) + sc->mode= SC_MODE_TRACKING; + } else { + sc->mode= mode; + } + + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CLIP, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_mode_set(wmOperatorType *ot) +{ + static EnumPropertyItem mode_items[] = { + {SC_MODE_TRACKING, "TRACKING", 0, "Tracking", "Show tracking and solving tools"}, + {SC_MODE_RECONSTRUCTION, "RECONSTRUCTION", 0, "Reconstruction", "Show tracking/reconstruction tools"}, + {SC_MODE_DISTORTION, "DISTORTION", 0, "Distortion", "Show distortion tools"}, + {0, NULL, 0, NULL, NULL}}; + + + /* identifiers */ + ot->name= "Set Clip Mode"; + ot->description = "Sets the clip interaction mode"; + ot->idname= "CLIP_OT_mode_set"; + + /* api callbacks */ + ot->exec= mode_set_exec; + + ot->poll= ED_space_clip_poll; + + /* properties */ + RNA_def_enum(ot->srna, "mode", mode_items, SC_MODE_TRACKING, "Mode", ""); + RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", ""); +} + +/********************** macroses *********************/ + +void ED_operatormacros_clip(void) +{ + wmOperatorType *ot; + wmOperatorTypeMacro *otmacro; + + ot= WM_operatortype_append_macro("CLIP_OT_add_marker_move", "Add Marker and Move", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new marker and move it on movie"; + WM_operatortype_macro_define(ot, "CLIP_OT_add_marker"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_struct_idprops_unset(otmacro->ptr, "release_confirm"); + + ot= WM_operatortype_append_macro("CLIP_OT_add_marker_slide", "Add Marker and Slide", OPTYPE_UNDO|OPTYPE_REGISTER); + ot->description = "Add new marker and slide it with mouse until mouse button release"; + WM_operatortype_macro_define(ot, "CLIP_OT_add_marker"); + otmacro= WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_boolean_set(otmacro->ptr, "release_confirm", 1); +} diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c new file mode 100644 index 00000000000..c8113c5ea7b --- /dev/null +++ b/source/blender/editors/space_clip/clip_toolbar.c @@ -0,0 +1,244 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_header.c + * \ingroup spclip + */ + +#include + +#include "DNA_windowmanager_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_screen.h" + +#include "ED_screen.h" +#include "ED_util.h" + +#include "WM_types.h" +#include "WM_api.h" + +#include "UI_interface.h" +#include "UI_resources.h" + +/* ************************ header area region *********************** */ + +/************************** properties ******************************/ + +static ARegion *clip_has_properties_region(ScrArea *sa) +{ + ARegion *ar, *arnew; + + ar= BKE_area_find_region_type(sa, RGN_TYPE_UI); + if(ar) + return ar; + + /* add subdiv level; after header */ + ar= BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + + /* is error! */ + if(ar==NULL) + return NULL; + + arnew= MEM_callocN(sizeof(ARegion), "clip properties region"); + + BLI_insertlinkafter(&sa->regionbase, ar, arnew); + arnew->regiontype= RGN_TYPE_UI; + arnew->alignment= RGN_ALIGN_RIGHT; + + arnew->flag= RGN_FLAG_HIDDEN; + + return arnew; +} + +static int properties_poll(bContext *C) +{ + return (CTX_wm_space_clip(C) != NULL); +} + +static int properties_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= clip_has_properties_region(sa); + + if(ar) + ED_region_toggle_hidden(C, ar); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_properties(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Properties"; + ot->description= "Toggle clip properties panel"; + ot->idname= "CLIP_OT_properties"; + + /* api callbacks */ + ot->exec= properties_exec; + ot->poll= properties_poll; +} + +/************************** tools ******************************/ + +static ARegion *clip_has_tools_region(ScrArea *sa) +{ + ARegion *ar, *artool=NULL, *arprops=NULL, *arhead; + + for(ar= sa->regionbase.first; ar; ar= ar->next) { + if(ar->regiontype==RGN_TYPE_TOOLS) + artool= ar; + if(ar->regiontype==RGN_TYPE_TOOL_PROPS) + arprops= ar; + } + + /* tool region hide/unhide also hides props */ + if(arprops && artool) + return artool; + + if(artool==NULL) { + /* add subdiv level; after header */ + arhead= BKE_area_find_region_type(sa, RGN_TYPE_HEADER); + + /* is error! */ + if(arhead==NULL) + return NULL; + + artool= MEM_callocN(sizeof(ARegion), "clip tools region"); + + BLI_insertlinkafter(&sa->regionbase, arhead, artool); + artool->regiontype= RGN_TYPE_TOOLS; + artool->alignment= RGN_ALIGN_LEFT; + + artool->flag= RGN_FLAG_HIDDEN; + } + + if(arprops==NULL) { + /* add extra subdivided region for tool properties */ + arprops= MEM_callocN(sizeof(ARegion), "tool props for clip"); + + BLI_insertlinkafter(&sa->regionbase, artool, arprops); + arprops->regiontype= RGN_TYPE_TOOL_PROPS; + arprops->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV; + } + + return artool; +} + +static int tools_poll(bContext *C) +{ + return (CTX_wm_space_clip(C) != NULL); +} + +static int tools_exec(bContext *C, wmOperator *UNUSED(op)) +{ + ScrArea *sa= CTX_wm_area(C); + ARegion *ar= clip_has_tools_region(sa); + + if(ar) + ED_region_toggle_hidden(C, ar); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_tools(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Tools"; + ot->description= "Toggle clip tools panel"; + ot->idname= "CLIP_OT_tools"; + + /* api callbacks */ + ot->exec= tools_exec; + ot->poll= tools_poll; +} + +/************************** redo panel ******************************/ + +static void clip_panel_operator_redo_buts(const bContext *C, Panel *pa, wmOperator *op) +{ + uiLayoutOperatorButs(C, pa->layout, op, NULL, 'V', 0); +} + +static void clip_panel_operator_redo_header(const bContext *C, Panel *pa) +{ + wmOperator *op= WM_operator_last_redo(C); + + if(op) BLI_strncpy(pa->drawname, op->type->name, sizeof(pa->drawname)); + else BLI_strncpy(pa->drawname, "Operator", sizeof(pa->drawname)); +} + +static void clip_panel_operator_redo_operator(const bContext *C, Panel *pa, wmOperator *op) +{ + if(op->type->flag & OPTYPE_MACRO) { + for(op= op->macro.first; op; op= op->next) { + uiItemL(pa->layout, op->type->name, ICON_NONE); + clip_panel_operator_redo_operator(C, pa, op); + } + } + else { + clip_panel_operator_redo_buts(C, pa, op); + } +} + +static void clip_panel_operator_redo(const bContext *C, Panel *pa) +{ + wmOperator *op= WM_operator_last_redo(C); + uiBlock *block; + + if(op==NULL) + return; + if(WM_operator_poll((bContext*)C, op->type) == 0) + return; + + block= uiLayoutGetBlock(pa->layout); + + if(ED_undo_valid(C, op->type->name)==0) + uiLayoutSetEnabled(pa->layout, 0); + + /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ + uiBlockSetHandleFunc(block, ED_undo_operator_repeat_cb_evt, op); + + clip_panel_operator_redo_operator(C, pa, op); +} + +void ED_clip_tool_props_register(ARegionType *art) +{ + PanelType *pt; + + pt= MEM_callocN(sizeof(PanelType), "spacetype clip panel last operator"); + strcpy(pt->idname, "CLIP_PT_last_operator"); + strcpy(pt->label, "Operator"); + pt->draw_header= clip_panel_operator_redo_header; + pt->draw= clip_panel_operator_redo; + BLI_addtail(&art->paneltypes, pt); +} diff --git a/source/blender/editors/space_clip/clip_utils.c b/source/blender/editors/space_clip/clip_utils.c new file mode 100644 index 00000000000..649b278ab3d --- /dev/null +++ b/source/blender/editors/space_clip/clip_utils.c @@ -0,0 +1,219 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/clip_utils.c + * \ingroup spclip + */ + +#include "DNA_object_types.h" /* SELECT */ + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" + +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" +#include "BKE_depsgraph.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +void clip_graph_tracking_values_iterate_track(SpaceClip *sc, MovieTrackingTrack *track, void *userdata, + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end) (void *userdata)) +{ + MovieClip *clip= ED_space_clip(sc); + int width, height, coord; + + BKE_movieclip_get_size(clip, &sc->user, &width, &height); + + for(coord= 0; coord<2; coord++) { + int i, open= 0, prevfra= 0; + float prevval= 0.0f; + + for(i= 0; imarkersnr; i++) { + MovieTrackingMarker *marker= &track->markers[i]; + float val; + + if(marker->flag&MARKER_DISABLED) { + if(open) { + if(segment_end) + segment_end(userdata); + + open= 0; + } + + continue; + } + + if(!open) { + if(segment_start) + segment_start(userdata, track, coord); + + open= 1; + prevval= marker->pos[coord]; + } + + /* value is a pixels per frame speed */ + val= (marker->pos[coord] - prevval) * ((i==0) ? (width) : (height)); + val/= marker->framenr-prevfra; + + if(func) + func(userdata, track, marker, coord, val); + + prevval= marker->pos[coord]; + prevfra= marker->framenr; + } + + if(open) { + if(segment_end) + segment_end(userdata); + } + } +} + +void clip_graph_tracking_values_iterate(SpaceClip *sc, void *userdata, + void (*func) (void *userdata, MovieTrackingTrack *track, MovieTrackingMarker *marker, int coord, float val), + void (*segment_start) (void *userdata, MovieTrackingTrack *track, int coord), + void (*segment_end) (void *userdata)) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + + track= tracking->tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + clip_graph_tracking_values_iterate_track(sc, track, userdata, func, segment_start, segment_end); + } + + track= track->next; + } +} + +void clip_graph_tracking_iterate(SpaceClip *sc, void *userdata, + void (*func) (void *userdata, MovieTrackingMarker *marker)) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + + track= tracking->tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + int i; + + for(i= 0; imarkersnr; i++) { + MovieTrackingMarker *marker= &track->markers[i]; + + if(marker->flag&MARKER_DISABLED) + continue; + + if(func) + func(userdata, marker); + } + } + + track= track->next; + } +} + +void clip_delete_track(bContext *C, MovieClip *clip, MovieTrackingTrack *track) +{ + MovieTracking *tracking= &clip->tracking; + MovieTrackingStabilization *stab= &tracking->stabilization; + + int has_bundle= 0, update_stab= 0; + + if(track==tracking->act_track) + tracking->act_track= NULL; + + if(track==stab->rot_track) { + stab->rot_track= NULL; + + update_stab= 1; + } + + /* handle reconstruction display in 3d viewport */ + if(track->flag&TRACK_HAS_BUNDLE) + has_bundle= 1; + + BKE_tracking_free_track(track); + BLI_freelinkN(&tracking->tracks, track); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + if(update_stab) { + tracking->stabilization.ok= 0; + + DAG_id_tag_update(&clip->id, 0); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + } + + if(has_bundle) + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL); +} + +void clip_delete_marker(bContext *C, MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker) +{ + if(track->markersnr==1) { + clip_delete_track(C, clip, track); + } + else { + BKE_tracking_delete_marker(track, marker->framenr); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + } +} + +void clip_view_center_to_point(SpaceClip *sc, float x, float y) +{ + int width, height; + float aspx, aspy; + + ED_space_clip_size(sc, &width, &height); + ED_space_clip_aspect(sc, &aspx, &aspy); + + sc->xof= (x-0.5f)*width*aspx; + sc->yof= (y-0.5f)*height*aspy; +} diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c new file mode 100644 index 00000000000..c8577f7760e --- /dev/null +++ b/source/blender/editors/space_clip/space_clip.c @@ -0,0 +1,949 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/space_clip.c + * \ingroup spclip + */ + +#include +#include + +#include "DNA_scene_types.h" +#include "DNA_movieclip_types.h" + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BKE_main.h" +#include "BKE_context.h" +#include "BKE_screen.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "IMB_imbuf_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_transform.h" + +#include "IMB_imbuf.h" + +#include "BIF_gl.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "UI_view2d.h" + +#include "RNA_access.h" + + +#include "clip_intern.h" // own include + +static void init_preview_region(const bContext *C, ARegion *ar) +{ + Scene *scene= CTX_data_scene(C); + + ar->regiontype= RGN_TYPE_PREVIEW; + ar->alignment= RGN_ALIGN_TOP; + ar->flag|= RGN_FLAG_HIDDEN; + + ar->v2d.tot.xmin= 0.0f; + ar->v2d.tot.ymin= (float)scene->r.sfra - 10.0f; + ar->v2d.tot.xmax= (float)scene->r.efra; + ar->v2d.tot.ymax= 10.0f; + + ar->v2d.cur= ar->v2d.tot; + + ar->v2d.min[0]= FLT_MIN; + ar->v2d.min[1]= FLT_MIN; + + ar->v2d.max[0]= MAXFRAMEF; + ar->v2d.max[1]= FLT_MAX; + + ar->v2d.scroll= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL); + ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL); + + ar->v2d.keeptot= 0; +} + +static ARegion *clip_has_preview_region(const bContext *C, ScrArea *sa) +{ + ARegion *ar, *arnew; + + ar= BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW); + if(ar) + return ar; + + /* add subdiv level; after header */ + ar= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + + /* is error! */ + if(ar==NULL) + return NULL; + + arnew= MEM_callocN(sizeof(ARegion), "clip preview region"); + + BLI_insertlinkbefore(&sa->regionbase, ar, arnew); + init_preview_region(C, arnew); + + return arnew; +} + +static void clip_scopes_tag_refresh(ScrArea *sa) +{ + SpaceClip *sc= (SpaceClip *)sa->spacedata.first; + ARegion *ar; + + if(sc->mode!=SC_MODE_TRACKING) + return; + + /* only while proeprties are visible */ + for (ar=sa->regionbase.first; ar; ar=ar->next) { + if (ar->regiontype == RGN_TYPE_UI && ar->flag & RGN_FLAG_HIDDEN) + return; + } + + sc->scopes.ok= 0; +} + +static void clip_stabilization_tag_refresh(ScrArea *sa) +{ + SpaceClip *sc= (SpaceClip *)sa->spacedata.first; + MovieClip *clip= ED_space_clip(sc); + + if(clip) { + MovieTrackingStabilization *stab= &clip->tracking.stabilization; + + stab->ok= 0; + } +} + +/* ******************** default callbacks for clip space ***************** */ + +static SpaceLink *clip_new(const bContext *C) +{ + ARegion *ar; + SpaceClip *sc; + + sc= MEM_callocN(sizeof(SpaceClip), "initclip"); + sc->spacetype= SPACE_CLIP; + sc->flag= SC_SHOW_MARKER_PATTERN|SC_SHOW_TRACK_PATH|SC_SHOW_GPENCIL|SC_MANUAL_CALIBRATION|SC_SHOW_GRAPH_TRACKS|SC_SHOW_GRAPH_FRAMES; + sc->zoom= 1.0f; + sc->path_length= 20; + sc->scopes.track_preview_height= 120; + + /* header */ + ar= MEM_callocN(sizeof(ARegion), "header for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype= RGN_TYPE_HEADER; + ar->alignment= RGN_ALIGN_BOTTOM; + + /* tools view */ + ar= MEM_callocN(sizeof(ARegion), "tools for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype= RGN_TYPE_TOOLS; + ar->alignment= RGN_ALIGN_LEFT; + + /* tool properties */ + ar= MEM_callocN(sizeof(ARegion), "tool properties for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype= RGN_TYPE_TOOL_PROPS; + ar->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV; + + /* properties view */ + ar= MEM_callocN(sizeof(ARegion), "properties for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype= RGN_TYPE_UI; + ar->alignment= RGN_ALIGN_RIGHT; + + /* preview view */ + ar= MEM_callocN(sizeof(ARegion), "preview for clip"); + + BLI_addtail(&sc->regionbase, ar); + init_preview_region(C, ar); + + /* main area */ + ar= MEM_callocN(sizeof(ARegion), "main area for clip"); + + BLI_addtail(&sc->regionbase, ar); + ar->regiontype= RGN_TYPE_WINDOW; + + return (SpaceLink *)sc; +} + +/* not spacelink itself */ +static void clip_free(SpaceLink *sl) +{ + SpaceClip *sc= (SpaceClip*) sl; + + sc->clip= NULL; + + if(sc->scopes.track_preview) + IMB_freeImBuf(sc->scopes.track_preview); +} + +/* spacetype; init callback */ +static void clip_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) +{ + +} + +static SpaceLink *clip_duplicate(SpaceLink *sl) +{ + SpaceClip *scn= MEM_dupallocN(sl); + + /* clear or remove stuff from old */ + scn->scopes.track_preview= NULL; + scn->scopes.ok= 0; + + return (SpaceLink *)scn; +} + +static void clip_listener(ScrArea *sa, wmNotifier *wmn) +{ + /* context changes */ + switch(wmn->category) { + case NC_SCENE: + switch(wmn->data) { + case ND_FRAME: + clip_scopes_tag_refresh(sa); + /* no break! */ + + case ND_FRAME_RANGE: + ED_area_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + } + break; + case NC_MOVIECLIP: + switch(wmn->data) { + case ND_DISPLAY: + case ND_SELECT: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + } + switch(wmn->action) { + case NA_REMOVED: + case NA_EDITED: + case NA_EVALUATED: + clip_stabilization_tag_refresh(sa); + /* no break! */ + + case NA_SELECTED: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + } + break; + case NC_GEOM: + switch(wmn->data) { + case ND_SELECT: + clip_scopes_tag_refresh(sa); + ED_area_tag_redraw(sa); + break; + } + break; + case NC_SCREEN: + if(wmn->data==ND_ANIMPLAY) { + ED_area_tag_redraw(sa); + } + break; + case NC_SPACE: + if(wmn->data==ND_SPACE_CLIP) { + clip_scopes_tag_refresh(sa); + clip_stabilization_tag_refresh(sa); + ED_area_tag_redraw(sa); + } + break; + } +} + +static void clip_operatortypes(void) +{ + /* ** clip_ops.c ** */ + WM_operatortype_append(CLIP_OT_open); + WM_operatortype_append(CLIP_OT_reload); + WM_operatortype_append(CLIP_OT_view_pan); + WM_operatortype_append(CLIP_OT_view_zoom); + WM_operatortype_append(CLIP_OT_view_zoom_in); + WM_operatortype_append(CLIP_OT_view_zoom_out); + WM_operatortype_append(CLIP_OT_view_zoom_ratio); + WM_operatortype_append(CLIP_OT_view_all); + WM_operatortype_append(CLIP_OT_view_selected); + WM_operatortype_append(CLIP_OT_change_frame); + WM_operatortype_append(CLIP_OT_rebuild_proxy); + WM_operatortype_append(CLIP_OT_mode_set); + + /* ** clip_toolbar.c ** */ + WM_operatortype_append(CLIP_OT_tools); + WM_operatortype_append(CLIP_OT_properties); + + /* ** tracking_ops.c ** */ + + /* navigation */ + WM_operatortype_append(CLIP_OT_frame_jump); + + /* foorage */ + WM_operatortype_append(CLIP_OT_set_center_principal); + + /* selection */ + WM_operatortype_append(CLIP_OT_select); + WM_operatortype_append(CLIP_OT_select_all); + WM_operatortype_append(CLIP_OT_select_border); + WM_operatortype_append(CLIP_OT_select_circle); + WM_operatortype_append(CLIP_OT_select_grouped); + + /* markers */ + WM_operatortype_append(CLIP_OT_add_marker); + WM_operatortype_append(CLIP_OT_slide_marker); + WM_operatortype_append(CLIP_OT_delete_track); + WM_operatortype_append(CLIP_OT_delete_marker); + + /* track */ + WM_operatortype_append(CLIP_OT_track_markers); + + /* solving */ + WM_operatortype_append(CLIP_OT_solve_camera); + WM_operatortype_append(CLIP_OT_clear_solution); + + WM_operatortype_append(CLIP_OT_disable_markers); + WM_operatortype_append(CLIP_OT_hide_tracks); + WM_operatortype_append(CLIP_OT_hide_tracks_clear); + WM_operatortype_append(CLIP_OT_lock_tracks); + + /* orientation */ + WM_operatortype_append(CLIP_OT_set_origin); + WM_operatortype_append(CLIP_OT_set_floor); + WM_operatortype_append(CLIP_OT_set_axis); + WM_operatortype_append(CLIP_OT_set_scale); + + /* detect */ + WM_operatortype_append(CLIP_OT_detect_features); + + /* stabilization */ + WM_operatortype_append(CLIP_OT_stabilize_2d_add); + WM_operatortype_append(CLIP_OT_stabilize_2d_remove); + WM_operatortype_append(CLIP_OT_stabilize_2d_select); + WM_operatortype_append(CLIP_OT_stabilize_2d_set_rotation); + + /* clean-up */ + WM_operatortype_append(CLIP_OT_clear_track_path); + WM_operatortype_append(CLIP_OT_join_tracks); + WM_operatortype_append(CLIP_OT_track_copy_color); + + WM_operatortype_append(CLIP_OT_clean_tracks); + + /* graph editing */ + WM_operatortype_append(CLIP_OT_graph_select); + WM_operatortype_append(CLIP_OT_graph_delete_curve); + WM_operatortype_append(CLIP_OT_graph_delete_knot); +} + +static void clip_keymap(struct wmKeyConfig *keyconf) +{ + wmKeyMap *keymap; + wmKeyMapItem *kmi; + + /* ******** Global hotkeys avalaible for all regions ******** */ + + keymap= WM_keymap_find(keyconf, "Clip", SPACE_CLIP, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_open", OKEY, KM_PRESS, KM_ALT, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_tools", TKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_properties", NKEY, KM_PRESS, 0, 0); + + /* 2d tracking */ + kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", LEFTARROWKEY, KM_PRESS, KM_ALT, 0); + RNA_boolean_set(kmi->ptr, "backwards", 1); + WM_keymap_add_item(keymap, "CLIP_OT_track_markers", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0); + kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "sequence", 1); + kmi= WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "backwards", 1); + RNA_boolean_set(kmi->ptr, "sequence", 1); + + /* mode */ + kmi= WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", SC_MODE_RECONSTRUCTION); + RNA_boolean_set(kmi->ptr, "toggle", 1); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "mode", SC_MODE_DISTORTION); + RNA_boolean_set(kmi->ptr, "toggle", 1); + + /* ******** Hotkeys avalaible for main region only ******** */ + + keymap= WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0); + + /* ** View/navigation ** */ + + WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MOUSEPAN, 0, 0, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0); + + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f); + RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f); + + WM_keymap_add_item(keymap, "CLIP_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); + + /* jump to special frame */ + kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "position", 0); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "position", 1); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "position", 2); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "position", 3); + + /* "timeline" */ + WM_keymap_add_item(keymap, "CLIP_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0); + + /* selection */ + WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0); + RNA_enum_set(WM_keymap_add_item(keymap, "CLIP_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "action", SEL_INVERT); + WM_keymap_add_item(keymap, "CLIP_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_select_circle", CKEY, KM_PRESS, 0, 0); + WM_keymap_add_menu(keymap, "CLIP_MT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0); + + /* marker */ + WM_keymap_add_item(keymap, "CLIP_OT_add_marker_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "action", 2); /* toggle */ + + /* tracks */ + WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "action", 0); /* lock */ + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "action", 1); /* unlock */ + + WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0); + + kmi= WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", 1); + + WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0); + + /* clean-up */ + kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0); + RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED); + kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO); + kmi= WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL); + + WM_keymap_add_item(keymap, "CLIP_OT_join_tracks", JKEY, KM_PRESS, KM_CTRL, 0); + + /* menus */ + WM_keymap_add_menu(keymap, "CLIP_MT_tracking_specials", WKEY, KM_PRESS, 0, 0); + + /* display */ + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.lock_selection"); + + kmi= WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.use_mute_footage"); + + transform_keymap_for_space(keyconf, keymap, SPACE_CLIP); + + /* ******** Hotkeys avalaible for preview region only ******** */ + + keymap= WM_keymap_find(keyconf, "Clip Graph Editor", SPACE_CLIP, 0); + + /* "timeline" */ + WM_keymap_add_item(keymap, "CLIP_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0); + + /* selection */ + WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, 0, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "extend", 1); + + /* delete */ + WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", DELKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", XKEY, KM_PRESS, 0, 0); + + WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", DELKEY, KM_PRESS, KM_SHIFT, 0); + WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", XKEY, KM_PRESS, KM_SHIFT, 0); +} + +const char *clip_context_dir[]= {"edit_movieclip", NULL}; + +static int clip_context(const bContext *C, const char *member, bContextDataResult *result) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + if(CTX_data_dir(member)) { + CTX_data_dir_set(result, clip_context_dir); + return 1; + } + else if(CTX_data_equals(member, "edit_movieclip")) { + CTX_data_id_pointer_set(result, &sc->clip->id); + return 1; + } + + return 0; +} + +static void clip_refresh(const bContext *C, ScrArea *sa) +{ + wmWindowManager *wm= CTX_wm_manager(C); + wmWindow *window= CTX_wm_window(C); + SpaceClip *sc= (SpaceClip *)sa->spacedata.first; + ARegion *ar_main= BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + ARegion *ar_preview= clip_has_preview_region(C, sa); + int view_changed= 0; + + switch (sc->view) { + case SC_VIEW_CLIP: + if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) { + ar_preview->flag |= RGN_FLAG_HIDDEN; + ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; + WM_event_remove_handlers((bContext*)C, &ar_preview->handlers); + view_changed= 1; + } + if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { + ar_main->alignment= RGN_ALIGN_NONE; + view_changed= 1; + } + if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) { + ar_preview->alignment= RGN_ALIGN_NONE; + view_changed= 1; + } + break; + case SC_VIEW_GRAPH: + if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) { + ar_preview->flag &= ~RGN_FLAG_HIDDEN; + ar_preview->v2d.flag &= ~V2D_IS_INITIALISED; + ar_preview->v2d.cur = ar_preview->v2d.tot; + view_changed= 1; + } + if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) { + ar_main->alignment= RGN_ALIGN_NONE; + view_changed= 1; + } + if (ar_preview && ar_preview->alignment != RGN_ALIGN_TOP) { + ar_preview->alignment= RGN_ALIGN_TOP; + view_changed= 1; + } + break; + } + + if(view_changed) { + ED_area_initialize(wm, window, sa); + ED_area_tag_redraw(sa); + } + + BKE_movieclip_user_set_frame(&sc->user, CTX_data_scene(C)->r.cfra); +} + +/********************* main region ********************/ + +/* sets up the fields of the View2D from zoom and offset */ +static void movieclip_main_area_set_view2d(SpaceClip *sc, ARegion *ar) +{ + MovieClip *clip= ED_space_clip(sc); + float x1, y1, w, h; + int width, height, winx, winy; + + ED_space_clip_size(sc, &width, &height); + + w= width; + h= height; + + if(clip) + h*= clip->aspy/clip->aspx/clip->tracking.camera.pixel_aspect; + + winx= ar->winrct.xmax - ar->winrct.xmin + 1; + winy= ar->winrct.ymax - ar->winrct.ymin + 1; + + ar->v2d.tot.xmin= 0; + ar->v2d.tot.ymin= 0; + ar->v2d.tot.xmax= w; + ar->v2d.tot.ymax= h; + + ar->v2d.mask.xmin= ar->v2d.mask.ymin= 0; + ar->v2d.mask.xmax= winx; + ar->v2d.mask.ymax= winy; + + /* which part of the image space do we see? */ + x1= ar->winrct.xmin+(winx-sc->zoom*w)/2.0f; + y1= ar->winrct.ymin+(winy-sc->zoom*h)/2.0f; + + x1-= sc->zoom*sc->xof; + y1-= sc->zoom*sc->yof; + + /* relative display right */ + ar->v2d.cur.xmin= ((ar->winrct.xmin - (float)x1)/sc->zoom); + ar->v2d.cur.xmax= ar->v2d.cur.xmin + ((float)winx/sc->zoom); + + /* relative display left */ + ar->v2d.cur.ymin= ((ar->winrct.ymin-(float)y1)/sc->zoom); + ar->v2d.cur.ymax= ar->v2d.cur.ymin + ((float)winy/sc->zoom); + + /* normalize 0.0..1.0 */ + ar->v2d.cur.xmin /= w; + ar->v2d.cur.xmax /= w; + ar->v2d.cur.ymin /= h; + ar->v2d.cur.ymax /= h; +} + +/* add handlers, stuff you only do once or on area/region changes */ +static void clip_main_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy); + + /* own keymap */ + keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + + keymap= WM_keymap_find(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); +} + +static void clip_main_area_draw(const bContext *C, ARegion *ar) +{ + /* draw entirely, view changes should be handled here */ + SpaceClip *sc= CTX_wm_space_clip(C); + Scene *scene= CTX_data_scene(C); + MovieClip *clip= ED_space_clip(sc); + + /* if trcking is in progress, we should sunchronize framenr from clipuser + so latest tracked frame would be shown */ + if(clip && clip->tracking_context) + BKE_tracking_sync_user(&sc->user, clip->tracking_context); + + if(sc->flag&SC_LOCK_SELECTION) { + ImBuf *tmpibuf= NULL; + + if(clip && clip->tracking.stabilization.flag&TRACKING_2D_STABILIZATION) { + tmpibuf= ED_space_clip_get_stable_buffer(sc, NULL, NULL, NULL); + } + + if(ED_clip_view_selection(sc, ar, 0)) { + sc->xof+= sc->xlockof; + sc->yof+= sc->ylockof; + } + + if(tmpibuf) + IMB_freeImBuf(tmpibuf); + } + + /* clear and setup matrix */ + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + + /* data... */ + movieclip_main_area_set_view2d(sc, ar); + + clip_draw_main(sc, ar, scene); + + /* Grease Pencil */ + clip_draw_grease_pencil((bContext *)C, 1); + + /* reset view matrix */ + UI_view2d_view_restore(C); + + /* draw Grease Pencil - screen space only */ + clip_draw_grease_pencil((bContext *)C, 0); +} + +static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch(wmn->category) { + case NC_SCREEN: + if (wmn->data==ND_GPENCIL) + ED_region_tag_redraw(ar); + break; + } +} + +/****************** preview region ******************/ + +static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); + + /* own keymap */ + keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); + + keymap= WM_keymap_find(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0); + WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); +} + +static void clip_preview_area_draw(const bContext *C, ARegion *ar) +{ + View2D *v2d= &ar->v2d; + View2DScrollers *scrollers; + SpaceClip *sc= CTX_wm_space_clip(C); + Scene *scene= CTX_data_scene(C); + short unitx= V2D_UNIT_FRAMESCALE, unity= V2D_UNIT_VALUES; + + /* clear and setup matrix */ + UI_ThemeClearColor(TH_BACK); + glClear(GL_COLOR_BUFFER_BIT); + + UI_view2d_view_ortho(v2d); + + /* data... */ + clip_draw_graph(sc, ar, scene); + + /* reset view matrix */ + UI_view2d_view_restore(C); + + /* scrollers */ + scrollers= UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP); + UI_view2d_scrollers_draw(C, v2d, scrollers); + UI_view2d_scrollers_free(scrollers); +} + +static void clip_preview_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) +{ +} + +/****************** header region ******************/ + +/* add handlers, stuff you only do once or on area/region changes */ +static void clip_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) +{ + ED_region_header_init(ar); +} + +static void clip_header_area_draw(const bContext *C, ARegion *ar) +{ + ED_region_header(C, ar); +} + +/****************** tools region ******************/ + +/* add handlers, stuff you only do once or on area/region changes */ +static void clip_tools_area_init(wmWindowManager *wm, ARegion *ar) +{ + ED_region_panels_init(wm, ar); +} + +static void clip_tools_area_draw(const bContext *C, ARegion *ar) +{ + ED_region_panels(C, ar, 1, NULL, -1); +} + +/****************** tool properties region ******************/ + +static void clip_props_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch(wmn->category) { + case NC_WM: + if(wmn->data == ND_HISTORY) + ED_region_tag_redraw(ar); + break; + case NC_SCENE: + if(wmn->data == ND_MODE) + ED_region_tag_redraw(ar); + break; + case NC_SPACE: + if(wmn->data == ND_SPACE_CLIP) + ED_region_tag_redraw(ar); + break; + case NC_SCREEN: + if(wmn->data == ND_GPENCIL) + ED_region_tag_redraw(ar); + break; + } +} + +/****************** properties region ******************/ + +/* add handlers, stuff you only do once or on area/region changes */ +static void clip_properties_area_init(wmWindowManager *wm, ARegion *ar) +{ + wmKeyMap *keymap; + + ED_region_panels_init(wm, ar); + + keymap= WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); +} + +static void clip_properties_area_draw(const bContext *C, ARegion *ar) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + BKE_movieclip_update_scopes(sc->clip, &sc->user, &sc->scopes); + + ED_region_panels(C, ar, 1, NULL, -1); +} + +static void clip_properties_area_listener(ARegion *ar, wmNotifier *wmn) +{ + /* context changes */ + switch(wmn->category) { + case NC_SCREEN: + if (wmn->data==ND_GPENCIL) + ED_region_tag_redraw(ar); + break; + case NC_BRUSH: + if(wmn->action==NA_EDITED) + ED_region_tag_redraw(ar); + break; + } +} + +/********************* registration ********************/ + +/* only called once, from space/spacetypes.c */ +void ED_spacetype_clip(void) +{ + SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype clip"); + ARegionType *art; + + st->spaceid= SPACE_CLIP; + strncpy(st->name, "Clip", BKE_ST_MAXNAME); + + st->new= clip_new; + st->free= clip_free; + st->init= clip_init; + st->duplicate= clip_duplicate; + st->operatortypes= clip_operatortypes; + st->keymap= clip_keymap; + st->listener= clip_listener; + st->context= clip_context; + st->refresh= clip_refresh; + + /* regions: main window */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip region"); + art->regionid= RGN_TYPE_WINDOW; + art->init= clip_main_area_init; + art->draw= clip_main_area_draw; + art->listener= clip_main_area_listener; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_GPENCIL; + + BLI_addhead(&st->regiontypes, art); + + /* preview */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip region preview"); + art->regionid = RGN_TYPE_PREVIEW; + art->prefsizey = 240; + art->init= clip_preview_area_init; + art->draw= clip_preview_area_draw; + art->listener= clip_preview_area_listener; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_VIEW2D; + + BLI_addhead(&st->regiontypes, art); + + /* regions: properties */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip region properties"); + art->regionid= RGN_TYPE_UI; + art->prefsizex= UI_COMPACT_PANEL_WIDTH; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI; + art->init= clip_properties_area_init; + art->draw= clip_properties_area_draw; + art->listener= clip_properties_area_listener; + BLI_addhead(&st->regiontypes, art); + ED_clip_buttons_register(art); + + /* regions: tools */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip region tools"); + art->regionid= RGN_TYPE_TOOLS; + art->prefsizex= UI_COMPACT_PANEL_WIDTH; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI; + art->listener= clip_props_area_listener; + art->init= clip_tools_area_init; + art->draw= clip_tools_area_draw; + + BLI_addhead(&st->regiontypes, art); + + /* tool properties */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip tool properties region"); + art->regionid = RGN_TYPE_TOOL_PROPS; + art->prefsizex= 0; + art->prefsizey= 120; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI; + art->listener= clip_props_area_listener; + art->init= clip_tools_area_init; + art->draw= clip_tools_area_draw; + ED_clip_tool_props_register(art); + + BLI_addhead(&st->regiontypes, art); + + /* regions: header */ + art= MEM_callocN(sizeof(ARegionType), "spacetype clip region"); + art->regionid= RGN_TYPE_HEADER; + art->prefsizey= HEADERY; + art->keymapflag= ED_KEYMAP_FRAMES|ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_HEADER; + + art->init= clip_header_area_init; + art->draw= clip_header_area_draw; + + BLI_addhead(&st->regiontypes, art); + + BKE_spacetype_register(st); +} diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c new file mode 100644 index 00000000000..aab7188c069 --- /dev/null +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -0,0 +1,2940 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_clip/tracking_ops.c + * \ingroup spclip + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_camera_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_object_types.h" /* SELECT */ +#include "DNA_scene_types.h" + +#include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" +#include "BLI_blenlib.h" + +#include "BKE_main.h" +#include "BKE_context.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" +#include "BKE_global.h" +#include "BKE_depsgraph.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_scene.h" +#include "BKE_library.h" +#include "BKE_sound.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_screen.h" +#include "ED_clip.h" +#include "ED_keyframing.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#include "UI_interface.h" + +#include "RNA_access.h" +#include "RNA_define.h" + +#include "PIL_time.h" + +#include "UI_view2d.h" + +#include "clip_intern.h" // own include + +static int space_clip_frame_poll(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + + if(sc) { + MovieClip *clip= ED_space_clip(sc); + + if(clip) + return BKE_movieclip_has_frame(clip, &sc->user); + } + + return 0; +} + +static int space_clip_frame_camera_poll(bContext *C) +{ + Scene *scene= CTX_data_scene(C); + + if(space_clip_frame_poll(C)) { + return scene->camera != NULL; + } + + return 0; +} + +static int space_clip_camera_poll(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + Scene *scene= CTX_data_scene(C); + + if(sc && sc->clip && scene->camera) + return 1; + + return 0; +} + +/********************** add marker operator *********************/ + +static void add_marker(SpaceClip *sc, float x, float y) +{ + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int width, height; + + ED_space_clip_size(sc, &width, &height); + + track= BKE_tracking_add_track(&clip->tracking, x, y, sc->user.framenr, width, height); + + BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, 0); + + clip->tracking.act_track= track; +} + +static int add_marker_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + float pos[2]; + int width, height; + + ED_space_clip_size(sc, &width, &height); + if(!width || !height) + return OPERATOR_CANCELLED; + + RNA_float_get_array(op->ptr, "location", pos); + + add_marker(sc, pos[0], pos[1]); + + /* reset offset from locked position, so frame jumping wouldn't be so confusing */ + sc->xlockof= 0; + sc->ylockof= 0; + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +static int add_marker_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + + ED_clip_mouse_pos(C, event, co); + + RNA_float_set_array(op->ptr, "location", co); + + return add_marker_exec(C, op); +} + +void CLIP_OT_add_marker(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Marker"; + ot->idname= "CLIP_OT_add_marker"; + ot->description= "Place new marker at specified location"; + + /* api callbacks */ + ot->invoke= add_marker_invoke; + ot->exec= add_marker_exec; + ot->poll= space_clip_frame_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + "Location", "Location of marker on frame", -1.0f, 1.0f); +} + +/********************** delete track operator *********************/ + +static int delete_track_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track= tracking->tracks.first, *next; + + while(track) { + next= track->next; + + if(TRACK_VIEW_SELECTED(sc, track)) + clip_delete_track(C, clip, track); + + track= next; + } + + /* nothing selected now, unlock view so it can be scrolled nice again */ + sc->flag&= ~SC_LOCK_SELECTION; + + return OPERATOR_FINISHED; +} + +void CLIP_OT_delete_track(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Track"; + ot->idname= "CLIP_OT_delete_track"; + ot->description= "Delete selected tracks"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= delete_track_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** delete marker operator *********************/ + +static int delete_marker_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track= clip->tracking.tracks.first, *next; + int framenr= sc->user.framenr; + int has_selection= 0; + + while(track) { + next= track->next; + + if(TRACK_VIEW_SELECTED(sc, track)) { + MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, framenr); + + if(marker) { + has_selection|= track->markersnr>1; + + clip_delete_marker(C, clip, track, marker); + } + } + + track= next; + } + + if(!has_selection) { + /* nothing selected now, unlock view so it can be scrolled nice again */ + sc->flag&= ~SC_LOCK_SELECTION; + } + + return OPERATOR_FINISHED; +} + +void CLIP_OT_delete_marker(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Delete Marker"; + ot->idname= "CLIP_OT_delete_marker"; + ot->description= "Delete marker for current frame from selected tracks"; + + /* api callbacks */ + ot->invoke= WM_operator_confirm; + ot->exec= delete_marker_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** slide marker operator *********************/ + +#define SLIDE_ACTION_POS 0 +#define SLIDE_ACTION_SIZE 1 +#define SLIDE_ACTION_OFFSET 2 + +typedef struct { + int area, action; + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + + int mval[2]; + int width, height; + float *min, *max, *pos, *offset; + float smin[2], smax[2], spos[2], soff[2]; + float (*smarkers)[2]; + + int lock, accurate; +} SlideMarkerData; + +static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track, + MovieTrackingMarker *marker, wmEvent *event, int area, int action, int width, int height) +{ + SlideMarkerData *data= MEM_callocN(sizeof(SlideMarkerData), "slide marker data"); + + marker= BKE_tracking_ensure_marker(track, sc->user.framenr); + + data->area= area; + data->action= action; + data->track= track; + data->marker= marker; + + if(area==TRACK_AREA_POINT) { + data->pos= marker->pos; + data->offset= track->offset; + copy_v2_v2(data->spos, marker->pos); + copy_v2_v2(data->soff, track->offset); + } else if(area==TRACK_AREA_PAT) { + if(action==SLIDE_ACTION_SIZE) { + data->min= track->pat_min; + data->max= track->pat_max; + } else { + int a; + + data->pos= marker->pos; + data->offset= track->offset; + + copy_v2_v2(data->soff, track->offset); + + data->smarkers= MEM_callocN(sizeof(*data->smarkers)*track->markersnr, "slide marekrs"); + for(a= 0; amarkersnr; a++) + copy_v2_v2(data->smarkers[a], track->markers[a].pos); + } + } else if(area==TRACK_AREA_SEARCH) { + data->min= track->search_min; + data->max= track->search_max; + } + + if(area==TRACK_AREA_SEARCH || (area==TRACK_AREA_PAT && action!=SLIDE_ACTION_OFFSET)) { + copy_v2_v2(data->smin, data->min); + copy_v2_v2(data->smax, data->max); + } + + data->mval[0]= event->mval[0]; + data->mval[1]= event->mval[1]; + + data->width= width; + data->height= height; + + if(action==SLIDE_ACTION_SIZE) + data->lock= 1; + + return data; +} + +/* corner = 0: right-bottom corner, + corner = 1: left-top corner */ +static int mouse_on_corner(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, + int area, float co[2], int corner, int width, int height) +{ + int inside= 0; + float size= 12.0f; + float min[2], max[2]; + float crn[2], dx, dy, tdx, tdy; + + if(area==TRACK_AREA_SEARCH) { + copy_v2_v2(min, track->search_min); + copy_v2_v2(max, track->search_max); + } else { + copy_v2_v2(min, track->pat_min); + copy_v2_v2(max, track->pat_max); + } + + dx= size/width/sc->zoom; + dy= size/height/sc->zoom; + + tdx= 5.0f/width/sc->zoom; + tdy= 5.0f/height/sc->zoom; + + dx= MIN2(dx, (max[0]-min[0])/6.0f) + tdx; + dy= MIN2(dy, (max[1]-min[1])/6.0f) + tdy; + + if(corner==0) { + crn[0]= marker->pos[0]+max[0]; + crn[1]= marker->pos[1]+min[1]; + + inside= co[0]>=crn[0]-dx && co[0]<=crn[0]+tdx && co[1]>=crn[1]-tdy && co[1]<=crn[1]+dy; + } else { + crn[0]= marker->pos[0]+min[0]; + crn[1]= marker->pos[1]+max[1]; + + inside= co[0]>=crn[0]-dx && co[0]<=crn[0]+dx && co[1]>=crn[1]-dy && co[1]<=crn[1]+dy; + } + + return inside; +} + +static int mouse_on_offset(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker, + float co[2], int width, int height) +{ + float pos[2], dx, dy; + + add_v2_v2v2(pos, marker->pos, track->offset); + + dx= 12.0f/width/sc->zoom; + dy= 12.0f/height/sc->zoom; + + dx=MIN2(dx, (track->pat_max[0]-track->pat_min[0])/2.0f); + dy=MIN2(dy, (track->pat_max[1]-track->pat_min[1])/2.0f); + + return co[0]>=pos[0]-dx && co[0]<=pos[0]+dx && co[1]>=pos[1]-dy && co[1]<=pos[1]+dy; +} + +static void hide_cursor(bContext *C) +{ + wmWindow *win= CTX_wm_window(C); + + WM_cursor_set(win, CURSOR_NONE); +} + +static void show_cursor(bContext *C) +{ + wmWindow *win= CTX_wm_window(C); + + WM_cursor_set(win, CURSOR_STD); +} + +static void *slide_marker_customdata(bContext *C, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int width, height; + float co[2]; + void *customdata= NULL; + + ED_space_clip_size(sc, &width, &height); + + if(width==0 || height==0) + return NULL; + + ED_clip_mouse_pos(C, event, co); + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); + + if((marker->flag&MARKER_DISABLED)==0) { + if(!customdata) + if(mouse_on_offset(sc, track, marker, co, width, height)) + customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_POINT, SLIDE_ACTION_POS, width, height); + + if(sc->flag&SC_SHOW_MARKER_SEARCH) { + if(mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 1, width, height)) + customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, SLIDE_ACTION_OFFSET, width, height); + else if(mouse_on_corner(sc, track, marker, TRACK_AREA_SEARCH, co, 0, width, height)) + customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_SEARCH, SLIDE_ACTION_SIZE, width, height); + } + + if(!customdata && sc->flag&SC_SHOW_MARKER_PATTERN) { + if(mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 1, width, height)) + customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, SLIDE_ACTION_OFFSET, width, height); + + if(!customdata && mouse_on_corner(sc, track, marker, TRACK_AREA_PAT, co, 0, width, height)) + customdata= create_slide_marker_data(sc, track, marker, event, TRACK_AREA_PAT, SLIDE_ACTION_SIZE, width, height); + } + + if(customdata) + break; + } + } + + track= track->next; + } + + return customdata; +} + +static int slide_marker_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + SlideMarkerData *slidedata= slide_marker_customdata(C, event); + + if(slidedata) { + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + + tracking->act_track= slidedata->track; + + op->customdata= slidedata; + + hide_cursor(C); + WM_event_add_modal_handler(C, op); + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_PASS_THROUGH; +} + +static void cancel_mouse_slide(SlideMarkerData *data) +{ + /* cancel sliding */ + if(data->area == TRACK_AREA_POINT) { + if(data->action==SLIDE_ACTION_OFFSET) + copy_v2_v2(data->offset, data->soff); + else + copy_v2_v2(data->pos, data->spos); + } else { + if(data->action==SLIDE_ACTION_SIZE) { + copy_v2_v2(data->min, data->smin); + copy_v2_v2(data->max, data->smax); + } else { + int a; + + for(a= 0; atrack->markersnr; a++) + copy_v2_v2(data->track->markers[a].pos, data->smarkers[a]); + + copy_v2_v2(data->offset, data->soff); + } + } +} + +static void free_slide_data(SlideMarkerData *data) +{ + if(data->smarkers) MEM_freeN(data->smarkers); + MEM_freeN(data); +} + +static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + SlideMarkerData *data= (SlideMarkerData *)op->customdata; + float dx, dy, mdelta[2]; + + switch(event->type) { + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if(data->action==SLIDE_ACTION_SIZE) + if(ELEM(event->type, LEFTCTRLKEY, RIGHTCTRLKEY)) + data->lock= event->val==KM_RELEASE; + + if(ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) + data->accurate= event->val==KM_PRESS; + + /* no break! update area size */ + + case MOUSEMOVE: + mdelta[0]= event->mval[0]-data->mval[0]; + mdelta[1]= event->mval[1]-data->mval[1]; + + dx= mdelta[0]/data->width/sc->zoom; + + if(data->lock) dy= -dx/data->height*data->width; + else dy= mdelta[1]/data->height/sc->zoom; + + if(data->accurate) { + dx/= 5; + dy/= 5; + } + + if(data->area==TRACK_AREA_POINT) { + if(data->action==SLIDE_ACTION_OFFSET) { + data->offset[0]= data->soff[0]+dx; + data->offset[1]= data->soff[1]+dy; + } else { + data->pos[0]= data->spos[0]+dx; + data->pos[1]= data->spos[1]+dy; + + data->marker->flag&= ~MARKER_TRACKED; + } + + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + DAG_id_tag_update(&sc->clip->id, 0); + } else { + if(data->action==SLIDE_ACTION_SIZE) { + data->min[0]= data->smin[0]-dx; + data->max[0]= data->smax[0]+dx; + + data->min[1]= data->smin[1]+dy; + data->max[1]= data->smax[1]-dy; + + if(data->area==TRACK_AREA_SEARCH) BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_DIM); + else BKE_tracking_clamp_track(data->track, CLAMP_PAT_DIM); + } else { + float d[2]={dx, dy}; + + if(data->area==TRACK_AREA_SEARCH) { + add_v2_v2v2(data->min, data->smin, d); + add_v2_v2v2(data->max, data->smax, d); + } else { + int a; + + for(a= 0; atrack->markersnr; a++) + add_v2_v2v2(data->track->markers[a].pos, data->smarkers[a], d); + + sub_v2_v2v2(data->offset, data->soff, d); + } + + if(data->area==TRACK_AREA_SEARCH) + BKE_tracking_clamp_track(data->track, CLAMP_SEARCH_POS); + } + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL); + + break; + + case LEFTMOUSE: + if(event->val==KM_RELEASE) { + free_slide_data(op->customdata); + + show_cursor(C); + + return OPERATOR_FINISHED; + } + + break; + + case ESCKEY: + cancel_mouse_slide(op->customdata); + + free_slide_data(op->customdata); + + show_cursor(C); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL); + + return OPERATOR_CANCELLED; + } + + return OPERATOR_RUNNING_MODAL; +} + +void CLIP_OT_slide_marker(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Slide Marker"; + ot->description= "Slide marker areas"; + ot->idname= "CLIP_OT_slide_marker"; + + /* api callbacks */ + ot->poll= space_clip_frame_poll; + ot->invoke= slide_marker_invoke; + ot->modal= slide_marker_modal; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_GRAB_POINTER|OPTYPE_BLOCKING; + + /* properties */ + RNA_def_float_vector(ot->srna, "offset", 2, NULL, -FLT_MAX, FLT_MAX, + "Offset", "Offset in floating point units, 1.0 is the width and height of the image", -FLT_MAX, FLT_MAX); +} + +/********************** mouse select operator *********************/ + +static int mouse_on_side(float co[2], float x1, float y1, float x2, float y2, float epsx, float epsy) +{ + if(x1>x2) SWAP(float, x1, x2); + if(y1>y2) SWAP(float, y1, y2); + + return (co[0]>=x1-epsx && co[0]<=x2+epsx) && (co[1]>=y1-epsy && co[1]<=y2+epsy); +} + +static int mouse_on_rect(float co[2], float pos[2], float min[2], float max[2], float epsx, float epsy) +{ + return mouse_on_side(co, pos[0]+min[0], pos[1]+min[1], pos[0]+max[0], pos[1]+min[1], epsx, epsy) || + mouse_on_side(co, pos[0]+min[0], pos[1]+min[1], pos[0]+min[0], pos[1]+max[1], epsx, epsy) || + mouse_on_side(co, pos[0]+min[0], pos[1]+max[1], pos[0]+max[0], pos[1]+max[1], epsx, epsy) || + mouse_on_side(co, pos[0]+max[0], pos[1]+min[1], pos[0]+max[0], pos[1]+max[1], epsx, epsy); +} + +static int track_mouse_area(SpaceClip *sc, float co[2], MovieTrackingTrack *track) +{ + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); + float epsx, epsy; + int width, height; + + ED_space_clip_size(sc, &width, &height); + + epsx= MIN4(track->pat_min[0]-track->search_min[0], track->search_max[0]-track->pat_max[0], + fabsf(track->pat_min[0]), fabsf(track->pat_max[0])) / 2; + epsy= MIN4(track->pat_min[1]-track->search_min[1], track->search_max[1]-track->pat_max[1], + fabsf(track->pat_min[1]), fabsf(track->pat_max[1])) / 2; + + epsx= MAX2(epsy, 2.0f / width); + epsy= MAX2(epsy, 2.0f / height); + + if(sc->flag&SC_SHOW_MARKER_SEARCH) + if(mouse_on_rect(co, marker->pos, track->search_min, track->search_max, epsx, epsy)) + return TRACK_AREA_SEARCH; + + if((marker->flag&MARKER_DISABLED)==0) { + if(sc->flag&SC_SHOW_MARKER_PATTERN) + if(mouse_on_rect(co, marker->pos, track->pat_min, track->pat_max, epsx, epsy)) + return TRACK_AREA_PAT; + + epsx= 12.0f/width; + epsy= 12.0f/height; + + if(fabsf(co[0]-marker->pos[0]-track->offset[0])< epsx && fabsf(co[1]-marker->pos[1]-track->offset[1])<=epsy) + return TRACK_AREA_POINT; + } + + return TRACK_AREA_NONE; +} + +static float dist_to_rect(float co[2], float pos[2], float min[2], float max[2]) +{ + float d1, d2, d3, d4; + float p[2]= {co[0]-pos[0], co[1]-pos[1]}; + float v1[2]= {min[0], min[1]}, v2[2]= {max[0], min[1]}, + v3[2]= {max[0], max[1]}, v4[2]= {min[0], max[1]}; + + d1= dist_to_line_segment_v2(p, v1, v2); + d2= dist_to_line_segment_v2(p, v2, v3); + d3= dist_to_line_segment_v2(p, v3, v4); + d4= dist_to_line_segment_v2(p, v4, v1); + + return MIN4(d1, d2, d3, d4); +} + +static MovieTrackingTrack *find_nearest_track(SpaceClip *sc, MovieClip *clip, float co[2]) +{ + MovieTrackingTrack *track= NULL, *cur; + float mindist= 0.0f; + + cur= clip->tracking.tracks.first; + while(cur) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(cur, sc->user.framenr); + + if(((cur->flag&TRACK_HIDDEN)==0) && MARKER_VISIBLE(sc, marker)) { + float dist, d1, d2=FLT_MAX, d3=FLT_MAX; + + d1= sqrtf((co[0]-marker->pos[0]-cur->offset[0])*(co[0]-marker->pos[0]-cur->offset[0])+ + (co[1]-marker->pos[1]-cur->offset[1])*(co[1]-marker->pos[1]-cur->offset[1])); /* distance to marker point */ + + /* distance to pattern boundbox */ + if(sc->flag&SC_SHOW_MARKER_PATTERN) + d2= dist_to_rect(co, marker->pos, cur->pat_min, cur->pat_max); + + /* distance to search boundbox */ + if(sc->flag&SC_SHOW_MARKER_SEARCH) + d3= dist_to_rect(co, marker->pos, cur->search_min, cur->search_max); + + /* choose minimal distance. useful for cases of overlapped markers. */ + dist= MIN3(d1, d2, d3); + + if(track==NULL || distnext; + } + + return track; +} + +static int mouse_select(bContext *C, float co[2], int extend) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *act_track= tracking->act_track; + MovieTrackingTrack *track= NULL; /* selected marker */ + + track= find_nearest_track(sc, clip, co); + + if(track) { + int area= track_mouse_area(sc, co, track); + + if(!extend || !TRACK_VIEW_SELECTED(sc, track)) + area= TRACK_AREA_ALL; + + if(extend && TRACK_AREA_SELECTED(track, area)) { + if(track==act_track) + BKE_tracking_deselect_track(track, area); + else + clip->tracking.act_track= track; + } else { + if(area==TRACK_AREA_POINT) + area= TRACK_AREA_ALL; + + BKE_tracking_select_track(tracking, track, area, extend); + clip->tracking.act_track= track; + } + } + + if(!extend) { + sc->xlockof= 0.0f; + sc->ylockof= 0.0f; + } + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +static int select_exec(bContext *C, wmOperator *op) +{ + float co[2]; + int extend; + + RNA_float_get_array(op->ptr, "location", co); + extend= RNA_boolean_get(op->ptr, "extend"); + + return mouse_select(C, co, extend); +} + +static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + float co[2]; + int extend= RNA_boolean_get(op->ptr, "extend"); + + if(!extend) { + SlideMarkerData *slidedata= slide_marker_customdata(C, event); + + if(slidedata) { + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + + clip->tracking.act_track= slidedata->track; + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + MEM_freeN(slidedata); + + return OPERATOR_PASS_THROUGH; + } + } + + ED_clip_mouse_pos(C, event, co); + RNA_float_set_array(op->ptr, "location", co); + + return select_exec(C, op); +} + +void CLIP_OT_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select"; + ot->description= "Select tracking markers"; + ot->idname= "CLIP_OT_select"; + + /* api callbacks */ + ot->exec= select_exec; + ot->invoke= select_invoke; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "extend", 0, + "Extend", "Extend selection rather than clearing the existing selection"); + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, + "Location", "Mouse location in normalized coordinates, 0.0 to 1.0 is within the image bounds", -100.0f, 100.0f); +} + +/********************** border select operator *********************/ + +static int border_select_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + rcti rect; + rctf rectf; + int change= 0, mode; + + /* get rectangle from operator */ + rect.xmin= RNA_int_get(op->ptr, "xmin"); + rect.ymin= RNA_int_get(op->ptr, "ymin"); + rect.xmax= RNA_int_get(op->ptr, "xmax"); + rect.ymax= RNA_int_get(op->ptr, "ymax"); + + ED_clip_point_stable_pos(C, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); + ED_clip_point_stable_pos(C, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); + + mode= RNA_int_get(op->ptr, "gesture_mode"); + + /* do actual selection */ + track= clip->tracking.tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); + + if(MARKER_VISIBLE(sc, marker) && BLI_in_rctf(&rectf, marker->pos[0], marker->pos[1])) { + BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode!=GESTURE_MODAL_SELECT); + + change= 1; + } + } + + track= track->next; + } + + if(change) { + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_select_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Border Select"; + ot->description= "Select markers using border selection"; + ot->idname= "CLIP_OT_select_border"; + + /* api callbacks */ + ot->invoke= WM_border_select_invoke; + ot->exec= border_select_exec; + ot->modal= WM_border_select_modal; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_gesture_border(ot, FALSE); +} + +/********************** circle select operator *********************/ + +static int marker_inside_ellipse(MovieTrackingMarker *marker, float offset[2], float ellipse[2]) +{ + /* normalized ellipse: ell[0] = scaleX, ell[1] = scaleY */ + float x, y; + + x= (marker->pos[0] - offset[0])*ellipse[0]; + y= (marker->pos[1] - offset[1])*ellipse[1]; + + return x*x + y*y < 1.0f; +} + +static int circle_select_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + ARegion *ar= CTX_wm_region(C); + MovieTrackingTrack *track; + int x, y, radius, width, height, mode, change= 0; + float zoomx, zoomy, offset[2], ellipse[2]; + + /* get operator properties */ + x= RNA_int_get(op->ptr, "x"); + y= RNA_int_get(op->ptr, "y"); + radius= RNA_int_get(op->ptr, "radius"); + + mode= RNA_int_get(op->ptr, "gesture_mode"); + + /* compute ellipse and position in unified coordinates */ + ED_space_clip_size(sc, &width, &height); + ED_space_clip_zoom(sc, ar, &zoomx, &zoomy); + + ellipse[0]= width*zoomx/radius; + ellipse[1]= height*zoomy/radius; + + ED_clip_point_stable_pos(C, x, y, &offset[0], &offset[1]); + + /* do selection */ + track= clip->tracking.tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, sc->user.framenr); + + if(MARKER_VISIBLE(sc, marker) && marker_inside_ellipse(marker, offset, ellipse)) { + BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, mode!=GESTURE_MODAL_SELECT); + + change= 1; + } + } + + track= track->next; + } + + if(change) { + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; + } + + return OPERATOR_CANCELLED; +} + +void CLIP_OT_select_circle(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Circle Select"; + ot->description= "Select markers using circle selection"; + ot->idname= "CLIP_OT_select_circle"; + + /* api callbacks */ + ot->invoke= WM_gesture_circle_invoke; + ot->modal= WM_gesture_circle_modal; + ot->exec= circle_select_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 0, INT_MIN, INT_MAX, "Radius", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX); +} + +/********************** select all operator *********************/ + +static int select_all_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track= NULL; /* selected track */ + int action= RNA_enum_get(op->ptr, "action"); + int framenr= sc->user.framenr; + int has_selection= 0; + + if(action == SEL_TOGGLE){ + action= SEL_SELECT; + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + action= SEL_DESELECT; + break; + } + + track= track->next; + } + } + + track= clip->tracking.tracks.first; + while(track) { + if((track->flag&TRACK_HIDDEN)==0) { + MovieTrackingMarker *marker= BKE_tracking_get_marker(track, framenr); + + if(marker && MARKER_VISIBLE(sc, marker)) { + switch (action) { + case SEL_SELECT: + track->flag|= SELECT; + track->pat_flag|= SELECT; + track->search_flag|= SELECT; + break; + case SEL_DESELECT: + track->flag&= ~SELECT; + track->pat_flag&= ~SELECT; + track->search_flag&= ~SELECT; + break; + case SEL_INVERT: + track->flag^= SELECT; + track->pat_flag^= SELECT; + track->search_flag^= SELECT; + break; + } + } + } + + if(TRACK_VIEW_SELECTED(sc, track)) + has_selection= 1; + + track= track->next; + } + + if(!has_selection) + sc->flag&= ~SC_LOCK_SELECTION; + + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select or Deselect All"; + ot->description= "Change selection of all tracking markers"; + ot->idname= "CLIP_OT_select_all"; + + /* api callbacks */ + ot->exec= select_all_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +/********************** select grouped operator *********************/ + +static int select_groped_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + int group= RNA_enum_get(op->ptr, "group"); + + track= clip->tracking.tracks.first; + while(track) { + int ok= 0; + + marker= BKE_tracking_get_marker(track, sc->user.framenr); + + if(group==0) { /* Keyframed */ + ok= marker->framenr==sc->user.framenr && (marker->flag&MARKER_TRACKED)==0; + } + else if(group==1) { /* Estimated */ + ok= marker->framenr!=sc->user.framenr; + } + else if(group==2) { /* tracked */ + ok= marker->framenr==sc->user.framenr && (marker->flag&MARKER_TRACKED); + } + else if(group==3) { /* locked */ + ok= track->flag&TRACK_LOCKED; + } + else if(group==4) { /* disabled */ + ok= marker->flag&MARKER_DISABLED; + } + else if(group==5) { /* color */ + if(clip->tracking.act_track) { + ok= (track->flag&TRACK_CUSTOMCOLOR) == (clip->tracking.act_track->flag&TRACK_CUSTOMCOLOR); + + if(ok && track->flag&TRACK_CUSTOMCOLOR) + ok= equals_v3v3(track->color, clip->tracking.act_track->color); + } + } + else if(group==6) { /* failed */ + ok= (track->flag&TRACK_HAS_BUNDLE) == 0; + } + + if(ok) { + track->flag|= SELECT; + if(sc->flag&SC_SHOW_MARKER_PATTERN) track->pat_flag|= SELECT;; + if(sc->flag&SC_SHOW_MARKER_SEARCH) track->search_flag|= SELECT;; + } + + track= track->next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_select_grouped(wmOperatorType *ot) +{ + static EnumPropertyItem select_group_items[] = { + {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, + {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, + {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, + {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, + {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, + {5, "COLOR", 0, "Tracks with same color", "Select all tracks with same color as actiev track"}, + {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Select Grouped"; + ot->description= "Joint Selected Tracks"; + ot->idname= "CLIP_OT_select_grouped"; + + /* api callbacks */ + ot->exec= select_groped_exec; + ot->poll= space_clip_frame_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* proeprties */ + RNA_def_enum(ot->srna, "group", select_group_items, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute"); +} + +/********************** track operator *********************/ + +typedef struct TrackMarkersJob { + struct MovieTrackingContext *context; /* tracking context */ + int sfra, efra, lastfra; /* Start, end and recently tracked frames */ + int backwards; /* Backwards tracking flag */ + MovieClip *clip; /* Clip which is tracking */ + float delay; /* Delay in milliseconds to allow tracking at fixed FPS */ + + struct Main *main; + struct Scene *scene; + struct bScreen *screen; +} TrackMarkersJob; + +static int track_markers_testbreak(void) +{ + return G.afbreek; +} + +static int track_count_markers(SpaceClip *sc, MovieClip *clip) +{ + int tot= 0; + MovieTrackingTrack *track; + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) + tot++; + + track= track->next; + } + + return tot; +} + +static void track_init_markers(SpaceClip *sc, MovieClip *clip) +{ + MovieTrackingTrack *track; + int framenr= sc->user.framenr, hidden= 0; + + if((sc->flag&SC_SHOW_MARKER_PATTERN)==0) hidden|= TRACK_AREA_PAT; + if((sc->flag&SC_SHOW_MARKER_SEARCH)==0) hidden|= TRACK_AREA_SEARCH; + + track= clip->tracking.tracks.first; + while(track) { + if(hidden) + BKE_tracking_track_flag(track, hidden, SELECT, 1); + + if(TRACK_SELECTED(track)) { + if((track->flag&TRACK_HIDDEN)==0 && (track->flag&TRACK_LOCKED)==0) + BKE_tracking_ensure_marker(track, framenr); + } + + track= track->next; + } +} + +static int track_markers_check_direction(int backwards, int curfra, int efra) +{ + if(backwards) { + if(curfraefra) return 0; + } + + return 1; +} + +static int track_markers_initjob(bContext *C, TrackMarkersJob *tmj, int backwards) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + Scene *scene= CTX_data_scene(C); + MovieTrackingSettings *settings= &clip->tracking.settings; + + tmj->sfra= sc->user.framenr; + tmj->clip= clip; + tmj->backwards= backwards; + + if(backwards) tmj->efra= SFRA; + else tmj->efra= EFRA; + + /* limit frames to be tracked by user setting */ + if(settings->frames_limit) { + if(backwards) tmj->efra= MAX2(tmj->efra, tmj->sfra-settings->frames_limit); + else tmj->efra= MIN2(tmj->efra, tmj->sfra+settings->frames_limit); + } + + if(settings->speed!=TRACKING_SPEED_FASTEST) { + tmj->delay= 1.0f/scene->r.frs_sec*1000.0f; + + if(settings->speed==TRACKING_SPEED_HALF) tmj->delay*= 2; + else if(settings->speed==TRACKING_SPEED_QUARTER) tmj->delay*= 4; + else if(settings->speed==TRACKING_SPEED_DOUBLE) tmj->delay/= 2; + } + + track_init_markers(sc, clip); + + tmj->context= BKE_tracking_context_new(clip, &sc->user, backwards, 1); + + clip->tracking_context= tmj->context; + + tmj->lastfra= tmj->sfra; + + /* XXX: silly to store this, but this data is needed to update scene and movieclip + frame numbers when tracking is finished. This introduces better feedback for artists. + Maybe there's another way to solve this problem, but can't think better way atm. + Anyway, this way isn't more unstable as animation rendering animation + which uses the same approach (except storing screen). */ + tmj->scene= scene; + tmj->main= CTX_data_main(C); + tmj->screen= CTX_wm_screen(C); + + return track_markers_check_direction(backwards, tmj->sfra, tmj->efra); +} + +static void track_markers_startjob(void *tmv, short *stop, short *do_update, float *progress) +{ + TrackMarkersJob *tmj= (TrackMarkersJob *)tmv; + int framenr= tmj->sfra; + //double t= PIL_check_seconds_timer(); + + while(framenr != tmj->efra) { + if(tmj->delay>0) { + /* tracking should happen with fixed fps. Calculate time + using current timer value before tracking frame and after. + + Small (and maybe unneeded optimization): do not calculate exec_time + for "Fastest" tracking */ + + double start_time= PIL_check_seconds_timer(), exec_time; + + if(!BKE_tracking_next(tmj->context)) + break; + + exec_time= PIL_check_seconds_timer()-start_time; + if(tmj->delay>exec_time) + PIL_sleep_ms(tmj->delay-exec_time); + } else if(!BKE_tracking_next(tmj->context)) + break; + + *do_update= 1; + *progress=(float)(framenr-tmj->sfra) / (tmj->efra-tmj->sfra); + + if(tmj->backwards) framenr--; + else framenr++; + + tmj->lastfra= framenr; + + if(*stop || track_markers_testbreak()) + break; + } + + //printf("Tracking time: %lf\n", PIL_check_seconds_timer()-t); +} + +static void track_markers_updatejob(void *tmv) +{ + TrackMarkersJob *tmj= (TrackMarkersJob *)tmv; + + BKE_tracking_sync(tmj->context); +} + +static void track_markers_freejob(void *tmv) +{ + TrackMarkersJob *tmj= (TrackMarkersJob *)tmv; + + tmj->clip->tracking_context= NULL; + tmj->scene->r.cfra= tmj->lastfra; + ED_update_for_newframe(tmj->main, tmj->scene, tmj->screen, 0); + + BKE_tracking_sync(tmj->context); + BKE_tracking_context_free(tmj->context); + + MEM_freeN(tmj); + + WM_main_add_notifier(NC_SCENE|ND_FRAME, tmj->scene); +} + +static int track_markers_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + Scene *scene= CTX_data_scene(C); + struct MovieTrackingContext *context; + int framenr= sc->user.framenr; + int sfra= framenr, efra; + int backwards= RNA_boolean_get(op->ptr, "backwards"); + int sequence= RNA_boolean_get(op->ptr, "sequence"); + MovieTrackingSettings *settings= &clip->tracking.settings; + + if(track_count_markers(sc, clip)==0) + return OPERATOR_CANCELLED; + + if(backwards) efra= SFRA; + else efra= EFRA; + + /* limit frames to be tracked by user setting */ + if(settings->frames_limit) { + if(backwards) efra= MAX2(efra, sfra-settings->frames_limit); + else efra= MIN2(efra, sfra+settings->frames_limit); + } + + if(!track_markers_check_direction(backwards, framenr, efra)) + return OPERATOR_CANCELLED; + + track_init_markers(sc, clip); + + /* do not disable tracks due to threshold when tracking frame-by-frame */ + context= BKE_tracking_context_new(clip, &sc->user, backwards, sequence); + + while(framenr != efra) { + if(!BKE_tracking_next(context)) + break; + + if(backwards) framenr--; + else framenr++; + + if(!sequence) + break; + } + + BKE_tracking_sync(context); + BKE_tracking_context_free(context); + + /* update scene current frame to the lastes tracked frame */ + scene->r.cfra= framenr; + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); + + return OPERATOR_FINISHED; +} + +static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + TrackMarkersJob *tmj; + ScrArea *sa= CTX_wm_area(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + wmJob *steve; + int backwards= RNA_boolean_get(op->ptr, "backwards"); + int sequence= RNA_boolean_get(op->ptr, "sequence"); + + if(clip->tracking_context) + return OPERATOR_CANCELLED; + + if(track_count_markers(sc, clip)==0) + return OPERATOR_CANCELLED; + + if(!sequence) + return track_markers_exec(C, op); + + tmj= MEM_callocN(sizeof(TrackMarkersJob), "TrackMarkersJob data"); + if(!track_markers_initjob(C, tmj, backwards)) { + track_markers_freejob(tmj); + + return OPERATOR_CANCELLED; + } + + /* setup job */ + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Track Markers", WM_JOB_PROGRESS); + WM_jobs_customdata(steve, tmj, track_markers_freejob); + + /* if there's delay set in tracking job, tracking should happen + with fixed FPS. To deal with editor refresh we have to syncronize + tracks from job and tracks in clip. Do this in timer callback + to prevent threading conflicts. */ + if(tmj->delay>0) WM_jobs_timer(steve, tmj->delay/1000.0f, NC_MOVIECLIP|NA_EVALUATED, 0); + else WM_jobs_timer(steve, 0.2, NC_MOVIECLIP|NA_EVALUATED, 0); + + WM_jobs_callbacks(steve, track_markers_startjob, NULL, track_markers_updatejob, NULL); + + G.afbreek= 0; + + WM_jobs_start(CTX_wm_manager(C), steve); + WM_cursor_wait(0); + + /* add modal handler for ESC */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event) +{ + /* no running blender, remove handler and pass through */ + if(0==WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C))) + return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH; + + /* running tracking */ + switch (event->type) { + case ESCKEY: + return OPERATOR_RUNNING_MODAL; + break; + } + + return OPERATOR_PASS_THROUGH; +} + +void CLIP_OT_track_markers(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Track Markers"; + ot->description= "Track selected markers"; + ot->idname= "CLIP_OT_track_markers"; + + /* api callbacks */ + ot->exec= track_markers_exec; + ot->invoke= track_markers_invoke; + ot->poll= space_clip_frame_poll; + ot->modal= track_markers_modal; + + /* flags */ + ot->flag= OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "backwards", 0, "Backwards", "Do backwards tracking"); + RNA_def_boolean(ot->srna, "sequence", 0, "Track Sequence", "Track marker during image sequence rather than single image"); +} + +/********************** solve camera operator *********************/ + +static int check_solve_track_count(MovieTracking *tracking) +{ + int tot= 0; + int frame1= tracking->settings.keyframe1, frame2= tracking->settings.keyframe2; + MovieTrackingTrack *track; + + track= tracking->tracks.first; + while(track) { + if(BKE_tracking_has_marker(track, frame1)) + if(BKE_tracking_has_marker(track, frame2)) + tot++; + + track= track->next; + } + + return tot>=8; +} + +static int solve_camera_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + Scene *scene= CTX_data_scene(C); + MovieTracking *tracking= &clip->tracking; + int width, height; + float error; + + if(!check_solve_track_count(tracking)) { + BKE_report(op->reports, RPT_ERROR, "At least 8 tracks on both of keyframes are needed for reconstruction"); + return OPERATOR_CANCELLED; + } + + /* could fail if footage uses images with different sizes */ + BKE_movieclip_get_size(clip, NULL, &width, &height); + + error= BKE_tracking_solve_reconstruction(tracking, width, height); + + if(error<0) + BKE_report(op->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details"); + else + BKE_reportf(op->reports, RPT_INFO, "Average reprojection error %.3f", error); + + scene->clip= clip; + id_us_plus(&clip->id); + + if(!scene->camera) + scene->camera= scene_find_camera(scene); + + if(scene->camera) { + /* set blender camera focal length so result would look fine there */ + Camera *camera= (Camera*)scene->camera->data; + + BKE_tracking_camera_to_blender(tracking, scene, camera, width, height); + + WM_event_add_notifier(C, NC_OBJECT, camera); + } + + DAG_id_tag_update(&clip->id, 0); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + /* update active clip displayed in scene buttons */ + WM_event_add_notifier(C, NC_SCENE, scene); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_solve_camera(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Solve Camera"; + ot->description= "Solve camera motion from tracks"; + ot->idname= "CLIP_OT_solve_camera"; + + /* api callbacks */ + ot->exec= solve_camera_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** clear solution operator *********************/ + +static int clear_solution_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track= tracking->tracks.first; + + while(track) { + track->flag&= ~TRACK_HAS_BUNDLE; + + track= track->next; + } + + if(tracking->reconstruction.cameras) + MEM_freeN(tracking->reconstruction.cameras); + + tracking->reconstruction.cameras= NULL; + tracking->reconstruction.camnr= 0; + + tracking->reconstruction.flag&= ~TRACKING_RECONSTRUCTED; + + DAG_id_tag_update(&clip->id, 0); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_clear_solution(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Clear Solution"; + ot->description= "Clear all calculated data"; + ot->idname= "CLIP_OT_clear_solution"; + + /* api callbacks */ + ot->exec= clear_solution_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** clear track operator *********************/ + +static int clear_track_path_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int action= RNA_enum_get(op->ptr, "action"); + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) + BKE_tracking_clear_path(track, sc->user.framenr, action); + + track= track->next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_clear_track_path(wmOperatorType *ot) +{ + static EnumPropertyItem clear_path_actions[] = { + {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"}, + {TRACK_CLEAR_REMAINED, "REMAINED", 0, "Clear remained", "Clear path at remained frames (after current)"}, + {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Clear Track Path"; + ot->description= "Clear path of selected tracks"; + ot->idname= "CLIP_OT_clear_track_path"; + + /* api callbacks */ + ot->exec= clear_track_path_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* proeprties */ + RNA_def_enum(ot->srna, "action", clear_path_actions, TRACK_CLEAR_REMAINED, "Action", "Clear action to execute"); +} + +/********************** disable markers operator *********************/ + +static int disable_markers_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track= tracking->tracks.first; + int action= RNA_enum_get(op->ptr, "action"); + + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { + MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr); + + if(action==0) marker->flag|= MARKER_DISABLED; + else if(action==1) marker->flag&= ~MARKER_DISABLED; + else marker->flag^= MARKER_DISABLED; + } + + track= track->next; + } + + DAG_id_tag_update(&clip->id, 0); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_disable_markers(wmOperatorType *ot) +{ + static EnumPropertyItem actions_items[] = { + {0, "DISABLE", 0, "Disable", "Disable selected markers"}, + {1, "ENABLE", 0, "Enable", "Enable selected markers"}, + {2, "TOGGLE", 0, "Toggle", "Toggle disabled flag for selected markers"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Disable Markers"; + ot->description= "Disable/enable selected markers"; + ot->idname= "CLIP_OT_disable_markers"; + + /* api callbacks */ + ot->exec= disable_markers_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Disable action to execute"); +} + +/********************** set origin operator *********************/ + +static int count_selected_bundles(bContext *C) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int tot= 0; + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_HAS_BUNDLE)) + tot++; + + track= track->next; + } + + return tot; +} + +static int set_origin_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + Scene *scene= CTX_data_scene(C); + Object *parent= scene->camera; + float mat[4][4], vec[3]; + + if(count_selected_bundles(C)!=1) { + BKE_report(op->reports, RPT_ERROR, "Track with bundle should be selected to define origin position"); + return OPERATOR_CANCELLED; + } + + if(scene->camera->parent) + parent= scene->camera->parent; + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) + break; + + track= track->next; + } + + BKE_get_tracking_mat(scene, NULL, mat); + mul_v3_m4v3(vec, mat, track->bundle_pos); + + sub_v3_v3(parent->loc, vec); + + DAG_id_tag_update(&clip->id, 0); + DAG_id_tag_update(&parent->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_set_origin(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Origin"; + ot->description= "Set active marker as origin by moving camera (or it's parent if present) in 3d space"; + ot->idname= "CLIP_OT_set_origin"; + + /* api callbacks */ + ot->exec= set_origin_exec; + ot->poll= space_clip_frame_camera_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** set floor operator *********************/ + +static void set_axis(Scene *scene, Object *ob, MovieTrackingTrack *track, char axis) +{ + float mat[4][4], vec[3], obmat[4][4]; + + BKE_get_tracking_mat(scene, NULL, mat); + mul_v3_m4v3(vec, mat, track->bundle_pos); + + if(len_v2(vec)<1e-3) + return; + + unit_m4(mat); + + if(axis=='X') { + if(fabsf(vec[1])<1e-3) { + mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f; + mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + } else { + copy_v3_v3(mat[0], vec); + mat[0][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + cross_v3_v3v3(mat[1], mat[2], mat[0]); + } + } else { + if(fabsf(vec[0])<1e-3) { + mat[0][0]= -1.0f; mat[0][1]= 0.0f; mat[0][2]= 0.0f; + mat[1][0]= 0.0f; mat[1][1]= -1.0f; mat[1][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + } else { + copy_v3_v3(mat[1], vec); + mat[1][2]= 0.0f; + mat[2][0]= 0.0f; mat[2][1]= 0.0f; mat[2][2]= 1.0f; + cross_v3_v3v3(mat[0], mat[1], mat[2]); + } + } + + normalize_v3(mat[0]); + normalize_v3(mat[1]); + normalize_v3(mat[2]); + + invert_m4(mat); + + object_to_mat4(ob, obmat); + mul_m4_m4m4(mat, obmat, mat); + object_apply_mat4(ob, mat, 0, 0); +} + +static int set_floor_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + Scene *scene= CTX_data_scene(C); + MovieTrackingTrack *track, *axis_track= NULL; + Object *camera= scene->camera; + Object *parent= camera; + int tot= 0; + float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3]= {0.0f, 0.0f, 0.0f}; + float rot[4][4]={{0.0f, 0.0f, -1.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f}}; /* 90 degrees Y-axis rotation matrix */ + + if(count_selected_bundles(C)!=3) { + BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor"); + return OPERATOR_CANCELLED; + } + + if(scene->camera->parent) + parent= scene->camera->parent; + + BKE_get_tracking_mat(scene, NULL, mat); + + /* get 3 bundles to use as reference */ + track= clip->tracking.tracks.first; + while(track && tot<3) { + if(track->flag&TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) { + mul_v3_m4v3(vec[tot], mat, track->bundle_pos); + + if(tot==0 || track==clip->tracking.act_track) + copy_v3_v3(orig, vec[tot]); + else + axis_track= track; + + tot++; + } + + track= track->next; + } + + sub_v3_v3(vec[1], vec[0]); + sub_v3_v3(vec[2], vec[0]); + + /* construct ortho-normal basis */ + unit_m4(mat); + + cross_v3_v3v3(mat[0], vec[1], vec[2]); + copy_v3_v3(mat[1], vec[1]); + cross_v3_v3v3(mat[2], mat[0], mat[1]); + + normalize_v3(mat[0]); + normalize_v3(mat[1]); + normalize_v3(mat[2]); + + /* move to origin point */ + mat[3][0]= orig[0]; + mat[3][1]= orig[1]; + mat[3][2]= orig[2]; + + invert_m4(mat); + + object_to_mat4(parent, obmat); + mul_m4_m4m4(mat, obmat, mat); + mul_m4_m4m4(newmat, mat, rot); + object_apply_mat4(parent, newmat, 0, 0); + + /* make camera have positive z-coordinate */ + mul_v3_m4v3(vec[0], mat, camera->loc); + if(camera->loc[2]<0) { + invert_m4(rot); + mul_m4_m4m4(newmat, mat, rot); + object_apply_mat4(camera, newmat, 0, 0); + } + + where_is_object(scene, parent); + set_axis(scene, parent, axis_track, 'X'); + + DAG_id_tag_update(&clip->id, 0); + DAG_id_tag_update(&parent->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_set_floor(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Floor"; + ot->description= "Set floor based on 3 selected bundles by moving camera (or it's parent if present) in 3d space"; + ot->idname= "CLIP_OT_set_floor"; + + /* api callbacks */ + ot->exec= set_floor_exec; + ot->poll= space_clip_camera_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** set axis operator *********************/ + +static int set_axis_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + Scene *scene= CTX_data_scene(C); + Object *parent= scene->camera; + int axis= RNA_enum_get(op->ptr, "axis"); + + if(count_selected_bundles(C)!=1) { + BKE_report(op->reports, RPT_ERROR, "Single track with bundle should be selected to define axis"); + + return OPERATOR_CANCELLED; + } + + if(scene->camera->parent) + parent= scene->camera->parent; + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) + break; + + track= track->next; + } + + set_axis(scene, parent, track, axis==0?'X':'Y'); + + DAG_id_tag_update(&clip->id, 0); + DAG_id_tag_update(&parent->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_set_axis(wmOperatorType *ot) +{ + static EnumPropertyItem axis_actions[] = { + {0, "X", 0, "X", "Align bundle align X axis"}, + {1, "Y", 0, "Y", "Align bundle align Y axis"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Set Axis"; + ot->description= "Set direction of scene axis rotating camera (or it's parent if present) and assuming selected track lies on real axis joining it with the origin"; + ot->idname= "CLIP_OT_set_axis"; + + /* api callbacks */ + ot->exec= set_axis_exec; + ot->poll= space_clip_frame_camera_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "axis", axis_actions, 0, "Axis", "Axis to use to align bundle along"); +} + +/********************** set scale operator *********************/ + +static int set_scale_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + Scene *scene= CTX_data_scene(C); + Object *parent= scene->camera; + int tot= 0; + float vec[2][3], mat[4][4], scale; + float dist= RNA_float_get(op->ptr, "distance"); + + if(count_selected_bundles(C)!=2) { + BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to scale scene"); + + return OPERATOR_CANCELLED; + } + + if(scene->camera->parent) + parent= scene->camera->parent; + + BKE_get_tracking_mat(scene, NULL, mat); + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + mul_v3_m4v3(vec[tot], mat, track->bundle_pos); + tot++; + } + + track= track->next; + } + + sub_v3_v3(vec[0], vec[1]); + + if(len_v3(vec[0])>1e-5) { + scale= dist / len_v3(vec[0]); + + mul_v3_fl(parent->size, scale); + mul_v3_fl(parent->loc, scale); + + DAG_id_tag_update(&clip->id, 0); + DAG_id_tag_update(&parent->id, OB_RECALC_OB); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + } + + return OPERATOR_FINISHED; +} + +static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + float dist= RNA_float_get(op->ptr, "distance"); + + if(dist==0.0f) + RNA_float_set(op->ptr, "distance", clip->tracking.settings.dist); + + return set_scale_exec(C, op); +} + +void CLIP_OT_set_scale(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Scale"; + ot->description= "Set scale of scene by scaling camera (or it's parent if present)"; + ot->idname= "CLIP_OT_set_scale"; + + /* api callbacks */ + ot->exec= set_scale_exec; + ot->invoke= set_scale_invoke; + ot->poll= space_clip_frame_camera_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_float(ot->srna, "distance", 0.0f, -FLT_MAX, FLT_MAX, + "Distance", "Distance between selected tracks", -100.0f, 100.0f); +} + +/********************** set principal center operator *********************/ + +static int set_center_principal_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + int width, height; + + BKE_movieclip_get_size(clip, &sc->user, &width, &height); + + if(width==0 || height==0) + return OPERATOR_CANCELLED; + + clip->tracking.camera.principal[0]= ((float)width)/2.0f; + clip->tracking.camera.principal[1]= ((float)height)/2.0f; + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_set_center_principal(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Principal to Center"; + ot->description= "Set principal point to center of footage"; + ot->idname= "CLIP_OT_set_center_principal"; + + /* api callbacks */ + ot->exec= set_center_principal_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** hide tracks operator *********************/ + +static int hide_tracks_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int unselected; + + unselected= RNA_boolean_get(op->ptr, "unselected"); + + track= clip->tracking.tracks.first; + while(track) { + if(unselected==0 && TRACK_VIEW_SELECTED(sc, track)) { + track->flag|= TRACK_HIDDEN; + } else if(unselected==1 && !TRACK_VIEW_SELECTED(sc, track)) { + track->flag|= TRACK_HIDDEN; + } + + track= track->next; + } + + if(clip->tracking.act_track && clip->tracking.act_track->flag&TRACK_HIDDEN) + clip->tracking.act_track= NULL; + + if(unselected==0) { + /* no selection on screen now, unlock view so it can be scrolled nice again */ + sc->flag&= ~SC_LOCK_SELECTION; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_hide_tracks(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Hide Tracks"; + ot->description= "Hide selected tracks"; + ot->idname= "CLIP_OT_hide_tracks"; + + /* api callbacks */ + ot->exec= hide_tracks_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected tracks"); +} + +/********************** hide tracks clear operator *********************/ + +static int hide_tracks_clear_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + + track= clip->tracking.tracks.first; + while(track) { + track->flag&= ~TRACK_HIDDEN; + + track= track->next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_hide_tracks_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Hide Tracks Clear"; + ot->description= "Clear hide selected tracks"; + ot->idname= "CLIP_OT_hide_tracks_clear"; + + /* api callbacks */ + ot->exec= hide_tracks_clear_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** detect features operator *********************/ + +static bGPDlayer *detect_get_layer(MovieClip *clip) +{ + bGPDlayer *layer; + + if(!clip->gpd) + return NULL; + + layer= clip->gpd->layers.first; + while(layer) { + if(layer->flag&GP_LAYER_ACTIVE) + return layer; + + layer= layer->next; + } + + return NULL; +} + +static int detect_features_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + ImBuf *ibuf= BKE_movieclip_get_ibuf_flag(clip, &sc->user, 0); + MovieTrackingTrack *track= clip->tracking.tracks.first; + int placement= RNA_enum_get(op->ptr, "placement"); + int margin= RNA_int_get(op->ptr, "margin"); + int min_trackness= RNA_int_get(op->ptr, "min_trackness"); + int min_distance= RNA_int_get(op->ptr, "min_distance"); + int place_outside_layer= 0; + bGPDlayer *layer= NULL; + + if(placement!=0) { + layer= detect_get_layer(clip); + place_outside_layer= placement==2; + } + + /* deselect existing tracks */ + while(track) { + track->flag&= ~SELECT; + track->pat_flag&= ~SELECT; + track->search_flag&= ~SELECT; + + track= track->next; + } + + BKE_tracking_detect_fast(&clip->tracking, ibuf, sc->user.framenr, margin, min_trackness, min_distance, layer, place_outside_layer); + + IMB_freeImBuf(ibuf); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_detect_features(wmOperatorType *ot) +{ + static EnumPropertyItem placement_items[] = { + {0, "FRAME", 0, "Whole Frame", "Place markers across the whole frame"}, + {1, "INSIDE_GPENCIL", 0, "Inside grease pencil", "Place markers only inside areas oulined with grease pencil"}, + {2, "OUTSIDE_GPENCIL", 0, "Outside grease pencil", "Place markers only outside areas oulined with grease pencil"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Detect Features"; + ot->description= "Automatically detect features to track"; + ot->idname= "CLIP_OT_detect_features"; + + /* api callbacks */ + ot->exec= detect_features_exec; + ot->poll= space_clip_frame_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "placement", placement_items, 0, "Placement", "Placement for detected features"); + RNA_def_int(ot->srna, "margin", 16, 0, INT_MAX, "Margin", "Only corners further than margin pixels from the image edges are considered", 0, 300); + RNA_def_int(ot->srna, "min_trackness", 16, 0, INT_MAX, "Trackness", "Minimum score to add a corner", 0, 300); + RNA_def_int(ot->srna, "min_distance", 120, 0, INT_MAX, "Distance", "Minimal distance accepted between two corners", 0, 300); +} + +/********************** frame jump operator *********************/ + +static int frame_jump_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + int pos= RNA_enum_get(op->ptr, "position"); + int delta; + + if(pos<=1) { /* jump to path */ + track= clip->tracking.act_track; + + if(!track) + return OPERATOR_CANCELLED; + + delta= pos == 1 ? 1 : -1; + + while(sc->user.framenr+delta >= SFRA && sc->user.framenr+delta <= EFRA) { + MovieTrackingMarker *marker= BKE_tracking_exact_marker(track, sc->user.framenr+delta); + + if(!marker || marker->flag&MARKER_DISABLED) + break; + + sc->user.framenr+= delta; + } + } + else { /* to to failed frame */ + if(clip->tracking.reconstruction.flag&TRACKING_RECONSTRUCTED) { + int a= sc->user.framenr; + MovieTracking *tracking= &clip->tracking; + + delta= pos == 3 ? 1 : -1; + + a+= delta; + + while(a+delta >= SFRA && a+delta <= EFRA) { + MovieReconstructedCamera *cam= BKE_tracking_get_reconstructed_camera(tracking, a); + + if(!cam) { + sc->user.framenr= a; + + break; + } + + a+= delta; + } + } + } + + if(CFRA!=sc->user.framenr) { + CFRA= sc->user.framenr; + sound_seek_scene(CTX_data_main(C), CTX_data_scene(C)); + + WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene); + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, NULL); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_frame_jump(wmOperatorType *ot) +{ + static EnumPropertyItem position_items[] = { + {0, "PATHSTART", 0, "Path Start", "Jump to start of current path"}, + {1, "PATHEND", 0, "Path End", "Jump to end of current path"}, + {2, "FAILEDPREV", 0, "Previons Failed", "Jump to previous failed frame"}, + {2, "FAILNEXT", 0, "Next Failed", "Jump to next failed frame"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Jump to Frame"; + ot->description= "Jump to special frame"; + ot->idname= "CLIP_OT_frame_jump"; + + /* api callbacks */ + ot->exec= frame_jump_exec; + ot->poll= space_clip_frame_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "position", position_items, 0, "Position", "Position to jumo to"); +} + +/********************** join tracks operator *********************/ + +static int join_tracks_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *act_track, *track, *next; + + act_track= clip->tracking.act_track; + + if(!act_track) { + BKE_report(op->reports, RPT_ERROR, "No active track to join to"); + return OPERATOR_CANCELLED; + } + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) { + if(!BKE_tracking_test_join_tracks(act_track, track)) { + BKE_report(op->reports, RPT_ERROR, "Some selected tracks have got keyframed markers to the same frame"); + return OPERATOR_CANCELLED; + } + } + + track= track->next; + } + + track= clip->tracking.tracks.first; + while(track) { + next= track->next; + + if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) { + BKE_tracking_join_tracks(act_track, track); + + BKE_tracking_free_track(track); + BLI_freelinkN(&clip->tracking.tracks, track); + } + + track= next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_join_tracks(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Join Tracks"; + ot->description= "Joint Selected Tracks"; + ot->idname= "CLIP_OT_join_tracks"; + + /* api callbacks */ + ot->exec= join_tracks_exec; + ot->poll= space_clip_frame_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** lock tracks operator *********************/ + +static int lock_tracks_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track= tracking->tracks.first; + int action= RNA_enum_get(op->ptr, "action"); + + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + if(action==0) track->flag|= TRACK_LOCKED; + else if(action==1) track->flag&= ~TRACK_LOCKED; + else track->flag^= TRACK_LOCKED; + } + + track= track->next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EVALUATED, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_lock_tracks(wmOperatorType *ot) +{ + static EnumPropertyItem actions_items[] = { + {0, "LOCK", 0, "Lock", "Lock selected tracks"}, + {1, "UNLOCK", 0, "Unlock", "Unlock selected tracks"}, + {2, "TOGGLE", 0, "Toggle", "Toggle locked flag for selected tracks"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Lock Tracks"; + ot->description= "Lock/unlock selected tracks"; + ot->idname= "CLIP_OT_lock_tracks"; + + /* api callbacks */ + ot->exec= lock_tracks_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Lock action to execute"); +} + +/********************** track copy color operator *********************/ + +static int track_copy_color_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track, *act_track= clip->tracking.act_track; + + if(!act_track) + return OPERATOR_CANCELLED; + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && track!=act_track) { + track->flag&= ~TRACK_CUSTOMCOLOR; + + if(act_track->flag&TRACK_CUSTOMCOLOR) { + copy_v3_v3(track->color, act_track->color); + track->flag|= TRACK_CUSTOMCOLOR; + } + } + + track= track->next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_track_copy_color(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Copy Color"; + ot->description= "Copy color to all selected tracks"; + ot->idname= "CLIP_OT_track_copy_color"; + + /* api callbacks */ + ot->exec= track_copy_color_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** add 2d stabilization tracks operator *********************/ + +static int stabilize_2d_add_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + MovieTrackingStabilization *stab= &tracking->stabilization; + int update= 0; + + track= tracking->tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_USE_2D_STAB)==0) { + track->flag|= TRACK_USE_2D_STAB; + stab->tot_track++; + + update= 1; + } + + track= track->next; + } + + if(update) { + stab->ok= 0; + + DAG_id_tag_update(&clip->id, 0); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + } + + return OPERATOR_FINISHED; +} + +void CLIP_OT_stabilize_2d_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Add Stabilization Tracks"; + ot->description= "Add selected tracks to 2D stabilization tool"; + ot->idname= "CLIP_OT_stabilize_2d_add"; + + /* api callbacks */ + ot->exec= stabilize_2d_add_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** remove 2d stabilization tracks operator *********************/ + +static int stabilize_2d_remove_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingStabilization *stab= &tracking->stabilization; + MovieTrackingTrack *track; + int a= 0, update= 0; + + track= tracking->tracks.first; + while(track) { + if(track->flag&TRACK_USE_2D_STAB) { + if(a==stab->act_track) { + track->flag&= ~TRACK_USE_2D_STAB; + + stab->act_track--; + stab->tot_track--; + + if(stab->act_track<0) + stab->act_track= 0; + + update= 1; + + break; + } + + a++; + } + + track= track->next; + } + + if(update) { + stab->ok= 0; + + DAG_id_tag_update(&clip->id, 0); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + } + + return OPERATOR_FINISHED; +} + +void CLIP_OT_stabilize_2d_remove(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Remove Stabilization Track"; + ot->description= "Remove selected track from stabilization"; + ot->idname= "CLIP_OT_stabilize_2d_remove"; + + /* api callbacks */ + ot->exec= stabilize_2d_remove_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** select 2d stabilization tracks operator *********************/ + +static int stabilize_2d_select_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + int update= 0; + + track= tracking->tracks.first; + while(track) { + if(track->flag&TRACK_USE_2D_STAB) { + BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0); + + update= 1; + } + + track= track->next; + } + + if(update) + WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip); + + return OPERATOR_FINISHED; +} + +void CLIP_OT_stabilize_2d_select(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Select Stabilization Tracks"; + ot->description= "Select track which are used for stabilization"; + ot->idname= "CLIP_OT_stabilize_2d_select"; + + /* api callbacks */ + ot->exec= stabilize_2d_select_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** set 2d stabilization rotation track operator *********************/ + +static int stabilize_2d_set_rotation_exec(bContext *C, wmOperator *UNUSED(op)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + + if(tracking->act_track) { + MovieTrackingStabilization *stab= &tracking->stabilization; + + stab->rot_track= tracking->act_track; + stab->ok= 0; + + DAG_id_tag_update(&clip->id, 0); + WM_event_add_notifier(C, NC_MOVIECLIP|ND_DISPLAY, clip); + } + + return OPERATOR_FINISHED; +} + +void CLIP_OT_stabilize_2d_set_rotation(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Set Rotation Track"; + ot->description= "Use active track to compensate rotaiton when doing 2D stabilization"; + ot->idname= "CLIP_OT_stabilize_2d_set_rotation"; + + /* api callbacks */ + ot->exec= stabilize_2d_set_rotation_exec; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +/********************** clean tracks operator *********************/ + +static int is_track_clean(MovieTrackingTrack *track, int frames, int del) +{ + int ok= 1, a, prev= -1, count= 0; + MovieTrackingMarker *markers= track->markers, *new_markers= NULL; + int start_disabled= 0; + int markersnr= track->markersnr; + + if(del) + new_markers= MEM_callocN(markersnr*sizeof(MovieTrackingMarker), "track cleaned markers"); + + for(a= 0; a= 0) { + end= a == markersnr-1; + end|= (a < markersnr-1) && (markers[a].framenr != markers[a+1].framenr-1 || + markers[a].flag&MARKER_DISABLED); + } + + if(end) { + int segok= 1, len= 0; + + if(a != prev && markers[a].framenr != markers[a-1].framenr+1) + len= a-prev; + else if(markers[a].flag&MARKER_DISABLED) + len= a-prev; + else len= a-prev+1; + + if(frames) { + if(len < frames) { + segok= 0; + ok= 0; + + if(!del) + break; + } + } + + if(del) { + if(segok) { + int t= len; + + if(markers[a].flag&MARKER_DISABLED) + t++; + + /* place disabled marker in front of current segment */ + if(start_disabled) { + memcpy(new_markers+count, markers+prev, sizeof(MovieTrackingMarker)); + new_markers[count].framenr--; + new_markers[count].flag|= MARKER_DISABLED; + + count++; + start_disabled= 0; + } + + memcpy(new_markers+count, markers+prev, t*sizeof(MovieTrackingMarker)); + count+= t; + } + else if(markers[a].flag&MARKER_DISABLED) { + /* current segment which would be deleted was finished by disabled marker, + so next segment should be started from disabled marker */ + start_disabled= 1; + } + } + + prev= -1; + } + } + + if(del) { + MEM_freeN(track->markers); + + if(count) { + track->markers= new_markers; + } + else { + track->markers= NULL; + MEM_freeN(new_markers); + } + + track->markersnr= count; + } + + return ok; +} + +static int clean_tracks_exec(bContext *C, wmOperator *op) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track, *next, *act_track= clip->tracking.act_track; + int frames= RNA_int_get(op->ptr, "frames"); + int action= RNA_enum_get(op->ptr, "action"); + float error= RNA_float_get(op->ptr, "error"); + + if(error && action==TRACKING_CLEAN_DELETE_SEGMENT) + action= TRACKING_CLEAN_DELETE_TRACK; + + track= tracking->tracks.first; + while(track) { + next= track->next; + + if((track->flag&TRACK_HIDDEN)==0 && (track->flag&TRACK_LOCKED)==0) { + int ok= 1; + + ok= (is_track_clean(track, frames, action==TRACKING_CLEAN_DELETE_SEGMENT)) && + (error == 0.0f || (track->flag&TRACK_HAS_BUNDLE)==0 || track->error < error); + + if(!ok) { + if(action==TRACKING_CLEAN_SELECT) { + BKE_tracking_track_flag(track, TRACK_AREA_ALL, SELECT, 0); + } + else if(action==TRACKING_CLEAN_DELETE_TRACK) { + if(track==act_track) + clip->tracking.act_track= NULL; + + BKE_tracking_free_track(track); + BLI_freelinkN(&clip->tracking.tracks, track); + } + + /* happens when all tracking segments are not long enough */ + if(track->markersnr==0) { + if(track==act_track) + clip->tracking.act_track= NULL; + + BKE_tracking_free_track(track); + BLI_freelinkN(&clip->tracking.tracks, track); + } + } + } + + track= next; + } + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, clip); + + return OPERATOR_FINISHED; +} + +static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + SpaceClip *sc= CTX_wm_space_clip(C); + MovieClip *clip= ED_space_clip(sc); + int frames= RNA_int_get(op->ptr, "frames"); + float error= RNA_float_get(op->ptr, "error"); + int action= RNA_enum_get(op->ptr, "action"); + + if(frames==0 && error==0 && action==0) { + RNA_int_set(op->ptr, "frames", clip->tracking.settings.clean_frames); + RNA_float_set(op->ptr, "error", clip->tracking.settings.clean_error); + RNA_enum_set(op->ptr, "action", clip->tracking.settings.clean_action); + } + + return clean_tracks_exec(C, op); +} + +void CLIP_OT_clean_tracks(wmOperatorType *ot) +{ + static EnumPropertyItem actions_items[] = { + {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, + {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"}, + {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name= "Clean Tracks"; + ot->description= "Clean tracks"; + ot->idname= "CLIP_OT_clean_tracks"; + + /* api callbacks */ + ot->exec= clean_tracks_exec; + ot->invoke= clean_tracks_invoke; + ot->poll= ED_space_clip_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "frames", 0, 0, INT_MAX, "Tracked Frames", "Effect on tracks which are tracked less than specified amount of frames", 0, INT_MAX); + RNA_def_float(ot->srna, "error", 0.0f, 0.0f, FLT_MAX, "Reprojection Error", "Effect on tracks with have got larger reprojection error", 0.0f, 100.0f); + RNA_def_enum(ot->srna, "action", actions_items, 0, "Action", "Cleanup action to execute"); +} diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6ebb7cf4a48..4809e463d75 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -76,6 +76,8 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_unit.h" +#include "BKE_movieclip.h" +#include "BKE_tracking.h" #include "smoke_API.h" @@ -202,6 +204,40 @@ static void view3d_project_short_noclip(ARegion *ar, const float vec[3], short * } } +/* same as view3d_project_short_clip but use persmat instead of persmatob for projection */ +static void view3d_project_short_clip_persmat(ARegion *ar, float *vec, short *adr, int local) +{ + RegionView3D *rv3d= ar->regiondata; + float fx, fy, vec4[4]; + + adr[0]= IS_CLIPPED; + + /* clipplanes in eye space */ + if(rv3d->rflag & RV3D_CLIPPING) { + if(ED_view3d_test_clipping(rv3d, vec, local)) + return; + } + + copy_v3_v3(vec4, vec); + vec4[3]= 1.0; + + mul_m4_v4(rv3d->persmat, vec4); + + /* clipplanes in window space */ + if( vec4[3] > (float)BL_NEAR_CLIP ) { /* is the NEAR clipping cutoff for picking */ + fx= (ar->winx/2)*(1 + vec4[0]/vec4[3]); + + if( fx>0 && fxwinx) { + + fy= (ar->winy/2)*(1 + vec4[1]/vec4[3]); + + if(fy > 0.0f && fy < (float)ar->winy) { + adr[0]= (short)floorf(fx); + adr[1]= (short)floorf(fy); + } + } + } +} /* ************************ */ /* check for glsl drawing */ @@ -733,7 +769,12 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa for(vos= strings->first; vos; vos= vos->next) { if(mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE)) mul_m4_v3(mat, vos->vec); - view3d_project_short_clip(ar, vos->vec, vos->sco, 0); + + if(vos->flag&V3D_CACHE_TEXT_GLOBALSPACE) + view3d_project_short_clip_persmat(ar, vos->vec, vos->sco, 0); + else + view3d_project_short_clip(ar, vos->vec, vos->sco, 0); + if(vos->sco[0]!=IS_CLIPPED) tot++; } @@ -1365,16 +1406,203 @@ float view3d_camera_border_hack_col[4]; short view3d_camera_border_hack_test= FALSE; #endif +/* ****************** draw clip data *************** */ + +static void draw_bundle_sphere(void) +{ + static GLuint displist= 0; + + if (displist == 0) { + GLUquadricObj *qobj; + + displist= glGenLists(1); + glNewList(displist, GL_COMPILE); + + qobj= gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_FILL); + glShadeModel(GL_SMOOTH); + gluSphere(qobj, 0.05, 8, 8); + glShadeModel(GL_FLAT); + gluDeleteQuadric(qobj); + + glEndList(); + } + + glCallList(displist); +} + +static void draw_viewport_reconstruction(Scene *scene, Base *base, View3D *v3d, MovieClip *clip, int flag) +{ + MovieTracking *tracking= &clip->tracking; + MovieTrackingTrack *track; + float mat[4][4], imat[4][4], curcol[4]; + unsigned char col[4], scol[4]; + int bundlenr= 1; + + if((v3d->flag2&V3D_SHOW_RECONSTRUCTION)==0) + return; + + if(v3d->flag2&V3D_RENDER_OVERRIDE) + return; + + glGetFloatv(GL_CURRENT_COLOR, curcol); + + UI_GetThemeColor4ubv(TH_TEXT, col); + UI_GetThemeColor4ubv(TH_SELECT, scol); + + BKE_get_tracking_mat(scene, base->object, mat); + + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + glShadeModel(GL_SMOOTH); + + /* current ogl matrix is translated in camera space, bundles should + be rendered in world space, so camera matrix should be "removed" + from current ogl matrix */ + invert_m4_m4(imat, base->object->obmat); + + glPushMatrix(); + glMultMatrixf(imat); + glMultMatrixf(mat); + + for ( track= tracking->tracks.first; track; track= track->next) { + int selected= track->flag&SELECT || track->pat_flag&SELECT || track->search_flag&SELECT; + if((track->flag&TRACK_HAS_BUNDLE)==0) + continue; + + if(flag&DRAW_PICKING) + glLoadName(base->selcol + (bundlenr<<16)); + + glPushMatrix(); + glTranslatef(track->bundle_pos[0], track->bundle_pos[1], track->bundle_pos[2]); + glScalef(v3d->bundle_size/0.05, v3d->bundle_size/0.05, v3d->bundle_size/0.05); + + if(v3d->drawtype==OB_WIRE) { + glDisable(GL_LIGHTING); + glDepthMask(0); + + if(selected) { + if(base==BASACT) UI_ThemeColor(TH_ACTIVE); + else UI_ThemeColor(TH_SELECT); + } else { + if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color); + else UI_ThemeColor(TH_WIRE); + } + + drawaxes(0.05f, v3d->bundle_drawtype); + + glDepthMask(1); + glEnable(GL_LIGHTING); + } else if(v3d->drawtype>OB_WIRE) { + if(v3d->bundle_drawtype==OB_EMPTY_SPHERE) { + /* selection outline */ + if(selected) { + if(base==BASACT) UI_ThemeColor(TH_ACTIVE); + else UI_ThemeColor(TH_SELECT); + + glDepthMask(0); + glLineWidth(2.f); + glDisable(GL_LIGHTING); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + draw_bundle_sphere(); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glEnable(GL_LIGHTING); + glLineWidth(1.f); + glDepthMask(1); + } + + if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color); + else UI_ThemeColor(TH_BUNDLE_SOLID); + + draw_bundle_sphere(); + } else { + glDisable(GL_LIGHTING); + glDepthMask(0); + + if(selected) { + if(base==BASACT) UI_ThemeColor(TH_ACTIVE); + else UI_ThemeColor(TH_SELECT); + } else { + if(track->flag&TRACK_CUSTOMCOLOR) glColor3fv(track->color); + else UI_ThemeColor(TH_WIRE); + } + + drawaxes(0.05f, v3d->bundle_drawtype); + + glDepthMask(1); + glEnable(GL_LIGHTING); + } + } + + glPopMatrix(); + + if((flag & DRAW_PICKING)==0 && (v3d->flag2&V3D_SHOW_BUNDLENAME)) { + float pos[3]; + unsigned char tcol[4]; + + if(selected) memcpy(tcol, scol, sizeof(tcol)); + else memcpy(tcol, col, sizeof(tcol)); + + mul_v3_m4v3(pos, mat, track->bundle_pos); + view3d_cached_text_draw_add(pos, track->name, 10, V3D_CACHE_TEXT_GLOBALSPACE, tcol); + } + + bundlenr++; + } + + if((flag & DRAW_PICKING)==0) { + if(v3d->flag2&V3D_SHOW_CAMERAPATH && clip->tracking.reconstruction.camnr) { + int a= 0; + MovieTrackingReconstruction *reconstruction= &tracking->reconstruction; + MovieReconstructedCamera *camera= tracking->reconstruction.cameras; + + glDisable(GL_LIGHTING); + UI_ThemeColor(TH_CAMERA_PATH); + glLineWidth(2.0f); + + glBegin(GL_LINE_STRIP); + for(a= 0; acamnr; a++, camera++) { + glVertex3f(camera->mat[3][0], camera->mat[3][1], camera->mat[3][2]); + } + glEnd(); + + glLineWidth(1.0f); + glEnable(GL_LIGHTING); + } + } + + glPopMatrix(); + + /* restore */ + glShadeModel(GL_FLAT); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + + glColor4fv(curcol); + + if(flag&DRAW_PICKING) + glLoadName(base->selcol); +} + /* flag similar to draw_object() */ -static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, int flag) +static void drawcamera(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int flag) { /* a standing up pyramid with (0,0,0) as top */ Camera *cam; + Object *ob= base->object; float tvec[3]; float vec[4][3], asp[2], shift[2], scale[3]; int i; float drawsize; const short is_view= (rv3d->persp==RV3D_CAMOB && ob==v3d->camera); + MovieClip *clip= object_get_movieclip(scene, base->object, 0); + + /* draw data for movie clip set as active for scene */ + if(clip) + draw_viewport_reconstruction(scene, base, v3d, clip, flag); #ifdef VIEW3D_CAMERA_BORDER_HACK if(is_view && !(G.f & G_PICKSEL)) { @@ -6082,7 +6310,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) break; case OB_CAMERA: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0 || (rv3d->persp==RV3D_CAMOB && v3d->camera==ob)) /* special exception for active camera */ - drawcamera(scene, v3d, rv3d, ob, flag); + drawcamera(scene, v3d, rv3d, base, flag); break; case OB_SPEAKER: if((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 0c7b81beb1e..c493e4af944 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -250,6 +250,7 @@ static SpaceLink *view3d_new(const bContext *C) v3d->gridflag &= ~V3D_SHOW_Z; v3d->flag |= V3D_SELECT_OUTLINE; + v3d->flag2 |= V3D_SHOW_RECONSTRUCTION; v3d->lens= 35.0f; v3d->near= 0.01f; @@ -259,6 +260,9 @@ static SpaceLink *view3d_new(const bContext *C) v3d->twtype= V3D_MANIP_TRANSLATE; v3d->around= V3D_CENTROID; + v3d->bundle_size= 0.2f; + v3d->bundle_drawtype= OB_PLAINAXES; + /* header */ ar= MEM_callocN(sizeof(ARegion), "header for view3d"); @@ -744,6 +748,10 @@ static void view3d_main_area_listener(ARegion *ar, wmNotifier *wmn) /* same as above */ ED_region_tag_redraw(ar); break; + case NC_MOVIECLIP: + if(wmn->data==ND_DISPLAY) + ED_region_tag_redraw(ar); + break; case NC_SPACE: if(wmn->data == ND_SPACE_VIEW3D) { if (wmn->subtype == NS_VIEW3D_GPU) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 309578699f7..51bbf591bb3 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -62,6 +62,7 @@ #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_unit.h" +#include "BKE_movieclip.h" #include "RE_engine.h" #include "RE_pipeline.h" // make_stars @@ -1487,7 +1488,8 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) RegionView3D *rv3d= ar->regiondata; BGpic *bgpic; Image *ima; - ImBuf *ibuf= NULL; + MovieClip *clip; + ImBuf *ibuf= NULL, *freeibuf; float vec[4], fac, asp, zoomx, zoomy; float x1, y1, x2, y2, cx, cy; @@ -1498,15 +1500,46 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) (bgpic->view & (1<view)) || /* check agaist flags */ (rv3d->persp==RV3D_CAMOB && bgpic->view == (1<ima; - if(ima==NULL) + freeibuf= NULL; + if(bgpic->source==V3D_BGPIC_IMAGE) { + ima= bgpic->ima; + if(ima==NULL) + continue; + BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0); + ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser); + } else { + clip= NULL; + + if(bgpic->flag&V3D_BGPIC_CAMERACLIP) { + if(!scene->camera) + scene->camera= scene_find_camera(scene); + + if(scene->camera) + clip= object_get_movieclip(scene, scene->camera, 1); + } else clip= bgpic->clip; + + if(clip==NULL) + continue; + + BKE_movieclip_user_set_frame(&bgpic->cuser, CFRA); + ibuf= BKE_movieclip_get_ibuf(clip, &bgpic->cuser); + + /* working with ibuf from image and clip has got different workflow now. + ibuf acquired from clip is referenced by cache system and should + be dereferenced after usage. */ + freeibuf= ibuf; + } + + if(ibuf==NULL) continue; - BKE_image_user_calc_frame(&bgpic->iuser, CFRA, 0); - ibuf= BKE_image_get_ibuf(ima, &bgpic->iuser); - if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL) ) - continue; - if(ibuf->channels!=4) + + if((ibuf->rect==NULL && ibuf->rect_float==NULL) || ibuf->channels!=4) { /* invalid image format */ + if(freeibuf) + IMB_freeImBuf(freeibuf); + continue; + } + if(ibuf->rect==NULL) IMB_rect_from_float(ibuf); @@ -1545,10 +1578,12 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) /* complete clip? */ - if(x2 < 0 ) continue; - if(y2 < 0 ) continue; - if(x1 > ar->winx ) continue; - if(y1 > ar->winy ) continue; + if(x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) { + if(freeibuf) + IMB_freeImBuf(freeibuf); + + continue; + } zoomx= (x2-x1)/ibuf->x; zoomy= (y2-y1)/ibuf->y; @@ -1603,6 +1638,9 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) glDepthMask(1); if(v3d->zbuf) glEnable(GL_DEPTH_TEST); + + if(freeibuf) + IMB_freeImBuf(freeibuf); } } } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index b677a8fd7cf..7331959ef51 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2940,18 +2940,8 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) static BGpic *background_image_add(bContext *C) { View3D *v3d= CTX_wm_view3d(C); - - BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image"); - bgpic->size= 5.0; - bgpic->blend= 0.5; - bgpic->iuser.fie_ima= 2; - bgpic->iuser.ok= 1; - bgpic->view= 0; /* 0 for all */ - bgpic->flag |= V3D_BGPIC_EXPANDED; - - BLI_addtail(&v3d->bgpicbase, bgpic); - - return bgpic; + + return ED_view3D_background_image_add(v3d); } static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -3027,7 +3017,8 @@ static int background_image_remove_exec(bContext *C, wmOperator *op) if(bgpic_rem) { BLI_remlink(&vd->bgpicbase, bgpic_rem); - if(bgpic_rem->ima) bgpic_rem->ima->id.us--; + if(bgpic_rem->ima) id_us_min(&bgpic_rem->ima->id); + if(bgpic_rem->clip) id_us_min(&bgpic_rem->clip->id); MEM_freeN(bgpic_rem); WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, vd); return OPERATOR_FINISHED; @@ -3534,3 +3525,18 @@ void ED_view3d_to_object(Object *ob, const float ofs[3], const float quat[4], co ED_view3d_to_m4(mat, ofs, quat, dist); object_apply_mat4(ob, mat, TRUE, TRUE); } + +BGpic *ED_view3D_background_image_add(View3D *v3d) +{ + BGpic *bgpic= MEM_callocN(sizeof(BGpic), "Background Image"); + + bgpic->size= 5.0; + bgpic->blend= 0.5; + bgpic->iuser.fie_ima= 2; + bgpic->iuser.ok= 1; + bgpic->view= 0; /* 0 for all */ + + BLI_addtail(&v3d->bgpicbase, bgpic); + + return bgpic; +} diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index b07d2d1ca73..5aa8d95912d 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -121,6 +121,7 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa #define V3D_CACHE_TEXT_ZBUF (1<<0) #define V3D_CACHE_TEXT_WORLDSPACE (1<<1) #define V3D_CACHE_TEXT_ASCII (1<<2) +#define V3D_CACHE_TEXT_GLOBALSPACE (1<<3) /* drawarmature.c */ int draw_armature(Scene *scene, View3D *v3d, ARegion *ar, Base *base, int dt, int flag, const short is_outline); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 94d3469dc8c..0163c29c9aa 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -42,6 +42,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_tracking_types.h" #include "MEM_guardedalloc.h" @@ -60,6 +61,9 @@ #include "BKE_context.h" #include "BKE_paint.h" #include "BKE_armature.h" +#include "BKE_movieclip.h" +#include "BKE_object.h" +#include "BKE_tracking.h" #include "BIF_gl.h" @@ -1373,6 +1377,7 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short obce if(hits>0) { int has_bones= 0; + /* note: bundles are handling in the same way as bones */ for(a=0; aobject->type==OB_CAMERA) { + if(BASACT==basact) { + int i, hitresult; + MovieTrackingTrack *track; + + for (i=0; i< hits; i++) { + hitresult= buffer[3+(i*4)]; + + /* if there's bundles in buffer select bundles first, + so non-camera elements should be ignored in buffer */ + if(basact->selcol != (hitresult & 0xFFFF)) + continue; + + /* index of bundle is 1<<16-based. if there's no "bone" index + in hight word, this buffer value belongs to camera,. not to bundle */ + if(buffer[4*i+3] & 0xFFFF0000) { + MovieClip *clip= object_get_movieclip(scene, basact->object, 0); + int selected; + track= BKE_tracking_indexed_track(&clip->tracking, hitresult >> 16); + + selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); + + if(selected && extend) BKE_tracking_deselect_track(track, TRACK_AREA_ALL); + else BKE_tracking_select_track(&clip->tracking, track, TRACK_AREA_ALL, extend); + + basact->flag|= SELECT; + basact->object->flag= basact->flag; + + retval= 1; + + WM_event_add_notifier(C, NC_MOVIECLIP|ND_SELECT, track); + WM_event_add_notifier(C, NC_SCENE|ND_OB_SELECT, scene); + + break; + } + } + } + } + else if(ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend) ) { /* then bone is found */ /* we make the armature selected: not-selected active object in posemode won't work well for tools */ diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 1b726cd90b3..012e08f98cb 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -55,6 +55,7 @@ #include "BKE_lattice.h" #include "BKE_main.h" #include "BKE_object.h" +#include "BKE_tracking.h" #include "WM_api.h" #include "WM_types.h" @@ -753,6 +754,37 @@ void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot) /* **************************************************** */ +static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) +{ + MovieTrackingTrack *track; + MovieClip *clip= object_get_movieclip(scene, ob, 0); + int ok= 0; + float min[3], max[3], mat[4][4], pos[3]; + + if(!clip) + return; + + BKE_get_tracking_mat(scene, ob, mat); + + INIT_MINMAX(min, max); + + track= clip->tracking.tracks.first; + while(track) { + int selected= (track->flag&SELECT) || (track->pat_flag&SELECT) || (track->search_flag&SELECT); + if((track->flag&TRACK_HAS_BUNDLE) && selected) { + ok= 1; + mul_v3_m4v3(pos, mat, track->bundle_pos); + DO_MINMAX(pos, min, max); + } + + track= track->next; + } + + if(ok) { + interp_v3_v3v3(vec, min, max, 0.5); + } +} + static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) { Object *obedit= CTX_data_edit_object(C); @@ -817,6 +849,15 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op)) else { CTX_DATA_BEGIN(C, Object*, ob, selected_objects) { copy_v3_v3(vec, ob->obmat[3]); + + /* special case for camera -- snap to bundles */ + if(ob->type==OB_CAMERA) { + /* snap to bundles should happen only when bundles are visible */ + if(v3d->flag2&V3D_SHOW_RECONSTRUCTION) { + bundle_midpoint(scene, ob, vec); + } + } + add_v3_v3(centroid, vec); DO_MINMAX(vec, min, max); count++; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 591bb99ae22..13d686508de 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -48,6 +48,7 @@ #include "DNA_armature_types.h" #include "DNA_constraint_types.h" #include "DNA_meshdata_types.h" +#include "DNA_movieclip_types.h" #include "DNA_scene_types.h" /* PET modes */ #include "RNA_access.h" @@ -71,6 +72,7 @@ #include "ED_markers.h" #include "ED_view3d.h" #include "ED_mesh.h" +#include "ED_clip.h" #include "UI_view2d.h" #include "WM_types.h" @@ -155,6 +157,17 @@ void convertViewVec(TransInfo *t, float *vec, int dx, int dy) else if(ELEM(t->spacetype, SPACE_NODE, SPACE_SEQ)) { convertViewVec2D(&t->ar->v2d, vec, dx, dy); } + else if(t->spacetype==SPACE_CLIP) { + View2D *v2d = t->view; + float divx, divy; + + divx= v2d->mask.xmax-v2d->mask.xmin; + divy= v2d->mask.ymax-v2d->mask.ymin; + + vec[0]= (v2d->cur.xmax-v2d->cur.xmin)*(dx)/divx; + vec[1]= (v2d->cur.ymax-v2d->cur.ymin)*(dy)/divy; + vec[2]= 0.0f; + } } void projectIntView(TransInfo *t, float *vec, int *adr) @@ -205,6 +218,9 @@ void projectIntView(TransInfo *t, float *vec, int *adr) adr[0]= out[0]; adr[1]= out[1]; } + else if(t->spacetype==SPACE_CLIP) { + UI_view2d_to_region_no_clip(t->view, vec[0], vec[1], adr, adr+1); + } } void projectFloatView(TransInfo *t, float *vec, float *adr) @@ -213,7 +229,7 @@ void projectFloatView(TransInfo *t, float *vec, float *adr) if(t->ar->regiontype == RGN_TYPE_WINDOW) project_float_noclip(t->ar, vec, adr); } - else if(t->spacetype==SPACE_IMAGE) { + else if(ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) { int a[2]; projectIntView(t, vec, a); @@ -311,6 +327,15 @@ static void viewRedrawForce(const bContext *C, TransInfo *t) if(sima->lock) WM_event_add_notifier(C, NC_GEOM|ND_DATA, t->obedit->data); else ED_area_tag_redraw(t->sa); } + else if (t->spacetype==SPACE_CLIP) { + SpaceClip *sc= (SpaceClip*)t->sa->spacedata.first; + MovieClip *clip= ED_space_clip(sc); + + /* objects could be parented to tracking data, so send this for viewport refresh */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + WM_event_add_notifier(C, NC_MOVIECLIP|NA_EDITED, clip); + } } static void viewRedrawPost(bContext *C, TransInfo *t) @@ -579,10 +604,18 @@ int transformEvent(TransInfo *t, wmEvent *event) initSnapping(t, NULL); // need to reinit after mode change t->redraw |= TREDRAW_HARD; } + else if(t->mode == TFM_TRANSLATION) { + if(t->options&CTX_MOVIECLIP) { + restoreTransObjects(t); + + t->flag^= T_ALT_TRANSFORM; + t->redraw |= TREDRAW_HARD; + } + } break; case TFM_MODAL_ROTATE: /* only switch when... */ - if(!(t->options & CTX_TEXTURE)) { + if(!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -837,7 +870,7 @@ int transformEvent(TransInfo *t, wmEvent *event) break; case RKEY: /* only switch when... */ - if(!(t->options & CTX_TEXTURE)) { + if(!(t->options & CTX_TEXTURE) && !(t->options & CTX_MOVIECLIP)) { if( ELEM4(t->mode, TFM_ROTATION, TFM_RESIZE, TFM_TRACKBALL, TFM_TRANSLATION) ) { resetTransRestrictions(t); @@ -1502,6 +1535,11 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL); } + else if(t->spacetype == SPACE_CLIP) { + unit_m3(t->spacemtx); + t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW); + t->options |= CTX_MOVIECLIP; + } else unit_m3(t->spacemtx); @@ -3293,7 +3331,7 @@ void initTranslation(TransInfo *t) t->snap[2] = t->snap[1] * 0.1f; } } - else if(t->spacetype == SPACE_IMAGE) { + else if(ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) { t->snap[0] = 0.0f; t->snap[1] = 0.125f; t->snap[2] = 0.0625f; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 77e7cfb4d12..8b8ae95631c 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -382,6 +382,9 @@ typedef struct TransInfo { #define T_RELEASE_CONFIRM (1 << 23) + /* alternative transformation. used to add offset to tracking markers */ +#define T_ALT_TRANSFORM (1 << 24) + /* TransInfo->modifiers */ #define MOD_CONSTRAINT_SELECT 0x01 #define MOD_PRECISION 0x02 @@ -546,6 +549,7 @@ void flushTransParticles(TransInfo *t); int clipUVTransform(TransInfo *t, float *vec, int resize); void flushTransNodes(TransInfo *t); void flushTransSeq(TransInfo *t); +void flushTransTracking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7eb8dc11a43..0a6f49f7c9f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -51,6 +51,7 @@ #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" #include "DNA_gpencil_types.h" +#include "DNA_movieclip_types.h" #include "MEM_guardedalloc.h" @@ -74,6 +75,9 @@ #include "BKE_bmesh.h" #include "BKE_scene.h" #include "BKE_report.h" +#include "BKE_tracking.h" +#include "BKE_movieclip.h" +#include "BKE_node.h" #include "ED_anim_api.h" @@ -88,8 +92,12 @@ #include "ED_node.h" #include "ED_types.h" #include "ED_uvedit.h" +#include "ED_clip.h" #include "ED_util.h" /* for crazyspace correction */ +#include "WM_api.h" /* for WM_event_add_notifier to deal with stabilization nodes */ +#include "WM_types.h" + #include "UI_view2d.h" #include "BLI_math.h" @@ -4796,6 +4804,17 @@ void special_aftertrans_update(bContext *C, TransInfo *t) /* clear link line */ ED_node_link_intersect_test(t->sa, 0); } + else if (t->spacetype == SPACE_CLIP) { + SpaceClip *sc= t->sa->spacedata.first; + MovieClip *clip= ED_space_clip(sc); + + if(t->scene->nodetree) { + /* tracks can be used for stabilization nodes, + flush update for such nodes */ + nodeUpdateID(t->scene->nodetree, &clip->id); + WM_event_add_notifier(C, NC_SCENE|ND_NODES, NULL); + } + } else if (t->spacetype == SPACE_ACTION) { SpaceAction *saction= (SpaceAction *)t->sa->spacedata.first; bAnimContext ac; @@ -5264,6 +5283,229 @@ static void createTransNodeData(bContext *C, TransInfo *t) CTX_DATA_END } +/* *** CLIP EDITOR *** */ + +typedef struct TransDataTracking { + int area; + float *relative, *loc; + float soffset[2], srelative[2]; + float offset[2]; + + float (*smarkers)[2]; + int markersnr; + MovieTrackingMarker *markers; +} TransDataTracking; + +static void markerToTransDataInit(TransData *td, TransData2D *td2d, + TransDataTracking *tdt, MovieTrackingTrack *track, int area, float *loc, float *rel, float *off) +{ + int anchor = area==TRACK_AREA_POINT && off; + + if(anchor) { + td2d->loc[0] = rel[0]; /* hold original location */ + td2d->loc[1] = rel[1]; + + tdt->loc= loc; + td2d->loc2d = loc; /* current location */ + } else { + td2d->loc[0] = loc[0]; /* hold original location */ + td2d->loc[1] = loc[1]; + + td2d->loc2d = loc; /* current location */ + } + td2d->loc[2] = 0.0f; + + tdt->relative= rel; + tdt->area= area; + + tdt->markersnr= track->markersnr; + tdt->markers= track->markers; + + if(rel) { + if(!anchor) { + td2d->loc[0]+= rel[0]; + td2d->loc[1]+= rel[1]; + } + + copy_v2_v2(tdt->srelative, rel); + } + + if(off) + copy_v2_v2(tdt->soffset, off); + + td->flag = 0; + td->loc = td2d->loc; + VECCOPY(td->center, td->loc); + VECCOPY(td->iloc, td->loc); + + memset(td->axismtx, 0, sizeof(td->axismtx)); + td->axismtx[2][2] = 1.0f; + + td->ext= NULL; td->val= NULL; + + td->flag |= TD_SELECTED; + td->dist= 0.0; + + unit_m3(td->mtx); + unit_m3(td->smtx); +} + +static void trackToTransData(SpaceClip *sc, TransData *td, TransData2D *td2d, + TransDataTracking *tdt, MovieTrackingTrack *track) +{ + MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr); + + track->transflag= marker->flag; + + marker->flag&= ~(MARKER_DISABLED|MARKER_TRACKED); + + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, track->offset, marker->pos, track->offset); + + if(track->flag&SELECT) + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_POINT, marker->pos, NULL, NULL); + + if(track->pat_flag&SELECT) { + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_min, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_PAT, track->pat_max, marker->pos, NULL); + } + + if(track->search_flag&SELECT) { + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_min, marker->pos, NULL); + markerToTransDataInit(td++, td2d++, tdt++, track, TRACK_AREA_SEARCH, track->search_max, marker->pos, NULL); + } +} + +static void transDataTrackingFree(TransInfo *t) +{ + TransDataTracking *tdt= t->customData; + + if(tdt) { + if(tdt->smarkers) MEM_freeN(tdt->smarkers); + MEM_freeN(tdt); + } +} + +static void createTransTrackingData(bContext *C, TransInfo *t) +{ + TransData *td; + TransData2D *td2d; + SpaceClip *sc = CTX_wm_space_clip(C); + MovieClip *clip = ED_space_clip(sc); + MovieTrackingTrack *track; + MovieTrackingMarker *marker; + TransDataTracking *tdt; + int framenr = sc->user.framenr; + + if(clip && !BKE_movieclip_has_frame(clip, &sc->user)) { + t->total = 0; + return; + } + + /* count */ + t->total = 0; + + track = clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + if(marker) { + t->total++; /* offset */ + + if(track->flag&SELECT) t->total++; + if(track->pat_flag&SELECT) t->total+= 2; + if(track->search_flag&SELECT) t->total+= 2; + } + } + + track = track->next; + } + + if(t->total==0) + return; + + td = t->data = MEM_callocN(t->total*sizeof(TransData), "TransTracking TransData"); + td2d = t->data2d = MEM_callocN(t->total*sizeof(TransData2D), "TransTracking TransData2D"); + tdt = t->customData = MEM_callocN(t->total*sizeof(TransDataTracking), "TransTracking TransDataTracking"); + + t->customFree= transDataTrackingFree; + + /* create actual data */ + track = clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track) && (track->flag&TRACK_LOCKED)==0) { + marker= BKE_tracking_get_marker(track, framenr); + + trackToTransData(sc, td, td2d, tdt, track); + + /* offset */ + td++; + td2d++; + tdt++; + + if((marker->flag&MARKER_DISABLED)==0) { + if(track->flag&SELECT) {td++; td2d++; tdt++;} + if(track->pat_flag&SELECT) {td+= 2; td2d+= 2;tdt+=2;} + } + + if(track->search_flag&SELECT) { + td+= 2; + td2d+= 2; + tdt+= 2; + + if(marker->flag&MARKER_DISABLED) { + td+= 3; + td2d+= 3; + tdt+= 3; + }; + } + } + + track = track->next; + } +} + +void flushTransTracking(TransInfo *t) +{ + TransData *td; + TransData2D *td2d; + TransDataTracking *tdt; + int a; + + /* flush to 2d vector from internally used 3d vector */ + for(a=0, td= t->data, td2d= t->data2d, tdt= t->customData; atotal; a++, td2d++, td++, tdt++) { + if(t->flag&T_ALT_TRANSFORM) { + if(tdt->area==TRACK_AREA_POINT && tdt->relative) { + float d[2], d2[2]; + + if(!tdt->smarkers) { + tdt->smarkers= MEM_callocN(sizeof(*tdt->smarkers)*tdt->markersnr, "flushTransTracking markers"); + for(a= 0; amarkersnr; a++) + copy_v2_v2(tdt->smarkers[a], tdt->markers[a].pos); + } + + sub_v2_v2v2(d, td2d->loc, tdt->soffset); + sub_v2_v2(d, tdt->srelative); + + sub_v2_v2v2(d2, td2d->loc, tdt->srelative); + + for(a= 0; amarkersnr; a++) + add_v2_v2v2(tdt->markers[a].pos, tdt->smarkers[a], d2); + + negate_v2_v2(td2d->loc2d, d); + } + } + + if(tdt->area!=TRACK_AREA_POINT || tdt->relative==0) { + td2d->loc2d[0] = td2d->loc[0]; + td2d->loc2d[1] = td2d->loc[1]; + + if(tdt->relative) + sub_v2_v2(td2d->loc2d, tdt->relative); + } + } +} + void createTransData(bContext *C, TransInfo *t) { Scene *scene = t->scene; @@ -5329,6 +5571,10 @@ void createTransData(bContext *C, TransInfo *t) sort_trans_data_dist(t); } } + else if (t->spacetype == SPACE_CLIP) { + t->flag |= T_POINTS|T_2D_EDIT; + createTransTrackingData(C, t); + } else if (t->obedit) { t->ext = NULL; if (t->obedit->type == OB_MESH) { diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 0c3e045d5ce..53e379a2d27 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -47,6 +47,7 @@ #include "DNA_meshdata_types.h" #include "DNA_view3d_types.h" #include "DNA_modifier_types.h" +#include "DNA_movieclip_types.h" #include "RNA_access.h" @@ -70,6 +71,7 @@ #include "BKE_mesh.h" #include "BKE_nla.h" #include "BKE_context.h" +#include "BKE_tracking.h" #include "ED_anim_api.h" #include "ED_armature.h" @@ -83,6 +85,7 @@ #include "ED_uvedit.h" #include "ED_view3d.h" #include "ED_curve.h" /* for curve_editnurbs */ +#include "ED_clip.h" //#include "BDR_unwrapper.h" @@ -863,6 +866,48 @@ void recalcData(TransInfo *t) else if (t->spacetype == SPACE_VIEW3D) { recalcData_view3d(t); } + else if (t->spacetype == SPACE_CLIP) { + SpaceClip *sc= t->sa->spacedata.first; + MovieClip *clip= ED_space_clip(sc); + MovieTrackingTrack *track; + + if(t->state == TRANS_CANCEL) { + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + MovieTrackingMarker *marker= BKE_tracking_ensure_marker(track, sc->user.framenr); + + marker->flag= track->transflag; + } + + track= track->next; + } + } + + flushTransTracking(t); + + track= clip->tracking.tracks.first; + while(track) { + if(TRACK_VIEW_SELECTED(sc, track)) { + if (t->mode == TFM_TRANSLATION) { + if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_track(track, CLAMP_PAT_POS); + if(TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_track(track, CLAMP_SEARCH_POS); + } + else if (t->mode == TFM_RESIZE) { + if(TRACK_AREA_SELECTED(track, TRACK_AREA_PAT)) + BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); + if(TRACK_AREA_SELECTED(track, TRACK_AREA_SEARCH)) + BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); + } + } + + track= track->next; + } + + DAG_id_tag_update(&clip->id, 0); + } } void drawLine(TransInfo *t, float *center, float *dir, char axis, short options) diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index f926f442830..7951fe0ee02 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -973,6 +973,11 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac km = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(km->ptr, "data_path", "tool_settings.use_snap"); break; + case SPACE_CLIP: + WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0); + WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0); + break; default: break; } diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index 69f576d8aa7..7a6ccdff08f 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -46,6 +46,7 @@ set(SRC ../include/BIF_glutil.h ../include/ED_anim_api.h ../include/ED_armature.h + ../include/ED_clip.h ../include/ED_curve.h ../include/ED_datafiles.h ../include/ED_fileselect.h diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 6f2933d154b..7fa26478ae2 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -194,6 +194,7 @@ typedef struct PreviewImage { #define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */ #define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */ #define ID_WM MAKE_ID2('W', 'M') /* WindowManager */ +#define ID_MC MAKE_ID2('M', 'C') /* MovieClip */ /* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */ #define ID_SEQ MAKE_ID2('S', 'Q') diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 00f6f2433af..3620131b8df 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -406,6 +406,18 @@ typedef struct bShrinkwrapConstraint { char pad[9]; } bShrinkwrapConstraint; +/* Follow Track constraints */ +typedef struct bFollowTrackConstraint { + struct MovieClip *clip; + char track[24]; + int flag, reference; +} bFollowTrackConstraint; + +/* Camera Solver constraints */ +typedef struct bCameraSolverConstraint { + struct MovieClip *clip; + int flag, pad; +} bCameraSolverConstraint; /* ------------------------------------------ */ @@ -440,6 +452,8 @@ typedef enum eBConstraint_Types { CONSTRAINT_TYPE_TRANSLIKE, /* Copy transform matrix */ CONSTRAINT_TYPE_SAMEVOL, /* Maintain volume during scaling */ CONSTRAINT_TYPE_PIVOT, /* Pivot Constraint */ + CONSTRAINT_TYPE_FOLLOWTRACK, /* Follow Track Constraint */ + CONSTRAINT_TYPE_CAMERASOLVER, /* Camera Solver Constraint */ /* NOTE: no constraints are allowed to be added after this */ NUM_CONSTRAINT_TYPES @@ -737,6 +751,21 @@ typedef enum ePivotConstraint_Flag { PIVOTCON_FLAG_ROTACT_NEG = (1<<1) } ePivotConstraint_Flag; +/* FollowTrack Constraint -> flag */ +typedef enum eFollowTrack_Reference { + FOLLOWTRACK_TRACK = (1<<0), + FOLLOWTRACK_BUNDLE = (1<<1) +} FollowTrack_Reference; + +typedef enum eFollowTrack_Flags { + FOLLOWTRACK_ACTIVECLIP = (1<<0) +} eFollowTrack_Flags; + +/* CameraSolver Constraint -> flag */ +typedef enum eCameraSolver_Flags { + CAMERASOLVER_ACTIVECLIP = (1<<0) +} eCameraSolver_Flags; + /* Rigid-Body Constraint */ #define CONSTRAINT_DRAW_PIVOT 0x40 #define CONSTRAINT_DISABLE_LINKED_COLLISION 0x80 diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h new file mode 100644 index 00000000000..fc21f26fa32 --- /dev/null +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -0,0 +1,126 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef DNA_MOVIECLIP_TYPES_H +#define DNA_MOVIECLIP_TYPES_H + +/** \file DNA_movieclip_types.h + * \ingroup DNA + * \since may-2011 + * \author Sergey Sharybin + */ + +#include "DNA_ID.h" +#include "DNA_tracking_types.h" + +struct anim; +struct bGPdata; +struct ImBuf; +struct MovieClipProxy; +struct MovieTrackingTrack; +struct MovieTrackingMarker; + +typedef struct MovieClipUser { + int framenr; /* current frame number */ + short render_size, render_flag; /* proxy render size */ +} MovieClipUser; + +typedef struct MovieClipProxy { + char dir[160]; /* custom directory for index and proxy files (defaults to BL_proxy) */ + + short tc; /* time code in use */ + short quality; /* proxy build quality */ + short build_size_flag; /* size flags (see below) of all proxies to build */ + short build_tc_flag; /* time code flags (see below) of all tc indices to build */ + short build_flag, pad; /* other build flags */ + char pad2[4]; +} MovieClipProxy; + +typedef struct MovieClip { + ID id; + + char name[240]; /* file path */ + + int source; /* sequence or movie */ + int lastframe; /* last accessed frame number */ + int lastsize[2]; /* size of last accessed frame */ + + float aspx, aspy; /* display aspect */ + + struct anim *anim; /* movie source data */ + struct MovieClipCache *cache; /* cache for different stuff, not in file */ + struct bGPdata *gpd; /* grease pencil data */ + + struct MovieTracking tracking; /* data for SfM tracking */ + void *tracking_context; /* context of tracking job + used to synchronize data like framenumber + in SpaceClip clip user */ + + struct MovieClipProxy proxy; /* proxy to clip data */ + int flag, pad; +} MovieClip; + +typedef struct MovieClipScopes { + int ok; /* 1 means scopes are ok and recalculation is unneeded */ + int track_preview_height; /* height of track preview widget */ + struct ImBuf *track_preview; /* ImBuf displayed in track preview */ + float track_pos[2]; /* sub-pizel position of marker in track ImBuf */ + short track_disabled; /* active track is disabled, special notifier should be drawn */ + char pad[2]; + int framenr; /* frame number scopes are created for */ + struct MovieTrackingTrack *track; /* track scopes are created for */ + struct MovieTrackingMarker *marker; /* marker scopes are created for */ + float slide_scale[2]; /* scale used for sliding from previewe area */ +} MovieClipScopes; + +/* MovieClipProxy->build_flag */ +#define MCLIP_PROXY_BUILD_UNDISTORT 1 /* build undistorted proxies as well */ + +/* MovieClip->source */ +#define MCLIP_SRC_SEQUENCE 1 +#define MCLIP_SRC_MOVIE 2 + +/* MovieClip->selection types */ +#define MCLIP_SEL_NONE 0 +#define MCLIP_SEL_TRACK 1 + +/* MovieClip->flag */ +#define MCLIP_USE_PROXY (1<<0) +#define MCLIP_USE_PROXY_CUSTOM_DIR (1<<1) + +/* MovieClip->render_size */ +#define MCLIP_PROXY_RENDER_SIZE_FULL 0 +#define MCLIP_PROXY_RENDER_SIZE_25 1 +#define MCLIP_PROXY_RENDER_SIZE_50 2 +#define MCLIP_PROXY_RENDER_SIZE_75 3 +#define MCLIP_PROXY_RENDER_SIZE_100 4 + +/* MovieClip->render_flag */ +#define MCLIP_PROXY_RENDER_UNDISTORT 1 + +#endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index cc77df7e679..27e21290a9b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -54,6 +54,7 @@ struct AnimData; struct Editing; struct SceneStats; struct bGPdata; +struct MovieClip; typedef struct Base { struct Base *next, *prev; @@ -863,6 +864,9 @@ typedef struct Scene { /* Physics simulation settings */ struct PhysicsSettings physics_settings; + + /* Movie Tracking */ + struct MovieClip *clip; /* active movie clip */ } Scene; @@ -1337,7 +1341,6 @@ typedef enum SculptFlags { #define USER_UNIT_OPT_SPLIT 1 #define USER_UNIT_ROT_RADIANS 2 - #ifdef __cplusplus } #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 0c7943ce056..289c7ac2fc3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -37,6 +37,7 @@ #include "DNA_vec_types.h" #include "DNA_outliner_types.h" /* for TreeStoreElem */ #include "DNA_image_types.h" /* ImageUser */ +#include "DNA_movieclip_types.h" /* MovieClipUser */ /* Hum ... Not really nice... but needed for spacebuts. */ #include "DNA_view2d_types.h" @@ -62,6 +63,8 @@ struct bScreen; struct Scene; struct wmOperator; struct wmTimer; +struct MovieClip; +struct MovieClipScopes; /** * The base structure all the other spaces @@ -489,6 +492,32 @@ typedef struct SpaceUserPref { } SpaceUserPref; +typedef struct SpaceClip { + SpaceLink *next, *prev; + ListBase regionbase; /* storage of regions for inactive spaces */ + int spacetype; + + float xof, yof; /* user defined offset, image is centered */ + float xlockof, ylockof; /* user defined offset from locked position */ + float zoom; /* user defined zoom level */ + + struct MovieClipUser user; /* user of clip */ + struct MovieClip *clip; /* clip data */ + struct MovieClipScopes scopes; /* different scoped displayed in space panels */ + + int flag; /* flags */ + short mode; /* editor mode (editing context being displayed) */ + short view; /* type of the clip editor view */ + + int path_length; /* length of displaying path, in frames */ + + /* current stabilization data */ + float loc[2], scale, angle; /* pre-composed stabilization data */ + int pad; + float stabmat[4][4], unistabmat[4][4]; /* current stabilization matrix and the same matrix in unified space, + defined when drawing and used for mouse position calculation */ +} SpaceClip; + /* view3d Now in DNA_view3d_types.h */ @@ -824,6 +853,7 @@ enum { #define TIME_ALL_IMAGE_WIN 64 #define TIME_CONTINUE_PHYSICS 128 #define TIME_NODES 256 +#define TIME_CLIPS 512 /* time->cache */ #define TIME_CACHE_DISPLAY 1 @@ -861,6 +891,33 @@ enum { #define SEQ_PROXY_RENDER_SIZE_100 99 #define SEQ_PROXY_RENDER_SIZE_FULL 100 +/* SpaceClip->flag */ +#define SC_SHOW_MARKER_PATTERN (1<<0) +#define SC_SHOW_MARKER_SEARCH (1<<1) +#define SC_LOCK_SELECTION (1<<2) +#define SC_SHOW_TINY_MARKER (1<<3) +#define SC_SHOW_TRACK_PATH (1<<4) +#define SC_SHOW_BUNDLES (1<<5) +#define SC_MUTE_FOOTAGE (1<<6) +#define SC_HIDE_DISABLED (1<<7) +#define SC_SHOW_NAMES (1<<8) +#define SC_SHOW_GRID (1<<9) +#define SC_SHOW_STABLE (1<<10) +#define SC_MANUAL_CALIBRATION (1<<11) +#define SC_SHOW_GPENCIL (1<<12) +#define SC_SHOW_FILTERS (1<<13) +#define SC_SHOW_GRAPH_FRAMES (1<<14) +#define SC_SHOW_GRAPH_TRACKS (1<<15) +#define SC_SHOW_PYRAMID_LEVELS (1<<16) + +/* SpaceClip->mode */ +#define SC_MODE_TRACKING 0 +#define SC_MODE_RECONSTRUCTION 1 +#define SC_MODE_DISTORTION 2 + +/* SpaceClip->view */ +#define SC_VIEW_CLIP 0 +#define SC_VIEW_GRAPH 1 /* space types, moved from DNA_screen_types.h */ /* Do NOT change order, append on end. types are hardcoded needed */ @@ -885,7 +942,8 @@ enum { SPACE_LOGIC, SPACE_CONSOLE, SPACE_USERPREF, - SPACEICONMAX = SPACE_USERPREF + SPACE_CLIP, + SPACEICONMAX = SPACE_CLIP }; #endif diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h new file mode 100644 index 00000000000..b359ea3544d --- /dev/null +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -0,0 +1,217 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef DNA_TRACKING_TYPES_H +#define DNA_TRACKING_TYPES_H + +/** \file DNA_tracking_types.h + * \ingroup DNA + * \since may-2011 + * \author Sergey Sharybin + */ + +#include "DNA_listBase.h" + +/* match-moving data */ + +struct ImBuf; +struct MovieReconstructedCamera; +struct MovieTrackingCamera; +struct MovieTrackingBundle; +struct MovieTrackingMarker; +struct MovieTrackingTrack; +struct MovieTracking; + +typedef struct MovieReconstructedCamera { + int framenr; + float error; + float mat[4][4]; +} MovieReconstructedCamera; + +typedef struct MovieTrackingCamera { + void *intrinsics; /* intrinsics handle */ + + float sensor_width; /* width of CCD sensor */ + float pixel_aspect; /* pixel aspect ratio */ + float pad; + float focal; /* focal length */ + short units; /* units of focal length user is working with */ + short pad1; + float principal[2]; /* principal point */ + float k1, k2, k3; /* radial distortion */ +} MovieTrackingCamera; + +typedef struct MovieTrackingMarker { + float pos[2]; /* 2d position of marker on frame (in unified 0..1 space) */ + int framenr; /* number of frame marker is associated with */ + int flag; /* Marker's flag (alive, ...) */ +} MovieTrackingMarker; + +typedef struct MovieTrackingTrack { + struct MovieTrackingTrack *next, *prev; + + char name[24]; + + /* ** setings ** */ + float pat_min[2], pat_max[2]; /* positions of left-bottom and right-top corners of pattern (in unified 0..1 space) */ + float search_min[2], search_max[2]; /* positions of left-bottom and right-top corners of search area (in unified 0..1 space) */ + float offset[2]; /* offset to "parenting" point */ + + /* ** track ** */ + int markersnr; /* count of markers in track */ + int last_marker; /* most recently used marker */ + MovieTrackingMarker *markers; /* markers in track */ + + /* ** reconstruction data ** */ + float bundle_pos[3]; /* reconstructed position */ + float error; /* average track reprojection error */ + + int pad; + + /* ** UI editing ** */ + int flag, pat_flag, search_flag; /* flags (selection, ...) */ + short transflag; /* transform flags */ + char pad3[2]; + float color[3]; /* custom color for track */ + + /* tracking algorithm to use; can be KLT or SAD */ + short tracker; + char pad4[2]; + + /* ** SAD tracker settings ** */ + float minimum_correlation; /* minimal correlation which is still treated as successful tracking */ + + /* ** KLT tracker settings ** */ + int pyramid_levels; /* number of pyramid levels to use for KLT tracking */ + char pad5[4]; +} MovieTrackingTrack; + +typedef struct MovieTrackingSettings { + /* ** common tracker settings ** */ + short speed; /* speed of tracking */ + short frames_limit; /* number of frames to be tarcked during single tracking session (if TRACKING_FRAMES_LIMIT is set) */ + short margin; /* margin from frame boundaries */ + char pad[2]; + + int adjframes; /* re-adjust every N frames */ + + /* ** reconstruction settings ** */ + int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ + + /* ** tool settings ** */ + + /* set scale */ + float dist; /* distance between two bundles used for scene scaling */ + + /* cleanup */ + int clean_frames, clean_action; + float clean_error; +} MovieTrackingSettings; + +typedef struct MovieTrackingStabilization { + int flag; + int tot_track, act_track; /* total number and index of active track in list */ + + /* 2d stabilization */ + float maxscale; /* max auto-scale factor */ + MovieTrackingTrack *rot_track; /* track used to stabilize rotation */ + + float locinf, scaleinf, rotinf; /* influence on location, scale and rotation */ + + /* some pre-computing run-time variables */ + int ok, pad; /* are precomputed values and scaled buf relevant? */ + float scale; /* autoscale factor */ + + struct ImBuf *scaleibuf; /* currently scaled ibuf */ +} MovieTrackingStabilization; + +typedef struct MovieTrackingReconstruction { + int flag; + + float error; /* average error of reconstruction */ + + int last_camera; /* most recently used camera */ + int camnr; /* number of reconstructed cameras */ + struct MovieReconstructedCamera *cameras; /* reconstructed cameras */ +} MovieTrackingReconstruction; + +typedef struct MovieTracking { + MovieTrackingSettings settings; /* different tracking-related settings */ + char pad2[4]; + + MovieTrackingCamera camera; /* camera intrinsics */ + ListBase tracks; /* all tracks */ + MovieTrackingReconstruction reconstruction; /* reconstruction data */ + MovieTrackingStabilization stabilization; /* stabilization data */ + MovieTrackingTrack *act_track; /* active track */ +} MovieTracking; + +/* MovieTrackingCamera->units */ +enum { + CAMERA_UNITS_PX = 0, + CAMERA_UNITS_MM +}; + +/* MovieTrackingMarker->flag */ +#define MARKER_DISABLED (1<<0) +#define MARKER_TRACKED (1<<1) +#define MARKER_GRAPH_SEL (1<<2) + +/* MovieTrackingTrack->flag */ +#define TRACK_HAS_BUNDLE (1<<1) +#define TRACK_DISABLE_RED (1<<2) +#define TRACK_DISABLE_GREEN (1<<3) +#define TRACK_DISABLE_BLUE (1<<4) +#define TRACK_HIDDEN (1<<5) +#define TRACK_LOCKED (1<<6) +#define TRACK_CUSTOMCOLOR (1<<7) +#define TRACK_USE_2D_STAB (1<<8) + +/* MovieTrackingSettings->tracker */ +#define TRACKER_KLT 0 +#define TRACKER_SAD 1 + +/* MovieTrackingSettings->speed */ +#define TRACKING_SPEED_FASTEST 0 +#define TRACKING_SPEED_REALTIME 1 +#define TRACKING_SPEED_HALF 2 +#define TRACKING_SPEED_QUARTER 4 +#define TRACKING_SPEED_DOUBLE 5 + +/* MovieTrackingStrabilization->flag */ +#define TRACKING_2D_STABILIZATION (1<<0) +#define TRACKING_AUTOSCALE (1<<1) + +/* MovieTrackingReconstruction->flag */ +#define TRACKING_RECONSTRUCTED (1<<0) + +#define TRACKING_CLEAN_SELECT 0 +#define TRACKING_CLEAN_DELETE_TRACK 1 +#define TRACKING_CLEAN_DELETE_SEGMENT 2 + +#endif diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index f54c83d6612..76d52d5b6d4 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -234,6 +234,11 @@ typedef struct ThemeSpace { char handle_vertex_select[4]; char handle_vertex_size; + + char marker_outline[4], marker[4], act_marker[4], sel_marker[4], dis_marker[4], lock_marker[4]; + char bundle_solid[4]; + char path_before[4], path_after[4]; + char camera_path[4]; char hpad[7]; char preview_back[4]; @@ -279,6 +284,7 @@ typedef struct bTheme { ThemeSpace tlogic; ThemeSpace tuserpref; ThemeSpace tconsole; + ThemeSpace tclip; /* 20 sets of bone colors for this theme */ ThemeWireColor tarm[20]; diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index aaf4186945e..93f4b209712 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -38,6 +38,8 @@ struct Tex; struct SpaceLink; struct Base; struct BoundBox; +struct MovieClip; +struct MovieClipUser; struct RenderInfo; struct RenderEngine; struct bGPdata; @@ -55,6 +57,7 @@ struct wmTimer; #include "DNA_listBase.h" #include "DNA_image_types.h" +#include "DNA_movieclip_types.h" /* ******************************** */ @@ -67,10 +70,12 @@ typedef struct BGpic { struct Image *ima; struct ImageUser iuser; + struct MovieClip *clip; + struct MovieClipUser cuser; float xof, yof, size, blend; short view; short flag; - float pad2; + short source, pad; } BGpic; /* ********************************* */ @@ -146,7 +151,12 @@ typedef struct View3D { float blockscale; short blockhandler[8]; - float viewquat[4], dist, pad1; /* XXX depricated */ + float viewquat[4], dist; /* XXX depricated */ + + float bundle_size; /* size of bundles in reconstructed data */ + short bundle_drawtype; /* display style for bundle */ + + char pad[6]; unsigned int lay_used; /* used while drawing */ @@ -248,6 +258,9 @@ typedef struct View3D { #define V3D_DISPGP 16 #define V3D_LOCK_CAMERA 32 #define V3D_RENDER_SHADOW 64 /* This is a runtime only flag that's used to tell draw_mesh_object() that we're doing a shadow pass instead of a regular draw */ +#define V3D_SHOW_RECONSTRUCTION 128 +#define V3D_SHOW_CAMERAPATH 256 +#define V3D_SHOW_BUNDLENAME 512 /* View3D->around */ #define V3D_CENTER 0 @@ -294,6 +307,12 @@ typedef struct View3D { /* BGPic->flag */ /* may want to use 1 for select ?*/ #define V3D_BGPIC_EXPANDED 2 +#define V3D_BGPIC_CAMERACLIP 4 + +/* BGPic->source */ +/* may want to use 1 for select ?*/ +#define V3D_BGPIC_IMAGE 0 +#define V3D_BGPIC_MOVIE 1 #define RV3D_CAMZOOM_MIN -30 #define RV3D_CAMZOOM_MAX 600 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index a966523d990..ec60fc7b2b8 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -131,6 +131,8 @@ const char *includefiles[] = { "DNA_boid_types.h", "DNA_smoke_types.h", "DNA_speaker_types.h", + "DNA_movieclip_types.h", + "DNA_tracking_types.h", // empty string to indicate end of includefiles "" @@ -1196,4 +1198,6 @@ int main(int argc, char ** argv) #include "DNA_boid_types.h" #include "DNA_smoke_types.h" #include "DNA_speaker_types.h" +#include "DNA_movieclip_types.h" +#include "DNA_tracking_types.h" /* end of list */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 7adfc9a5c16..b40c2936bd5 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -471,6 +471,7 @@ extern StructRNA RNA_SpaceTimeline; extern StructRNA RNA_SpaceUVEditor; extern StructRNA RNA_SpaceUserPreferences; extern StructRNA RNA_SpaceView3D; +extern StructRNA RNA_SpaceClipEditor; extern StructRNA RNA_Speaker; extern StructRNA RNA_SpeedControlSequence; extern StructRNA RNA_Spline; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index ab69addbbdb..1667ca17e37 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -59,6 +59,7 @@ set(DEFSRC rna_mesh.c rna_meta.c rna_modifier.c + rna_movieclip.c rna_nla.c rna_nodetree.c rna_object.c @@ -82,6 +83,7 @@ set(DEFSRC rna_text.c rna_texture.c rna_timeline.c + rna_tracking.c rna_ui.c rna_userdef.c rna_vfont.c diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 891b62f7c79..533d1e2c929 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -2479,6 +2479,8 @@ static RNAProcessItem PROCESS_ITEMS[]= { {"rna_vfont.c", NULL, RNA_def_vfont}, {"rna_wm.c", "rna_wm_api.c", RNA_def_wm}, {"rna_world.c", NULL, RNA_def_world}, + {"rna_movieclip.c", NULL, RNA_def_movieclip}, + {"rna_tracking.c", NULL, RNA_def_tracking}, {NULL, NULL}}; static void rna_generate(BlenderRNA *brna, FILE *f, const char *filename, const char *api_filename) diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index e4692d32338..eed178b238d 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -143,6 +143,7 @@ short RNA_type_to_ID_code(StructRNA *type) if(RNA_struct_is_a(type, &RNA_VectorFont)) return ID_VF; if(RNA_struct_is_a(type, &RNA_World)) return ID_WO; if(RNA_struct_is_a(type, &RNA_WindowManager)) return ID_WM; + if(RNA_struct_is_a(type, &RNA_MovieClip)) return ID_MC; return 0; } @@ -177,6 +178,7 @@ StructRNA *ID_code_to_RNA_type(short idcode) case ID_VF: return &RNA_VectorFont; case ID_WO: return &RNA_World; case ID_WM: return &RNA_WindowManager; + case ID_MC: return &RNA_MovieClip; default: return &RNA_ID; } } diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index fdbb4f09f93..e1e4f3929b2 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -64,9 +64,11 @@ EnumPropertyItem constraint_type_items[] ={ {CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To", "Legacy tracking constraint prone to twisting artifacts"}, {0, "", 0, "Relationship", ""}, {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action", ""}, + {CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""}, {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of", ""}, {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor", ""}, {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path", ""}, + {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""}, {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""}, {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint", ""}, {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script", ""}, @@ -156,6 +158,10 @@ static StructRNA *rna_ConstraintType_refine(struct PointerRNA *ptr) return &RNA_CopyTransformsConstraint; case CONSTRAINT_TYPE_PIVOT: return &RNA_PivotConstraint; + case CONSTRAINT_TYPE_FOLLOWTRACK: + return &RNA_FollowTrackConstraint; + case CONSTRAINT_TYPE_CAMERASOLVER: + return &RNA_CameraSolverConstraint; default: return &RNA_UnknownType; } @@ -2026,6 +2032,70 @@ static void rna_def_constraint_pivot(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); } +static void rna_def_constraint_follow_track(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem reference_items[] = { + {FOLLOWTRACK_TRACK, "TRACK", 0, "Track", "Use 2D track position as reference"}, + {FOLLOWTRACK_BUNDLE, "BUNDLE", 0, "Bundle", "Use 3D reconstructed bundle position as reference"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "FollowTrackConstraint", "Constraint"); + RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Locks motion to the target motion track"); + RNA_def_struct_sdna_from(srna, "bFollowTrackConstraint", "data"); + + /* movie clip */ + prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "clip"); + RNA_def_property_ui_text(prop, "Movie Clip", "Movie Clip to get tracking data from"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* track */ + prop= RNA_def_property(srna, "track", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "track"); + RNA_def_property_ui_text(prop, "Track", "Movie tracking track to follow"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* reference */ + prop= RNA_def_property(srna, "reference", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "reference"); + RNA_def_property_enum_items(prop, reference_items); + RNA_def_property_ui_text(prop, "Reference", "Reference source to follow"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + /* use default clip */ + prop= RNA_def_property(srna, "use_active_clip", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", FOLLOWTRACK_ACTIVECLIP); + RNA_def_property_ui_text(prop, "Active Clip", "Use active clip defined in scene"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); +} + +static void rna_def_constraint_camera_solver(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "CameraSolverConstraint", "Constraint"); + RNA_def_struct_ui_text(srna, "Follow Track Constraint", "Locks motion to the reconstructed camera movenment"); + RNA_def_struct_sdna_from(srna, "bCameraSolverConstraint", "data"); + + /* movie clip */ + prop= RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "clip"); + RNA_def_property_ui_text(prop, "Movie Clip", "Movie Clip to get tracking data from"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update"); + + /* use default clip */ + prop= RNA_def_property(srna, "use_active_clip", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CAMERASOLVER_ACTIVECLIP); + RNA_def_property_ui_text(prop, "Active Clip", "Use active clip defined in scene"); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); +} + /* base struct for constraints */ void RNA_def_constraint(BlenderRNA *brna) { @@ -2136,6 +2206,8 @@ void RNA_def_constraint(BlenderRNA *brna) rna_def_constraint_damped_track(brna); rna_def_constraint_spline_ik(brna); rna_def_constraint_pivot(brna); + rna_def_constraint_follow_track(brna); + rna_def_constraint_camera_solver(brna); } #endif diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 2e3b371c3f3..a137ddc6bc0 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -177,6 +177,8 @@ void RNA_def_userdef(struct BlenderRNA *brna); void RNA_def_vfont(struct BlenderRNA *brna); void RNA_def_wm(struct BlenderRNA *brna); void RNA_def_world(struct BlenderRNA *brna); +void RNA_def_movieclip(struct BlenderRNA *brna); +void RNA_def_tracking(struct BlenderRNA *brna); /* Common Define functions */ @@ -290,6 +292,7 @@ void RNA_def_main_armatures(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_actions(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_particles(BlenderRNA *brna, PropertyRNA *cprop); void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop); +void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop); /* ID Properties */ diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c index 076bdfe1964..be03da6839d 100644 --- a/source/blender/makesrna/intern/rna_main.c +++ b/source/blender/makesrna/intern/rna_main.c @@ -245,6 +245,12 @@ static void rna_Main_wm_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) rna_iterator_listbase_begin(iter, &bmain->wm, NULL); } +static void rna_Main_movieclips_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Main *bmain= (Main*)ptr->data; + rna_iterator_listbase_begin(iter, &bmain->movieclip, NULL); +} + #ifdef UNIT_TEST static PointerRNA rna_Test_test_get(PointerRNA *ptr) @@ -307,6 +313,7 @@ void RNA_def_main(BlenderRNA *brna) {"actions", "Action", "rna_Main_action_begin", "Actions", "Action datablocks", RNA_def_main_actions}, {"particles", "ParticleSettings", "rna_Main_particle_begin", "Particles", "Particle datablocks", RNA_def_main_particles}, {"grease_pencil", "GreasePencil", "rna_Main_gpencil_begin", "Grease Pencil", "Grease Pencil datablocks", RNA_def_main_gpencil}, + {"movieclips", "MovieClip", "rna_Main_movieclips_begin", "Movie Clips", "Movie Clip datablocks", RNA_def_main_movieclips}, {NULL, NULL, NULL, NULL, NULL, NULL}}; int i; diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index dfa368d6b94..f568f6de855 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -66,6 +66,7 @@ #include "BKE_node.h" #include "BKE_depsgraph.h" #include "BKE_speaker.h" +#include "BKE_movieclip.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" @@ -85,6 +86,7 @@ #include "DNA_particle_types.h" #include "DNA_vfont_types.h" #include "DNA_node_types.h" +#include "DNA_movieclip_types.h" #include "ED_screen.h" @@ -521,6 +523,26 @@ void rna_Main_particles_remove(Main *bmain, ReportList *reports, ParticleSetting /* XXX python now has invalid pointer? */ } +MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *reports, const char *filepath) +{ + MovieClip *clip; + + errno= 0; + clip= BKE_add_movieclip_file(filepath); + + if(!clip) + BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s.", filepath, errno ? strerror(errno) : "Unable to load movie clip"); + + return clip; +} + +void rna_Main_movieclips_remove(Main *bmain, MovieClip *clip) +{ + unlink_movieclip(bmain, clip); + free_libblock(&bmain->movieclip, clip); + /* XXX python now has invalid pointer? */ +} + /* tag functions, all the same */ void rna_Main_cameras_tag(Main *bmain, int value) { tag_main_lb(&bmain->camera, value); } void rna_Main_scenes_tag(Main *bmain, int value) { tag_main_lb(&bmain->scene, value); } @@ -550,6 +572,7 @@ void rna_Main_armatures_tag(Main *bmain, int value) { tag_main_lb(&bmain->armatu void rna_Main_actions_tag(Main *bmain, int value) { tag_main_lb(&bmain->action, value); } void rna_Main_particles_tag(Main *bmain, int value) { tag_main_lb(&bmain->particle, value); } void rna_Main_gpencil_tag(Main *bmain, int value) { tag_main_lb(&bmain->gpencil, value); } +void rna_Main_movieclips_tag(Main *bmain, int value) { tag_main_lb(&bmain->text, value); } static int rna_Main_cameras_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_CA); } static int rna_Main_scenes_is_updated_get(PointerRNA *ptr) { return DAG_id_type_tagged(ptr->data, ID_SCE); } @@ -1468,5 +1491,36 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL); } +void RNA_def_main_movieclips(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "BlendDataMovieClips"); + srna= RNA_def_struct(brna, "BlendDataMovieClips", NULL); + RNA_def_struct_sdna(srna, "Main"); + RNA_def_struct_ui_text(srna, "Main Movie Clips", "Collection of movie clips"); + + func= RNA_def_function(srna, "tag", "rna_Main_movieclips_tag"); + parm= RNA_def_boolean(func, "value", 0, "Value", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "remove", "rna_Main_movieclips_remove"); + RNA_def_function_ui_description(func, "Remove a movie clip from the current blendfile."); + parm= RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_NEVER_NULL); + + /* load func */ + func= RNA_def_function(srna, "load", "rna_Main_movieclip_load"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a new movie clip to the main database from a file"); + parm= RNA_def_string_file_path(func, "filepath", "Path", FILE_MAXDIR + FILE_MAXFILE, "", "path for the datablock"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm= RNA_def_pointer(func, "clip", "MovieClip", "", "New movie clip datablock"); + RNA_def_function_return(func, parm); +} + #endif diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c new file mode 100644 index 00000000000..afdf3cd9c46 --- /dev/null +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -0,0 +1,278 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/makesrna/intern/rna_movieclip.c + * \ingroup RNA + */ + + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "RNA_define.h" + +#include "rna_internal.h" + +#include "DNA_movieclip_types.h" +#include "DNA_scene_types.h" + +#include "WM_types.h" + +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" + +#ifdef RNA_RUNTIME + +#include "BKE_depsgraph.h" + +static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + BKE_movieclip_reload(clip); + DAG_id_tag_update(&clip->id, 0); +} + +static void rna_MovieClip_size_get(PointerRNA *ptr, int *values) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + values[0]= clip->lastsize[0]; + values[1]= clip->lastsize[1]; +} + +static void rna_MovieClip_resolution_get(PointerRNA *ptr, float *values) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + ImBuf *ibuf; + + ibuf= BKE_movieclip_get_ibuf(clip, NULL); + if (ibuf) { + values[0]= ibuf->ppm[0]; + values[1]= ibuf->ppm[1]; + + IMB_freeImBuf(ibuf); + } + else { + values[0]= 0; + values[1]= 0; + } +} + +#else + +static void rna_def_movieclip_proxy(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static const EnumPropertyItem clip_tc_items[]= { + {IMB_TC_NONE, "NONE", 0, "No TC in use", ""}, + {IMB_TC_RECORD_RUN, "RECORD_RUN", 0, "Record Run", "use images in the order as they are recorded"}, + {IMB_TC_FREE_RUN, "FREE_RUN", 0, "Free Run", "use global timestamp written by recording device"}, + {IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN, "FREE_RUN_REC_DATE", 0, "Free Run (rec date)", "interpolate a global timestamp using the record date and time written by recording device"}, + {0, NULL, 0, NULL, NULL}}; + + srna = RNA_def_struct(brna, "MovieClipProxy", NULL); + RNA_def_struct_ui_text(srna, "Movie Clip Proxy", "Proxy parameters for a movie clip"); + RNA_def_struct_sdna(srna, "MovieClipProxy"); + + /* build proxy sized */ + prop= RNA_def_property(srna, "build_25", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_25); + RNA_def_property_ui_text(prop, "25%", "Build 25% proxy resolution"); + + prop= RNA_def_property(srna, "build_50", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_50); + RNA_def_property_ui_text(prop, "50%", "Build 50% proxy resolution"); + + prop= RNA_def_property(srna, "build_75", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_75); + RNA_def_property_ui_text(prop, "75%", "Build 75% proxy resolution"); + + prop= RNA_def_property(srna, "build_100", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_size_flag", IMB_PROXY_100); + RNA_def_property_ui_text(prop, "100%", "Build 100% proxy resolution"); + + prop= RNA_def_property(srna, "build_undistorted", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_flag", MCLIP_PROXY_BUILD_UNDISTORT); + RNA_def_property_ui_text(prop, "Build Undistorted", "Also build undistorted proxies for selected sizes"); + + /* build timecodes */ + prop= RNA_def_property(srna, "build_record_run", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_RECORD_RUN); + RNA_def_property_ui_text(prop, "Rec Run", "Build record run time code index"); + + prop= RNA_def_property(srna, "build_free_run", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_FREE_RUN); + RNA_def_property_ui_text(prop, "Free Run", "Build free run time code index"); + + prop= RNA_def_property(srna, "build_free_run_rec_date", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "build_tc_flag", IMB_TC_INTERPOLATED_REC_DATE_FREE_RUN); + RNA_def_property_ui_text(prop, "Free Run (Rec Date)", "Build free run time code index using Record Date/Time"); + + /* quality of proxied image */ + prop= RNA_def_property(srna, "quality", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "quality"); + RNA_def_property_ui_text(prop, "Quality", "JPEG Quality of proxies to build"); + RNA_def_property_ui_range(prop, 1, 100, 1, 0); + + prop= RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "tc"); + RNA_def_property_enum_items(prop, clip_tc_items); + RNA_def_property_ui_text(prop, "Timecode", ""); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* directory */ + prop= RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH); + RNA_def_property_string_sdna(prop, NULL, "dir"); + RNA_def_property_ui_text(prop, "Directory", "Location to store the proxy files"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update"); +} + +static void rna_def_moviecliUser(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem clip_render_size_items[] = { + {MCLIP_PROXY_RENDER_SIZE_25, "PROXY_25", 0, "Proxy size 25%", ""}, + {MCLIP_PROXY_RENDER_SIZE_50, "PROXY_50", 0, "Proxy size 50%", ""}, + {MCLIP_PROXY_RENDER_SIZE_75, "PROXY_75", 0, "Proxy size 75%", ""}, + {MCLIP_PROXY_RENDER_SIZE_100, "PROXY_100", 0, "Proxy size 100%", ""}, + {MCLIP_PROXY_RENDER_SIZE_FULL, "FULL", 0, "No proxy, full render", ""}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "MovieClipUser", NULL); + RNA_def_struct_ui_text(srna, "Movie Clip User", "Parameters defining how a MovieClip datablock is used by another datablock"); + + prop= RNA_def_property(srna, "current_frame", PROP_INT, PROP_TIME); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_sdna(prop, NULL, "framenr"); + RNA_def_property_range(prop, MINAFRAME, MAXFRAME); + RNA_def_property_ui_text(prop, "Current Frame", "Current frame number in movie or image sequence"); + + /* render size */ + prop= RNA_def_property(srna, "proxy_render_size", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "render_size"); + RNA_def_property_enum_items(prop, clip_render_size_items); + RNA_def_property_ui_text(prop, "Proxy render size", "Draw preview using full resolution or different proxy resolutions"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* render undistorted */ + prop= RNA_def_property(srna, "use_render_undistorted", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "render_flag", MCLIP_PROXY_RENDER_UNDISTORT); + RNA_def_property_ui_text(prop, "Render Undistorted", "Draw preview using undistorted proxy"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); +} + +static void rna_def_movieClipScopes(BlenderRNA *brna) +{ + StructRNA *srna; + + srna= RNA_def_struct(brna, "MovieClipScopes", NULL); + RNA_def_struct_ui_text(srna, "MovieClipScopes", "Scopes for statistical view of a movie clip"); +} + + +static void rna_def_movieclip(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem clip_source_items[]= { + {MCLIP_SRC_SEQUENCE, "SEQUENCE", 0, "Image Sequence", "Multiple image files, as a sequence"}, + {MCLIP_SRC_MOVIE, "MOVIE", 0, "Movie File", "Movie file"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "MovieClip", "ID"); + RNA_def_struct_ui_text(srna, "MovieClip", "MovieClip datablock referencing an external movie file"); + RNA_def_struct_ui_icon(srna, ICON_SEQUENCE); + + prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_property_ui_text(prop, "File Path", "Filename of the text file"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update"); + + prop= RNA_def_property(srna, "tracking", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTracking"); + + prop= RNA_def_property(srna, "proxy", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieClipProxy"); + + /* use proxy */ + prop= RNA_def_property(srna, "use_proxy", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY); + RNA_def_property_ui_text(prop, "Use Proxy / Timecode", "Use a preview proxy and/or timecode index for this clip"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + prop= RNA_def_int_vector(srna, "size" , 2 , NULL , 0, 0, "Size" , "Width and height in pixels, zero when image data cant be loaded" , 0 , 0); + RNA_def_property_int_funcs(prop, "rna_MovieClip_size_get" , NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_float_vector(srna, "resolution" , 2 , NULL , 0, 0, "Resolution" , "X/Y pixels per meter" , 0 , 0); + RNA_def_property_float_funcs(prop, "rna_MovieClip_resolution_get", NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop= RNA_def_property(srna, "display_aspect", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "aspx"); + RNA_def_property_array(prop, 2); + RNA_def_property_range(prop, 0.1f, 5000.0f); + RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); + RNA_def_property_ui_text(prop, "Display Aspect", "Display Aspect for this clip, does not affect rendering"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* source */ + prop= RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, clip_source_items); + RNA_def_property_ui_text(prop, "Source", "Where the clip comes from"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + /* custom proxy directory */ + prop= RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", MCLIP_USE_PROXY_CUSTOM_DIR); + RNA_def_property_ui_text(prop, "Proxy Custom Directory", "Use a custom directory to store data"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_MovieClip_reload_update"); + + /* grease pencil */ + prop= RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "gpd"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "GreasePencil"); + RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this movie clip"); +} + +void RNA_def_movieclip(BlenderRNA *brna) +{ + rna_def_movieclip(brna); + rna_def_movieclip_proxy(brna); + rna_def_moviecliUser(brna); + rna_def_movieClipScopes(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 63fce2d9edb..4245d606f61 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1074,6 +1074,15 @@ static void rna_Scene_update_active_object_data(Main *UNUSED(bmain), Scene *scen } } +static void rna_SceneCamera_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + Scene *scene= (Scene*)ptr->id.data; + Object *camera= scene->camera; + + if(camera) + DAG_id_tag_update(&camera->id, 0); +} + #else static void rna_def_transform_orientation(BlenderRNA *brna) @@ -2428,13 +2437,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_int_sdna(prop, NULL, "xsch"); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution X", "Number of horizontal pixels in the rendered image"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "resolution_y", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "ysch"); RNA_def_property_range(prop, 4, 10000); RNA_def_property_ui_text(prop, "Resolution Y", "Number of vertical pixels in the rendered image"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "resolution_percentage", PROP_INT, PROP_PERCENTAGE); RNA_def_property_int_sdna(prop, NULL, "size"); @@ -2459,13 +2468,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "xasp"); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect X", "Horizontal aspect ratio - for anamorphic or non-square pixel output"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); prop= RNA_def_property(srna, "pixel_aspect_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "yasp"); RNA_def_property_range(prop, 1.0f, 200.0f); RNA_def_property_ui_text(prop, "Pixel Aspect Y", "Vertical aspect ratio - for anamorphic or non-square pixel output"); - RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE|ND_RENDER_OPTIONS, "rna_SceneCamera_update"); /* JPEG and AVI JPEG */ @@ -3752,6 +3761,14 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "TransformOrientation"); RNA_def_property_ui_text(prop, "Transform Orientations", ""); + /* acctive MovieClip */ + prop= RNA_def_property(srna, "active_clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "clip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_ui_text(prop, "Active Movie Clip", "Active movie clip used for constraints and viewport drawing"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + /* Nestled Data */ rna_def_tool_settings(brna); rna_def_unit_settings(brna); diff --git a/source/blender/makesrna/intern/rna_screen.c b/source/blender/makesrna/intern/rna_screen.c index 795ea417d90..c8792ef30f3 100644 --- a/source/blender/makesrna/intern/rna_screen.c +++ b/source/blender/makesrna/intern/rna_screen.c @@ -288,6 +288,11 @@ static void rna_def_screen(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_NODES); RNA_def_property_ui_text(prop, "Node Editors", ""); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_Screen_redraw_update"); + + prop= RNA_def_property(srna, "use_play_clip_editors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "redraws_flag", TIME_CLIPS); + RNA_def_property_ui_text(prop, "Clip Editors", ""); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_TIME, "rna_Screen_redraw_update"); } void RNA_def_screen(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 0dc4ca343fe..580f759c38f 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -70,6 +70,7 @@ EnumPropertyItem space_type_items[] = { {SPACE_LOGIC, "LOGIC_EDITOR", 0, "Logic Editor", ""}, {SPACE_CONSOLE, "CONSOLE", 0, "Python Console", ""}, {SPACE_USERPREF, "USER_PREFERENCES", 0, "User Preferences", ""}, + {SPACE_CLIP, "CLIP_EDITOR", 0, "Clip Editor", ""}, {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem draw_channels_items[] = { @@ -126,6 +127,7 @@ EnumPropertyItem viewport_shade_items[] = { #include "ED_screen.h" #include "ED_view3d.h" #include "ED_sequencer.h" +#include "ED_clip.h" #include "IMB_imbuf_types.h" @@ -166,6 +168,8 @@ static StructRNA* rna_Space_refine(struct PointerRNA *ptr) return &RNA_SpaceConsole; case SPACE_USERPREF: return &RNA_SpaceUserPreferences; + case SPACE_CLIP: + return &RNA_SpaceClipEditor; default: return &RNA_Space; } @@ -883,6 +887,15 @@ static void rna_BackgroundImage_opacity_set(PointerRNA *ptr, float value) bgpic->blend = 1.0f - value; } +static BGpic *rna_BackgroundImage_add(View3D *v3d) +{ + BGpic *bgpic= ED_view3D_background_image_add(v3d);; + + WM_main_add_notifier(NC_SPACE|ND_SPACE_VIEW3D, NULL); + + return bgpic; +} + /* Space Node Editor */ static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, PointerRNA value) @@ -955,6 +968,34 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C, return item; } +static void rna_SpaceClipEditor_clip_set(PointerRNA *ptr, PointerRNA value) +{ + SpaceClip *sc= (SpaceClip*)(ptr->data); + + ED_space_clip_set(NULL, sc, (MovieClip*)value.data); +} + +static void rna_SpaceClipEditor_clip_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + SpaceClip *sc= (SpaceClip*)(ptr->data); + + sc->scopes.ok= 0; +} + +static void rna_SpaceClipEditor_lock_selection_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + SpaceClip *sc= (SpaceClip*)(ptr->data); + + sc->xlockof= 0.f; + sc->ylockof= 0.f; +} + +static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + ScrArea *sa= rna_area_from_space(ptr); + ED_area_tag_refresh(sa); +} + #else static void rna_def_space(BlenderRNA *brna) @@ -1170,21 +1211,46 @@ static void rna_def_background_image(BlenderRNA *brna) {(1< +#include + +#include "MEM_guardedalloc.h" + +#include "BKE_movieclip.h" +#include "BKE_tracking.h" + +#include "RNA_define.h" + +#include "rna_internal.h" + +#include "DNA_movieclip_types.h" +#include "DNA_scene_types.h" + +#include "WM_types.h" + +#ifdef RNA_RUNTIME + +#include "BKE_depsgraph.h" +#include "BKE_node.h" + +#include "IMB_imbuf.h" + +#include "WM_api.h" + +static void rna_tracking_tracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + rna_iterator_listbase_begin(iter, &clip->tracking.tracks, NULL); +} + +static void rna_tracking_tracks_add(MovieTracking *tracking, int frame, int number) +{ + int a; + + for(a= 0; aid.data; + + return rna_pointer_inherit_refine(ptr, &RNA_MovieTrackingTrack, clip->tracking.act_track); +} + +static void rna_tracking_active_track_set(PointerRNA *ptr, PointerRNA value) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingTrack *track= (MovieTrackingTrack *)value.data; + int index= BLI_findindex(&clip->tracking.tracks, track); + + if(index>=0) clip->tracking.act_track= track; + else clip->tracking.act_track= NULL; +} + +void rna_trackingTrack_name_set(PointerRNA *ptr, const char *value) +{ + MovieClip *clip= (MovieClip *)ptr->id.data; + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + BLI_strncpy(track->name, value, sizeof(track->name)); + + BKE_track_unique_name(&clip->tracking, track); +} + +static void rna_tracking_trackerPattern_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + BKE_tracking_clamp_track(track, CLAMP_PAT_DIM); +} + +static void rna_tracking_trackerSearch_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); +} + +static void rna_tracking_trackerAlgorithm_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + if(track->tracker==TRACKER_KLT) + BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); + else + BKE_tracking_clamp_track(track, CLAMP_SEARCH_DIM); +} + +static void rna_tracking_trackerPyramid_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); +} + +static int rna_tracking_markers_length(PointerRNA *ptr) +{ + MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; + + return track->markersnr; +} + +static float rna_trackingCamera_focal_mm_get(PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingCamera *camera= &clip->tracking.camera; + float val= camera->focal; + + if(clip->lastsize[0]) + val= val*camera->sensor_width/(float)clip->lastsize[0]; + + return val; +} + +static void rna_trackingCamera_focal_mm_set(PointerRNA *ptr, float value) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingCamera *camera= &clip->tracking.camera; + + if(clip->lastsize[0]) + value= clip->lastsize[0]*value/camera->sensor_width; + + camera->focal= value; +} + +static int rna_track_2d_stabilization(CollectionPropertyIterator *UNUSED(iter), void *data) +{ + MovieTrackingTrack *track= (MovieTrackingTrack*)data; + + if((track->flag&TRACK_USE_2D_STAB)==0) + return 1; + + return 0; +} + +static void rna_tracking_stabTracks_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + rna_iterator_listbase_begin(iter, &clip->tracking.tracks, rna_track_2d_stabilization); +} + +static int rna_tracking_stabTracks_active_index_get(PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + return clip->tracking.stabilization.act_track; +} + +static void rna_tracking_stabTracks_active_index_set(PointerRNA *ptr, int value) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + clip->tracking.stabilization.act_track= value; +} + +static void rna_tracking_stabTracks_active_index_range(PointerRNA *ptr, int *min, int *max) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + + *min= 0; + *max= clip->tracking.stabilization.tot_track-1; + *max= MAX2(0, *max); +} + +static void rna_tracking_flushUpdate(Main *UNUSED(bmain), Scene *scene, PointerRNA *ptr) +{ + MovieClip *clip= (MovieClip*)ptr->id.data; + MovieTrackingStabilization *stab= &clip->tracking.stabilization; + + stab->ok= 0; + + nodeUpdateID(scene->nodetree, &clip->id); + + WM_main_add_notifier(NC_SCENE|ND_NODES, NULL); + DAG_id_tag_update(&clip->id, 0); +} + +/* API */ + +static MovieTrackingMarker *rna_trackingTrack_marker_find_frame(MovieTrackingTrack *track, int framenr) +{ + return BKE_tracking_get_marker(track, framenr); +} + +#else + +static int rna_matrix_dimsize_4x4[]= {4, 4}; + +static void rna_def_trackingSettings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem speed_items[] = { + {0, "FASTEST", 0, "Fastest", "Track as fast as it's possible"}, + {TRACKING_SPEED_DOUBLE, "DOUBLE", 0, "Double", "Track with double speed"}, + {TRACKING_SPEED_REALTIME, "REALTIME", 0, "Realtime", "Track with realtime speed"}, + {TRACKING_SPEED_HALF, "HALF", 0, "Half", "Track with half of realtime speed"}, + {TRACKING_SPEED_QUARTER, "QUARTER", 0, "Quarter", "Track with quarter of realtime speed"}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem cleanup_items[] = { + {TRACKING_CLEAN_SELECT, "SELECT", 0, "Select", "Select unclean tracks"}, + {TRACKING_CLEAN_DELETE_TRACK, "DELETE_TRACK", 0, "Delete Track", "Delete unclean tracks"}, + {TRACKING_CLEAN_DELETE_SEGMENT, "DELETE_SEGMENTS", 0, "Delete Segments", "Delete unclean segments of tracks"}, + {0, NULL, 0, NULL, NULL} + }; + + srna= RNA_def_struct(brna, "MovieTrackingSettings", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking settings", "Match moving settings"); + + /* speed */ + prop= RNA_def_property(srna, "speed", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, speed_items); + RNA_def_property_ui_text(prop, "Speed", "Speed to make tracking with"); + + /* limit frames */ + prop= RNA_def_property(srna, "frames_limit", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "frames_limit"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Frames Limit", "Amount of frames to be tracked during single tracking operation"); + + /* adjust frames */ + prop= RNA_def_property(srna, "frames_adjust", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "adjframes"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Adjust Frames", "Automatically re-adjust marker position using position on each N frames. 0 means only keyframed position is used"); + + /* margin */ + prop= RNA_def_property(srna, "margin", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "margin"); + RNA_def_property_range(prop, 0, 300); + RNA_def_property_ui_text(prop, "Margin", "Margin for markers from image boundary"); + + /* keyframe_a */ + prop= RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe1"); + RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); + + /* keyframe_b */ + prop= RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe2"); + RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); + + /* tool settings */ + + /* distance */ + prop= RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "dist"); + RNA_def_property_ui_text(prop, "Distance", "Distance between two bundles used for scene scaling"); + + /* frames count */ + prop= RNA_def_property(srna, "clean_frames", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "clean_frames"); + RNA_def_property_range(prop, 0, INT_MAX); + RNA_def_property_ui_text(prop, "Tracked Frames", "Effect on tracks which are tracked less than the specified amount of frames"); + + /* reprojection error */ + prop= RNA_def_property(srna, "clean_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "clean_error"); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_text(prop, "Reprojection Error", "Effect on tracks which have a larger reprojection error"); + + /* cleanup action */ + prop= RNA_def_property(srna, "clean_action", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "clean_action"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, cleanup_items); + RNA_def_property_ui_text(prop, "Action", "Cleanup action to execute"); +} + +static void rna_def_trackingCamera(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem camera_units_items[] = { + {CAMERA_UNITS_PX, "PIXELS", 0, "px", "Use pixels for units of focal length"}, + {CAMERA_UNITS_MM, "MILLIMETERS", 0, "mm", "Use millimeters for units of focal length"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "MovieTrackingCamera", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking camera data", "Match-moving camera data for tracking"); + + /* Sensor */ + prop= RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "sensor_width"); + RNA_def_property_range(prop, 0.0f, 500.0f); + RNA_def_property_ui_text(prop, "Sensor", "Width of CCD sensor in millimeters"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* Focal Length */ + prop= RNA_def_property(srna, "focal_length", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "focal"); + RNA_def_property_range(prop, 0.0f, 5000.0f); + RNA_def_property_float_funcs(prop, "rna_trackingCamera_focal_mm_get", "rna_trackingCamera_focal_mm_set", NULL); + RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* Focal Length in pixels */ + prop= RNA_def_property(srna, "focal_length_pixels", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "focal"); + RNA_def_property_range(prop, 0.0f, 5000.0f); + RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* Units */ + prop= RNA_def_property(srna, "units", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "units"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, camera_units_items); + RNA_def_property_ui_text(prop, "Units", "Units used for camera focal length"); + + /* Principal Point */ + prop= RNA_def_property(srna, "principal", PROP_FLOAT, PROP_NONE); + RNA_def_property_array(prop, 2); + RNA_def_property_float_sdna(prop, NULL, "principal"); + RNA_def_property_ui_text(prop, "Principal Point", "Optical center of lens"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* Radial distortion parameters */ + prop= RNA_def_property(srna, "k1", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "k1"); + RNA_def_property_ui_range(prop, -10, 10, .1, 3); + RNA_def_property_ui_text(prop, "K1", "First coefficient of third order polynomial radial distortion"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + + prop= RNA_def_property(srna, "k2", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "k2"); + RNA_def_property_ui_range(prop, -10, 10, .1, 3); + RNA_def_property_ui_text(prop, "K2", "Second coefficient of third order polynomial radial distortion"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + + prop= RNA_def_property(srna, "k3", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "k3"); + RNA_def_property_ui_range(prop, -10, 10, .1, 3); + RNA_def_property_ui_text(prop, "K3", "Third coefficient of third order polynomial radial distortion"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + + /* pixel aspect */ + prop= RNA_def_property(srna, "pixel_aspect", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "pixel_aspect"); + RNA_def_property_range(prop, 0.1f, 5000.0f); + RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); + RNA_def_property_ui_text(prop, "Pixel Aspect", "Pixel aspect ratio"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); +} + +static void rna_def_trackingMarker(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MovieTrackingMarker", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking marker data", "Match-moving marker data for tracking"); + + /* position */ + prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5); + RNA_def_property_float_sdna(prop, NULL, "pos"); + RNA_def_property_ui_text(prop, "Position", "Marker position at frame in normalized coordinates"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* frame */ + prop= RNA_def_property(srna, "frame", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* can't be safty edited for now, need to re-sort markers array after change */ + RNA_def_property_int_sdna(prop, NULL, "framenr"); + RNA_def_property_ui_text(prop, "Frame", "Frame number marker is keyframed on"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + + /* enable */ + prop= RNA_def_property(srna, "enable", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MARKER_DISABLED); + RNA_def_property_ui_text(prop, "Enable", "Is marker enabled for current frame"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); +} + +static void rna_def_trackingTrack(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + FunctionRNA *func; + PropertyRNA *parm; + + static EnumPropertyItem tracker_items[] = { + {TRACKER_SAD, "SAD", 0, "SAD", "Sum of Absolute Differences tracker"}, + {TRACKER_KLT, "KLT", 0, "KLT", "Kanade–Lucas–Tomasi racker"}, + {0, NULL, 0, NULL, NULL}}; + + rna_def_trackingMarker(brna); + + srna= RNA_def_struct(brna, "MovieTrackingTrack", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking track data", "Match-moving track data for tracking"); + RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA); + + /* name */ + prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", "Unique name of track"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_trackingTrack_name_set"); + RNA_def_property_string_maxlength(prop, MAX_ID_NAME); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, NULL); + RNA_def_struct_name_property(srna, prop); + + /* Pattern */ + prop= RNA_def_property(srna, "pattern_min", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5); + RNA_def_property_float_sdna(prop, NULL, "pat_min"); + RNA_def_property_ui_text(prop, "Pattern Min", "Left-bottom corner of pattern area in normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); + + prop= RNA_def_property(srna, "pattern_max", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5); + RNA_def_property_float_sdna(prop, NULL, "pat_max"); + RNA_def_property_ui_text(prop, "Pattern Max", "Right-bottom corner of pattern area in normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPattern_update"); + + /* Search */ + prop= RNA_def_property(srna, "search_min", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5); + RNA_def_property_float_sdna(prop, NULL, "search_min"); + RNA_def_property_ui_text(prop, "Search Min", "Left-bottom corner of search area in normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); + + prop= RNA_def_property(srna, "search_max", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 5); + RNA_def_property_float_sdna(prop, NULL, "search_max"); + RNA_def_property_ui_text(prop, "Search Max", "Right-bottom corner of search area in normalized coordinates relative to marker position"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerSearch_update"); + + /* tracking algorithm */ + prop= RNA_def_property(srna, "tracker", PROP_ENUM, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_enum_items(prop, tracker_items); + RNA_def_property_ui_text(prop, "Tracker", "Tracking algorithm to use"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerAlgorithm_update"); + + /* pyramid level for pyramid klt tracking */ + prop= RNA_def_property(srna, "pyramid_levels", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "pyramid_levels"); + RNA_def_property_range(prop, 1, 16); + RNA_def_property_ui_text(prop, "Pyramid levels", "Number of pyramid levels for KLT tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update"); + + /* minmal correlation - only used for SAD tracker */ + prop= RNA_def_property(srna, "minimum_correlation", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_float_sdna(prop, NULL, "minimum_correlation"); + RNA_def_property_range(prop, -1.0f, 1.0f); + RNA_def_property_ui_range(prop, -1.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Correlation", "Minimal value of correlation between mathed pattern and reference which is still treated as successful tracking"); + + /* markers */ + prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingMarker"); + RNA_def_property_collection_sdna(prop, NULL, "markers", "markersnr"); + RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, "rna_tracking_markers_length", NULL, NULL, NULL); + RNA_def_property_ui_text(prop, "Markers", "Collection of markers in track"); + + /* ** channels ** */ + + /* use_red_channel */ + prop= RNA_def_property(srna, "use_red_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_RED); + RNA_def_property_ui_text(prop, "Use Red Channel", "Use red channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_green_channel */ + prop= RNA_def_property(srna, "use_green_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_GREEN); + RNA_def_property_ui_text(prop, "Use Green Channel", "Use green channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* use_blue_channel */ + prop= RNA_def_property(srna, "use_blue_channel", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TRACK_DISABLE_BLUE); + RNA_def_property_ui_text(prop, "Use Blue Channel", "Use blue channel from footage for tracking"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* has bundle */ + prop= RNA_def_property(srna, "has_bundle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HAS_BUNDLE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Has Bundle", "True if track has a valid bundle"); + + /* bundle position */ + prop= RNA_def_property(srna, "bundle", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_float_sdna(prop, NULL, "bundle_pos"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Bundle", "Position of bundle reconstructed from this track"); + + /* hide */ + prop= RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_HIDDEN); + RNA_def_property_ui_text(prop, "Hide", "Track is hidden"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* locked */ + prop= RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_LOCKED); + RNA_def_property_ui_text(prop, "Lock", "Track is locked and all changes to it are disabled"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* custom color */ + prop= RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACK_CUSTOMCOLOR); + RNA_def_property_ui_text(prop, "Custom Color", "Use custom color instead of theme-defined"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* color */ + prop= RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Color", "Color of the track in the Clip Editor"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, NULL); + + /* average error */ + prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "error"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Average Error", "Average error of re-projection"); + + /* ** api ** */ + + func= RNA_def_function(srna, "marker_find_frame", "rna_trackingTrack_marker_find_frame"); + RNA_def_function_ui_description(func, "Get marker for specified frame"); + parm= RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "type for the new spline", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "marker", "MovieTrackingMarker", "", "Marker for specified frame"); + RNA_def_function_return(func, parm); +} + +static void rna_def_trackingStabilization(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MovieTrackingStabilization", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking stabilization data", "Match-moving stabilization data for tracking"); + + /* 2d stabilization */ + prop= RNA_def_property(srna, "use_2d_stabilization", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_2D_STABILIZATION); + RNA_def_property_ui_text(prop, "Use 2D stabilization", "Use 2D stabilization for footage"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* tracks */ + prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_tracking_stabTracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MovieTrackingTrack"); + RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks used for stabilization"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* rotation track */ + prop= RNA_def_property(srna, "rotation_track", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "rot_track"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Rotation Track", "Track used to compensate rotation"); + RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_flushUpdate"); + + /* active track index */ + prop= RNA_def_property(srna, "active_track_index", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "act_track"); + RNA_def_property_int_funcs(prop, "rna_tracking_stabTracks_active_index_get", "rna_tracking_stabTracks_active_index_set", "rna_tracking_stabTracks_active_index_range"); + RNA_def_property_ui_text(prop, "Active Track Index", "Index of active track in stabilization tracks list"); + + /* autoscale */ + prop= RNA_def_property(srna, "use_autoscale", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_AUTOSCALE); + RNA_def_property_ui_text(prop, "Autoscale", "Automatically scale footage to cover unfilled areas when stabilizating"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* max scale */ + prop= RNA_def_property(srna, "scale_max", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "maxscale"); + RNA_def_property_range(prop, 0.0f, 10.0f); + RNA_def_property_ui_text(prop, "Miximal Scale", "Maximal value for scale factor"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* influence_location */ + prop= RNA_def_property(srna, "influence_location", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "locinf"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Location Influence", "Influence of stabilization algorithm on footage location"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* influence_scale */ + prop= RNA_def_property(srna, "influence_scale", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "scaleinf"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Scale Influence", "Influence of stabilization algorithm on footage scale"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); + + /* influence_rotation */ + prop= RNA_def_property(srna, "influence_rotation", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "rotinf"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Rotation Influence", "Influence of stabilization algorithm on footage rotation"); + RNA_def_property_update(prop, NC_MOVIECLIP|ND_DISPLAY, "rna_tracking_flushUpdate"); +} + +static void rna_def_reconstructedCamera(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "MovieReconstructedCamera", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking reconstructed camera data", "Match-moving reconstructed camera data from tracker"); + + /* frame */ + prop= RNA_def_property(srna, "frame", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_int_sdna(prop, NULL, "framenr"); + RNA_def_property_ui_text(prop, "Frame", "Frame number marker is keyframed on"); + + /* matrix */ + prop= RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); + RNA_def_property_float_sdna(prop, NULL, "mat"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); + RNA_def_property_ui_text(prop, "Matrix", "Worldspace transformation matrix"); + + /* average_error */ + prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "error"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Average Error", "Average error of resonctruction"); +} + +static void rna_def_trackingReconstruction(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + rna_def_reconstructedCamera(brna); + + srna= RNA_def_struct(brna, "MovieTrackingReconstruction", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking reconstruction data", "Match-moving reconstruction data from tracker"); + + /* is_valid */ + prop= RNA_def_property(srna, "is_valid", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", TRACKING_RECONSTRUCTED); + RNA_def_property_ui_text(prop, "Reconstructed", "Is tracking data contains valid reconstruction information"); + + /* average_error */ + prop= RNA_def_property(srna, "average_error", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "error"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Average Error", "Average error of resonctruction"); + + /* cameras */ + prop= RNA_def_property(srna, "cameras", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieReconstructedCamera"); + RNA_def_property_collection_sdna(prop, NULL, "cameras", "camnr"); + RNA_def_property_ui_text(prop, "Cameras", "Collection of solved cameras"); +} + +static void rna_def_trackingTracks(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + FunctionRNA *func; + PropertyRNA *prop; + + RNA_def_property_srna(cprop, "MovieTrackingTracks"); + srna= RNA_def_struct(brna, "MovieTrackingTracks", NULL); + RNA_def_struct_sdna(srna, "MovieTracking"); + RNA_def_struct_ui_text(srna, "Movie Tracks", "Collection of movie tracking tracks"); + + func= RNA_def_function(srna, "add", "rna_tracking_tracks_add"); + RNA_def_function_ui_description(func, "Add a number of tracks to this movie clip"); + RNA_def_int(func, "frame", 1, MINFRAME, MAXFRAME, "Frame", "Frame number to add tracks on", MINFRAME, MAXFRAME); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of tracks to add to the movie clip", 0, INT_MAX); + + /* active track */ + prop= RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingTrack"); + RNA_def_property_pointer_funcs(prop, "rna_tracking_active_track_get", "rna_tracking_active_track_set", NULL, NULL); + RNA_def_property_flag(prop, PROP_EDITABLE|PROP_NEVER_UNLINK); + RNA_def_property_ui_text(prop, "Active Track", "Active track in this tracking data object"); +} + +static void rna_def_tracking(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + rna_def_trackingSettings(brna); + rna_def_trackingCamera(brna); + rna_def_trackingTrack(brna); + rna_def_trackingStabilization(brna); + rna_def_trackingReconstruction(brna); + + srna= RNA_def_struct(brna, "MovieTracking", NULL); + RNA_def_struct_ui_text(srna, "Movie tracking data", "Match-moving data for tracking"); + + /* settings */ + prop= RNA_def_property(srna, "settings", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingSettings"); + + /* camera properties */ + prop= RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingCamera"); + + /* tracks */ + prop= RNA_def_property(srna, "tracks", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_funcs(prop, "rna_tracking_tracks_begin", "rna_iterator_listbase_next", "rna_iterator_listbase_end", "rna_iterator_listbase_get", 0, 0, 0, 0); + RNA_def_property_struct_type(prop, "MovieTrackingTrack"); + RNA_def_property_ui_text(prop, "Tracks", "Collection of tracks in this tracking data object"); + rna_def_trackingTracks(brna, prop); + + /* stabilization */ + prop= RNA_def_property(srna, "stabilization", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingStabilization"); + + /* reconstruction */ + prop= RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); +} + +void RNA_def_tracking(BlenderRNA *brna) +{ + rna_def_tracking(brna); +} + +#endif diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 25c673a168f..5ab9c334016 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -397,6 +397,25 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); + func= RNA_def_function(srna, "template_movieclip", "uiTemplateMovieClip"); + RNA_def_function_ui_description(func, "Item(s). User interface for selecting movie clips and their source paths"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + api_ui_item_rna_common(func); + RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); + + func= RNA_def_function(srna, "template_track", "uiTemplateTrack"); + RNA_def_function_ui_description(func, "Item. A movie-track widget to preview tracking image."); + api_ui_item_rna_common(func); + + func= RNA_def_function(srna, "template_marker", "uiTemplateMarker"); + RNA_def_function_ui_description(func, "Item. A widget to control single marker settings."); + api_ui_item_rna_common(func); + parm= RNA_def_pointer(func, "clip_user", "MovieClipUser", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); + parm= RNA_def_pointer(func, "track", "MovieTrackingTrack", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); + RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); + func= RNA_def_function(srna, "template_list", "uiTemplateList"); RNA_def_function_ui_description(func, "Item. A list widget to display data. e.g. vertexgroups"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fc9c8a241c6..e4e1c78ab3e 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1030,8 +1030,21 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_range(prop, 1, 5); RNA_def_property_ui_text(prop, "Outline Width", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "bundle_solid", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "bundle_solid"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Bundle Solid", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "camera_path", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "camera_path"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Camera Path", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); } + static void rna_def_userdef_theme_space_graph(BlenderRNA *brna) { StructRNA *srna; @@ -1741,6 +1754,94 @@ static void rna_def_userdef_theme_colorset(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_userdef_update"); } +static void rna_def_userdef_theme_space_clip(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + /* space_clip */ + + srna= RNA_def_struct(brna, "ThemeClipEditor", NULL); + RNA_def_struct_sdna(srna, "ThemeSpace"); + RNA_def_struct_ui_text(srna, "Theme Clip Editor", "Theme settings for the Movie Clip Editor"); + + rna_def_userdef_theme_spaces_main(srna, SPACE_CLIP); + + prop= RNA_def_property(srna, "marker_outline", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "marker_outline"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Marker Outline Color", "Color of marker's outile"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "marker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "marker"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Marker Color", "Color of marker"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "active_marker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "act_marker"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Active Marker", "Color of active marker"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "selected_marker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "sel_marker"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Selected Marker", "Color of sleected marker"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "disabled_marker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "dis_marker"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Disabled Marker", "Color of disabled marker"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "locked_marker", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "lock_marker"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Locked Marker", "Color of locked marker"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "path_before", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "path_before"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Path Before", "Color of path before current frame"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "path_after", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "path_after"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Path After", "Color of path after current frame"); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Grid", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "frame_current", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "cframe"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Current Frame", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "handle_vertex", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Handle Vertex", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "handle_vertex_select", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Handle Vertex Select", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + + prop= RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE); + RNA_def_property_range(prop, 0, 255); + RNA_def_property_ui_text(prop, "Handle Vertex Size", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); +} + static void rna_def_userdef_themes(BlenderRNA *brna) { StructRNA *srna; @@ -1765,6 +1866,7 @@ static void rna_def_userdef_themes(BlenderRNA *brna) {15, "INFO", ICON_INFO, "Info", ""}, {16, "FILE_BROWSER", ICON_FILESEL, "File Browser", ""}, {17, "CONSOLE", ICON_CONSOLE, "Python Console", ""}, + {20, "CLIP_EDITOR", ICON_CLIP, "Movie Clip Editor", ""}, {0, NULL, 0, NULL, NULL}}; srna= RNA_def_struct(brna, "Theme", NULL); @@ -1887,6 +1989,12 @@ static void rna_def_userdef_themes(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "tarm", ""); RNA_def_property_struct_type(prop, "ThemeBoneColorSet"); RNA_def_property_ui_text(prop, "Bone Color Sets", ""); + + prop= RNA_def_property(srna, "clip_editor", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "tclip"); + RNA_def_property_struct_type(prop, "ThemeClipEditor"); + RNA_def_property_ui_text(prop, "Clip Editor", ""); } static void rna_def_userdef_addon(BlenderRNA *brna) @@ -1926,6 +2034,7 @@ static void rna_def_userdef_dothemes(BlenderRNA *brna) rna_def_userdef_theme_space_userpref(brna); rna_def_userdef_theme_space_console(brna); rna_def_userdef_theme_space_logic(brna); + rna_def_userdef_theme_space_clip(brna); rna_def_userdef_theme_colorset(brna); rna_def_userdef_themes(brna); } diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index dbcc478990a..758cf7bd61c 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -166,6 +166,7 @@ typedef struct wmNotifier { #define NC_NODE (17<<24) #define NC_ID (18<<24) #define NC_LOGIC (19<<24) +#define NC_MOVIECLIP (20<<24) /* data type, 256 entries is enough, it can overlap */ #define NOTE_DATA 0x00FF0000 @@ -275,6 +276,7 @@ typedef struct wmNotifier { #define ND_SPACE_SEQUENCER (16<<16) #define ND_SPACE_NODE_VIEW (17<<16) #define ND_SPACE_CHANGED (18<<16) /*sent to a new editor type after it's replaced an old one*/ +#define ND_SPACE_CLIP (19<<16) /* subtype, 256 entries too */ #define NOTE_SUBTYPE 0x0000FF00 diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 19e9a6bd483..f12dec6459a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -3625,6 +3625,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) /* assign map to operators */ WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle"); WM_modalkeymap_assign(keymap, "UV_OT_circle_select"); + WM_modalkeymap_assign(keymap, "CLIP_OT_select_circle"); } @@ -3704,6 +3705,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_assign(keymap, "SEQUENCER_OT_select_border"); WM_modalkeymap_assign(keymap, "SEQUENCER_OT_view_ghost_border"); WM_modalkeymap_assign(keymap, "UV_OT_select_border"); + WM_modalkeymap_assign(keymap, "CLIP_OT_select_border"); WM_modalkeymap_assign(keymap, "VIEW2D_OT_zoom_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_clip_border"); WM_modalkeymap_assign(keymap, "VIEW3D_OT_render_border"); diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt index 701ad244fc1..3c93d718bb3 100644 --- a/source/blenderplayer/CMakeLists.txt +++ b/source/blenderplayer/CMakeLists.txt @@ -166,6 +166,12 @@ endif() list(APPEND BLENDER_SORTED_LIBS extern_colamd) + if(WITH_LIBMV) + list(APPEND BLENDER_SORTED_LIBS extern_libmv) + endif() + + list(APPEND BLENDER_SORTED_LIBS extern_colamd) + if(WITH_MOD_DECIMATE) list(APPEND BLENDER_SORTED_LIBS bf_intern_decimate) endif() diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 812844398b8..0e489107066 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -193,6 +193,7 @@ void ED_space_image_paint_update(struct wmWindowManager *wm, struct ToolSettings void ED_space_image_set(struct bContext *C, struct SpaceImage *sima, struct Scene *scene, struct Object *obedit, struct Image *ima){} struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima){return (struct ImBuf *) NULL;} void ED_screen_set_scene(struct bContext *C, struct Scene *scene){} +void ED_space_clip_set(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip){} void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype){} void ED_render_engine_changed(struct Main *bmain) {} @@ -250,6 +251,7 @@ void ED_view3d_scene_layers_update(struct Main *bmain, struct Scene *scene){} int ED_view3d_scene_layer_set(int lay, const int *values){return 0;} void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar){} void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist){} +struct BGpic *ED_view3D_background_image_add(struct View3D *v3d){return (struct BGpic *) NULL;} void view3d_apply_mat4(float mat[][4], float *ofs, float *quat, float *dist){} int text_file_modified(struct Text *text){return 0;} void ED_node_shader_default(struct Material *ma){} @@ -368,6 +370,9 @@ void uiTemplateReportsBanner(struct uiLayout *layout, struct bContext *C, struct void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand){} void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){} void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){} +void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){} +void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){} +void uiTemplateMarker(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname, PointerRNA *userptr, PointerRNA *trackptr, int compact){} /* rna render */ struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h){return (struct RenderResult *) NULL;} diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 867ea37e0a1..a633a139995 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -68,6 +68,11 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_LIBMV) + blender_include_dirs(../../extern/libmv) + add_definitions(-DWITH_LIBMV) +endif() + if(WITH_PYTHON) blender_include_dirs(../blender/python) add_definitions(-DWITH_PYTHON) @@ -758,6 +763,7 @@ endif() bf_editor_space_time bf_editor_space_userpref bf_editor_space_view3d + bf_editor_space_clip bf_editor_text bf_editor_transform @@ -815,6 +821,7 @@ endif() extern_minilzo extern_lzma extern_colamd + extern_libmv ge_logic_ketsji extern_recastnavigation ge_phys_common @@ -838,6 +845,10 @@ endif() bf_intern_mikktspace ) + if(WITH_LIBMV) + list(APPEND BLENDER_SORTED_LIBS extern_libmv) + endif() + if(WITH_MOD_CLOTH_ELTOPO) list(APPEND BLENDER_SORTED_LIBS extern_eltopo) endif() diff --git a/source/creator/creator.c b/source/creator/creator.c index 39ea82f141f..1f6f4d85f43 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -120,6 +120,10 @@ #include "binreloc.h" #endif +#ifdef WITH_LIBMV +#include "libmv-capi.h" +#endif + // from buildinfo.c #ifdef BUILD_DATE extern char build_date[]; @@ -352,6 +356,10 @@ static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data) printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type); #endif // WITH_BUILDINFO +#ifdef WITH_LIBMV + libmv_startDebugLogging(); +#endif + BLI_argsPrint(data); return 0; } @@ -1132,6 +1140,10 @@ int main(int argc, const char **argv) br_init( NULL ); #endif +#ifdef WITH_LIBMV + libmv_initLogging(argv[0]); +#endif + setCallbacks(); #ifdef __APPLE__ /* patch to ignore argument finder gives us (pid?) */ From 7b43abb90e2895292e183fcbca7140447025acd7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Nov 2011 12:56:05 +0000 Subject: [PATCH 126/147] Camera tracking integration =========================== Rest of changes from camera tracking gsoc project. This commit includes: - New compositor nodes: * Movie Clip input node * Movie Undistortion node * Transformation node * 2D stabilization node - Slight changes in existing node to prevent code duplication --- source/blender/blenkernel/BKE_node.h | 4 + source/blender/blenkernel/intern/node.c | 4 + source/blender/blenloader/intern/readfile.c | 26 ++- source/blender/blenloader/intern/writefile.c | 2 + source/blender/editors/space_node/drawnode.c | 48 ++++++ source/blender/editors/space_node/node_edit.c | 8 +- source/blender/makesrna/intern/rna_nodetree.c | 78 +++++++++ .../makesrna/intern/rna_nodetree_types.h | 4 + source/blender/nodes/CMakeLists.txt | 4 + source/blender/nodes/NOD_composite.h | 4 + .../nodes/composite/node_composite_tree.c | 16 ++ .../nodes/composite/node_composite_util.h | 10 ++ .../composite/nodes/node_composite_image.c | 51 +++--- .../nodes/node_composite_movieclip.c | 157 ++++++++++++++++++ .../nodes/node_composite_moviedistortion.c | 135 +++++++++++++++ .../composite/nodes/node_composite_scale.c | 21 ++- .../nodes/node_composite_stabilize2d.c | 79 +++++++++ .../nodes/node_composite_transform.c | 142 ++++++++++++++++ 18 files changed, 769 insertions(+), 24 deletions(-) create mode 100644 source/blender/nodes/composite/nodes/node_composite_movieclip.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_moviedistortion.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_stabilize2d.c create mode 100644 source/blender/nodes/composite/nodes/node_composite_transform.c diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 7509205e968..278e57125c5 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -567,6 +567,10 @@ void ntreeGPUMaterialNodes(struct bNodeTree *ntree, struct GPUMaterial *mat); #define CMP_NODE_COLOR_MATTE 259 #define CMP_NODE_COLORBALANCE 260 #define CMP_NODE_HUECORRECT 261 +#define CMP_NODE_MOVIECLIP 262 +#define CMP_NODE_STABILIZE2D 263 +#define CMP_NODE_TRANSFORM 264 +#define CMP_NODE_MOVIEDISTORTION 265 #define CMP_NODE_GLARE 301 #define CMP_NODE_TONEMAP 302 diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index a9b2ffe7529..115591863cc 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1790,6 +1790,7 @@ static void registerCompositNodes(ListBase *ntypelist) register_node_type_cmp_value(ntypelist); register_node_type_cmp_rgb(ntypelist); register_node_type_cmp_curve_time(ntypelist); + register_node_type_cmp_movieclip(ntypelist); register_node_type_cmp_composite(ntypelist); register_node_type_cmp_viewer(ntypelist); @@ -1854,6 +1855,9 @@ static void registerCompositNodes(ListBase *ntypelist) register_node_type_cmp_glare(ntypelist); register_node_type_cmp_tonemap(ntypelist); register_node_type_cmp_lensdist(ntypelist); + register_node_type_cmp_transform(ntypelist); + register_node_type_cmp_stabilize2d(ntypelist); + register_node_type_cmp_moviedistortion(ntypelist); } static void registerShaderNodes(ListBase *ntypelist) diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ce7ff489465..9f6ce4eb79b 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -1254,6 +1254,7 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain) void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) { MovieClip *clip= oldmain->movieclip.first; + Scene *sce= oldmain->scene.first; fd->movieclipmap= oldnewmap_new(); @@ -1264,6 +1265,15 @@ void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain) if(clip->tracking.camera.intrinsics) oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0); } + + for(; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->type==CMP_NODE_MOVIEDISTORTION) + oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0); + } + } } /* set old main movie clips caches to zero if it has been restored */ @@ -1272,6 +1282,7 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) { OldNew *entry= fd->movieclipmap->entries; MovieClip *clip= oldmain->movieclip.first; + Scene *sce= oldmain->scene.first; int i; /* used entries were restored, so we put them to zero */ @@ -1284,6 +1295,15 @@ void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain) clip->cache= newmclipadr(fd, clip->cache); clip->tracking.camera.intrinsics= newmclipadr(fd, clip->tracking.camera.intrinsics); } + + for(; sce; sce= sce->id.next) { + if(sce->nodetree) { + bNode *node; + for(node= sce->nodetree->nodes.first; node; node= node->next) + if(node->type==CMP_NODE_MOVIEDISTORTION) + node->storage= newmclipadr(fd, node->storage); + } + } } @@ -2273,7 +2293,11 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &node->inputs); link_list(fd, &node->outputs); - node->storage= newdataadr(fd, node->storage); + if(node->type == CMP_NODE_MOVIEDISTORTION) { + node->storage= newmclipadr(fd, node->storage); + } else + node->storage= newdataadr(fd, node->storage); + if(node->storage) { /* could be handlerized at some point */ if(ntree->type==NTREE_SHADER && (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB)) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index f49148342ec..021aa6a8a92 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -711,6 +711,8 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if(ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); + else if(ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) + /* pass */ ; else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 24ea51567ad..b4d89e1365d 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1679,6 +1679,40 @@ static void node_composit_buts_ycc(uiLayout *layout, bContext *UNUSED(C), Pointe uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); } +static void node_composit_buts_movieclip(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); +} + +static void node_composit_buts_stabilize2d(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); + + if(!node->id) + return; + + uiItemR(layout, ptr, "filter_type", 0, "", 0); +} + +static void node_composit_buts_transform(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "filter_type", 0, "", 0); +} + +static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, PointerRNA *ptr) +{ + bNode *node= ptr->data; + + uiTemplateID(layout, C, ptr, "clip", NULL, "CLIP_OT_open", NULL); + + if(!node->id) + return; + + uiItemR(layout, ptr, "distortion_type", 0, "", 0); +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -1829,6 +1863,20 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_SEPYCCA: ntype->uifunc=node_composit_buts_ycc; break; + case CMP_NODE_MOVIECLIP: + ntype->uifunc= node_composit_buts_movieclip; + break; + case CMP_NODE_STABILIZE2D: + ntype->uifunc= node_composit_buts_stabilize2d; + break; + case CMP_NODE_TRANSFORM: + ntype->uifunc= node_composit_buts_transform; + break; + case CMP_NODE_MOVIEDISTORTION: + ntype->uifunc= node_composit_buts_moviedistortion; + break; + default: + ntype->uifunc= NULL; } if (ntype->uifuncbut == NULL) ntype->uifuncbut = ntype->uifunc; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c1e50c112fa..745611c6251 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -2207,8 +2207,14 @@ bNode *node_add_node(SpaceNode *snode, Main *bmain, Scene *scene, bNodeTemplate ED_node_set_active(bmain, snode->edittree, node); if(snode->nodetree->type==NTREE_COMPOSIT) { - if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) + if(ELEM4(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS, CMP_NODE_OUTPUT_FILE)) { node->id = &scene->id; + } + else if(ELEM3(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_MOVIEDISTORTION, CMP_NODE_STABILIZE2D)) { + if(G.main->movieclip.first == G.main->movieclip.last) { + node->id= G.main->movieclip.first; + } + } ntreeCompositForceHidden(snode->edittree, scene); } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 1445cf3b537..f024ad3addd 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2414,6 +2414,84 @@ static void def_cmp_ycc(StructRNA *srna) RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); } +static void def_cmp_movieclip(StructRNA *srna) +{ + PropertyRNA *prop; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + RNA_def_struct_sdna_from(srna, "MovieClipUser", "storage"); +} + +static void def_cmp_stabilize2d(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem filter_type_items[] = { + {0, "NEAREST", 0, "Nearest", ""}, + {1, "BILINEAR", 0, "Bilinear", ""}, + {2, "BICUBIC", 0, "Bicubic", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, filter_type_items); + RNA_def_property_ui_text(prop, "Filter", "Method to use to filter stabilization"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + +static void def_cmp_moviedistortion(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem distortion_type_items[] = { + {0, "UNDISTORT", 0, "Undistort", ""}, + {1, "DISTORT", 0, "Distort", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "clip", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "id"); + RNA_def_property_struct_type(prop, "MovieClip"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Movie Clip", ""); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + + prop = RNA_def_property(srna, "distortion_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, distortion_type_items); + RNA_def_property_ui_text(prop, "Distortion", "Distortion to use to filter image"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + +static void dev_cmd_transform(StructRNA *srna) +{ + PropertyRNA *prop; + + static EnumPropertyItem filter_type_items[] = { + {0, "NEAREST", 0, "Nearest", ""}, + {1, "BILINEAR", 0, "Bilinear", ""}, + {2, "BICUBIC", 0, "Bicubic", ""}, + {0, NULL, 0, NULL, NULL}}; + + prop = RNA_def_property(srna, "filter_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "custom1"); + RNA_def_property_enum_items(prop, filter_type_items); + RNA_def_property_ui_text(prop, "Filter", "Method to use to filter transform"); + RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); +} + /* -- Texture Nodes --------------------------------------------------------- */ diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index 1bbf47db094..2545826cd46 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -117,6 +117,10 @@ DefNode( CompositorNode, CMP_NODE_COLOR_MATTE, def_cmp_color_matte, "COLOR DefNode( CompositorNode, CMP_NODE_DIST_MATTE, def_cmp_distance_matte, "DISTANCE_MATTE", DistanceMatte, "Distance Matte", "" ) DefNode( CompositorNode, CMP_NODE_COLORBALANCE, def_cmp_colorbalance, "COLORBALANCE", ColorBalance, "Color Balance", "" ) DefNode( CompositorNode, CMP_NODE_HUECORRECT, def_cmp_huecorrect, "HUECORRECT", HueCorrect, "Hue Correct", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIECLIP, def_cmp_movieclip, "MOVIECLIP", MovieClip, "MovieClip", "" ) +DefNode( CompositorNode, CMP_NODE_TRANSFORM, dev_cmd_transform, "TRANSFORM", Transform, "Transform", "" ) +DefNode( CompositorNode, CMP_NODE_STABILIZE2D, def_cmp_stabilize2d, "STABILIZE2D", Stabilize, "Stabilize 2D", "" ) +DefNode( CompositorNode, CMP_NODE_MOVIEDISTORTION,def_cmp_moviedistortion,"MOVIEDISTORTION",MovieDistortion, "Movie Distortion", "" ) DefNode( TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode( TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 82848c6a5d7..69e7f9cac6b 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -80,6 +80,8 @@ set(SRC composite/nodes/node_composite_mapValue.c composite/nodes/node_composite_math.c composite/nodes/node_composite_mixrgb.c + composite/nodes/node_composite_movieclip.c + composite/nodes/node_composite_moviedistortion.c composite/nodes/node_composite_normal.c composite/nodes/node_composite_normalize.c composite/nodes/node_composite_outputFile.c @@ -93,8 +95,10 @@ set(SRC composite/nodes/node_composite_sepcombYUVA.c composite/nodes/node_composite_setalpha.c composite/nodes/node_composite_splitViewer.c + composite/nodes/node_composite_stabilize2d.c composite/nodes/node_composite_texture.c composite/nodes/node_composite_tonemap.c + composite/nodes/node_composite_transform.c composite/nodes/node_composite_translate.c composite/nodes/node_composite_valToRgb.c composite/nodes/node_composite_value.c diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index d768a5d794f..f1415a8c8f0 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -52,6 +52,7 @@ void register_node_type_cmp_texture(ListBase *lb); void register_node_type_cmp_value(ListBase *lb); void register_node_type_cmp_rgb(ListBase *lb); void register_node_type_cmp_curve_time(ListBase *lb); +void register_node_type_cmp_movieclip(ListBase *lb); void register_node_type_cmp_composite(ListBase *lb); void register_node_type_cmp_viewer(ListBase *lb); @@ -113,6 +114,9 @@ void register_node_type_cmp_flip(ListBase *lb); void register_node_type_cmp_crop(ListBase *lb); void register_node_type_cmp_displace(ListBase *lb); void register_node_type_cmp_mapuv(ListBase *lb); +void register_node_type_cmp_transform(ListBase *lb); +void register_node_type_cmp_stabilize2d(ListBase *lb); +void register_node_type_cmp_moviedistortion(ListBase *lb); void register_node_type_cmp_glare(ListBase *lb); void register_node_type_cmp_tonemap(ListBase *lb); diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index 2151176f907..d3f4a5b2999 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -45,6 +45,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_tracking.h" #include "BKE_utildefines.h" #include "node_exec.h" @@ -168,6 +169,17 @@ static void local_merge(bNodeTree *localtree, bNodeTree *ntree) BKE_image_merge((Image *)lnode->new_node->id, (Image *)lnode->id); } } + else if(lnode->type==CMP_NODE_MOVIEDISTORTION) { + /* special case for distortion node: distortion context is allocating in exec function + and to achive much better performance on further calls this context should be + copied back to original node */ + if(lnode->storage) { + if(lnode->new_node->storage) + BKE_tracking_distortion_destroy(lnode->new_node->storage); + + lnode->new_node->storage= BKE_tracking_distortion_copy(lnode->storage); + } + } for(lsock= lnode->outputs.first; lsock; lsock= lsock->next) { if(ntreeOutputExists(lnode->new_node, lsock->new_sock)) { @@ -806,6 +818,10 @@ int ntreeCompositTagAnimated(bNodeTree *ntree) nodeUpdate(ntree, node); } } + else if(ELEM(node->type, CMP_NODE_MOVIECLIP, CMP_NODE_TRANSFORM)) { + nodeUpdate(ntree, node); + tagged= 1; + } } return tagged; diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 6da9b901e76..9cac4c477eb 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -44,6 +44,7 @@ #include "DNA_ID.h" #include "DNA_image_types.h" #include "DNA_material_types.h" +#include "DNA_movieclip_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -63,8 +64,10 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_material.h" +#include "BKE_movieclip.h" #include "BKE_node.h" #include "BKE_texture.h" +#include "BKE_tracking.h" #include "BKE_library.h" #include "BKE_object.h" @@ -210,4 +213,11 @@ CompBuf* qd_downScaledCopy(CompBuf* src, int scale); void IIR_gauss(CompBuf* src, float sigma, int chan, int xy); /* end utility funcs */ +/* transformations */ + +#define CMP_SCALE_MAX 12000 + +CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type); +float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc); + #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c index c1e9d28bb4d..41427c42286 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.c +++ b/source/blender/nodes/composite/nodes/node_composite_image.c @@ -58,6 +58,36 @@ static bNodeSocketTemplate cmp_node_rlayers_out[]= { { -1, 0, "" } }; +/* float buffer from the image with matching color management */ +float *node_composit_get_float_buffer(RenderData *rd, ImBuf *ibuf, int *alloc) +{ + float *rect; + + *alloc= FALSE; + + if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { + if(ibuf->profile != IB_PROFILE_NONE) { + rect= ibuf->rect_float; + } + else { + rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); + srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + *alloc= TRUE; + } + } + else { + if(ibuf->profile == IB_PROFILE_NONE) { + rect= ibuf->rect_float; + } + else { + rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); + linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); + *alloc= TRUE; + } + } + + return rect; +} /* note: this function is used for multilayer too, to ensure uniform handling with BKE_image_get_ibuf() */ @@ -82,26 +112,7 @@ static CompBuf *node_composit_get_image(RenderData *rd, Image *ima, ImageUser *i /* now we need a float buffer from the image with matching color management */ /* XXX weak code, multilayer is excluded from this */ if(ibuf->channels == 4 && ima->rr==NULL) { - if(rd->color_mgt_flag & R_COLOR_MANAGEMENT) { - if(ibuf->profile != IB_PROFILE_NONE) { - rect= ibuf->rect_float; - } - else { - rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - srgb_to_linearrgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); - alloc= TRUE; - } - } - else { - if(ibuf->profile == IB_PROFILE_NONE) { - rect= ibuf->rect_float; - } - else { - rect= MEM_mapallocN(sizeof(float) * 4 * ibuf->x * ibuf->y, "node_composit_get_image"); - linearrgb_to_srgb_rgba_rgba_buf(rect, ibuf->rect_float, ibuf->x * ibuf->y); - alloc= TRUE; - } - } + rect= node_composit_get_float_buffer(rd, ibuf, &alloc); } else { /* non-rgba passes can't use color profiles */ diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.c b/source/blender/nodes/composite/nodes/node_composite_movieclip.c new file mode 100644 index 00000000000..8931b899017 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.c @@ -0,0 +1,157 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_movieclip.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +static bNodeSocketTemplate cmp_node_movieclip_out[]= { + { SOCK_RGBA, 0, "Image"}, + { SOCK_FLOAT, 1, "Offset X"}, + { SOCK_FLOAT, 1, "Offset Y"}, + { SOCK_FLOAT, 1, "Scale"}, + { SOCK_FLOAT, 1, "Angle"}, + { -1, 0, "" } +}; + +static CompBuf *node_composit_get_movieclip(RenderData *rd, MovieClip *clip, MovieClipUser *user) +{ + ImBuf *ibuf; + CompBuf *stackbuf; + int type; + + float *rect; + int alloc= FALSE; + + ibuf= BKE_movieclip_get_ibuf(clip, user); + + if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) { + IMB_freeImBuf(ibuf); + return NULL; + } + + if (ibuf->rect_float == NULL || ibuf->userflags&IB_RECT_INVALID) { + IMB_float_from_rect(ibuf); + ibuf->userflags&= ~IB_RECT_INVALID; + } + + /* now we need a float buffer from the image with matching color management */ + if(ibuf->channels == 4) { + rect= node_composit_get_float_buffer(rd, ibuf, &alloc); + } + else { + /* non-rgba passes can't use color profiles */ + rect= ibuf->rect_float; + } + /* done coercing into the correct color management */ + + if(!alloc) { + rect= MEM_dupallocN(rect); + alloc= 1; + } + + type= ibuf->channels; + + if(rd->scemode & R_COMP_CROP) { + stackbuf= get_cropped_compbuf(&rd->disprect, rect, ibuf->x, ibuf->y, type); + if(alloc) + MEM_freeN(rect); + } + else { + /* we put imbuf copy on stack, cbuf knows rect is from other ibuf when freed! */ + stackbuf= alloc_compbuf(ibuf->x, ibuf->y, type, FALSE); + stackbuf->rect= rect; + stackbuf->malloc= alloc; + } + + IMB_freeImBuf(ibuf); + + return stackbuf; +} + +static void node_composit_exec_movieclip(void *data, bNode *node, bNodeStack **UNUSED(in), bNodeStack **out) +{ + if(node->id) { + RenderData *rd= data; + MovieClip *clip= (MovieClip *)node->id; + MovieClipUser *user= (MovieClipUser *)node->storage; + CompBuf *stackbuf= NULL; + + BKE_movieclip_user_set_frame(user, rd->cfra); + + stackbuf= node_composit_get_movieclip(rd, clip, user); + + if (stackbuf) { + MovieTrackingStabilization *stab= &clip->tracking.stabilization; + + /* put image on stack */ + out[0]->data= stackbuf; + + if(stab->flag&TRACKING_2D_STABILIZATION) { + float loc[2], scale, angle; + + BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, stackbuf->x, stackbuf->y, + loc, &scale, &angle); + + out[1]->vec[0]= loc[0]; + out[2]->vec[0]= loc[1]; + + out[3]->vec[0]= scale; + out[4]->vec[0]= angle; + } + + /* generate preview */ + generate_preview(data, node, stackbuf); + } + } +} + +static void init(bNodeTree *UNUSED(ntree), bNode *node, bNodeTemplate *UNUSED(ntemp)) +{ + MovieClipUser *user= MEM_callocN(sizeof(MovieClipUser), "node movie clip user"); + + node->storage= user; + user->framenr= 1; +} + +void register_node_type_cmp_movieclip(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIECLIP, "Movie Clip", NODE_CLASS_INPUT, NODE_PREVIEW|NODE_OPTIONS); + node_type_socket_templates(&ntype, NULL, cmp_node_movieclip_out); + node_type_size(&ntype, 120, 80, 300); + node_type_init(&ntype, init); + node_type_storage(&ntype, "MovieClipUser", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, node_composit_exec_movieclip); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c new file mode 100644 index 00000000000..439616377a1 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_moviedistortion.c @@ -0,0 +1,135 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_moviedistortion.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_moviedistortion_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_moviedistortion_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void exec(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data) { + if(node->id) { + MovieClip *clip= (MovieClip *)node->id; + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 0); + ImBuf *ibuf; + + ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); + + if(ibuf) { + ImBuf *obuf; + MovieTracking *tracking= &clip->tracking; + int width, height; + float overscan= 0.0f; + + ibuf->rect_float= cbuf->rect; + + BKE_movieclip_get_size(clip, NULL, &width, &height); + + if(!node->storage) + node->storage= BKE_tracking_distortion_create(); + + if(node->custom1==0) + obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 1); + else + obuf= BKE_tracking_distortion_exec(node->storage, tracking, ibuf, width, height, overscan, 0); + + stackbuf->rect= obuf->rect_float; + stackbuf->malloc= 1; + + obuf->mall&= ~IB_rectfloat; + obuf->rect_float= NULL; + + IMB_freeImBuf(ibuf); + IMB_freeImBuf(obuf); + } + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } else { + CompBuf *cbuf= in[0]->data; + CompBuf *stackbuf= pass_on_compbuf(cbuf); + + out[0]->data= stackbuf; + } + } +} + +static const char *label(bNode *node) +{ + if(node->custom1==0) + return "Undistortion"; + else + return "Distortion"; +} + +static void storage_free(bNode *node) +{ + if(node->storage) + BKE_tracking_distortion_destroy(node->storage); + + node->storage= NULL; +} + +void storage_copy(bNode *orig_node, bNode *new_node) +{ + if(orig_node->storage) + new_node->storage= BKE_tracking_distortion_copy(orig_node->storage); +} + +void register_node_type_cmp_moviedistortion(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_MOVIEDISTORTION, "Movie Distortion", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_moviedistortion_in, cmp_node_moviedistortion_out); + node_type_size(&ntype, 140, 100, 320); + node_type_label(&ntype, label); + node_type_exec(&ntype, exec); + node_type_storage(&ntype, NULL, storage_free, storage_copy); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.c b/source/blender/nodes/composite/nodes/node_composite_scale.c index 5eb789ae0c9..37332c9bd7e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.c +++ b/source/blender/nodes/composite/nodes/node_composite_scale.c @@ -34,8 +34,6 @@ /* **************** Scale ******************** */ -#define CMP_SCALE_MAX 12000 - static bNodeSocketTemplate cmp_node_scale_in[]= { { SOCK_RGBA, 1, "Image", 1.0f, 1.0f, 1.0f, 1.0f}, { SOCK_FLOAT, 1, "X", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX, PROP_FACTOR}, @@ -110,6 +108,25 @@ static void node_composit_exec_scale(void *data, bNode *node, bNodeStack **in, b if(cbuf!=in[0]->data) free_compbuf(cbuf); } + else if (node->custom1==CMP_SCALE_ABSOLUTE) { + CompBuf *stackbuf; + int a, x, y; + float *fp; + + x = MAX2((int)in[1]->vec[0], 1); + y = MAX2((int)in[2]->vec[0], 1); + + stackbuf = alloc_compbuf(x, y, CB_RGBA, 1); + fp = stackbuf->rect; + + a = stackbuf->x * stackbuf->y; + while(a--) { + copy_v4_v4(fp, in[0]->vec); + fp += 4; + } + + out[0]->data= stackbuf; + } } void register_node_type_cmp_scale(ListBase *lb) diff --git a/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c new file mode 100644 index 00000000000..c5d60e65530 --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_stabilize2d.c @@ -0,0 +1,79 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_stabilize2d.c + * \ingroup cmpnodes + */ + + +#include "node_composite_util.h" + +/* **************** Translate ******************** */ + +static bNodeSocketTemplate cmp_node_stabilize2d_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_stabilize2d_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +static void node_composit_exec_stabilize2d(void *data, bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data && node->id) { + RenderData *rd= data; + MovieClip *clip= (MovieClip *)node->id; + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf; + float loc[2], scale, angle; + + BKE_tracking_stabilization_data(&clip->tracking, rd->cfra, cbuf->x, cbuf->y, loc, &scale, &angle); + + stackbuf= node_composit_transform(cbuf, loc[0], loc[1], angle, scale, node->custom1); + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +void register_node_type_cmp_stabilize2d(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_STABILIZE2D, "Stabilize 2D", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_stabilize2d_in, cmp_node_stabilize2d_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_stabilize2d); + + nodeRegisterType(lb, &ntype); +} diff --git a/source/blender/nodes/composite/nodes/node_composite_transform.c b/source/blender/nodes/composite/nodes/node_composite_transform.c new file mode 100644 index 00000000000..de9b8fceaee --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_transform.c @@ -0,0 +1,142 @@ +/* + * ***** 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. + * + * The Original Code is Copyright (C) 2011 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Blender Foundation, + * Sergey Sharybin + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/composite/nodes/node_composite_transform.c + * \ingroup cmpnodes + */ + +#include "node_composite_util.h" + +/* **************** Transform ******************** */ + +static bNodeSocketTemplate cmp_node_transform_in[]= { + { SOCK_RGBA, 1, "Image", 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_FLOAT, 1, "X", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { SOCK_FLOAT, 1, "Y", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f}, + { SOCK_FLOAT, 1, "Angle", 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f, PROP_ANGLE}, + { SOCK_FLOAT, 1, "Scale", 1.0f, 0.0f, 0.0f, 0.0f, 0.0001f, CMP_SCALE_MAX}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate cmp_node_transform_out[]= { + { SOCK_RGBA, 0, "Image"}, + { -1, 0, "" } +}; + +CompBuf* node_composit_transform(CompBuf *cbuf, float x, float y, float angle, float scale, int filter_type) +{ + CompBuf *stackbuf= alloc_compbuf(cbuf->x, cbuf->y, CB_RGBA, 1); + ImBuf *ibuf, *obuf; + float mat[4][4], lmat[4][4], rmat[4][4], smat[4][4], cmat[4][4], icmat[4][4]; + float svec[3]= {scale, scale, scale}, loc[2]= {x, y}; + + unit_m4(rmat); + unit_m4(lmat); + unit_m4(smat); + unit_m4(cmat); + + /* image center as rotation center */ + cmat[3][0]= (float)cbuf->x/2.0f; + cmat[3][1]= (float)cbuf->y/2.0f; + invert_m4_m4(icmat, cmat); + + size_to_mat4(smat, svec); /* scale matrix */ + add_v2_v2(lmat[3], loc); /* tranlation matrix */ + rotate_m4(rmat, 'Z', angle); /* rotation matrix */ + + /* compose transformation matrix */ + mul_serie_m4(mat, lmat, cmat, rmat, smat, icmat, NULL, NULL, NULL); + + invert_m4(mat); + + ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0); + obuf= IMB_allocImBuf(stackbuf->x, stackbuf->y, 32, 0); + + if(ibuf && obuf) { + int i, j; + + ibuf->rect_float= cbuf->rect; + obuf->rect_float= stackbuf->rect; + + for(j=0; jy; j++) { + for(i=0; ix;i++) { + float vec[3]= {i, j, 0}; + + mul_v3_m4v3(vec, mat, vec); + + switch(filter_type) { + case 0: + neareast_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break ; + case 1: + bilinear_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break; + case 2: + bicubic_interpolation(ibuf, obuf, vec[0], vec[1], i, j); + break; + } + } + } + + IMB_freeImBuf(ibuf); + IMB_freeImBuf(obuf); + } + + /* pass on output and free */ + return stackbuf; +} + +static void node_composit_exec_transform(void *UNUSED(data), bNode *node, bNodeStack **in, bNodeStack **out) +{ + if(in[0]->data) { + CompBuf *cbuf= typecheck_compbuf(in[0]->data, CB_RGBA); + CompBuf *stackbuf; + + stackbuf= node_composit_transform(cbuf, in[1]->vec[0], in[2]->vec[0], in[3]->vec[0], in[4]->vec[0], node->custom1); + + /* pass on output and free */ + out[0]->data= stackbuf; + + if(cbuf!=in[0]->data) + free_compbuf(cbuf); + } +} + +void register_node_type_cmp_transform(ListBase *lb) +{ + static bNodeType ntype; + + node_type_base(&ntype, CMP_NODE_TRANSFORM, "Transform", NODE_CLASS_DISTORT, NODE_OPTIONS); + node_type_socket_templates(&ntype, cmp_node_transform_in, cmp_node_transform_out); + node_type_size(&ntype, 140, 100, 320); + node_type_exec(&ntype, node_composit_exec_transform); + + nodeRegisterType(lb, &ntype); +} + + From 2b6e4f242230d99470ef70c7c00f1809a098d200 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Mon, 7 Nov 2011 13:25:17 +0000 Subject: [PATCH 127/147] Bugfix [#29064] armature with curve contraint - crash Spline IK and Auto-IK working together on the same bone chain could crash due to the somewhat hacky way that they were sharing the same list for the "iktree" forest. Resolved by doing what I should have done from the beginning, and made Spline-IK save its ik chains off into a separate list. While this fixes the crash, it might be worth investigating outright disabling this from working in this case, since it can be a bit confusing to have it appear to not work. --- source/blender/blenkernel/intern/armature.c | 35 +++++++++---------- source/blender/blenloader/intern/readfile.c | 1 + .../blender/ikplugin/intern/iksolver_plugin.c | 6 ++-- source/blender/makesdna/DNA_action_types.h | 4 ++- 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 50f305e4400..a9c29728650 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1818,7 +1818,7 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos tree->ikData= ikData; /* AND! link the tree to the root */ - BLI_addtail(&pchanRoot->iktree, tree); + BLI_addtail(&pchanRoot->siktree, tree); } /* mark root channel having an IK tree */ @@ -2045,27 +2045,24 @@ static void splineik_execute_tree(Scene *scene, Object *ob, bPoseChannel *pchan_ tSplineIK_Tree *tree; /* for each pose-tree, execute it if it is spline, otherwise just free it */ - for (tree= pchan_root->iktree.first; tree; tree= pchan_root->iktree.first) { - /* only evaluate if tagged for Spline IK */ - if (tree->type == CONSTRAINT_TYPE_SPLINEIK) { - int i; - - /* walk over each bone in the chain, calculating the effects of spline IK - * - the chain is traversed in the opposite order to storage order (i.e. parent to children) - * so that dependencies are correct - */ - for (i= tree->chainlen-1; i >= 0; i--) { - bPoseChannel *pchan= tree->chain[i]; - splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); - } - - /* free the tree info specific to SplineIK trees now */ - if (tree->chain) MEM_freeN(tree->chain); - if (tree->free_points) MEM_freeN(tree->points); + while ((tree = pchan_root->siktree.first) != NULL) { + int i; + + /* walk over each bone in the chain, calculating the effects of spline IK + * - the chain is traversed in the opposite order to storage order (i.e. parent to children) + * so that dependencies are correct + */ + for (i= tree->chainlen-1; i >= 0; i--) { + bPoseChannel *pchan= tree->chain[i]; + splineik_evaluate_bone(tree, scene, ob, pchan, i, ctime); } + /* free the tree info specific to SplineIK trees now */ + if (tree->chain) MEM_freeN(tree->chain); + if (tree->free_points) MEM_freeN(tree->points); + /* free this tree */ - BLI_freelinkN(&pchan_root->iktree, tree); + BLI_freelinkN(&pchan_root->siktree, tree); } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9f6ce4eb79b..ba1d333f44f 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4064,6 +4064,7 @@ static void direct_link_pose(FileData *fd, bPose *pose) direct_link_motionpath(fd, pchan->mpath); pchan->iktree.first= pchan->iktree.last= NULL; + pchan->siktree.first= pchan->siktree.last= NULL; /* incase this value changes in future, clamp else we get undefined behavior */ CLAMP(pchan->rotmode, ROT_MODE_MIN, ROT_MODE_MAX); diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c index 787766f0fa6..2a83052c827 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.c +++ b/source/blender/ikplugin/intern/iksolver_plugin.c @@ -526,12 +526,14 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose /* 6. apply the differences to the channels, we need to calculate the original differences first */ - for(a=0; atotchannel; a++) + for(a=0; atotchannel; a++) { make_dmats(tree->pchan[a]); + } - for(a=0; atotchannel; a++) + for(a=0; atotchannel; a++) { /* sets POSE_DONE */ where_is_ik_bone(tree->pchan[a], tree->basis_change[a]); + } /* 7. and free */ BLI_remlink(&pchan->iktree, tree); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index db574160771..b198231df3a 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -198,7 +198,9 @@ typedef struct bPoseChannel { struct Bone *bone; /* set on read file or rebuild pose */ struct bPoseChannel *parent; /* set on read file or rebuild pose */ struct bPoseChannel *child; /* set on read file or rebuild pose, the 'ik' child, for b-bones */ - struct ListBase iktree; /* only while evaluating pose */ + + struct ListBase iktree; /* "IK trees" - only while evaluating pose */ + struct ListBase siktree; /* Spline-IK "trees" - only while evaluating pose */ bMotionPath *mpath; /* motion path cache for this bone */ struct Object *custom; /* draws custom object instead of default bone shape */ From 5ebee683bd736ef80df939552bbe0d8e104b56df Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Nov 2011 14:34:56 +0000 Subject: [PATCH 128/147] 2.6 UI: * Minor tweaks after tomato merge, rest of Tomato UI code is excellent. :) --- .../startup/bl_ui/properties_object_constraint.py | 3 +-- release/scripts/startup/bl_ui/properties_scene.py | 11 +---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py index 4def354741e..c493124c5bb 100644 --- a/release/scripts/startup/bl_ui/properties_object_constraint.py +++ b/release/scripts/startup/bl_ui/properties_object_constraint.py @@ -761,8 +761,7 @@ class ConstraintButtonsPanel(): layout.prop(con, "track") - row = layout.row() - row.prop(con, "reference", expand=True) + layout.row().prop(con, "reference", expand=True) layout.operator("clip.constraint_to_fcurve") diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py index 6e28c8b42f1..86880b9ddec 100644 --- a/release/scripts/startup/bl_ui/properties_scene.py +++ b/release/scripts/startup/bl_ui/properties_scene.py @@ -42,6 +42,7 @@ class SCENE_PT_scene(SceneButtonsPanel, Panel): layout.prop(scene, "camera") layout.prop(scene, "background_set", text="Background") + layout.prop(scene, "active_clip", text="Active Clip") class SCENE_PT_audio(SceneButtonsPanel, Panel): @@ -218,16 +219,6 @@ class SCENE_PT_simplify(SceneButtonsPanel, Panel): col.prop(rd, "simplify_ao_sss", text="AO and SSS") -class SCENE_PT_movie_clip(SceneButtonsPanel, Panel): - bl_label = "Movie Clip" - - def draw(self, context): - layout = self.layout - scene = context.scene - - layout.prop(scene, "active_clip", text="Active Clip") - - class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} _context_path = "scene" From 50ef1b14e47d74bfa4ac4bf77c61deaaefb33137 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 7 Nov 2011 15:19:13 +0000 Subject: [PATCH 129/147] Tracker/Movie Clip Editor: * Fix property not showing up: correlation_min, was actually called minimum_correlation in RNA. --- release/scripts/startup/bl_ui/space_clip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 09209017823..a6ed53039ef 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -445,7 +445,7 @@ class CLIP_PT_track_settings(Panel): if active.tracker == "KLT": layout.prop(active, "pyramid_levels") if active.tracker == "SAD": - layout.prop(active, "correlation_min") + layout.prop(active, "minimum_correlation") layout.prop(settings, "frames_adjust") layout.prop(settings, "speed") From 9b5652215abb91e5aa3ce40664fc0067567382b0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 15:19:26 +0000 Subject: [PATCH 130/147] minor warning nicer api use --- source/blender/blenkernel/intern/movieclip.c | 25 +++++++------------ .../blender/editors/gpencil/gpencil_paint.c | 2 -- source/blender/makesrna/intern/rna_scene.c | 2 +- .../blender/makesrna/intern/rna_texture_api.c | 8 +++--- source/blender/makesrna/intern/rna_ui_api.c | 6 ++--- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 18a7ad65dae..c7ebef82d6f 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -156,13 +156,10 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name) autoguess offset for now. could be something smarter in the future */ offset= sequence_guess_offset(clip->name, strlen(head), numlen); - if(numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1); - else strncpy(name, clip->name, sizeof(name)); + if (numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1); + else BLI_strncpy(name, clip->name, sizeof(name)); - if(clip->id.lib) - BLI_path_abs(name, clip->id.lib->filepath); - else - BLI_path_abs(name, G.main->name); + BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id)); } /* supposed to work with sequences only */ @@ -174,7 +171,7 @@ static void get_proxy_fname(MovieClip *clip, int proxy_render_size, int undistor BLI_split_dirfile(clip->name, clipdir, clipfile, FILE_MAX, FILE_MAX); if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) { - strcpy(dir, clip->proxy.dir); + BLI_strncpy(dir, clip->proxy.dir, sizeof(dir)); } else { BLI_snprintf(dir, FILE_MAX, "%s/BL_proxy", clipdir); } @@ -194,9 +191,9 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user, { struct ImBuf *ibuf; char name[FILE_MAX]; - int loadflag, size, undistort; + int loadflag /*, size */ /* UNUSED */, undistort; - size= rendersize_to_number(user->render_size); + /* size= rendersize_to_number(user->render_size); */ undistort= user->render_flag&MCLIP_PROXY_RENDER_UNDISTORT; @@ -222,11 +219,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in if(!clip->anim) { BLI_strncpy(str, clip->name, FILE_MAX); - - if(clip->id.lib) - BLI_path_abs(str, clip->id.lib->filepath); - else - BLI_path_abs(str, G.main->name); + BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id)); /* FIXME: make several stream accessible in image editor, too */ clip->anim= openanim(str, IB_rect, 0); @@ -234,7 +227,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in if(clip->anim) { if(clip->flag&MCLIP_USE_PROXY_CUSTOM_DIR) { char dir[FILE_MAX]; - strcpy(dir, clip->proxy.dir); + BLI_strncpy(dir, clip->proxy.dir, sizeof(dir)); BLI_path_abs(dir, G.main->name); IMB_anim_set_index_dir(clip->anim, dir); } @@ -243,7 +236,7 @@ static ImBuf *movieclip_load_movie_file(MovieClip *clip, MovieClipUser *user, in if(clip->anim) { int dur; - int fra= framenr-1; + int fra; dur= IMB_anim_get_duration(clip->anim, tc); fra= framenr-1; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index b89b0cda451..bd02df2ddba 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1772,8 +1772,6 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) if (gp_session_initdata(C, p)) gp_paint_initstroke(p, p->paintmode); - p= op->customdata; - if(p->status != GP_STATUS_ERROR) p->status= GP_STATUS_PAINTING; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 4245d606f61..b1d4654f76b 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -3761,7 +3761,7 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "TransformOrientation"); RNA_def_property_ui_text(prop, "Transform Orientations", ""); - /* acctive MovieClip */ + /* active MovieClip */ prop= RNA_def_property(srna, "active_clip", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "clip"); RNA_def_property_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index d4e39a5a8e4..f1a6bb1b921 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -118,10 +118,10 @@ void RNA_api_environment_map(StructRNA *srna) RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken"); - parm = RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", - "Flat array describing the X,Y position of each cube face in the " - "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); + RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", + "Flat array describing the X,Y position of each cube face in the " + "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " + "(use -1 to skip a face)", 0.0f, 0.0f); } #endif diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 5ab9c334016..a7e7a7b7577 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -427,9 +427,9 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); parm= RNA_def_string(func, "active_property", "", 0, "", "Identifier of property in data, for the active element"); RNA_def_property_flag(parm, PROP_REQUIRED); - parm= RNA_def_string(func, "prop_list", "", 0, "", - "Identifier of a string property in each data member, specifying which " - "of its properties should have a widget displayed in its row"); + RNA_def_string(func, "prop_list", "", 0, "", + "Identifier of a string property in each data member, specifying which " + "of its properties should have a widget displayed in its row"); RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Number of rows to display", 0, INT_MAX); RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Maximum number of rows to display", 0, INT_MAX); RNA_def_enum(func, "type", list_type_items, 0, "Type", "Type of list to use"); From a3e5bd02bbf9883953ccc423726e5b5c0ee5aac0 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Nov 2011 15:32:32 +0000 Subject: [PATCH 131/147] Some small fixed for camera tracking: - Lock to selection and center to selection will now work fine with undistorted rendering - Do not display pyramid for disabled tracks - Corrected fix for wrong correlation_min property name --- release/scripts/startup/bl_ui/space_clip.py | 2 +- source/blender/editors/space_clip/clip_draw.c | 4 ++-- source/blender/editors/space_clip/clip_editor.c | 12 ++++++++++-- source/blender/makesrna/intern/rna_tracking.c | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index a6ed53039ef..09209017823 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -445,7 +445,7 @@ class CLIP_PT_track_settings(Panel): if active.tracker == "KLT": layout.prop(active, "pyramid_levels") if active.tracker == "SAD": - layout.prop(active, "minimum_correlation") + layout.prop(active, "correlation_min") layout.prop(settings, "frames_adjust") layout.prop(settings, "speed") diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 0da68953593..9eb96a9a4c5 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -594,7 +594,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra } /* pyramid */ - if((sel == TRACK_SELECTED(track) && sel && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (track->tracker==TRACKER_KLT))) { + if(sel && TRACK_SELECTED(track) && (sc->flag&SC_SHOW_PYRAMID_LEVELS) && (track->tracker==TRACKER_KLT) && (marker->flag&MARKER_DISABLED)==0) { if(track->flag&TRACK_LOCKED) { if(act) UI_ThemeColor(TH_ACT_MARKER); else if(track->pat_flag&SELECT) UI_ThemeColorShade(TH_LOCK_MARKER, 64); @@ -626,7 +626,7 @@ static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTra glDisable(GL_LINE_STIPPLE); glPopMatrix(); } - } + } if(tiny) glDisable(GL_LINE_STIPPLE); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 0de7fed1f1a..c5036145792 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -184,10 +184,18 @@ static int selected_boundbox(SpaceClip *sc, float min[2], float max[2]) if(marker) { float pos[3]; - pos[0]= (marker->pos[0]+track->offset[0])*width; - pos[1]= (marker->pos[1]+track->offset[1])*height; + pos[0]= marker->pos[0]+track->offset[0]; + pos[1]= marker->pos[1]+track->offset[1]; pos[2]= 0.0f; + /* undistortion happens for normalized coords */ + if(sc->user.render_flag&MCLIP_PROXY_RENDER_UNDISTORT) + /* undistortion happens for normalized coords */ + ED_clip_point_undistorted_pos(sc, pos, pos); + + pos[0]*= width; + pos[1]*= height; + mul_v3_m4v3(pos, sc->stabmat, pos); DO_MINMAX2(pos, min, max); diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 34307f972c5..f72fd3d465c 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -488,7 +488,7 @@ static void rna_def_trackingTrack(BlenderRNA *brna) RNA_def_property_update(prop, NC_MOVIECLIP|NA_EDITED, "rna_tracking_trackerPyramid_update"); /* minmal correlation - only used for SAD tracker */ - prop= RNA_def_property(srna, "minimum_correlation", PROP_FLOAT, PROP_NONE); + prop= RNA_def_property(srna, "correlation_min", PROP_FLOAT, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_float_sdna(prop, NULL, "minimum_correlation"); RNA_def_property_range(prop, -1.0f, 1.0f); From 0b82cef03f8691f3456b3de29e5d940f49ca5955 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 15:41:20 +0000 Subject: [PATCH 132/147] fix for error using freed memory --- source/blender/editors/space_clip/tracking_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index aab7188c069..e5bf053aa1c 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2873,10 +2873,11 @@ static int clean_tracks_exec(bContext *C, wmOperator *op) BKE_tracking_free_track(track); BLI_freelinkN(&clip->tracking.tracks, track); + track= NULL; } /* happens when all tracking segments are not long enough */ - if(track->markersnr==0) { + if(track && track->markersnr==0) { if(track==act_track) clip->tracking.act_track= NULL; From b06db617a04e7ca378c6e38d90c37c9924207d82 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 15:44:09 +0000 Subject: [PATCH 133/147] CMake: Boost and OpenImageIO building support (unused still). --- CMakeLists.txt | 90 ++++++++++++++++++++++++++++++++++ build_files/cmake/macros.cmake | 12 +++++ 2 files changed, 102 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bc409fe0df..43f52eff009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -491,6 +491,36 @@ if(UNIX AND NOT APPLE) endif() endif() + if(WITH_BOOST) + set(BOOST "/usr" CACHE PATH "Boost Directory") + + if(NOT BOOST_CUSTOM) + set(BOOST_ROOT ${BOOST}) + set(Boost_USE_MULTITHREADED ON) + find_package(Boost 1.34 REQUIRED COMPONENTS filesystem regex system thread) + endif() + + set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS}) + set(BOOST_LIBRARIES ${Boost_LIBRARIES}) + set(BOOST_LIBPATH ${Boost_LIBRARY_DIRS}) + set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") + endif() + + if(WITH_OPENIMAGEIO) + set(OPENIMAGEIO "/usr" CACHE PATH "OpenImageIO Directory") + + set(OPENIMAGEIO_ROOT_DIR ${OPENIMAGEIO}) + find_package(OpenImageIO REQUIRED) + + set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES} ${BOOST_LIBRARIES}) + set(OPENIMAGEIO_LIBPATH) # TODO, remove and reference the absolute path everywhere + set(OPENIMAGEIO_DEFINITIONS) + + if(NOT OPENIMAGEIO_FOUND) + set(WITH_OPENIMAGEIO OFF) + endif() + endif() + # OpenSuse needs lutil, ArchLinux not, for now keep, can avoid by using --as-needed set(PLATFORM_LINKLIBS "-lutil -lc -lm -lpthread -lstdc++") @@ -777,6 +807,28 @@ elseif(WIN32) set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") endif() + if(WITH_BOOST) + set(BOOST ${LIBDIR}/boost) + set(BOOST_INCLUDE_DIR ${BOOST}/include) + set(BOOST_POSTFIX "vc90-mt-s-1_47.lib") + set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_47.lib") + set(BOOST_LIBRARIES + optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX} + libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX} + debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX} + libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX}) + set(BOOST_LIBPATH ${BOOST}/lib) + set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") + endif() + + if(WITH_OPENIMAGEIO) + set(OPENIMAGEIO ${LIBDIR}/openimageio) + set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) + set(OPENIMAGEIO_LIBRARIES OpenImageIO) + set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) + set(OPENIMAGEIO_DEFINITIONS) + endif() + set(PLATFORM_LINKFLAGS "/SUBSYSTEM:CONSOLE /STACK:2097152 /INCREMENTAL:NO /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:msvcmrt.lib /NODEFAULTLIB:msvcurt.lib /NODEFAULTLIB:msvcrtd.lib") # MSVC only, Mingw doesnt need @@ -887,6 +939,28 @@ elseif(WIN32) set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}") endif() + if(WITH_BOOST) + set(BOOST ${LIBDIR}/boost) + set(BOOST_INCLUDE_DIR ${BOOST}/include) + set(BOOST_POSTFIX "vc90-mt-s-1_46_1") + set(BOOST_DEBUG_POSTFIX "vc90-mt-sgd-1_46_1") + set(BOOST_LIBRARIES + optimized libboost_date_time-${BOOST_POSTFIX} libboost_filesystem-${BOOST_POSTFIX} + libboost_regex-${BOOST_POSTFIX} libboost_system-${BOOST_POSTFIX} libboost_thread-${BOOST_POSTFIX} + debug libboost_date_time-${BOOST_DEBUG_POSTFIX} libboost_filesystem-${BOOST_DEBUG_POSTFIX} + libboost_regex-${BOOST_DEBUG_POSTFIX} libboost_system-${BOOST_DEBUG_POSTFIX} libboost_thread-${BOOST_DEBUG_POSTFIX}) + set(BOOST_LIBPATH ${BOOST}/lib) + set(BOOST_DEFINITIONS "-DBOOST_ALL_NO_LIB") + endif() + + if(WITH_OPENIMAGEIO) + set(OPENIMAGEIO ${LIBDIR}/openimageio) + set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) + set(OPENIMAGEIO_LIBRARIES OpenImageIO) + set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib) + set(OPENIMAGEIO_DEFINITIONS) + endif() + set(PLATFORM_LINKFLAGS "--stack,2097152") endif() @@ -1090,6 +1164,22 @@ elseif(APPLE) # linker needs "-weak_framework 3DconnexionClient" endif() + if(WITH_BOOST) + set(BOOST ${LIBDIR}/boost) + set(BOOST_INCLUDE_DIR ${BOOST}/include) + set(BOOST_LIBRARIES boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt) + set(BOOST_LIBPATH ${BOOST}/lib) + set(BOOST_DEFINITIONS) + endif() + + if(WITH_OPENIMAGEIO) + set(OPENIMAGEIO ${LIBDIR}/openimageio) + set(OPENIMAGEIO_INCLUDE_DIRS ${OPENIMAGEIO}/include) + set(OPENIMAGEIO_LIBRARIES OpenImageIO ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${TIFF_LIBRARY} ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES}) + set(OPENIMAGEIO_LIBPATH ${OPENIMAGEIO}/lib ${JPEG_LIBPATH} ${PNG_LIBPATH} ${TIFF_LIBPATH} ${OPENEXR_LIBPATH} ${ZLIB_LIBPATH}) + set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD") + endif() + set(EXETYPE MACOSX_BUNDLE) set(CMAKE_C_FLAGS_DEBUG "-fno-strict-aliasing -g") diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 10f89797754..ba1cdd9013b 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -165,6 +165,12 @@ macro(SETUP_LIBDIRS) if(WITH_IMAGE_TIFF) link_directories(${TIFF_LIBPATH}) endif() + if(WITH_BOOST) + link_directories(${BOOST_LIBPATH}) + endif() + if(WITH_OPENIMAGEIO) + link_directories(${OPENIMAGEIO_LIBPATH}) + endif() if(WITH_IMAGE_OPENJPEG AND UNIX AND NOT APPLE) link_directories(${OPENJPEG_LIBPATH}) endif() @@ -259,6 +265,12 @@ macro(setup_liblinks if(WITH_IMAGE_TIFF) target_link_libraries(${target} ${TIFF_LIBRARY}) endif() + if(WITH_OPENIMAGEIO) + target_link_libraries(${target} ${OPENIMAGEIO_LIBRARIES}) + endif() + if(WITH_BOOST) + target_link_libraries(${target} ${BOOST_LIBRARIES}) + endif() if(WITH_IMAGE_OPENEXR) if(WIN32 AND NOT UNIX) file_list_suffix(OPENEXR_LIBRARIES_DEBUG "${OPENEXR_LIBRARIES}" "_d") From a6828b9c6f2ec24853cccac16bfdfae870c0d8c2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 15:53:40 +0000 Subject: [PATCH 134/147] CMake: add delayed_install macro to specify files to be installed from modules other than source/creator. --- build_files/cmake/macros.cmake | 35 ++++++++++++++++++++++++++++++++++ source/creator/CMakeLists.txt | 11 +++++++++++ 2 files changed, 46 insertions(+) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index ba1cdd9013b..c9a04f87148 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -630,3 +630,38 @@ macro(blender_project_hack_post) endif() endmacro() + +# pair of macros to allow libraries to be specify files to install, but to +# only install them at the end so the directories don't get cleared with +# the files in them. used by cycles to install addon. +macro(delayed_install + base + files + destination) + + foreach(f ${files}) + set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_FILES ${base}/${f}) + set_property(GLOBAL APPEND PROPERTY DELAYED_INSTALL_DESTINATIONS ${destination}) + endforeach() +endmacro() + +# note this is a function instead of a macro so that ${BUILD_TYPE} in targetdir +# does not get expanded in calling but is preserved +function(delayed_do_install + targetdir) + + get_property(files GLOBAL PROPERTY DELAYED_INSTALL_FILES) + get_property(destinations GLOBAL PROPERTY DELAYED_INSTALL_DESTINATIONS) + + if(files) + list(LENGTH files n) + math(EXPR n "${n}-1") + + foreach(i RANGE ${n}) + list(GET files ${i} f) + list(GET destinations ${i} d) + install(FILES ${f} DESTINATION ${targetdir}/${d}) + endforeach() + endif() +endfunction() + diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a633a139995..b0e5427500b 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -575,6 +575,14 @@ elseif(WIN32) DESTINATION ${TARGETDIR} ) + if(WITH_OPENIMAGEIO) + install( + FILES + ${LIBDIR}/openimageio/bin/OpenImageIO.dll + DESTINATION ${TARGETDIR} + ) + endif() + elseif(APPLE) set(SOURCEDIR ${CMAKE_SOURCE_DIR}/source/darwin/blender.app) set(SOURCEINFO ${SOURCEDIR}/Contents/Info.plist) @@ -720,6 +728,9 @@ elseif(APPLE) endif() endif() +# install more files specified elsewhere +delayed_do_install(${TARGETDIR_VER}) + unset(BLENDER_TEXT_FILES) From 1d225c6696a8fe6538922c7ab5963d547ba30dd2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 15:55:03 +0000 Subject: [PATCH 135/147] use macro for access to library filepath --- source/blender/blenlib/intern/bpath.c | 2 +- source/blender/editors/space_buttons/buttons_ops.c | 5 ++--- source/blender/windowmanager/intern/wm_files.c | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 259b25e67dd..8ad79dd819a 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -362,7 +362,7 @@ static int rewrite_path_alloc(char **path, BPathVisitor visit_cb, const char *ab void bpath_traverse_id(Main *bmain, ID *id, BPathVisitor visit_cb, const int flag, void *bpath_user_data) { Image *ima; - const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? (id->lib ? id->lib->filepath : bmain->name) : NULL; + const char *absbase= (flag & BPATH_TRAVERSE_ABS) ? ID_BLEND_PATH(bmain, id) : NULL; if ((flag & BPATH_TRAVERSE_SKIP_LIBRARY) && id->lib) { return; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 39fae43a877..05fdcd50067 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -100,7 +100,7 @@ static int file_browse_exec(bContext *C, wmOperator *op) { FileBrowseOp *fbo= op->customdata; ID *id; - char *base, *str, path[FILE_MAX]; + char *str, path[FILE_MAX]; const char *path_prop= RNA_struct_find_property(op->ptr, "directory") ? "directory" : "filepath"; if (RNA_property_is_set(op->ptr, path_prop)==0 || fbo==NULL) @@ -113,10 +113,9 @@ static int file_browse_exec(bContext *C, wmOperator *op) char name[FILE_MAX]; id = fbo->ptr.id.data; - base = (id && id->lib)? id->lib->filepath: G.main->name; BLI_strncpy(path, str, FILE_MAX); - BLI_path_abs(path, base); + BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name); if(BLI_is_dir(path)) { str = MEM_reallocN(str, strlen(str)+2); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 83e4681251f..8d7e812a386 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -733,7 +733,7 @@ int WM_write_file(bContext *C, const char *target, int fileflags, ReportList *re /* send the OnSave event */ for (li= G.main->library.first; li; li= li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { - BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.200s'", filepath); + BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath); return -1; } } From 9de67a61aa431012625d4bd8910c6681595c6685 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 15:57:52 +0000 Subject: [PATCH 136/147] fix for error in own recent commit. --- source/blender/blenkernel/intern/movieclip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index c7ebef82d6f..e3bfdd54ab1 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -157,7 +157,7 @@ static void get_sequence_fname(MovieClip *clip, int framenr, char *name) offset= sequence_guess_offset(clip->name, strlen(head), numlen); if (numlen) BLI_stringenc(name, head, tail, numlen, offset+framenr-1); - else BLI_strncpy(name, clip->name, sizeof(name)); + else BLI_strncpy(name, clip->name, sizeof(clip->name)); BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id)); } From 9ced8a23fe57e20366d63bc6bfedf0b24f0bf767 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 7 Nov 2011 16:26:23 +0000 Subject: [PATCH 137/147] quiet warnings when building without libmv --- build_files/cmake/config/blender_lite.cmake | 1 + source/blender/blenkernel/intern/tracking.c | 44 +++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index 6791028a888..0da28a943eb 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -13,6 +13,7 @@ set(WITH_BULLET OFF CACHE FORCE BOOL) set(WITH_CODEC_FFMPEG OFF CACHE FORCE BOOL) set(WITH_CODEC_SNDFILE OFF CACHE FORCE BOOL) set(WITH_FFTW3 OFF CACHE FORCE BOOL) +set(WITH_LIBMV OFF CACHE FORCE BOOL) set(WITH_GAMEENGINE OFF CACHE FORCE BOOL) set(WITH_IK_ITASC OFF CACHE FORCE BOOL) set(WITH_IMAGE_CINEON OFF CACHE FORCE BOOL) diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index 06a985e7d72..a834628641a 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -58,7 +58,9 @@ #include "IMB_imbuf.h" #ifdef WITH_LIBMV -#include "libmv-capi.h" +# include "libmv-capi.h" +#else +struct libmv_Features; #endif typedef struct MovieDistortion { @@ -1379,6 +1381,12 @@ float BKE_tracking_solve_reconstruction(MovieTracking *tracking, int width, int return error; } +#else + (void)tracking; + (void)width; + (void)height; + + return -1.0f; #endif } @@ -1581,6 +1589,10 @@ void BKE_tracking_apply_intrinsics(MovieTracking *tracking, float co[2], float n /* result is in image coords already */ nco[0]= x; nco[1]= y; +#else + (void)camera; + (void)co; + (void)nco; #endif } @@ -1597,9 +1609,14 @@ void BKE_tracking_invert_intrinsics(MovieTracking *tracking, float co[2], float nco[0]= x * camera->focal + camera->principal[0]; nco[1]= y * camera->focal + camera->principal[1] * aspy; +#else + (void)camera; + (void)co; + (void)nco; #endif } +#ifdef WITH_LIBMV static int point_in_stroke(bGPDstroke *stroke, float x, float y) { int i, prev; @@ -1643,7 +1660,6 @@ static int point_in_layer(bGPDlayer *layer, float x, float y) static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Features *features, int framenr, int width, int height, bGPDlayer *layer, int place_outside_layer) { -#ifdef WITH_LIBMV int a; a= libmv_countFeatures(features); @@ -1668,8 +1684,8 @@ static void retrieve_libmv_features(MovieTracking *tracking, struct libmv_Featur track->search_flag|= SELECT; } } -#endif } +#endif void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf, int framenr, int margin, int min_trackness, int min_distance, bGPDlayer *layer, @@ -1686,6 +1702,15 @@ void BKE_tracking_detect_fast(MovieTracking *tracking, ImBuf *ibuf, retrieve_libmv_features(tracking, features, framenr, ibuf->x, ibuf->y, layer, place_outside_layer); libmv_destroyFeatures(features); +#else + (void)tracking; + (void)ibuf; + (void)framenr; + (void)margin; + (void)min_trackness; + (void)min_distance; + (void)layer; + (void)place_outside_layer; #endif } @@ -2048,6 +2073,8 @@ MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion) #ifdef WITH_LIBMV new_distortion->intrinsics= libmv_CameraIntrinsicsCopy(distortion->intrinsics); +#else + (void)distortion; #endif return new_distortion; @@ -2068,6 +2095,12 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking * camera->principal[0], camera->principal[1] * aspy, camera->k1, camera->k2, camera->k3, width, height * aspy); } +#else + (void)distortion; + (void)width; + (void)height; + (void)camera; + (void)aspy; #endif } @@ -2108,6 +2141,11 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * #endif } +#ifndef WITH_LIBMV + (void)overscan; + (void)undistort; +#endif + return resibuf; } From 4d7a9e5c055fd3903162b61fdd40fb77b2b96793 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 16:26:53 +0000 Subject: [PATCH 138/147] RNA: * Expose 3D view camera zoom and offset, needed if you want to precisely reconstruct camera parameters. * Rename SpaceFileBrowser.operator to active_operator, to avoid conflict with c++ keyword. --- .../scripts/startup/bl_ui/space_filebrowser.py | 2 +- source/blender/makesrna/intern/rna_space.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index cf0d10c5844..435b968f243 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -62,7 +62,7 @@ class FILEBROWSER_HT_header(Header): row.prop(params, "use_filter_folder", text="") if params.filter_glob: - #if st.operator and hasattr(st.operator, "filter_glob"): + #if st.active_operator and hasattr(st.active_operator, "filter_glob"): # row.prop(params, "filter_glob", text="") row.label(params.filter_glob) else: diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 580f759c38f..bb07fa86f3a 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1668,6 +1668,17 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "dist"); RNA_def_property_ui_text(prop, "Distance", "Distance to the view location"); RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + + prop= RNA_def_property(srna, "view_camera_zoom", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "camzoom"); + RNA_def_property_ui_text(prop, "Camera Zoom", "Zoom factor in camera view"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); + + prop= RNA_def_property(srna, "view_camera_offset", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "camdx"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Camera Offset", "View shift in camera view"); + RNA_def_property_update(prop, NC_SPACE|ND_SPACE_VIEW3D, NULL); } static void rna_def_space_buttons(BlenderRNA *brna) @@ -2564,9 +2575,9 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "params"); RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser"); - prop= RNA_def_property(srna, "operator", PROP_POINTER, PROP_NONE); + prop= RNA_def_property(srna, "active_operator", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "op"); - RNA_def_property_ui_text(prop, "Operator", ""); + RNA_def_property_ui_text(prop, "Active Operator", ""); } static void rna_def_space_info(BlenderRNA *brna) From 69ad40f9ea81ddf5cd0d83dc21cc7f66a8008765 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 17:07:54 +0000 Subject: [PATCH 139/147] Revert fix for #29146, needs deeper changes to solve this fully. --- source/blender/blenkernel/intern/depsgraph.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 79930fdd8bf..7f099c03d09 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -592,7 +592,10 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if(part->ren_as == PART_DRAW_OB && part->dup_ob) { node2 = dag_get_node(dag, part->dup_ob); - dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Object Visualisation"); + /* note that this relation actually runs in the wrong direction, the problem + is that dupli system all have this (due to parenting), and the render + engine instancing assumes particular ordering of objects in list */ + dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualisation"); if(part->dup_ob->type == OB_MBALL) dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA, "Particle Object Visualisation"); } From 448731834839bbddee02558080dd9a5e586f6f21 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 17:30:52 +0000 Subject: [PATCH 140/147] Nodes: add socket option to hide the default value in the UI, to be used for sockets that get their default value if no node is connected from elsewhere, e.g. a texture coordinate. --- source/blender/blenkernel/BKE_node.h | 1 + source/blender/editors/space_node/node_draw.c | 5 +++-- source/blender/nodes/intern/node_socket.c | 2 ++ source/blender/nodes/shader/nodes/node_shader_texture.c | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 278e57125c5..6080981dc32 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -83,6 +83,7 @@ typedef struct bNodeSocketTemplate { float val1, val2, val3, val4; /* default alloc value for inputs */ float min, max; PropertySubType subtype; + int flag; /* after this line is used internal only */ struct bNodeSocket *sock; /* used to hold verified socket */ diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index c2a2f319c28..a932f1b10d9 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -108,7 +108,8 @@ void ED_node_changed_update(ID *id, bNode *node) WM_main_add_notifier(NC_WORLD|ND_WORLD_DRAW, id); } else if(treetype==NTREE_COMPOSIT) { - nodeUpdate(edittree, node); + if(node) + nodeUpdate(edittree, node); /* don't use NodeTagIDChanged, it gives far too many recomposites for image, scene layers, ... */ node= node_tree_get_editgroup(nodetree); @@ -691,7 +692,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN node_socket_circle_draw(ntree, sock, NODE_SOCKSIZE); - if (sock->link) { + if (sock->link || (sock->flag & SOCK_HIDE_VALUE)) { uiDefBut(node->block, LABEL, 0, sock->name, sock->locx+NODE_DYS, sock->locy-NODE_DYS, node->width-NODE_DY, NODE_DY, NULL, 0, 0, 0, 0, ""); } diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 4a851a3acac..9381eff30dd 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -305,6 +305,7 @@ struct bNodeSocket *node_add_input_from_template(struct bNodeTree *ntree, struct default: sock = nodeAddSocket(ntree, node, SOCK_IN, stemp->name, stemp->type); } + sock->flag |= stemp->flag; return sock; } @@ -351,6 +352,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree, bNode *node, int in sock->type= stemp->type; /* in future, read this from tydefs! */ if(stemp->limit==0) sock->limit= 0xFFF; else sock->limit= stemp->limit; + sock->flag |= stemp->flag; /* Copy the property range and subtype parameters in case the template changed. * NOT copying the actual value here, only button behavior changes! diff --git a/source/blender/nodes/shader/nodes/node_shader_texture.c b/source/blender/nodes/shader/nodes/node_shader_texture.c index 42460e141e2..dbf9fdbdb7e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_texture.c +++ b/source/blender/nodes/shader/nodes/node_shader_texture.c @@ -36,7 +36,7 @@ /* **************** TEXTURE ******************** */ static bNodeSocketTemplate sh_node_texture_in[]= { - { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE}, /* no limit */ + { SOCK_VECTOR, 1, "Vector", 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, /* no limit */ { -1, 0, "" } }; static bNodeSocketTemplate sh_node_texture_out[]= { From f3407e7d60d8000d71c66192d760bd5700345b21 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 17:35:20 +0000 Subject: [PATCH 141/147] Textures/Shaders: extend TexMapping to include projection options, and add a ColorMapping struct for color manipulation of textures. These will be the standard built-in texture node options for manipulating the incoming texture coordinate and outgoing color. --- source/blender/blenkernel/BKE_blender.h | 2 +- source/blender/blenkernel/BKE_texture.h | 7 +- source/blender/blenkernel/intern/texture.c | 100 ++++++++-- source/blender/blenloader/intern/readfile.c | 25 ++- source/blender/editors/space_node/drawnode.c | 27 ++- source/blender/makesdna/DNA_texture_types.h | 24 ++- source/blender/makesrna/intern/rna_nodetree.c | 55 +----- source/blender/makesrna/intern/rna_texture.c | 176 ++++++++++++++---- .../composite/nodes/node_composite_mapValue.c | 2 +- .../nodes/shader/nodes/node_shader_mapping.c | 2 +- 10 files changed, 299 insertions(+), 121 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 7033a2e0cce..ac56cd02eb0 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 260 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 2 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index de72428b3d7..508fef8d9a4 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -103,9 +103,12 @@ void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex int has_current_material_texture(struct Material *ma); -struct TexMapping *add_mapping(void); -void init_mapping(struct TexMapping *texmap); +struct TexMapping *add_tex_mapping(void); +void default_tex_mapping(struct TexMapping *texmap); +void init_tex_mapping(struct TexMapping *texmap); +struct ColorMapping *add_color_mapping(void); +void default_color_mapping(struct ColorMapping *colormap); void BKE_free_envmapdata(struct EnvMap *env); void BKE_free_envmap(struct EnvMap *env); diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 377eeef117e..c80b2880d12 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -202,33 +202,95 @@ void free_plugin_tex(PluginTex *pit) /* ****************** Mapping ******************* */ -TexMapping *add_mapping(void) +TexMapping *add_tex_mapping(void) { - TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "Tex map"); + TexMapping *texmap= MEM_callocN(sizeof(TexMapping), "TexMapping"); - texmap->size[0]= texmap->size[1]= texmap->size[2]= 1.0f; - texmap->max[0]= texmap->max[1]= texmap->max[2]= 1.0f; - unit_m4(texmap->mat); + default_tex_mapping(texmap); return texmap; } -void init_mapping(TexMapping *texmap) +void default_tex_mapping(TexMapping *texmap) { - float eul[3], smat[3][3], rmat[3][3], mat[3][3]; - - size_to_mat3( smat,texmap->size); - - eul[0]= DEG2RADF(texmap->rot[0]); - eul[1]= DEG2RADF(texmap->rot[1]); - eul[2]= DEG2RADF(texmap->rot[2]); - eul_to_mat3( rmat,eul); - - mul_m3_m3m3(mat, rmat, smat); - - copy_m4_m3(texmap->mat, mat); - copy_v3_v3(texmap->mat[3], texmap->loc); + memset(texmap, 0, sizeof(TexMapping)); + texmap->size[0]= texmap->size[1]= texmap->size[2]= 1.0f; + texmap->max[0]= texmap->max[1]= texmap->max[2]= 1.0f; + unit_m4(texmap->mat); + + texmap->projx= PROJ_X; + texmap->projy= PROJ_Y; + texmap->projz= PROJ_Z; + texmap->mapping= MTEX_FLAT; +} + +void init_tex_mapping(TexMapping *texmap) +{ + float eul[3], smat[3][3], rmat[3][3], mat[3][3], proj[3][3]; + + if(texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z && + is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size)) { + unit_m4(texmap->mat); + + texmap->flag |= TEXMAP_UNIT_MATRIX; + } + else { + /* axis projection */ + zero_m3(proj); + + if(texmap->projx != PROJ_N) + proj[texmap->projx-1][0]= 1.0f; + if(texmap->projy != PROJ_N) + proj[texmap->projy-1][1]= 1.0f; + if(texmap->projz != PROJ_N) + proj[texmap->projz-1][2]= 1.0f; + + /* scale */ + size_to_mat3(smat, texmap->size); + + /* rotation */ + eul[0]= DEG2RADF(texmap->rot[0]); + eul[1]= DEG2RADF(texmap->rot[1]); + eul[2]= DEG2RADF(texmap->rot[2]); + eul_to_mat3( rmat,eul); + + /* compose it all */ + mul_m3_m3m3(mat, rmat, smat); + mul_m3_m3m3(mat, proj, mat); + + /* translation */ + copy_m4_m3(texmap->mat, mat); + copy_v3_v3(texmap->mat[3], texmap->loc); + + texmap->flag &= ~TEXMAP_UNIT_MATRIX; + } +} + +ColorMapping *add_color_mapping(void) +{ + ColorMapping *colormap= MEM_callocN(sizeof(ColorMapping), "ColorMapping"); + + default_color_mapping(colormap); + + return colormap; +} + +void default_color_mapping(ColorMapping *colormap) +{ + memset(colormap, 0, sizeof(ColorMapping)); + + init_colorband(&colormap->coba, 1); + + colormap->bright= 1.0; + colormap->contrast= 1.0; + colormap->saturation= 1.0; + + colormap->blend_color[0]= 0.8f; + colormap->blend_color[1]= 0.8f; + colormap->blend_color[2]= 0.8f; + colormap->blend_type= MA_RAMP_BLEND; + colormap->blend_factor= 0.0f; } /* ****************** COLORBAND ******************* */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ba1d333f44f..96fbe392922 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5991,7 +5991,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, int flag, ID if(id->flag & LIB_FAKEUSER) id->us= 1; else id->us= 0; id->icon_id = 0; - id->flag &= ~LIB_ID_RECALC; + id->flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA); /* this case cannot be direct_linked: it's just the ID part */ if(bhead->code==ID_ID) { @@ -7235,6 +7235,22 @@ static void do_versions_nodetree_image_default_alpha_output(bNodeTree *ntree) } } +static void do_version_ntree_tex_mapping_260(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + + for(node=ntree->nodes.first; node; node=node->next) { + if(node->type == SH_NODE_MAPPING) { + TexMapping *tex_mapping; + + tex_mapping= node->storage; + tex_mapping->projx= PROJ_X; + tex_mapping->projy= PROJ_Y; + tex_mapping->projz= PROJ_Z; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -12320,6 +12336,13 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 260 || (main->versionfile == 260 && main->subversionfile < 2)) { + bNodeTreeType *ntreetype= ntreeGetType(NTREE_SHADER); + + if(ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_ntree_tex_mapping_260); + } + /* put compatibility code here until next subversion bump */ { { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index b4d89e1365d..648027b9c58 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -95,6 +95,14 @@ static void node_sync_cb(bContext *UNUSED(C), void *snode_v, void *node_v) } } +static void node_socket_button_label(const bContext *UNUSED(C), uiBlock *block, + bNodeTree *UNUSED(ntree), bNode *UNUSED(node), bNodeSocket *sock, + const char *UNUSED(name), int x, int y, int width) +{ + uiDefBut(block, LABEL, 0, sock->name, x, y, width, NODE_DY, NULL, 0, 0, 0, 0, ""); +} + + static void node_socket_button_default(const bContext *C, uiBlock *block, bNodeTree *ntree, bNode *node, bNodeSocket *sock, const char *name, int x, int y, int width) @@ -938,28 +946,28 @@ static void node_shader_buts_material(uiLayout *layout, bContext *C, PointerRNA static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { + PointerRNA mappingptr = RNA_pointer_get(ptr, "mapping"); uiLayout *row; uiItemL(layout, "Location:", ICON_NONE); row= uiLayoutRow(layout, 1); - uiItemR(row, ptr, "location", 0, "", ICON_NONE); + uiItemR(row, &mappingptr, "location", 0, "", ICON_NONE); uiItemL(layout, "Rotation:", ICON_NONE); row= uiLayoutRow(layout, 1); - uiItemR(row, ptr, "rotation", 0, "", ICON_NONE); + uiItemR(row, &mappingptr, "rotation", 0, "", ICON_NONE); uiItemL(layout, "Scale:", ICON_NONE); row= uiLayoutRow(layout, 1); - uiItemR(row, ptr, "scale", 0, "", ICON_NONE); + uiItemR(row, &mappingptr, "scale", 0, "", ICON_NONE); row= uiLayoutRow(layout, 1); - uiItemR(row, ptr, "use_min", 0, "Min", ICON_NONE); - uiItemR(row, ptr, "min", 0, "", ICON_NONE); + uiItemR(row, &mappingptr, "use_min", 0, "Min", ICON_NONE); + uiItemR(row, &mappingptr, "min", 0, "", ICON_NONE); row= uiLayoutRow(layout, 1); - uiItemR(row, ptr, "use_max", 0, "Max", ICON_NONE); - uiItemR(row, ptr, "max", 0, "", ICON_NONE); - + uiItemR(row, &mappingptr, "use_max", 0, "Max", ICON_NONE); + uiItemR(row, &mappingptr, "max", 0, "", ICON_NONE); } static void node_shader_buts_vect_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) @@ -2089,6 +2097,9 @@ void ED_init_node_butfuncs(void) case SOCK_RGBA: stype->buttonfunc = node_socket_button_color; break; + case SOCK_SHADER: + stype->buttonfunc = node_socket_button_label; + break; default: stype->buttonfunc = NULL; } diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 4cf31edb891..1ecca5a0b2a 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -267,11 +267,13 @@ typedef struct Tex { } Tex; -/* used for mapping node. note: rot is in degrees */ +/* used for mapping and texture nodes. note: rot is in degrees */ typedef struct TexMapping { float loc[3], rot[3], size[3]; int flag; + char projx, projy, projz, mapping; + int pad; float mat[4][4]; float min[3], max[3]; @@ -279,10 +281,24 @@ typedef struct TexMapping { } TexMapping; -/* texmap->flag */ -#define TEXMAP_CLIP_MIN 1 -#define TEXMAP_CLIP_MAX 2 +typedef struct ColorMapping { + struct ColorBand coba; + float bright, contrast, saturation; + int flag; + + float blend_color[3]; + float blend_factor; + int blend_type, pad[3]; +} ColorMapping; + +/* texmap->flag */ +#define TEXMAP_CLIP_MIN 1 +#define TEXMAP_CLIP_MAX 2 +#define TEXMAP_UNIT_MATRIX 4 + +/* colormap->flag */ +#define COLORMAP_USE_RAMP 1 /* **************** TEX ********************* */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index f024ad3addd..7e74c490e5c 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -425,15 +425,6 @@ static void rna_NodeSocketVector_range(PointerRNA *ptr, float *min, float *max) *max = val->max; } -static void rna_Node_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr) -{ - bNode *node= (bNode*)ptr->data; - - init_mapping((TexMapping *)node->storage); - - rna_Node_update(bmain, scene, ptr); -} - static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNode *node= (bNode*)ptr->data; @@ -1077,48 +1068,12 @@ static void def_sh_material(StructRNA *srna) static void def_sh_mapping(StructRNA *srna) { PropertyRNA *prop; - - RNA_def_struct_sdna_from(srna, "TexMapping", "storage"); - prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_float_sdna(prop, NULL, "loc"); - RNA_def_property_ui_text(prop, "Location", "Location offset for the input coordinate"); - RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update"); - - prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_XYZ); /* Not PROP_EUL, this is already in degrees, not radians */ - RNA_def_property_float_sdna(prop, NULL, "rot"); - RNA_def_property_ui_text(prop, "Rotation", "Rotation offset for the input coordinate"); - RNA_def_property_ui_range(prop, -360.f, 360.f, 1.f, 2); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update"); - - prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, NULL, "size"); - RNA_def_property_ui_text(prop, "Scale", "Scale adjustment for the input coordinate"); - RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_mapping_update"); - - prop = RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN); - RNA_def_property_ui_text(prop, "Clamp Minimum", "Clamp the output coordinate to a minimum value"); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); - - prop= RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, NULL, "min"); - RNA_def_property_ui_text(prop, "Minimum", "Minimum value to clamp coordinate to"); - RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); - - prop = RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX); - RNA_def_property_ui_text(prop, "Clamp Maximum", "Clamp the output coordinate to a maximum value"); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); - - prop= RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, NULL, "max"); - RNA_def_property_ui_text(prop, "Maximum", "Maximum value to clamp coordinate to"); - RNA_def_property_ui_range(prop, -10.f, 10.f, 0.1f, 2); - RNA_def_property_update(prop, NC_NODE|NA_EDITED, "rna_Node_update"); + prop= RNA_def_property(srna, "mapping", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "storage"); + RNA_def_property_struct_type(prop, "TexMapping"); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_ui_text(prop, "Mapping", "Texture coordinate mapping settings"); } static void def_sh_geometry(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index c420ecefdae..aac4da9e6f6 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -75,6 +75,25 @@ EnumPropertyItem texture_type_items[] = { {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - Wave generated bands or rings, with optional noise"}, {0, NULL, 0, NULL, NULL}}; +EnumPropertyItem blend_type_items[] = { + {MTEX_BLEND, "MIX", 0, "Mix", ""}, + {MTEX_ADD, "ADD", 0, "Add", ""}, + {MTEX_SUB, "SUBTRACT", 0, "Subtract", ""}, + {MTEX_MUL, "MULTIPLY", 0, "Multiply", ""}, + {MTEX_SCREEN, "SCREEN", 0, "Screen", ""}, + {MTEX_OVERLAY, "OVERLAY", 0, "Overlay", ""}, + {MTEX_DIFF, "DIFFERENCE", 0, "Difference", ""}, + {MTEX_DIV, "DIVIDE", 0, "Divide", ""}, + {MTEX_DARK, "DARKEN", 0, "Darken", ""}, + {MTEX_LIGHT, "LIGHTEN", 0, "Lighten", ""}, + {MTEX_BLEND_HUE, "HUE", 0, "Hue", ""}, + {MTEX_BLEND_SAT, "SATURATION", 0, "Saturation", ""}, + {MTEX_BLEND_VAL, "VALUE", 0, "Value", ""}, + {MTEX_BLEND_COLOR, "COLOR", 0, "Color", ""}, + {MTEX_SOFT_LIGHT, "SOFT_LIGHT", 0, "Soft Light", ""}, + {MTEX_LIN_LIGHT , "LINEAR_LIGHT", 0, "Linear Light", ""}, + {0, NULL, 0, NULL, NULL}}; + #ifdef RNA_RUNTIME #include "MEM_guardedalloc.h" @@ -131,13 +150,33 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr) } } -static void rna_Texture_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - Tex *tex= ptr->id.data; + ID *id= ptr->id.data; - DAG_id_tag_update(&tex->id, 0); - WM_main_add_notifier(NC_TEXTURE, tex); - WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, NULL); + if(GS(id->name) == ID_TE) { + Tex *tex= ptr->id.data; + + DAG_id_tag_update(&tex->id, 0); + WM_main_add_notifier(NC_TEXTURE, tex); + WM_main_add_notifier(NC_MATERIAL|ND_SHADING_DRAW, NULL); + } + else if(GS(id->name) == ID_NT) { + bNodeTree *ntree= ptr->id.data; + ED_node_generic_update(bmain, ntree, NULL); + } +} + +static void rna_Texture_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + TexMapping *texmap = ptr->data; + init_tex_mapping(texmap); + rna_Texture_update(bmain, scene, ptr); +} + +static void rna_Color_mapping_update(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + /* nothing to do */ } static void rna_Texture_voxeldata_update(Main *bmain, Scene *scene, PointerRNA *ptr) @@ -400,46 +439,133 @@ static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr)) static void rna_def_texmapping(BlenderRNA *brna) { + static EnumPropertyItem prop_mapping_items[] = { + {MTEX_FLAT, "FLAT", 0, "Flat", "Map X and Y coordinates directly"}, + {MTEX_CUBE, "CUBE", 0, "Cube", "Map using the normal vector"}, + {MTEX_TUBE, "TUBE", 0, "Tube", "Map with Z as central axis"}, + {MTEX_SPHERE, "SPHERE", 0, "Sphere", "Map with Z as central axis"}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem prop_xyz_mapping_items[] = { + {0, "NONE", 0, "None", ""}, + {1, "X", 0, "X", ""}, + {2, "Y", 0, "Y", ""}, + {3, "Z", 0, "Z", ""}, + {0, NULL, 0, NULL, NULL}}; + StructRNA *srna; PropertyRNA *prop; srna= RNA_def_struct(brna, "TexMapping", NULL); - RNA_def_struct_ui_text(srna, "Texture Mapping", "Mapping settings"); + RNA_def_struct_ui_text(srna, "Texture Mapping", "Texture coordinate mapping settings"); prop= RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION); RNA_def_property_float_sdna(prop, NULL, "loc"); RNA_def_property_ui_text(prop, "Location", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); - prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER); + prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_XYZ); /* Not PROP_EUL, this is already in degrees, not radians */ RNA_def_property_float_sdna(prop, NULL, "rot"); RNA_def_property_ui_text(prop, "Rotation", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "size"); RNA_def_property_ui_text(prop, "Scale", ""); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop= RNA_def_property(srna, "min", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "min"); RNA_def_property_ui_text(prop, "Minimum", "Minimum value for clipping"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop= RNA_def_property(srna, "max", PROP_FLOAT, PROP_XYZ); RNA_def_property_float_sdna(prop, NULL, "max"); RNA_def_property_ui_text(prop, "Maximum", "Maximum value for clipping"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop= RNA_def_property(srna, "use_min", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MIN); RNA_def_property_ui_text(prop, "Has Minimum", "Whether to use minimum clipping value"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); prop= RNA_def_property(srna, "use_max", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TEXMAP_CLIP_MAX); RNA_def_property_ui_text(prop, "Has Maximum", "Whether to use maximum clipping value"); - RNA_def_property_update(prop, 0, "rna_Texture_update"); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); + + prop= RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "projx"); + RNA_def_property_enum_items(prop, prop_xyz_mapping_items); + RNA_def_property_ui_text(prop, "X Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); + + prop= RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "projy"); + RNA_def_property_enum_items(prop, prop_xyz_mapping_items); + RNA_def_property_ui_text(prop, "Y Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); + + prop= RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "projz"); + RNA_def_property_enum_items(prop, prop_xyz_mapping_items); + RNA_def_property_ui_text(prop, "Z Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); + + prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_mapping_items); + RNA_def_property_ui_text(prop, "Mapping", ""); + RNA_def_property_update(prop, 0, "rna_Texture_mapping_update"); +} + +static void rna_def_colormapping(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "ColorMapping", NULL); + RNA_def_struct_ui_text(srna, "Color Mapping", "Color mapping settings"); + + prop= RNA_def_property(srna, "use_color_ramp", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", COLORMAP_USE_RAMP); + RNA_def_property_ui_text(prop, "Use Color Ramp", "Toggle color ramp operations"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "color_ramp", PROP_POINTER, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "coba"); + RNA_def_property_struct_type(prop, "ColorRamp"); + RNA_def_property_ui_text(prop, "Color Ramp", ""); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "brightness", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "bright"); + RNA_def_property_range(prop, 0, 2); + RNA_def_property_ui_text(prop, "Brightness", "Adjust the brightness of the texture"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 5); + RNA_def_property_ui_text(prop, "Contrast", "Adjust the contrast of the texture"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "saturation", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0, 2); + RNA_def_property_ui_text(prop, "Saturation", "Adjust the saturation of colors in the texture"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, blend_type_items); + RNA_def_property_ui_text(prop, "Blend Type", "Mode used to mix with texture output color"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "blend_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Color", "Blend color to mix with texture output color"); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); + + prop= RNA_def_property(srna, "blend_factor", PROP_FLOAT, PROP_NONE); + RNA_def_property_ui_text(prop, "Blend Factor", ""); + RNA_def_property_update(prop, 0, "rna_Color_mapping_update"); } static void rna_def_mtex(BlenderRNA *brna) @@ -447,25 +573,6 @@ static void rna_def_mtex(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem prop_blend_type_items[] = { - {MTEX_BLEND, "MIX", 0, "Mix", ""}, - {MTEX_ADD, "ADD", 0, "Add", ""}, - {MTEX_SUB, "SUBTRACT", 0, "Subtract", ""}, - {MTEX_MUL, "MULTIPLY", 0, "Multiply", ""}, - {MTEX_SCREEN, "SCREEN", 0, "Screen", ""}, - {MTEX_OVERLAY, "OVERLAY", 0, "Overlay", ""}, - {MTEX_DIFF, "DIFFERENCE", 0, "Difference", ""}, - {MTEX_DIV, "DIVIDE", 0, "Divide", ""}, - {MTEX_DARK, "DARKEN", 0, "Darken", ""}, - {MTEX_LIGHT, "LIGHTEN", 0, "Lighten", ""}, - {MTEX_BLEND_HUE, "HUE", 0, "Hue", ""}, - {MTEX_BLEND_SAT, "SATURATION", 0, "Saturation", ""}, - {MTEX_BLEND_VAL, "VALUE", 0, "Value", ""}, - {MTEX_BLEND_COLOR, "COLOR", 0, "Color", ""}, - {MTEX_SOFT_LIGHT, "SOFT_LIGHT", 0, "Soft Light", ""}, - {MTEX_LIN_LIGHT , "LINEAR_LIGHT", 0, "Linear Light", ""}, - {0, NULL, 0, NULL, NULL}}; - static EnumPropertyItem output_node_items[] = { {0, "DUMMY", 0, "Dummy", ""}, {0, NULL, 0, NULL, NULL}}; @@ -512,7 +619,7 @@ static void rna_def_mtex(BlenderRNA *brna) prop= RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "blendtype"); - RNA_def_property_enum_items(prop, prop_blend_type_items); + RNA_def_property_enum_items(prop, blend_type_items); RNA_def_property_ui_text(prop, "Blend Type", "Mode used to apply the texture"); RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); @@ -1866,6 +1973,7 @@ void RNA_def_texture(BlenderRNA *brna) rna_def_mtex(brna); rna_def_environment_map(brna); rna_def_texmapping(brna); + rna_def_colormapping(brna); } #endif diff --git a/source/blender/nodes/composite/nodes/node_composite_mapValue.c b/source/blender/nodes/composite/nodes/node_composite_mapValue.c index 81e963d4790..6930fbf0664 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mapValue.c +++ b/source/blender/nodes/composite/nodes/node_composite_mapValue.c @@ -79,7 +79,7 @@ static void node_composit_exec_map_value(void *UNUSED(data), bNode *node, bNodeS static void node_composit_init_map_value(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { - node->storage= add_mapping(); + node->storage= add_tex_mapping(); } void register_node_type_cmp_map_value(ListBase *lb) diff --git a/source/blender/nodes/shader/nodes/node_shader_mapping.c b/source/blender/nodes/shader/nodes/node_shader_mapping.c index 862c52187dc..35007724037 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mapping.c +++ b/source/blender/nodes/shader/nodes/node_shader_mapping.c @@ -69,7 +69,7 @@ static void node_shader_exec_mapping(void *UNUSED(data), bNode *node, bNodeStack static void node_shader_init_mapping(bNodeTree *UNUSED(ntree), bNode* node, bNodeTemplate *UNUSED(ntemp)) { - node->storage= add_mapping(); + node->storage= add_tex_mapping(); } static int gpu_shader_mapping(GPUMaterial *mat, bNode *node, GPUNodeStack *in, GPUNodeStack *out) From ae06ebcd95a63f44501b4ee30e120162f53e940a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 7 Nov 2011 18:14:50 +0000 Subject: [PATCH 142/147] Hopefully compilation with MinGW will work again. Tested with official MinGW and SCons, not sure how ti check it when using CMake. --- extern/libmv/CMakeLists.txt | 7 +- extern/libmv/SConscript | 4 +- extern/libmv/bundle.sh | 15 +- .../libmv/multiview/euclidean_resection.cc | 2 + extern/libmv/patches/mingw.patch | 158 ++++++++++++++++++ extern/libmv/third_party/glog/src/config.h | 2 + extern/libmv/third_party/glog/src/utilities.h | 4 +- .../glog/src/windows/glog/logging.h | 18 +- .../libmv/third_party/glog/src/windows/port.h | 37 +++- 9 files changed, 233 insertions(+), 14 deletions(-) diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 41fc39c97ac..7ab01598cef 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -159,9 +159,14 @@ IF(WIN32) list(APPEND INC ./third_party/glog/src/windows - ./third_party/msinttypes ) + IF(NOT MINGW) + list(APPEND INC + ./third_party/msinttypes + ) + ENDIF(NOT MINGW) + IF(MSVC) set(MSVC_OFLAGS O1 O2 Ox) foreach(FLAG ) diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript index 1ffc6233c1d..60705e913f7 100644 --- a/extern/libmv/SConscript +++ b/extern/libmv/SConscript @@ -30,7 +30,9 @@ incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): - incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes' + incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog' + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + incs += ' ./third_party/msinttypes' src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc'] src += ['./third_party/glog/src/windows/port.cc'] diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh index c8df8ae7341..690f78df387 100755 --- a/extern/libmv/bundle.sh +++ b/extern/libmv/bundle.sh @@ -166,6 +166,16 @@ IF(WIN32) third_party/glog/src/windows/config.h ) + list(APPEND INC + ./third_party/glog/src/windows + ) + + IF(NOT MINGW) + list(APPEND INC + ./third_party/msinttypes + ) + ENDIF(MINGW) + list(APPEND INC ./third_party/glog/src/windows ./third_party/msinttypes @@ -219,7 +229,10 @@ incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): - incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog ./third_party/msinttypes' + incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog' + incs += ' ./third_party/glog/src/windows ./third_party/glog/src/windows/glog' + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): + incs += ' ./third_party/msinttypes' ${win_src} src += ['./third_party/glog/src/logging.cc', './third_party/glog/src/raw_logging.cc', './third_party/glog/src/utilities.cc', './third_party/glog/src/vlog_is_on.cc'] src += ['./third_party/glog/src/windows/port.cc'] diff --git a/extern/libmv/libmv/multiview/euclidean_resection.cc b/extern/libmv/libmv/multiview/euclidean_resection.cc index 6d918a1a8bc..92862515d7e 100644 --- a/extern/libmv/libmv/multiview/euclidean_resection.cc +++ b/extern/libmv/libmv/multiview/euclidean_resection.cc @@ -32,6 +32,8 @@ namespace libmv { namespace euclidean_resection { +typedef unsigned int uint; + bool EuclideanResection(const Mat2X &x_camera, const Mat3X &X_world, Mat3 *R, Vec3 *t, diff --git a/extern/libmv/patches/mingw.patch b/extern/libmv/patches/mingw.patch index 0b08a483bea..029e7d7f979 100644 --- a/extern/libmv/patches/mingw.patch +++ b/extern/libmv/patches/mingw.patch @@ -1,3 +1,16 @@ +diff --git a/src/libmv/multiview/euclidean_resection.cc b/src/libmv/multiview/euclidean_resection.cc +index 6d918a1..9286251 100644 +--- a/src/libmv/multiview/euclidean_resection.cc ++++ b/src/libmv/multiview/euclidean_resection.cc +@@ -32,6 +32,8 @@ + namespace libmv { + namespace euclidean_resection { + ++typedef unsigned int uint; ++ + bool EuclideanResection(const Mat2X &x_camera, + const Mat3X &X_world, + Mat3 *R, Vec3 *t, diff --git a/src/libmv/numeric/numeric.h b/src/libmv/numeric/numeric.h index f39d126..21e0f06 100644 --- a/src/libmv/numeric/numeric.h @@ -11,3 +24,148 @@ index f39d126..21e0f06 100644 inline long lround(double d) { return (long)(d>0 ? d+0.5 : ceil(d-0.5)); } +diff --git a/src/third_party/glog/src/config.h b/src/third_party/glog/src/config.h +index ed8d56e..06ed686 100644 +--- a/src/third_party/glog/src/config.h ++++ b/src/third_party/glog/src/config.h +@@ -4,6 +4,8 @@ + /* Namespace for Google classes */ + #ifdef __APPLE__ + #include "config_mac.h" ++#elif __MINGW32__ ++ #include "windows/config.h" + #elif __GNUC__ + #include "config_linux.h" + #elif _MSC_VER +diff --git a/src/third_party/glog/src/utilities.h b/src/third_party/glog/src/utilities.h +index ee54f94..c4ae256 100644 +--- a/src/third_party/glog/src/utilities.h ++++ b/src/third_party/glog/src/utilities.h +@@ -101,7 +101,9 @@ + // correctly when GetStackTrace() is called with max_depth == 0. + // Some code may do that. + +-#if defined(HAVE_LIB_UNWIND) ++#if __MINGW32__ ++# undef STACKTRACE_H ++#elif defined(HAVE_LIB_UNWIND) + # define STACKTRACE_H "stacktrace_libunwind-inl.h" + #elif !defined(NO_FRAME_POINTER) + # if defined(__i386__) && __GNUC__ >= 2 +diff --git a/src/third_party/glog/src/windows/glog/logging.h b/src/third_party/glog/src/windows/glog/logging.h +index 7a6df74..4257375 100755 +--- a/src/third_party/glog/src/windows/glog/logging.h ++++ b/src/third_party/glog/src/windows/glog/logging.h +@@ -59,7 +59,7 @@ + + // Annoying stuff for windows -- makes sure clients can import these functions + #ifndef GOOGLE_GLOG_DLL_DECL +-# if defined(_WIN32) && !defined(__CYGWIN__) ++# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) + # define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) + # else + # define GOOGLE_GLOG_DLL_DECL +@@ -86,6 +86,15 @@ + #include + #endif + ++#ifdef __MINGW32__ ++# include ++# include ++# include // the normal place uint16_t is defined ++# include // the normal place u_int16_t is defined ++# include // a third place for uint16_t or u_int16_t ++# define _exit(x) exit(x) ++#endif ++ + namespace google { + + #if 0 // the C99 format +@@ -98,11 +107,16 @@ typedef int32_t int32; + typedef u_int32_t uint32; + typedef int64_t int64; + typedef u_int64_t uint64; +-#elif 1 // the windows (vc7) format ++#elif defined(_MSC_VER) + typedef __int32 int32; + typedef unsigned __int32 uint32; + typedef __int64 int64; + typedef unsigned __int64 uint64; ++#elif defined(__MINGW32__) ++typedef int32_t int32; ++typedef uint32_t uint32; ++typedef int64_t int64; ++typedef uint64_t uint64; + #else + #error Do not know how to define a 32-bit integer quantity on your system + #endif +diff --git a/src/third_party/glog/src/windows/port.h b/src/third_party/glog/src/windows/port.h +index d093bf5..d507812 100755 +--- a/src/third_party/glog/src/windows/port.h ++++ b/src/third_party/glog/src/windows/port.h +@@ -59,14 +59,16 @@ + * used by both C and C++ code, so we put all the C++ together. + */ + +-/* 4244: otherwise we get problems when substracting two size_t's to an int +- * 4251: it's complaining about a private struct I've chosen not to dllexport +- * 4355: we use this in a constructor, but we do it safely +- * 4715: for some reason VC++ stopped realizing you can't return after abort() +- * 4800: we know we're casting ints/char*'s to bools, and we're ok with that +- * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() +- */ +-#pragma warning(disable:4244 4251 4355 4715 4800 4996) ++#if _MSC_VER ++ /* 4244: otherwise we get problems when substracting two size_t's to an int ++ * 4251: it's complaining about a private struct I've chosen not to dllexport ++ * 4355: we use this in a constructor, but we do it safely ++ * 4715: for some reason VC++ stopped realizing you can't return after abort() ++ * 4800: we know we're casting ints/char*'s to bools, and we're ok with that ++ * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() ++ */ ++# pragma warning(disable:4244 4251 4355 4715 4800 4996) ++#endif + + /* file I/O */ + #define PATH_MAX 1024 +@@ -108,7 +110,9 @@ extern int snprintf(char *str, size_t size, + extern int safe_vsnprintf(char *str, size_t size, + const char *format, va_list ap); + #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) ++#if !defined(__MINGW32__) + #define va_copy(dst, src) (dst) = (src) ++#endif + + /* Windows doesn't support specifying the number of buckets as a + * hash_map constructor arg, so we leave this blank. +@@ -130,13 +134,30 @@ enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock + #define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) + + inline struct tm* localtime_r(const time_t* timep, struct tm* result) { ++#if __MINGW32__ ++ struct tm *local_result; ++ local_result = localtime (timep); ++ ++ if (local_result == NULL || result == NULL) ++ return NULL; ++ ++ memcpy (result, local_result, sizeof (result)); ++ ++ return result; ++#else + localtime_s(result, timep); + return result; ++#endif + } + + inline char* strerror_r(int errnum, char* buf, size_t buflen) { ++#if __MINGW32__ ++ strncpy(buf, "Not implemented yet", buflen); ++ return buf; ++#else + strerror_s(buf, buflen, errnum); + return buf; ++#endif + } + + #ifndef __cplusplus diff --git a/extern/libmv/third_party/glog/src/config.h b/extern/libmv/third_party/glog/src/config.h index ed8d56e7799..06ed686f87c 100644 --- a/extern/libmv/third_party/glog/src/config.h +++ b/extern/libmv/third_party/glog/src/config.h @@ -4,6 +4,8 @@ /* Namespace for Google classes */ #ifdef __APPLE__ #include "config_mac.h" +#elif __MINGW32__ + #include "windows/config.h" #elif __GNUC__ #include "config_linux.h" #elif _MSC_VER diff --git a/extern/libmv/third_party/glog/src/utilities.h b/extern/libmv/third_party/glog/src/utilities.h index 2d4e99e595e..5c841a0b90b 100644 --- a/extern/libmv/third_party/glog/src/utilities.h +++ b/extern/libmv/third_party/glog/src/utilities.h @@ -101,7 +101,9 @@ // correctly when GetStackTrace() is called with max_depth == 0. // Some code may do that. -#if defined(HAVE_LIB_UNWIND) +#if __MINGW32__ +# undef STACKTRACE_H +#elif defined(HAVE_LIB_UNWIND) # define STACKTRACE_H "stacktrace_libunwind-inl.h" #elif !defined(NO_FRAME_POINTER) # if defined(__i386__) && __GNUC__ >= 2 diff --git a/extern/libmv/third_party/glog/src/windows/glog/logging.h b/extern/libmv/third_party/glog/src/windows/glog/logging.h index de51586f8e3..2f41681edbe 100644 --- a/extern/libmv/third_party/glog/src/windows/glog/logging.h +++ b/extern/libmv/third_party/glog/src/windows/glog/logging.h @@ -59,7 +59,7 @@ // Annoying stuff for windows -- makes sure clients can import these functions #ifndef GOOGLE_GLOG_DLL_DECL -# if defined(_WIN32) && !defined(__CYGWIN__) +# if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__) # define GOOGLE_GLOG_DLL_DECL __declspec(dllimport) # else # define GOOGLE_GLOG_DLL_DECL @@ -86,6 +86,15 @@ #include "third_party/gflags/gflags.h" #endif +#ifdef __MINGW32__ +# include +# include +# include // the normal place uint16_t is defined +# include // the normal place u_int16_t is defined +# include // a third place for uint16_t or u_int16_t +# define _exit(x) exit(x) +#endif + namespace google { #if 0 // the C99 format @@ -98,11 +107,16 @@ typedef int32_t int32; typedef u_int32_t uint32; typedef int64_t int64; typedef u_int64_t uint64; -#elif 1 // the windows (vc7) format +#elif defined(_MSC_VER) typedef __int32 int32; typedef unsigned __int32 uint32; typedef __int64 int64; typedef unsigned __int64 uint64; +#elif defined(__MINGW32__) +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; #else #error Do not know how to define a 32-bit integer quantity on your system #endif diff --git a/extern/libmv/third_party/glog/src/windows/port.h b/extern/libmv/third_party/glog/src/windows/port.h index d093bf5d34c..d5078120009 100644 --- a/extern/libmv/third_party/glog/src/windows/port.h +++ b/extern/libmv/third_party/glog/src/windows/port.h @@ -59,14 +59,16 @@ * used by both C and C++ code, so we put all the C++ together. */ -/* 4244: otherwise we get problems when substracting two size_t's to an int - * 4251: it's complaining about a private struct I've chosen not to dllexport - * 4355: we use this in a constructor, but we do it safely - * 4715: for some reason VC++ stopped realizing you can't return after abort() - * 4800: we know we're casting ints/char*'s to bools, and we're ok with that - * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() - */ -#pragma warning(disable:4244 4251 4355 4715 4800 4996) +#if _MSC_VER + /* 4244: otherwise we get problems when substracting two size_t's to an int + * 4251: it's complaining about a private struct I've chosen not to dllexport + * 4355: we use this in a constructor, but we do it safely + * 4715: for some reason VC++ stopped realizing you can't return after abort() + * 4800: we know we're casting ints/char*'s to bools, and we're ok with that + * 4996: Yes, we're ok using "unsafe" functions like fopen() and strerror() + */ +# pragma warning(disable:4244 4251 4355 4715 4800 4996) +#endif /* file I/O */ #define PATH_MAX 1024 @@ -108,7 +110,9 @@ extern int snprintf(char *str, size_t size, extern int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap); #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) +#if !defined(__MINGW32__) #define va_copy(dst, src) (dst) = (src) +#endif /* Windows doesn't support specifying the number of buckets as a * hash_map constructor arg, so we leave this blank. @@ -130,13 +134,30 @@ enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock #define pthread_equal(pthread_t_1, pthread_t_2) ((pthread_t_1)==(pthread_t_2)) inline struct tm* localtime_r(const time_t* timep, struct tm* result) { +#if __MINGW32__ + struct tm *local_result; + local_result = localtime (timep); + + if (local_result == NULL || result == NULL) + return NULL; + + memcpy (result, local_result, sizeof (result)); + + return result; +#else localtime_s(result, timep); return result; +#endif } inline char* strerror_r(int errnum, char* buf, size_t buflen) { +#if __MINGW32__ + strncpy(buf, "Not implemented yet", buflen); + return buf; +#else strerror_s(buf, buflen, errnum); return buf; +#endif } #ifndef __cplusplus From 6981e68c92266ada536f33eb50af493de2ef8ce7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 7 Nov 2011 19:25:13 +0000 Subject: [PATCH 143/147] Fix [#29194] Spelling error (yes sir, it is a bugfix :P ). --- source/blender/makesrna/intern/rna_scene.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b1d4654f76b..ca325747d8e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -76,7 +76,7 @@ EnumPropertyItem proportional_falloff_items[] ={ {PROP_ROOT, "ROOT", ICON_ROOTCURVE, "Root", "Root falloff"}, {PROP_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", "Sharp falloff"}, {PROP_LIN, "LINEAR", ICON_LINCURVE, "Linear", "Linear falloff"}, - {PROP_CONST, "CONSTANT", ICON_NOCURVE, "Constant", "Consant falloff"}, + {PROP_CONST, "CONSTANT", ICON_NOCURVE, "Constant", "Constant falloff"}, {PROP_RANDOM, "RANDOM", ICON_RNDCURVE, "Random", "Random falloff"}, {0, NULL, 0, NULL, NULL}}; From be23090aae643f3c5a01ec47c601aa50a7174eb4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 22:14:48 +0000 Subject: [PATCH 144/147] Nodes: add foreach_nodeclass iterator over node classes, use for node add menu. --- source/blender/blenkernel/BKE_node.h | 2 + .../blender/editors/space_node/node_header.c | 48 ++++--------------- .../nodes/composite/node_composite_tree.c | 15 ++++++ .../blender/nodes/shader/node_shader_tree.c | 20 ++++++++ .../blender/nodes/texture/node_texture_tree.c | 14 ++++++ 5 files changed, 61 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 6080981dc32..b94fffab714 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -245,6 +245,7 @@ typedef struct bNodeType { struct bNodeTreeExec; typedef void (*bNodeTreeCallback)(void *calldata, struct ID *owner_id, struct bNodeTree *ntree); +typedef void (*bNodeClassCallback)(void *calldata, int nclass, const char *name); typedef struct bNodeTreeType { int type; /* type identifier */ @@ -256,6 +257,7 @@ typedef struct bNodeTreeType void (*free_cache)(struct bNodeTree *ntree); void (*free_node_cache)(struct bNodeTree *ntree, struct bNode *node); void (*foreach_nodetree)(struct Main *main, void *calldata, bNodeTreeCallback func); /* iteration over all node trees */ + void (*foreach_nodeclass)(struct Scene *scene, void *calldata, bNodeClassCallback func); /* iteration over all node classes */ /* calls allowing threaded composite */ void (*localize)(struct bNodeTree *localtree, struct bNodeTree *ntree); diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c index 42b5dafa3e1..d752dd79a19 100644 --- a/source/blender/editors/space_node/node_header.c +++ b/source/blender/editors/space_node/node_header.c @@ -226,52 +226,24 @@ static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass) } } +static void node_menu_add_foreach_cb(void *calldata, int nclass, const char *name) +{ + uiLayout *layout= calldata; + uiItemMenuF(layout, IFACE_(name), 0, node_add_menu, SET_INT_IN_POINTER(nclass)); +} + static void node_menu_add(const bContext *C, Menu *menu) { Scene *scene= CTX_data_scene(C); SpaceNode *snode= CTX_wm_space_node(C); uiLayout *layout= menu->layout; + bNodeTreeType *ntreetype= ntreeGetType(snode->treetype); if(!snode->nodetree) uiLayoutSetActive(layout, 0); - - if(snode->treetype==NTREE_SHADER) { - uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - if(scene_use_new_shading_nodes(scene)) { - uiItemMenuF(layout, IFACE_("Shader"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_SHADER)); - uiItemMenuF(layout, IFACE_("Texture"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE)); - } - uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, IFACE_("Vector"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); - uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); - //uiItemMenuF(layout, IFACE_("Dynamic"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_DYNAMIC)); - uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT)); - } - else if(snode->treetype==NTREE_COMPOSIT) { - uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, IFACE_("Vector"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_VECTOR)); - uiItemMenuF(layout, IFACE_("Filter"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_FILTER)); - uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, IFACE_("Matte"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_MATTE)); - uiItemMenuF(layout, IFACE_("Distort"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); - uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); - uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT)); - } - else if(snode->treetype==NTREE_TEXTURE) { - uiItemMenuF(layout, IFACE_("Input"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_INPUT)); - uiItemMenuF(layout, IFACE_("Output"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OUTPUT)); - uiItemMenuF(layout, IFACE_("Color"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_OP_COLOR)); - uiItemMenuF(layout, IFACE_("Patterns"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_PATTERN)); - uiItemMenuF(layout, IFACE_("Textures"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_TEXTURE)); - uiItemMenuF(layout, IFACE_("Convertor"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_CONVERTOR)); - uiItemMenuF(layout, IFACE_("Distort"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_DISTORT)); - uiItemMenuF(layout, IFACE_("Group"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_GROUP)); - uiItemMenuF(layout, IFACE_("Layout"), 0, node_add_menu, SET_INT_IN_POINTER(NODE_CLASS_LAYOUT)); - } + + if(ntreetype && ntreetype->foreach_nodeclass) + ntreetype->foreach_nodeclass(scene, layout, node_menu_add_foreach_cb); } void node_menus_register(void) diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c index d3f4a5b2999..06f88002a70 100644 --- a/source/blender/nodes/composite/node_composite_tree.c +++ b/source/blender/nodes/composite/node_composite_tree.c @@ -68,6 +68,20 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) } } +static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func) +{ + func(calldata, NODE_CLASS_INPUT, "Input"); + func(calldata, NODE_CLASS_OUTPUT, "Output"); + func(calldata, NODE_CLASS_OP_COLOR, "Color"); + func(calldata, NODE_CLASS_OP_VECTOR, "Vector"); + func(calldata, NODE_CLASS_OP_FILTER, "Filter"); + func(calldata, NODE_CLASS_CONVERTOR, "Convertor"); + func(calldata, NODE_CLASS_MATTE, "Matte"); + func(calldata, NODE_CLASS_DISTORT, "Distort"); + func(calldata, NODE_CLASS_GROUP, "Group"); + func(calldata, NODE_CLASS_LAYOUT, "Layout"); +} + static void free_node_cache(bNodeTree *UNUSED(ntree), bNode *node) { bNodeSocket *sock; @@ -207,6 +221,7 @@ bNodeTreeType ntreeType_Composite = { /* free_cache */ free_cache, /* free_node_cache */ free_node_cache, /* foreach_nodetree */ foreach_nodetree, + /* foreach_nodeclass */ foreach_nodeclass, /* localize */ localize, /* local_sync */ local_sync, /* local_merge */ local_merge, diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index d0ae17914ca..aa8ba12f799 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -35,6 +35,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_node_types.h" +#include "DNA_scene_types.h" #include "DNA_world_types.h" #include "BLI_listbase.h" @@ -45,6 +46,7 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_scene.h" #include "BKE_utildefines.h" #include "GPU_material.h" @@ -74,6 +76,23 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) func(calldata, &wo->id, wo->nodetree); } +static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func) +{ + func(calldata, NODE_CLASS_INPUT, "Input"); + func(calldata, NODE_CLASS_OUTPUT, "Output"); + + if(scene_use_new_shading_nodes(scene)) { + func(calldata, NODE_CLASS_SHADER, "Shader"); + func(calldata, NODE_CLASS_TEXTURE, "Texture"); + } + + func(calldata, NODE_CLASS_OP_COLOR, "Color"); + func(calldata, NODE_CLASS_OP_VECTOR, "Vector"); + func(calldata, NODE_CLASS_CONVERTOR, "Convertor"); + func(calldata, NODE_CLASS_GROUP, "Group"); + func(calldata, NODE_CLASS_LAYOUT, "Layout"); +} + static void local_sync(bNodeTree *localtree, bNodeTree *ntree) { bNode *lnode; @@ -108,6 +127,7 @@ bNodeTreeType ntreeType_Shader = { /* free_cache */ NULL, /* free_node_cache */ NULL, /* foreach_nodetree */ foreach_nodetree, + /* foreach_nodeclass */ foreach_nodeclass, /* localize */ NULL, /* local_sync */ local_sync, /* local_merge */ NULL, diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 5e5d44540dc..84bb53e2215 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -62,6 +62,19 @@ static void foreach_nodetree(Main *main, void *calldata, bNodeTreeCallback func) } } +static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func) +{ + func(calldata, NODE_CLASS_INPUT, "Input"); + func(calldata, NODE_CLASS_OUTPUT, "Output"); + func(calldata, NODE_CLASS_OP_COLOR, "Color"); + func(calldata, NODE_CLASS_PATTERN, "Patterns"); + func(calldata, NODE_CLASS_TEXTURE, "Textures"); + func(calldata, NODE_CLASS_CONVERTOR, "Convertor"); + func(calldata, NODE_CLASS_DISTORT, "Distort"); + func(calldata, NODE_CLASS_GROUP, "Group"); + func(calldata, NODE_CLASS_LAYOUT, "Layout"); +} + static void local_sync(bNodeTree *localtree, bNodeTree *ntree) { bNode *lnode; @@ -91,6 +104,7 @@ bNodeTreeType ntreeType_Texture = { /* free_cache */ NULL, /* free_node_cache */ NULL, /* foreach_nodetree */ foreach_nodetree, + /* foreach_nodeclass */ foreach_nodeclass, /* localize */ NULL, /* local_sync */ local_sync, /* local_merge */ NULL, From cd191b7d17c42e90dcdda56ba3fbddf08666b3ab Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 7 Nov 2011 22:28:49 +0000 Subject: [PATCH 145/147] UI/Nodes: templates to edit nodes from the properties editor using a tree view, to be used by cycles. For testing there's a panel in the node editor if you set debug to 777, didn't enable it because I'm not sure it's very useful there. --- source/blender/editors/include/UI_interface.h | 19 +- .../editors/interface/interface_intern.h | 6 +- .../editors/interface/interface_regions.c | 9 - .../editors/interface/interface_widgets.c | 42 +- .../blender/editors/space_node/CMakeLists.txt | 1 + .../blender/editors/space_node/node_buttons.c | 37 + .../editors/space_node/node_templates.c | 636 ++++++++++++++++++ source/blender/makesrna/intern/rna_ui_api.c | 17 + .../bad_level_call_stubs/stubs.c | 3 + 9 files changed, 750 insertions(+), 20 deletions(-) create mode 100644 source/blender/editors/space_node/node_templates.c diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 942252bc00f..02b8cc9e2c6 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -66,6 +66,9 @@ struct uiWidgetColors; struct Tex; struct MTex; struct ImBuf; +struct bNodeTree; +struct bNode; +struct bNodeSocket; typedef struct uiBut uiBut; typedef struct uiBlock uiBlock; @@ -74,6 +77,10 @@ typedef struct uiLayout uiLayout; /* Defines */ +/* names */ +#define UI_MAX_DRAW_STR 400 +#define UI_MAX_NAME_STR 128 + /* uiBlock->dt */ #define UI_EMBOSS 0 /* use widget style for drawing */ #define UI_EMBOSSN 1 /* Nothing, only icon and/or text */ @@ -128,11 +135,11 @@ typedef struct uiLayout uiLayout; #define UI_ICON_LEFT 128 #define UI_ICON_SUBMENU 256 #define UI_ICON_PREVIEW 512 - /* control for button type block */ -#define UI_MAKE_TOP 1024 -#define UI_MAKE_DOWN 2048 -#define UI_MAKE_LEFT 4096 -#define UI_MAKE_RIGHT 8192 + +#define UI_TEXT_RIGHT 1024 +#define UI_BUT_NODE_LINK 2048 +#define UI_BUT_NODE_ACTIVE 4096 +#define UI_FLAG_UNUSED 8192 /* button align flag, for drawing groups together */ #define UI_BUT_ALIGN (UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT|UI_BUT_ALIGN_RIGHT|UI_BUT_ALIGN_DOWN) @@ -749,6 +756,8 @@ void uiTemplateReportsBanner(uiLayout *layout, struct bContext *C); void uiTemplateKeymapItemProperties(uiLayout *layout, struct PointerRNA *ptr); void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, struct PointerRNA *activeptr, const char *activeprop, const char *prop_list, int rows, int maxrows, int type); +void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); +void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact); void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 29447d492c5..aa4158ad4b7 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -79,6 +79,7 @@ typedef enum { UI_WTYPE_MENU_RADIO, UI_WTYPE_MENU_ICON_RADIO, UI_WTYPE_MENU_POINTER_LINK, + UI_WTYPE_MENU_NODE_LINK, UI_WTYPE_PULLDOWN, UI_WTYPE_MENU_ITEM, @@ -96,11 +97,6 @@ typedef enum { } uiWidgetTypeEnum; - - -#define UI_MAX_DRAW_STR 400 -#define UI_MAX_NAME_STR 128 - /* panel limits */ #define UI_PANEL_MINX 100 #define UI_PANEL_MINY 70 diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index edbd5c5684e..34b62155314 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1533,15 +1533,6 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut if(ELEM(but->type, BLOCK, PULLDOWN)) block->xofs = -2; /* for proper alignment */ - /* only used for automatic toolbox, so can set the shift flag */ - if(but->flag & UI_MAKE_TOP) { - block->direction= UI_TOP|UI_SHIFT_FLIPPED; - uiBlockFlipOrder(block); - } - if(but->flag & UI_MAKE_DOWN) block->direction= UI_DOWN|UI_SHIFT_FLIPPED; - if(but->flag & UI_MAKE_LEFT) block->direction |= UI_LEFT; - if(but->flag & UI_MAKE_RIGHT) block->direction |= UI_RIGHT; - ui_block_position(window, butregion, but, block); } else { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 8ab48ac8ffa..aa407bbf6d4 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1181,6 +1181,12 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB widget_draw_icon(but, ICON_DOT, dualset?1.0f:0.25f, rect); } + else if(but->type==MENU && (but->flag & UI_BUT_NODE_LINK)) { + int tmp = rect->xmin; + rect->xmin = rect->xmax - (rect->ymax - rect->ymin) - 1; + widget_draw_icon(but, ICON_LAYER_USED, 1.0f, rect); + rect->xmin = tmp; + } /* If there's an icon too (made with uiDefIconTextBut) then draw the icon and offset the text label to accommodate it */ @@ -1543,6 +1549,10 @@ static void widget_state(uiWidgetType *wt, int state) char red[4]= {255, 0, 0}; widget_state_blend(wt->wcol.inner, red, 0.4f); } + if(state & UI_BUT_NODE_ACTIVE) { + char blue[4]= {86, 128, 194}; + widget_state_blend(wt->wcol.inner, blue, 0.3f); + } } /* sliders use special hack which sets 'item' as inner when drawing filling */ @@ -2530,6 +2540,29 @@ static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(stat widgetbase_draw(&wtb, wcol); } +static void widget_menunodebut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) +{ + /* silly node link button hacks */ + uiWidgetBase wtb; + uiWidgetColors wcol_backup= *wcol; + + widget_init(&wtb); + + /* half rounded */ + round_box_edges(&wtb, roundboxalign, rect, 4.0f); + + wcol->inner[0] += 15; + wcol->inner[1] += 15; + wcol->inner[2] += 15; + wcol->outline[0] += 15; + wcol->outline[1] += 15; + wcol->outline[2] += 15; + + /* decoration */ + widgetbase_draw(&wtb, wcol); + *wcol= wcol_backup; +} + static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) { if(state & UI_ACTIVE) { @@ -2804,6 +2837,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type) wt.wcol_theme= &btheme->tui.wcol_menu; wt.draw= widget_menubut; break; + + case UI_WTYPE_MENU_NODE_LINK: + wt.wcol_theme= &btheme->tui.wcol_menu; + wt.draw= widget_menunodebut; + break; case UI_WTYPE_PULLDOWN: wt.wcol_theme= &btheme->tui.wcol_pulldown; @@ -2996,7 +3034,9 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct case MENU: case BLOCK: case ICONTEXTROW: - if(!but->str[0] && but->icon) + if(but->flag & UI_BUT_NODE_LINK) + wt= widget_type(UI_WTYPE_MENU_NODE_LINK); + else if(!but->str[0] && but->icon) wt= widget_type(UI_WTYPE_MENU_ICON_RADIO); else wt= widget_type(UI_WTYPE_MENU_RADIO); diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 8a27bcca8af..991b35585a6 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -47,6 +47,7 @@ set(SRC node_ops.c node_select.c node_state.c + node_templates.c space_node.c node_intern.h diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 3886c709196..15e5719be37 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -45,6 +45,7 @@ #include "BLI_utildefines.h" #include "BKE_context.h" +#include "BKE_global.h" #include "BKE_node.h" #include "BKE_screen.h" @@ -122,6 +123,34 @@ static void active_node_panel(const bContext *C, Panel *pa) node->typeinfo->uifunc(layout, (bContext *)C, &ptr); } +static int node_sockets_poll(const bContext *C, PanelType *UNUSED(pt)) +{ + SpaceNode *snode= CTX_wm_space_node(C); + + return (snode && snode->nodetree && G.rt == 777); +} + +static void node_sockets_panel(const bContext *C, Panel *pa) +{ + SpaceNode *snode= CTX_wm_space_node(C); + bNodeTree *ntree= (snode) ? snode->edittree : NULL; + bNode *node = (ntree) ? nodeGetActive(ntree) : NULL; + bNodeSocket *sock; + uiLayout *layout= pa->layout, *split; + char name[UI_MAX_NAME_STR]; + + if(ELEM(NULL, ntree, node)) + return; + + for(sock=node->inputs.first; sock; sock=sock->next) { + BLI_snprintf(name, sizeof(name), "%s:", sock->name); + + split = uiLayoutSplit(layout, 0.35f, 0); + uiItemL(split, name, ICON_NONE); + uiTemplateNodeLink(split, ntree, node, sock); + } +} + /* ******************* node buttons registration ************** */ void node_buttons_register(ARegionType *art) @@ -134,6 +163,14 @@ void node_buttons_register(ARegionType *art) pt->draw= active_node_panel; pt->poll= active_node_poll; BLI_addtail(&art->paneltypes, pt); + + pt= MEM_callocN(sizeof(PanelType), "spacetype node panel node sockets"); + strcpy(pt->idname, "NODE_PT_sockets"); + strcpy(pt->label, "Sockets"); + pt->draw= node_sockets_panel; + pt->poll= node_sockets_poll; + pt->flag |= PNL_DEFAULT_CLOSED; + BLI_addtail(&art->paneltypes, pt); pt= MEM_callocN(sizeof(PanelType), "spacetype node panel gpencil"); strcpy(pt->idname, "NODE_PT_gpencil"); diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c new file mode 100644 index 00000000000..b877bea6be9 --- /dev/null +++ b/source/blender/editors/space_node/node_templates.c @@ -0,0 +1,636 @@ +/* + * $Id$ + * + * ***** 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. + * + * Contributor(s): Blender Foundation 2009. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/interface/interface_node.c + * \ingroup edinterface + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_node_types.h" +#include "DNA_scene_types.h" +#include "DNA_screen_types.h" + +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" +#include "BKE_depsgraph.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_scene.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "UI_interface.h" +#include "UI_resources.h" +#include "../interface/interface_intern.h" + +#include "ED_node.h" + +/************************* Node Socket Manipulation **************************/ + +static void node_tag_recursive(bNode *node) +{ + bNodeSocket *input; + + if(!node || (node->flag & NODE_TEST)) + return; /* in case of cycles */ + + node->flag |= NODE_TEST; + + for(input=node->inputs.first; input; input=input->next) + if(input->link) + node_tag_recursive(input->link->fromnode); +} + +static void node_clear_recursive(bNode *node) +{ + bNodeSocket *input; + + if(!node || !(node->flag & NODE_TEST)) + return; /* in case of cycles */ + + node->flag &= ~NODE_TEST; + + for(input=node->inputs.first; input; input=input->next) + if(input->link) + node_clear_recursive(input->link->fromnode); +} + +static void node_remove_linked(bNodeTree *ntree, bNode *rem_node) +{ + bNode *node, *next; + bNodeSocket *sock; + + if(!rem_node) + return; + + /* tag linked nodes to be removed */ + for(node=ntree->nodes.first; node; node=node->next) + node->flag &= ~NODE_TEST; + + node_tag_recursive(rem_node); + + /* clear tags on nodes that are still used by other nodes */ + for(node=ntree->nodes.first; node; node=node->next) + if(!(node->flag & NODE_TEST)) + for(sock=node->inputs.first; sock; sock=sock->next) + if(sock->link && sock->link->fromnode != rem_node) + node_clear_recursive(sock->link->fromnode); + + /* remove nodes */ + for(node=ntree->nodes.first; node; node=next) { + next = node->next; + + if(node->flag & NODE_TEST) { + if(node->id) + node->id->us--; + nodeFreeNode(ntree, node); + } + } +} + +/* disconnect socket from the node it is connected to */ +static void node_socket_disconnect(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to) +{ + if(!sock_to->link) + return; + + nodeRemLink(ntree, sock_to->link); + + nodeUpdate(ntree, node_to); + ntreeUpdateTree(ntree); + + ED_node_generic_update(bmain, ntree, node_to); +} + +/* remove all nodes connected to this socket, if they aren't connected to other nodes */ +static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to) +{ + if(!sock_to->link) + return; + + node_remove_linked(ntree, sock_to->link->fromnode); + + nodeUpdate(ntree, node_to); + ntreeUpdateTree(ntree); + + ED_node_generic_update(bmain, ntree, node_to); +} + +/* add new node connected to this socket, or replace an existing one */ +static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num) +{ + bNode *node_from; + bNodeSocket *sock_from; + bNode *node_prev = NULL; + + /* unlink existing node */ + if(sock_to->link) { + node_prev = sock_to->link->fromnode; + nodeRemLink(ntree, sock_to->link); + } + + /* find existing node that we can use */ + for(node_from=ntree->nodes.first; node_from; node_from=node_from->next) + if(node_from->type == ntemp->type) + break; + + if(node_from) + if(!(node_from->inputs.first == NULL && !(node_from->typeinfo->flag & NODE_OPTIONS))) + node_from = NULL; + + if(node_prev && node_prev->type == ntemp->type && + (ntemp->type != NODE_GROUP || node_prev->id == &ntemp->ngroup->id)) { + /* keep the previous node if it's the same type */ + node_from = node_prev; + } + else if(!node_from) { + node_from= nodeAddNode(ntree, ntemp); + node_from->locx = node_to->locx - (node_from->typeinfo->width + 50); + node_from->locy = node_to->locy; + + if(node_from->id) + id_us_plus(node_from->id); + } + + nodeSetActive(ntree, node_from); + + /* add link */ + sock_from = BLI_findlink(&node_from->outputs, sock_num); + nodeAddLink(ntree, node_from, sock_from, node_to, sock_to); + + /* copy input sockets from previous node */ + if(node_prev && node_from != node_prev) { + bNodeSocket *sock_prev, *sock_from; + + for(sock_prev=node_prev->inputs.first; sock_prev; sock_prev=sock_prev->next) { + for(sock_from=node_from->inputs.first; sock_from; sock_from=sock_from->next) { + if(strcmp(sock_prev->name, sock_from->name) == 0 && sock_prev->type == sock_from->type) { + bNodeLink *link = sock_prev->link; + + if(link && link->fromnode) { + nodeAddLink(ntree, link->fromnode, link->fromsock, node_from, sock_from); + nodeRemLink(ntree, link); + } + + if(sock_prev->default_value) { + if(sock_from->default_value) + MEM_freeN(sock_from->default_value); + + sock_from->default_value = MEM_dupallocN(sock_prev->default_value); + } + } + } + } + + /* remove node */ + node_remove_linked(ntree, node_prev); + } + + nodeUpdate(ntree, node_from); + nodeUpdate(ntree, node_to); + ntreeUpdateTree(ntree); + + ED_node_generic_update(bmain, ntree, node_to); +} + +/****************************** Node Link Menu *******************************/ + +#define UI_NODE_LINK_ADD 0 +#define UI_NODE_LINK_DISCONNECT -1 +#define UI_NODE_LINK_REMOVE -2 + +typedef struct NodeLinkArg { + Main *bmain; + Scene *scene; + bNodeTree *ntree; + bNode *node; + bNodeSocket *sock; + + bNodeTree *ngroup; + int type; + int output; + + uiLayout *layout; +} NodeLinkArg; + +static void ui_node_link(bContext *UNUSED(C), void *arg_p, void *event_p) +{ + NodeLinkArg *arg = (NodeLinkArg*)arg_p; + Main *bmain = arg->bmain; + bNode *node_to = arg->node; + bNodeSocket *sock_to = arg->sock; + bNodeTree *ntree = arg->ntree; + int event = GET_INT_FROM_POINTER(event_p); + bNodeTemplate ntemp; + + ntemp.type = arg->type; + ntemp.ngroup = arg->ngroup; + + if(event == UI_NODE_LINK_DISCONNECT) + node_socket_disconnect(bmain, ntree, node_to, sock_to); + else if(event == UI_NODE_LINK_REMOVE) + node_socket_remove(bmain, ntree, node_to, sock_to); + else + node_socket_add_replace(bmain, ntree, node_to, sock_to, &ntemp, arg->output); +} + +static void ui_node_sock_name(bNodeSocket *sock, char name[UI_MAX_NAME_STR]) +{ + if(sock->link && sock->link->fromnode) { + bNode *node = sock->link->fromnode; + char node_name[UI_MAX_NAME_STR]; + + if(node->type == NODE_GROUP) + BLI_strncpy(node_name, node->id->name+2, UI_MAX_NAME_STR); + else + BLI_strncpy(node_name, node->typeinfo->name, UI_MAX_NAME_STR); + + if(node->inputs.first == NULL && + node->outputs.first != node->outputs.last && + !(node->typeinfo->flag & NODE_OPTIONS)) + BLI_snprintf(name, UI_MAX_NAME_STR, "%s | %s", node_name, sock->link->fromsock->name); + else + BLI_strncpy(name, node_name, UI_MAX_NAME_STR); + } + else if(sock->type == SOCK_SHADER) + BLI_strncpy(name, "None", UI_MAX_NAME_STR); + else + BLI_strncpy(name, "Default", UI_MAX_NAME_STR); +} + +static int ui_compatible_sockets(int typeA, int typeB) +{ + return (typeA == typeB); +} + +static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname) +{ + Main *bmain = arg->bmain; + bNodeTree *ntree = arg->ntree; + bNodeSocket *sock = arg->sock; + uiLayout *layout = arg->layout; + uiLayout *column = NULL; + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but; + bNodeType *ntype; + bNodeTree *ngroup; + NodeLinkArg *argN; + int first = 1; + int compatibility= 0; + + if(ntree->type == NTREE_SHADER) { + if(scene_use_new_shading_nodes(arg->scene)) + compatibility= NODE_NEW_SHADING; + else + compatibility= NODE_OLD_SHADING; + } + + if(nclass == NODE_CLASS_GROUP) { + for(ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) { + bNodeSocket *gsock; + char name[UI_MAX_NAME_STR]; + int i, j, num = 0; + + if(ngroup->type != ntree->type) + continue; + + for(gsock=ngroup->inputs.first; gsock; gsock=gsock->next) + if(ui_compatible_sockets(gsock->type, sock->type)) + num++; + + for(i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) { + if(!ui_compatible_sockets(gsock->type, sock->type)) + continue; + + if(first) { + column= uiLayoutColumn(layout, 0); + uiBlockSetCurLayout(block, column); + + uiItemL(column, cname, ICON_NODE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + + first = 0; + } + + if(num > 1) { + if(j == 0) { + uiItemL(column, ngroup->id.name+2, ICON_NODE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + } + + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", gsock->name); + j++; + } + else + BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR); + + but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); + + argN = MEM_dupallocN(arg); + argN->ngroup = ngroup; + argN->output = i; + uiButSetNFunc(but, ui_node_link, argN, NULL); + } + } + } + else { + bNodeTreeType *ttype= ntreeGetType(ntree->type); + + for(ntype=ttype->node_types.first; ntype; ntype=ntype->next) { + bNodeSocketTemplate *stemp; + char name[UI_MAX_NAME_STR]; + int i, j, num = 0; + + if(compatibility && !(ntype->compatibility & compatibility)) + continue; + + if(ntype->nclass != nclass) + continue; + + for(i=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) + if(ui_compatible_sockets(stemp->type, sock->type)) + num++; + + for(i=0, j=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) { + if(!ui_compatible_sockets(stemp->type, sock->type)) + continue; + + if(first) { + column= uiLayoutColumn(layout, 0); + uiBlockSetCurLayout(block, column); + + uiItemL(column, cname, ICON_NODE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + + first = 0; + } + + if(num > 1) { + if(j == 0) { + uiItemL(column, ntype->name, ICON_NODE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + } + + BLI_snprintf(name, UI_MAX_NAME_STR, " %s", stemp->name); + j++; + } + else + BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR); + + but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input"); + + argN = MEM_dupallocN(arg); + argN->type = ntype->type; + argN->output = i; + uiButSetNFunc(but, ui_node_link, argN, NULL); + } + } + } +} + +static void node_menu_column_foreach_cb(void *calldata, int nclass, const char *name) +{ + NodeLinkArg *arg = (NodeLinkArg*)calldata; + + if(!ELEM(nclass, NODE_CLASS_GROUP, NODE_CLASS_LAYOUT)) + ui_node_menu_column(arg, nclass, IFACE_(name)); +} + +static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_p) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *but = (uiBut*)but_p; + uiLayout *split, *column; + NodeLinkArg *arg = (NodeLinkArg*)but->func_argN; + bNodeSocket *sock = arg->sock; + bNodeTreeType *ntreetype= ntreeGetType(arg->ntree->type); + + uiBlockSetCurLayout(block, layout); + split= uiLayoutSplit(layout, 0, 0); + + arg->bmain= bmain; + arg->scene= scene; + arg->layout= split; + + if(ntreetype && ntreetype->foreach_nodeclass) + ntreetype->foreach_nodeclass(scene, arg, node_menu_column_foreach_cb); + + column= uiLayoutColumn(split, 0); + uiBlockSetCurLayout(block, column); + + if(sock->link) { + uiItemL(column, "Link", ICON_NONE); + but= block->buttons.last; + but->flag= UI_TEXT_LEFT; + + but = uiDefBut(block, BUT, 0, "Remove", 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Remove nodes connected to the input"); + uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_REMOVE)); + + but = uiDefBut(block, BUT, 0, "Disconnect", 0, 0, UI_UNIT_X*4, UI_UNIT_Y, + NULL, 0.0, 0.0, 0.0, 0.0, "Disconnect nodes connected to the input"); + uiButSetNFunc(but, ui_node_link, MEM_dupallocN(arg), SET_INT_IN_POINTER(UI_NODE_LINK_DISCONNECT)); + } + + ui_node_menu_column(arg, NODE_CLASS_GROUP, IFACE_("Group")); +} + +void uiTemplateNodeLink(uiLayout *layout, bNodeTree *ntree, bNode *node, bNodeSocket *sock) +{ + uiBlock *block = uiLayoutGetBlock(layout); + NodeLinkArg *arg; + uiBut *but; + + arg = MEM_callocN(sizeof(NodeLinkArg), "NodeLinkArg"); + arg->ntree = ntree; + arg->node = node; + arg->sock = sock; + arg->type = 0; + arg->output = 0; + + uiBlockSetCurLayout(block, layout); + + if(sock->link || sock->type == SOCK_SHADER || (sock->flag & SOCK_HIDE_VALUE)) { + char name[UI_MAX_NAME_STR]; + ui_node_sock_name(sock, name); + but= uiDefMenuBut(block, ui_template_node_link_menu, NULL, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y, ""); + } + else + but= uiDefIconMenuBut(block, ui_template_node_link_menu, NULL, ICON_NONE, 0, 0, UI_UNIT_X, UI_UNIT_Y, ""); + + but->type= MENU; + but->flag |= UI_TEXT_LEFT|UI_BUT_NODE_LINK; + but->poin= (char*)but; + but->func_argN = arg; +} + +/**************************** Node Tree Layout *******************************/ + +static void ui_node_draw_input(uiLayout *layout, bContext *C, + bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth); + +static void ui_node_draw_node(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, int depth) +{ + bNodeSocket *input; + uiLayout *col, *split; + PointerRNA nodeptr; + + RNA_pointer_create(&ntree->id, &RNA_Node, node, &nodeptr); + + if(node->typeinfo->uifunc) { + if(node->type != NODE_GROUP) { + split = uiLayoutSplit(layout, 0.35f, 0); + col = uiLayoutColumn(split, 0); + col = uiLayoutColumn(split, 0); + + node->typeinfo->uifunc(col, C, &nodeptr); + } + } + + for(input=node->inputs.first; input; input=input->next) + ui_node_draw_input(layout, C, ntree, node, input, depth+1); +} + +static void ui_node_draw_input(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input, int depth) +{ + PointerRNA inputptr; + uiBlock *block = uiLayoutGetBlock(layout); + uiBut *bt; + uiLayout *split, *row, *col; + bNode *lnode; + char label[UI_MAX_NAME_STR]; + int indent = (depth > 1)? 2*(depth - 1): 0; + + if(input->flag & SOCK_UNAVAIL) + return; + + /* to avoid eternal loops on cyclic dependencies */ + node->flag |= NODE_TEST; + lnode = (input->link)? input->link->fromnode: NULL; + + /* socket RNA pointer */ + RNA_pointer_create(&ntree->id, &RNA_NodeSocket, input, &inputptr); + + /* indented label */ + memset(label, ' ', indent); + label[indent] = '\0'; + BLI_snprintf(label, UI_MAX_NAME_STR, "%s%s:", label, input->name); + + /* split in label and value */ + split = uiLayoutSplit(layout, 0.35f, 0); + + row = uiLayoutRow(split, 1); + + if(depth > 0) { + uiBlockSetEmboss(block, UI_EMBOSSN); + + if(lnode && (lnode->inputs.first || (lnode->typeinfo->uifunc && lnode->type != NODE_GROUP))) { + int icon = (input->flag & SOCK_COLLAPSED)? ICON_DISCLOSURE_TRI_RIGHT: ICON_DISCLOSURE_TRI_DOWN; + uiItemR(row, &inputptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", icon); + } + else + uiItemL(row, "", ICON_BLANK1); + + bt = block->buttons.last; + bt->x2 = UI_UNIT_X/2; + + uiBlockSetEmboss(block, UI_EMBOSS); + } + + uiItemL(row, label, ICON_NONE); + bt= block->buttons.last; + bt->flag= UI_TEXT_LEFT; + + if(lnode) { + /* input linked to a node */ + uiTemplateNodeLink(split, ntree, node, input); + + if(!(input->flag & SOCK_COLLAPSED)) { + if(depth == 0) + uiItemS(layout); + + ui_node_draw_node(layout, C, ntree, lnode, depth); + } + } + else { + /* input not linked, show value */ + if(input->type != SOCK_SHADER && !(input->flag & SOCK_HIDE_VALUE)) { + if(input->type == SOCK_VECTOR) { + row = uiLayoutRow(split, 0); + col = uiLayoutColumn(row, 0); + + uiItemR(col, &inputptr, "default_value", 0, "", 0); + } + else { + row = uiLayoutRow(split, 1); + uiItemR(row, &inputptr, "default_value", 0, "", 0); + } + } + else + row = uiLayoutRow(split, 0); + + uiTemplateNodeLink(row, ntree, node, input); + } + + /* clear */ + node->flag &= ~NODE_TEST; +} + +void uiTemplateNodeView(uiLayout *layout, bContext *C, bNodeTree *ntree, bNode *node, bNodeSocket *input) +{ + bNode *tnode; + + if(!ntree) + return; + + /* clear for cycle check */ + for(tnode=ntree->nodes.first; tnode; tnode=tnode->next) + tnode->flag &= ~NODE_TEST; + + if(input) + ui_node_draw_input(layout, C, ntree, node, input, 0); + else + ui_node_draw_node(layout, C, ntree, node, 0); +} + diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index a7e7a7b7577..9ff56f1aeb0 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -448,6 +448,23 @@ void RNA_api_ui_layout(StructRNA *srna) func= RNA_def_function(srna, "template_reports_banner", "uiTemplateReportsBanner"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); + func= RNA_def_function(srna, "template_node_link", "uiTemplateNodeLink"); + parm= RNA_def_pointer(func, "ntree", "NodeTree", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "node", "Node", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "socket", "NodeSocket", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + + func= RNA_def_function(srna, "template_node_view", "uiTemplateNodeView"); + RNA_def_function_flag(func, FUNC_USE_CONTEXT); + parm= RNA_def_pointer(func, "ntree", "NodeTree", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "node", "Node", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm= RNA_def_pointer(func, "socket", "NodeSocket", "", ""); + RNA_def_property_flag(parm, PROP_REQUIRED); + func= RNA_def_function(srna, "template_keymap_item_properties", "uiTemplateKeymapItemProperties"); parm= RNA_def_pointer(func, "item", "KeyMapItem", "", ""); RNA_def_property_flag(parm, PROP_REQUIRED|PROP_RNAPTR|PROP_NEVER_NULL); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 0e489107066..4bc7aa4d689 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -41,6 +41,7 @@ struct ARegionType; struct Base; struct Brush; struct bNodeTree; +struct bNodeSocket; struct CSG_FaceIteratorDescriptor; struct CSG_VertexIteratorDescriptor; struct ColorBand; @@ -369,6 +370,8 @@ void uiTemplateHistogram(struct uiLayout *layout, struct PointerRNA *ptr, char * void uiTemplateReportsBanner(struct uiLayout *layout, struct bContext *C, struct wmOperator *op){} void uiTemplateWaveform(struct uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand){} void uiTemplateVectorscope(struct uiLayout *_self, struct PointerRNA *data, char* property, int expand){} +void uiTemplateNodeLink(struct uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {} +void uiTemplateNodeView(struct uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input) {} void uiTemplateKeymapItemProperties(struct uiLayout *layout, struct PointerRNA *ptr){} void uiTemplateMovieClip(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname, int compact){} void uiTemplateTrack(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname){} From 95948d0e0e1e3308b8449486f676ca1663afe124 Mon Sep 17 00:00:00 2001 From: "Guillermo S. Romero" Date: Mon, 7 Nov 2011 23:50:12 +0000 Subject: [PATCH 146/147] SVN maintenance. --- doc/python_api/examples/bpy.app.handlers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/python_api/examples/bpy.app.handlers.py b/doc/python_api/examples/bpy.app.handlers.py index 7c176063b7c..02b00bf2fbc 100644 --- a/doc/python_api/examples/bpy.app.handlers.py +++ b/doc/python_api/examples/bpy.app.handlers.py @@ -9,4 +9,4 @@ import bpy def my_handler(scene): print("Frame Change", scene.frame_current) -bpy.app.handlers.frame_change_pre.append(my_handler) \ No newline at end of file +bpy.app.handlers.frame_change_pre.append(my_handler) From f086201518b85f6dd2ae60ae37dc14f1d1406c01 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 8 Nov 2011 01:32:34 +0000 Subject: [PATCH 147/147] cmake & pep8 tidy up, also some style edits. remove unneeded collection length function. --- doc/python_api/examples/bpy.app.handlers.1.py | 2 +- doc/python_api/examples/bpy.app.handlers.py | 3 ++- extern/libmv/CMakeLists.txt | 24 +++++++++---------- release/scripts/modules/bpy/ops.py | 4 ++-- release/scripts/modules/bpyml_ui.py | 6 +++-- release/scripts/startup/bl_operators/clip.py | 9 +++---- .../bl_operators/object_quick_effects.py | 3 +-- .../bl_operators/uvcalc_smart_project.py | 18 ++++++++------ .../startup/bl_ui/properties_data_camera.py | 7 ++++-- .../startup/bl_ui/properties_data_lamp.py | 4 ++-- .../scripts/startup/bl_ui/properties_game.py | 7 +++--- .../startup/bl_ui/properties_material.py | 6 ++--- .../startup/bl_ui/properties_object.py | 4 ++-- .../startup/bl_ui/properties_physics_cloth.py | 4 ++-- .../startup/bl_ui/properties_physics_fluid.py | 4 ++-- .../startup/bl_ui/properties_render.py | 4 ++-- release/scripts/startup/bl_ui/space_clip.py | 22 ++++++++--------- release/scripts/startup/bl_ui/space_image.py | 14 +++++------ .../scripts/startup/bl_ui/space_userpref.py | 8 +++---- .../startup/bl_ui/space_userpref_keymap.py | 8 +++---- release/scripts/startup/bl_ui/space_view3d.py | 2 +- .../startup/bl_ui/space_view3d_toolbar.py | 14 +++++------ source/blender/blenkernel/CMakeLists.txt | 4 +++- source/blender/blenkernel/intern/movieclip.c | 6 ++--- source/blender/makesdna/DNA_modifier_types.h | 3 ++- source/blender/makesrna/intern/rna_tracking.c | 8 ------- 26 files changed, 101 insertions(+), 97 deletions(-) diff --git a/doc/python_api/examples/bpy.app.handlers.1.py b/doc/python_api/examples/bpy.app.handlers.1.py index a6591f6b83f..48fdb95d793 100644 --- a/doc/python_api/examples/bpy.app.handlers.1.py +++ b/doc/python_api/examples/bpy.app.handlers.1.py @@ -15,6 +15,6 @@ from bpy.app.handlers import persistent @persistent def load_handler(dummy): - print("Load Handler:", bpy.data.filepath) + print("Load Handler:", bpy.data.filepath) bpy.app.handlers.load_post.append(load_handler) diff --git a/doc/python_api/examples/bpy.app.handlers.py b/doc/python_api/examples/bpy.app.handlers.py index 02b00bf2fbc..57b209e15f0 100644 --- a/doc/python_api/examples/bpy.app.handlers.py +++ b/doc/python_api/examples/bpy.app.handlers.py @@ -6,7 +6,8 @@ This script shows the most simple example of adding a handler. import bpy + def my_handler(scene): - print("Frame Change", scene.frame_current) + print("Frame Change", scene.frame_current) bpy.app.handlers.frame_change_pre.append(my_handler) diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 7ab01598cef..333791e28eb 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -25,8 +25,8 @@ set(INC . ../Eigen3 - ./third_party/ssba - ./third_party/ldl/Include + third_party/ssba + third_party/ldl/Include ../colamd/Include ) @@ -130,7 +130,7 @@ set(SRC third_party/msinttypes/inttypes.h ) -IF(WIN32) +if(WIN32) list(APPEND SRC third_party/glog/src/logging.cc third_party/glog/src/raw_logging.cc @@ -158,23 +158,23 @@ IF(WIN32) ) list(APPEND INC - ./third_party/glog/src/windows + third_party/glog/src/windows ) - IF(NOT MINGW) + if(NOT MINGW) list(APPEND INC - ./third_party/msinttypes + third_party/msinttypes ) - ENDIF(NOT MINGW) + endif() - IF(MSVC) + if(MSVC) set(MSVC_OFLAGS O1 O2 Ox) foreach(FLAG ) string(REPLACE "" "Od" CMAKE_CXX_FLAGS_RELEASE "") string(REPLACE "" "Od" CMAKE_C_FLAGS_RELWITHDEBINFO "") endforeach() - ENDIF(MSVC) -ELSE(WIN32) + endif() +else(WIN32) list(APPEND SRC third_party/glog/src/utilities.cc third_party/glog/src/symbolize.cc @@ -206,9 +206,9 @@ ELSE(WIN32) ) list(APPEND INC - ./third_party/glog/src + third_party/glog/src ) -ENDIF(WIN32) +endif() add_definitions(-DV3DLIB_ENABLE_SUITESPARSE -DGOOGLE_GLOG_DLL_DECL=) diff --git a/release/scripts/modules/bpy/ops.py b/release/scripts/modules/bpy/ops.py index 382a47cb4e6..d01b706cc37 100644 --- a/release/scripts/modules/bpy/ops.py +++ b/release/scripts/modules/bpy/ops.py @@ -208,7 +208,7 @@ class BPyOpsSubModOp(object): return "# %s\n%s" % (descr, as_string) def __str__(self): # used for print(...) - return "" % \ - (self.module, self.func, id(self)) + return ("" % + (self.module, self.func, id(self))) ops_fake_module = BPyOps() diff --git a/release/scripts/modules/bpyml_ui.py b/release/scripts/modules/bpyml_ui.py index f4b6de23dbb..4828b3649d3 100644 --- a/release/scripts/modules/bpyml_ui.py +++ b/release/scripts/modules/bpyml_ui.py @@ -25,9 +25,11 @@ from bpyml import TAG, ARGS, CHILDREN _uilayout_rna = _bpy.types.UILayout.bl_rna -_uilayout_tags = ["ui"] + \ - _uilayout_rna.properties.keys() + \ +_uilayout_tags = ( + ["ui"] + + _uilayout_rna.properties.keys() + _uilayout_rna.functions.keys() + ) # these need to be imported directly # >>> from bpyml_ui.locals import * diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index d085b7ea105..55592621112 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -155,7 +155,8 @@ class CLIP_OT_delete_proxy(Operator): self._rmproxy(d + '_undistorted') self._rmproxy(os.path.join(absproxy, 'proxy_' + str(x) + '.avi')) - tc = ('free_run.blen_tc', 'interp_free_run.blen_tc', \ + tc = ('free_run.blen_tc', + 'interp_free_run.blen_tc', 'record_run.blen_tc') for x in tc: @@ -280,10 +281,10 @@ class CLIP_OT_constraint_to_fcurve(Operator): efra = max(efra, track.markers[-1].frame) if sfra is None or efra is None: - return + return # Store object matrices - for x in range(sfra, efra+1): + for x in range(sfra, efra + 1): scene.frame_set(x) matrices.append(ob.matrix_world.copy()) @@ -291,7 +292,7 @@ class CLIP_OT_constraint_to_fcurve(Operator): # Apply matrices on object and insert keyframes i = 0 - for x in range(sfra, efra+1): + for x in range(sfra, efra + 1): scene.frame_set(x) ob.matrix_world = matrices[i] diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index 490ee230220..a062ac6f4c5 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -105,8 +105,7 @@ class QuickFur(Operator): psys.settings.child_type = 'INTERPOLATED' obj.data.materials.append(mat) - obj.particle_systems[-1].settings.material = \ - len(obj.data.materials) + psys.settings.material = len(obj.data.materials) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/uvcalc_smart_project.py b/release/scripts/startup/bl_operators/uvcalc_smart_project.py index 66d0d72efc1..17e353ff238 100644 --- a/release/scripts/startup/bl_operators/uvcalc_smart_project.py +++ b/release/scripts/startup/bl_operators/uvcalc_smart_project.py @@ -212,8 +212,11 @@ def islandIntersectUvIsland(source, target, SourceOffset): # Edge intersect test for ed in edgeLoopsSource: for seg in edgeLoopsTarget: - i = geometry.intersect_line_line_2d(\ - seg[0], seg[1], SourceOffset+ed[0], SourceOffset+ed[1]) + i = geometry.intersect_line_line_2d(seg[0], + seg[1], + SourceOffset+ed[0], + SourceOffset+ed[1], + ) if i: return 1 # LINE INTERSECTION @@ -773,15 +776,16 @@ def main_consts(): global ROTMAT_2D_POS_45D global RotMatStepRotation - ROTMAT_2D_POS_90D = Matrix.Rotation( radians(90.0), 2) - ROTMAT_2D_POS_45D = Matrix.Rotation( radians(45.0), 2) + ROTMAT_2D_POS_90D = Matrix.Rotation(radians(90.0), 2) + ROTMAT_2D_POS_45D = Matrix.Rotation(radians(45.0), 2) RotMatStepRotation = [] rot_angle = 22.5 #45.0/2 while rot_angle > 0.1: - RotMatStepRotation.append([\ - Matrix.Rotation( radians(rot_angle), 2),\ - Matrix.Rotation( radians(-rot_angle), 2)]) + RotMatStepRotation.append([ + Matrix.Rotation(radians(+rot_angle), 2), + Matrix.Rotation(radians(-rot_angle), 2), + ]) rot_angle = rot_angle/2.0 diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 0abbf281754..1a0fb0ef4ac 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -108,6 +108,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): col.prop(cam, "clip_start", text="Start") col.prop(cam, "clip_end", text="End") + class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @@ -120,8 +121,8 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): row = layout.row(align=True) row.menu("CAMERA_MT_presets", text=bpy.types.CAMERA_MT_presets.bl_label) - row.operator("camera.preset_add", text="", icon="ZOOMIN") - row.operator("camera.preset_add", text="", icon="ZOOMOUT").remove_active = True + row.operator("camera.preset_add", text="", icon='ZOOMIN') + row.operator("camera.preset_add", text="", icon='ZOOMOUT').remove_active = True layout.label(text="Sensor:") @@ -137,6 +138,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): col = split.column(align=True) col.prop(cam, "sensor_fit", text="") + class DATA_PT_camera_dof(CameraButtonsPanel, Panel): bl_label = "Depth of Field" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} @@ -156,6 +158,7 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel): col.active = cam.dof_object is None col.prop(cam, "dof_distance", text="Distance") + class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Display" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'} diff --git a/release/scripts/startup/bl_ui/properties_data_lamp.py b/release/scripts/startup/bl_ui/properties_data_lamp.py index 4ff180f74fb..974924be46c 100644 --- a/release/scripts/startup/bl_ui/properties_data_lamp.py +++ b/release/scripts/startup/bl_ui/properties_data_lamp.py @@ -134,8 +134,8 @@ class DATA_PT_sunsky(DataButtonsPanel, Panel): row = layout.row(align=True) row.prop(lamp, "use_sky") row.menu("LAMP_MT_sunsky_presets", text=bpy.types.LAMP_MT_sunsky_presets.bl_label) - row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMIN") - row.operator("lamp.sunsky_preset_add", text="", icon="ZOOMOUT").remove_active = True + row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMIN') + row.operator("lamp.sunsky_preset_add", text="", icon='ZOOMOUT').remove_active = True row = layout.row() row.active = lamp.use_sky or lamp.use_atmosphere diff --git a/release/scripts/startup/bl_ui/properties_game.py b/release/scripts/startup/bl_ui/properties_game.py index 0d104571e4b..ba9bb4a624d 100644 --- a/release/scripts/startup/bl_ui/properties_game.py +++ b/release/scripts/startup/bl_ui/properties_game.py @@ -315,11 +315,9 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): split = layout.split() - if dome_type == 'FISHEYE' or \ - dome_type == 'TRUNCATED_REAR' or \ - dome_type == 'TRUNCATED_FRONT': - + if dome_type in {'FISHEYE', 'TRUNCATED_REAR', 'TRUNCATED_FRONT'}: col = split.column() + col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) col.prop(gs, "dome_angle", slider=True) @@ -336,6 +334,7 @@ class RENDER_PT_game_stereo(RenderButtonsPanel, Panel): else: # cube map col = split.column() + col.prop(gs, "dome_buffer_resolution", text="Resolution", slider=True) col = split.column() diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index 62cb735fda9..f5a95016baa 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -124,7 +124,7 @@ class MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): split.template_ID(ob, "active_material", new="material.new") row = split.row() if mat: - row.prop(mat, "use_nodes", icon="NODETREE", text="") + row.prop(mat, "use_nodes", icon='NODETREE', text="") if slot: row.prop(slot, "link", text="") @@ -501,8 +501,8 @@ class MATERIAL_PT_sss(MaterialButtonsPanel, Panel): row = layout.row().split() sub = row.row(align=True).split(percentage=0.75) sub.menu("MATERIAL_MT_sss_presets", text=bpy.types.MATERIAL_MT_sss_presets.bl_label) - sub.operator("material.sss_preset_add", text="", icon="ZOOMIN") - sub.operator("material.sss_preset_add", text="", icon="ZOOMOUT").remove_active = True + sub.operator("material.sss_preset_add", text="", icon='ZOOMIN') + sub.operator("material.sss_preset_add", text="", icon='ZOOMOUT').remove_active = True split = layout.split() diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index a359d58b59e..36b8129ad8a 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -267,12 +267,12 @@ class OBJECT_PT_relations_extras(ObjectButtonsPanel, Panel): ob = context.object split = layout.split() - + col = split.column() col.label(text="Tracking Axes:") col.prop(ob, "track_axis", text="Axis") col.prop(ob, "up_axis", text="Up Axis") - + col = split.column() col.prop(ob, "use_slow_parent") row = col.row() diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index c66a0563754..afb3c000980 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -73,8 +73,8 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): col.label(text="Presets:") sub = col.row(align=True) sub.menu("CLOTH_MT_presets", text=bpy.types.CLOTH_MT_presets.bl_label) - sub.operator("cloth.preset_add", text="", icon="ZOOMIN") - sub.operator("cloth.preset_add", text="", icon="ZOOMOUT").remove_active = True + sub.operator("cloth.preset_add", text="", icon='ZOOMIN') + sub.operator("cloth.preset_add", text="", icon='ZOOMOUT').remove_active = True col.label(text="Quality:") col.prop(cloth, "quality", text="Steps", slider=True) diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index efb760c0b43..ce65350e69b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -206,7 +206,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): col = split.column() if scene.use_gravity: - col.label(text="Use Scene Gravity", icon="SCENE_DATA") + col.label(text="Use Scene Gravity", icon='SCENE_DATA') sub = col.column() sub.enabled = False sub.prop(fluid, "gravity", text="") @@ -215,7 +215,7 @@ class PHYSICS_PT_domain_gravity(PhysicButtonsPanel, Panel): col.prop(fluid, "gravity", text="") if scene.unit_settings.system != 'NONE': - col.label(text="Use Scene Size Units", icon="SCENE_DATA") + col.label(text="Use Scene Size Units", icon='SCENE_DATA') sub = col.column() sub.enabled = False sub.prop(fluid, "simulation_scale", text="Metres") diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 815f0a77570..145ae292e11 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -186,8 +186,8 @@ class RENDER_PT_dimensions(RenderButtonsPanel, Panel): row = layout.row(align=True) row.menu("RENDER_MT_presets", text=bpy.types.RENDER_MT_presets.bl_label) - row.operator("render.preset_add", text="", icon="ZOOMIN") - row.operator("render.preset_add", text="", icon="ZOOMOUT").remove_active = True + row.operator("render.preset_add", text="", icon='ZOOMIN') + row.operator("render.preset_add", text="", icon='ZOOMOUT').remove_active = True split = layout.split() diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 09209017823..3148c0dd51a 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -312,10 +312,10 @@ class CLIP_PT_track(Panel): row = layout.row(align=True) label = bpy.types.CLIP_MT_track_color_presets.bl_label row.menu('CLIP_MT_track_color_presets', text=label) - row.menu('CLIP_MT_track_color_specials', text="", icon="DOWNARROW_HLT") - row.operator("clip.track_color_preset_add", text="", icon="ZOOMIN") + row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT') + row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN') props = row.operator("clip.track_color_preset_add", - text="", icon="ZOOMOUT") + text="", icon='ZOOMOUT') props.remove_active = True row = layout.row() @@ -349,8 +349,8 @@ class CLIP_PT_tracking_camera(Panel): row = layout.row(align=True) label = bpy.types.CLIP_MT_camera_presets.bl_label row.menu('CLIP_MT_camera_presets', text=label) - row.operator("clip.camera_preset_add", text="", icon="ZOOMIN") - props = row.operator("clip.camera_preset_add", text="", icon="ZOOMOUT") + row.operator("clip.camera_preset_add", text="", icon='ZOOMIN') + props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT') props.remove_active = True row = layout.row(align=True) @@ -441,11 +441,11 @@ class CLIP_PT_track_settings(Panel): active = clip.tracking.tracks.active if active: - layout.prop(active, "tracker") - if active.tracker == "KLT": - layout.prop(active, "pyramid_levels") - if active.tracker == "SAD": - layout.prop(active, "correlation_min") + layout.prop(active, "tracker") + if active.tracker == 'KLT': + layout.prop(active, "pyramid_levels") + elif active.tracker == 'SAD': + layout.prop(active, "correlation_min") layout.prop(settings, "frames_adjust") layout.prop(settings, "speed") @@ -489,7 +489,7 @@ class CLIP_PT_stabilization(Panel): sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="") sub.menu('CLIP_MT_stabilize_2d_specials', text="", - icon="DOWNARROW_HLT") + icon='DOWNARROW_HLT') layout.prop(stab, "influence_location") diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 50db989a2e2..170ba3ccd0e 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -61,7 +61,7 @@ class IMAGE_MT_view(Menu): layout.separator() - ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]] + ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1)) for a, b in ratios: layout.operator("image.view_zoom_ratio", text="Zoom" + " %d:%d" % (a, b)).ratio = a / b @@ -746,12 +746,12 @@ class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel): layout.template_curve_mapping(brush, "curve") row = layout.row(align=True) - row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH' - row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND' - row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT' - row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP' - row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE' - row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX' + row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH' + row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND' + row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT' + row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP' + row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' + row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index c6c4a8f3335..a2ede26ecc6 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -967,10 +967,10 @@ class USERPREF_PT_addons(Panel): continue # check if addon should be visible with current filters - if (filter == "All") or \ - (filter == info["category"]) or \ - (filter == "Enabled" and is_enabled) or \ - (filter == "Disabled" and not is_enabled): + if ((filter == "All") or + (filter == info["category"]) or + (filter == "Enabled" and is_enabled) or + (filter == "Disabled" and not is_enabled)): if search and search not in info["name"].lower(): if info["author"]: diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index 5e5ce462da9..d738e806320 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -223,7 +223,7 @@ class InputKeyMapPanel: col = layout.column() row = col.row() - row.label(text=km.name, icon="DOT") + row.label(text=km.name, icon='DOT') row.label() row.label() @@ -265,13 +265,13 @@ class InputKeyMapPanel: if not text: text = "Blender (default)" row.menu("USERPREF_MT_keyconfigs", text=text) - row.operator("wm.keyconfig_preset_add", text="", icon="ZOOMIN") - row.operator("wm.keyconfig_preset_add", text="", icon="ZOOMOUT").remove_active = True + row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMIN') + row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMOUT').remove_active = True #~ layout.context_pointer_set("keyconfig", wm.keyconfigs.active) #~ row.operator("wm.keyconfig_remove", text="", icon='X') - row.prop(context.space_data, "filter_text", icon="VIEWZOOM") + row.prop(context.space_data, "filter_text", icon='VIEWZOOM') col.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 9edb1ea1197..2d3be2015d7 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1536,7 +1536,7 @@ class VIEW3D_MT_edit_mesh_select_mode(Menu): class VIEW3D_MT_edit_mesh_extrude(Menu): bl_label = "Extrude" - _extrude_funcs = { \ + _extrude_funcs = { "VERT": lambda layout: layout.operator("mesh.extrude_vertices_move", text="Vertices Only"), "EDGE": lambda layout: layout.operator("mesh.extrude_edges_move", text="Edges Only"), "FACE": lambda layout: layout.operator("mesh.extrude_faces_move", text="Individual Faces"), diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 332577a7902..5bcdbc1efe8 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -172,7 +172,7 @@ class VIEW3D_PT_tools_meshedit(View3DPanel, Panel): class VIEW3D_PT_tools_meshedit_options(View3DPanel, Panel): bl_context = "mesh_edit" bl_label = "Mesh Options" - + @classmethod def poll(cls, context): return context.active_object @@ -912,12 +912,12 @@ class VIEW3D_PT_tools_brush_curve(PaintPanel, Panel): layout.template_curve_mapping(brush, "curve", brush=True) row = layout.row(align=True) - row.operator("brush.curve_preset", icon="SMOOTHCURVE", text="").shape = 'SMOOTH' - row.operator("brush.curve_preset", icon="SPHERECURVE", text="").shape = 'ROUND' - row.operator("brush.curve_preset", icon="ROOTCURVE", text="").shape = 'ROOT' - row.operator("brush.curve_preset", icon="SHARPCURVE", text="").shape = 'SHARP' - row.operator("brush.curve_preset", icon="LINCURVE", text="").shape = 'LINE' - row.operator("brush.curve_preset", icon="NOCURVE", text="").shape = 'MAX' + row.operator("brush.curve_preset", icon='SMOOTHCURVE', text="").shape = 'SMOOTH' + row.operator("brush.curve_preset", icon='SPHERECURVE', text="").shape = 'ROUND' + row.operator("brush.curve_preset", icon='ROOTCURVE', text="").shape = 'ROOT' + row.operator("brush.curve_preset", icon='SHARPCURVE', text="").shape = 'SHARP' + row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' + row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' class VIEW3D_PT_sculpt_options(PaintPanel, Panel): diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index df4e247bc93..c21806b4bc1 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -370,7 +370,9 @@ if(WITH_GAMEENGINE) endif() if(WITH_LIBMV) - list(APPEND INC ../../../extern/libmv) + list(APPEND INC + ../../../extern/libmv + ) add_definitions(-DWITH_LIBMV) endif() diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index e3bfdd54ab1..b72a3be1014 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -517,7 +517,7 @@ static ImBuf *get_undistorted_cache(MovieClip *clip, MovieClipUser *user) return cache->undistibuf; } -static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distoriton, ImBuf *ibuf) +static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *distortion, ImBuf *ibuf) { ImBuf *undistibuf; @@ -525,8 +525,8 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist otherwise, undistorted proxy can be darker than it should */ imb_freerectfloatImBuf(ibuf); - if(distoriton) - undistibuf= BKE_tracking_distortion_exec(distoriton, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); + if(distortion) + undistibuf= BKE_tracking_distortion_exec(distortion, &clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f, 1); else undistibuf= BKE_tracking_undistort(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 7991a903bbb..8e60fe984e6 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -30,7 +30,8 @@ #define MODSTACK_DEBUG 1 -/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! */ +/* WARNING ALERT! TYPEDEF VALUES ARE WRITTEN IN FILES! SO DO NOT CHANGE! + * (ONLY ADD NEW ITEMS AT THE END) */ typedef enum ModifierType { eModifierType_None = 0, diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index f72fd3d465c..15ded001237 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -125,13 +125,6 @@ static void rna_tracking_trackerPyramid_update(Main *UNUSED(bmain), Scene *UNUSE BKE_tracking_clamp_track(track, CLAMP_PYRAMID_LEVELS); } -static int rna_tracking_markers_length(PointerRNA *ptr) -{ - MovieTrackingTrack *track= (MovieTrackingTrack *)ptr->data; - - return track->markersnr; -} - static float rna_trackingCamera_focal_mm_get(PointerRNA *ptr) { MovieClip *clip= (MovieClip*)ptr->id.data; @@ -499,7 +492,6 @@ static void rna_def_trackingTrack(BlenderRNA *brna) prop= RNA_def_property(srna, "markers", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "MovieTrackingMarker"); RNA_def_property_collection_sdna(prop, NULL, "markers", "markersnr"); - RNA_def_property_collection_funcs(prop, NULL, NULL, NULL, NULL, "rna_tracking_markers_length", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Markers", "Collection of markers in track"); /* ** channels ** */