From: rnv Date: Wed, 28 Dec 2016 12:43:14 +0000 (+0300) Subject: Merge remote-tracking branch 'origin/fbt/fix_french_translation' X-Git-Tag: V8_3_0a2~33 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=a1920ff31054e2c882bd94d4f3c04abe53980ce0;hp=2618d1a2f08c632705809a277cd3138a265b9b23;p=modules%2Fsmesh.git Merge remote-tracking branch 'origin/fbt/fix_french_translation' --- diff --git a/CMakeLists.txt b/CMakeLists.txt index ece28f210..a2d069f66 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ ENDIF(WIN32) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 0) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 2) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) diff --git a/doc/salome/examples/a3DmeshOnModified2Dmesh.py b/doc/salome/examples/a3DmeshOnModified2Dmesh.py index 7fcdcaca8..5520d7afe 100644 --- a/doc/salome/examples/a3DmeshOnModified2Dmesh.py +++ b/doc/salome/examples/a3DmeshOnModified2Dmesh.py @@ -10,7 +10,7 @@ geompy = geomBuilder.New(salome.myStudy) # The requirement is to have a surface mesh on the cube comprised of # triangles of exactly the same size arranged in a grid pattern. # -# To fulfill this requirement we mesh the box using Quadrangle (Mapping) +# To fulfill this requirement we mesh the box using Quadrangle: Mapping # meshing algorithm, split quadrangles into triangles and then generate # tetrahedrons. @@ -59,4 +59,4 @@ Mesh_1.Tetrahedron() Mesh_1.Compute() if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/creating_meshes_ex07.py b/doc/salome/examples/creating_meshes_ex07.py index 3b003961e..acaaf5dc3 100644 --- a/doc/salome/examples/creating_meshes_ex07.py +++ b/doc/salome/examples/creating_meshes_ex07.py @@ -78,4 +78,4 @@ Compound2 = smesh.Concatenate([Mesh_inf, Mesh_sup], 1, 0, 1e-05, True, name='Compound_with_UniteGrps_and_GrpsOfAllElems') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/defining_hypotheses_ex01.py b/doc/salome/examples/defining_hypotheses_ex01.py index 1d5d281c8..c9f02bc12 100644 --- a/doc/salome/examples/defining_hypotheses_ex01.py +++ b/doc/salome/examples/defining_hypotheses_ex01.py @@ -1,4 +1,4 @@ -# Arithmetic 1D and Geometric Progression +# Arithmetic Progression and Geometric Progression import salome salome.salome_init() diff --git a/doc/salome/examples/defining_hypotheses_ex02.py b/doc/salome/examples/defining_hypotheses_ex02.py index 3662d5632..572404569 100644 --- a/doc/salome/examples/defining_hypotheses_ex02.py +++ b/doc/salome/examples/defining_hypotheses_ex02.py @@ -1,4 +1,4 @@ -# Deflection 1D and Number of Segments +# Deflection and Number of Segments import salome salome.salome_init() diff --git a/doc/salome/examples/defining_hypotheses_ex13.py b/doc/salome/examples/defining_hypotheses_ex13.py index e3eeee8f1..339cd200d 100644 --- a/doc/salome/examples/defining_hypotheses_ex13.py +++ b/doc/salome/examples/defining_hypotheses_ex13.py @@ -1,4 +1,4 @@ -# Radial Quadrangle 1D2D example +# Radial Quadrangle 1D-2D example import salome salome.salome_init() diff --git a/doc/salome/examples/filters_ex03.py b/doc/salome/examples/filters_ex03.py index c9313bceb..9d5467e6f 100644 --- a/doc/salome/examples/filters_ex03.py +++ b/doc/salome/examples/filters_ex03.py @@ -3,9 +3,6 @@ # create mesh from SMESH_mechanic import * # get faces with warping angle = 2.0e-13 with tolerance 5.0e-14 -criterion = smesh.GetCriterion(SMESH.FACE, SMESH.FT_Warping, SMESH.FT_EqualTo, 2.0e-13) -criterion.Tolerance = 5.0e-14 -filter = smesh.CreateFilterManager().CreateFilter() -filter.SetCriteria([criterion]) +filter = smesh.GetFilter(SMESH.FACE, SMESH.FT_Warping, "=", 2.0e-13, Tolerance=5.0e-14) ids = mesh.GetIdsFromFilter(filter) print "Number of faces with warping angle = 2.0e-13 (tolerance 5.0e-14):", len(ids) diff --git a/doc/salome/examples/filters_ex07.py b/doc/salome/examples/filters_ex07.py index 6c42d5217..3afee5e1a 100644 --- a/doc/salome/examples/filters_ex07.py +++ b/doc/salome/examples/filters_ex07.py @@ -3,10 +3,8 @@ # create mesh from SMESH_mechanic import * # get faces with area > 60 and < 90 -criterion1 = smesh.GetCriterion(SMESH.FACE, SMESH.FT_Area, SMESH.FT_MoreThan, 60,\ - SMESH.FT_Undefined, SMESH.FT_LogicalAND) +criterion1 = smesh.GetCriterion(SMESH.FACE, SMESH.FT_Area, SMESH.FT_MoreThan, 60) criterion2 = smesh.GetCriterion(SMESH.FACE, SMESH.FT_Area, SMESH.FT_LessThan, 90) -filter = smesh.CreateFilterManager().CreateFilter() -filter.SetCriteria([criterion1,criterion2]) +filter = smesh.GetFilterFromCriteria([criterion1,criterion2], SMESH.FT_LogicalAND) ids = mesh.GetIdsFromFilter(filter) print "Number of faces with area in range (60,90):", len(ids) diff --git a/doc/salome/examples/filters_ex09.py b/doc/salome/examples/filters_ex09.py index dd6415930..032d55ddd 100644 --- a/doc/salome/examples/filters_ex09.py +++ b/doc/salome/examples/filters_ex09.py @@ -9,8 +9,7 @@ from salome.smesh import smeshBuilder smesh = smeshBuilder.New(salome.myStudy) # create mesh -face = geompy.MakeFaceHW(100, 100, 1) -geompy.addToStudy( face, "quadrangle" ) +face = geompy.MakeFaceHW(100, 100, 1, theName="quadrangle") mesh = smesh.Mesh(face) mesh.Segment().NumberOfSegments(10) mesh.Triangle().MaxElementArea(25) diff --git a/doc/salome/examples/filters_ex33.py b/doc/salome/examples/filters_ex33.py index c844e9063..7ffb5548f 100644 --- a/doc/salome/examples/filters_ex33.py +++ b/doc/salome/examples/filters_ex33.py @@ -2,16 +2,19 @@ # create mesh from SMESH_mechanic import * -# get number of linear and quadratic edges -filter_linear = smesh.GetFilter(SMESH.EDGE, SMESH.FT_LinearOrQuadratic) + +# get linear and quadratic edges +filter_linear = smesh.GetFilter(SMESH.EDGE, SMESH.FT_LinearOrQuadratic) filter_quadratic = smesh.GetFilter(SMESH.EDGE, SMESH.FT_LinearOrQuadratic, SMESH.FT_LogicalNOT) -ids_linear = mesh.GetIdsFromFilter(filter_linear) +ids_linear = mesh.GetIdsFromFilter(filter_linear) ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) + # convert mesh to quadratic print "Convert to quadratic..." -mesh.ConvertToQuadratic(True) -# get number of linear and quadratic edges -ids_linear = mesh.GetIdsFromFilter(filter_linear) +mesh.ConvertToQuadratic() + +# get linear and quadratic edges +ids_linear = mesh.GetIdsFromFilter(filter_linear) ids_quadratic = mesh.GetIdsFromFilter(filter_quadratic) print "Number of linear edges:", len(ids_linear), "; number of quadratic edges:", len(ids_quadratic) diff --git a/doc/salome/examples/grouping_elements_ex01.py b/doc/salome/examples/grouping_elements_ex01.py index 4016a8359..0bb1b9a2f 100644 --- a/doc/salome/examples/grouping_elements_ex01.py +++ b/doc/salome/examples/grouping_elements_ex01.py @@ -77,4 +77,4 @@ aGroup.Remove( [2,3,4] ) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex02.py b/doc/salome/examples/grouping_elements_ex02.py index 909a9b482..841501253 100644 --- a/doc/salome/examples/grouping_elements_ex02.py +++ b/doc/salome/examples/grouping_elements_ex02.py @@ -43,4 +43,4 @@ aSmeshGroup1 = quadra.GroupOnGeom(face, "SMESHGroup1") # create SMESH group on with default name aSmeshGroup2 = quadra.GroupOnGeom(aGeomGroupE) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex03.py b/doc/salome/examples/grouping_elements_ex03.py index 375749cb4..bd85e09e0 100644 --- a/doc/salome/examples/grouping_elements_ex03.py +++ b/doc/salome/examples/grouping_elements_ex03.py @@ -46,4 +46,4 @@ filt2.SetCriteria( [ smesh.GetCriterion( SMESH.FACE, SMESH.FT_RangeOfIds, "1-70" filtIDs3 = filtGroup.GetIDs() print "After filter modification, group on filter contains %s elemens" % filtGroup.Size() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex04.py b/doc/salome/examples/grouping_elements_ex04.py index ebd59e76f..56901320a 100644 --- a/doc/salome/examples/grouping_elements_ex04.py +++ b/doc/salome/examples/grouping_elements_ex04.py @@ -41,4 +41,4 @@ for i in range(len(aGroupElemIDs)): pass print "" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex05.py b/doc/salome/examples/grouping_elements_ex05.py index 9883ebda2..aa526d295 100644 --- a/doc/salome/examples/grouping_elements_ex05.py +++ b/doc/salome/examples/grouping_elements_ex05.py @@ -50,4 +50,4 @@ aGroup4.Add(anIds) aGroup5 = mesh.UnionListOfGroups([aGroup3, aGroup4], "Any Area") print "Criterion: Any Area, Nb = ", len(aGroup5.GetListOfID()) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex06.py b/doc/salome/examples/grouping_elements_ex06.py index 060a22d6c..bf9e3708b 100644 --- a/doc/salome/examples/grouping_elements_ex06.py +++ b/doc/salome/examples/grouping_elements_ex06.py @@ -34,4 +34,4 @@ aGroup3 = mesh.IntersectListOfGroups([aGroup1, aGroup2], "20 < Area < 60") print "Criterion: 20 < Area < 60, Nb = ", len(aGroup3.GetListOfID()) # Please note that also there is IntersectGroups() method which works with two groups only -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex07.py b/doc/salome/examples/grouping_elements_ex07.py index 891ed889a..1a79c5fe2 100644 --- a/doc/salome/examples/grouping_elements_ex07.py +++ b/doc/salome/examples/grouping_elements_ex07.py @@ -32,4 +32,4 @@ aGroupRes = mesh.CutGroups(aGroupMain, aGroupTool, "Area >= 60") print "Criterion: Area >= 60, Nb = ", len(aGroupRes.GetListOfID()) # Please note that also there is CutListOfGroups() method which works with lists of groups of any lengths -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/grouping_elements_ex08.py b/doc/salome/examples/grouping_elements_ex08.py index 92dd71ce0..c06e8e39e 100644 --- a/doc/salome/examples/grouping_elements_ex08.py +++ b/doc/salome/examples/grouping_elements_ex08.py @@ -28,4 +28,4 @@ aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], SMESH.EDGE, "Edges" ) # Create group of nodes using source groups of faces aGrp = mesh.CreateDimGroup( [aSrcGroup1, aSrcGroup2], SMESH.NODE, "Nodes" ) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex09.py b/doc/salome/examples/modifying_meshes_ex09.py index cba753e51..c09cb62c6 100644 --- a/doc/salome/examples/modifying_meshes_ex09.py +++ b/doc/salome/examples/modifying_meshes_ex09.py @@ -34,4 +34,4 @@ f1 = MakePolygon(mesh, 0, 0, 0, 30, 13) f2 = MakePolygon(mesh, 0, 0, 10, 21, 9) f3 = MakePolygon(mesh, 0, 0, 20, 13, 6) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex10.py b/doc/salome/examples/modifying_meshes_ex10.py index 26607e740..bf13423ed 100644 --- a/doc/salome/examples/modifying_meshes_ex10.py +++ b/doc/salome/examples/modifying_meshes_ex10.py @@ -60,4 +60,4 @@ mesh.AddPolyhedralVolume([dd[0], dd[1], dd[2], dd[3], dd[4], # top [5,5,5,5,5,5,5,5,5,5,5,5]) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex16.py b/doc/salome/examples/modifying_meshes_ex16.py index 076cebf6c..0786445eb 100644 --- a/doc/salome/examples/modifying_meshes_ex16.py +++ b/doc/salome/examples/modifying_meshes_ex16.py @@ -51,4 +51,4 @@ res = mesh.InverseDiag(bb[1], tt[2]) if not res: print "failed!" else: print "done." -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex17.py b/doc/salome/examples/modifying_meshes_ex17.py index c45fd2829..ebeb247a8 100644 --- a/doc/salome/examples/modifying_meshes_ex17.py +++ b/doc/salome/examples/modifying_meshes_ex17.py @@ -51,4 +51,4 @@ res = mesh.DeleteDiag(bb[1], tt[2]) if not res: print "failed!" else: print "done." -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex18.py b/doc/salome/examples/modifying_meshes_ex18.py index 60b395af9..458b0fe25 100644 --- a/doc/salome/examples/modifying_meshes_ex18.py +++ b/doc/salome/examples/modifying_meshes_ex18.py @@ -51,4 +51,4 @@ res = mesh.TriToQuad([ff[2], ff[3], ff[4], ff[5]], SMESH.FT_MinimumAngle, 60.) if not res: print "failed!" else: print "done." -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex19.py b/doc/salome/examples/modifying_meshes_ex19.py index 7223fb099..8ef2c7c8a 100644 --- a/doc/salome/examples/modifying_meshes_ex19.py +++ b/doc/salome/examples/modifying_meshes_ex19.py @@ -42,4 +42,4 @@ f5 = mesh.AddFace([n5, n6, n12, n11]) # Change the orientation of the second and the fourth faces. mesh.Reorient([2, 4]) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex21.py b/doc/salome/examples/modifying_meshes_ex21.py index 50355fd8b..650d998e5 100644 --- a/doc/salome/examples/modifying_meshes_ex21.py +++ b/doc/salome/examples/modifying_meshes_ex21.py @@ -32,4 +32,4 @@ print "\nSmoothing ... ", if not res: print "failed!" else: print "done." -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex22.py b/doc/salome/examples/modifying_meshes_ex22.py index e6d5fd6ed..b4f5f3cd3 100644 --- a/doc/salome/examples/modifying_meshes_ex22.py +++ b/doc/salome/examples/modifying_meshes_ex22.py @@ -31,4 +31,4 @@ GroupTri = mesh.GroupOnGeom(face, "Group of faces (extrusion)", SMESH.FACE) # perform extrusion of the group mesh.ExtrusionSweepObject(GroupTri, vector, 5) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/modifying_meshes_ex23.py b/doc/salome/examples/modifying_meshes_ex23.py index bad439d99..3db2c3e12 100644 --- a/doc/salome/examples/modifying_meshes_ex23.py +++ b/doc/salome/examples/modifying_meshes_ex23.py @@ -128,4 +128,4 @@ error = quad_6.ExtrusionAlongPath(ff_6 , Edge_Circle_mesh, Edge_Circle, 1, error = quad_7.ExtrusionAlongPath(ff_7, Edge_Circle_mesh, Edge_Circle, 1, 1, [a45, -a45, a45, -a45, a45, -a45, a45, -a45], 0, refPoint) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/prism_3d_algo.py b/doc/salome/examples/prism_3d_algo.py index e51822561..5aa283edf 100644 --- a/doc/salome/examples/prism_3d_algo.py +++ b/doc/salome/examples/prism_3d_algo.py @@ -1,4 +1,4 @@ -# Usage of 3D Extrusion meshing algorithm +# Usage of Extrusion 3D meshing algorithm import salome salome.salome_init() diff --git a/doc/salome/examples/quality_controls_ex01.py b/doc/salome/examples/quality_controls_ex01.py index 0f73a5619..6990aa66b 100644 --- a/doc/salome/examples/quality_controls_ex01.py +++ b/doc/salome/examples/quality_controls_ex01.py @@ -44,4 +44,4 @@ print "" aGroup = mesh.GetMesh().CreateGroup(SMESH.EDGE, "Free borders") aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex02.py b/doc/salome/examples/quality_controls_ex02.py index 491c81eb4..c2fc56f86 100644 --- a/doc/salome/examples/quality_controls_ex02.py +++ b/doc/salome/examples/quality_controls_ex02.py @@ -46,4 +46,4 @@ print "" aGroup = mesh.GetMesh().CreateGroup(SMESH.EDGE, "Borders at multi-connections") aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex03.py b/doc/salome/examples/quality_controls_ex03.py index b1da190f5..7c5a804f5 100644 --- a/doc/salome/examples/quality_controls_ex03.py +++ b/doc/salome/examples/quality_controls_ex03.py @@ -46,4 +46,4 @@ print "" aGroup = mesh.GetMesh().CreateGroup(SMESH.EDGE, "Edges with length > " + `length_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex04.py b/doc/salome/examples/quality_controls_ex04.py index c687d9293..373ddbe02 100644 --- a/doc/salome/examples/quality_controls_ex04.py +++ b/doc/salome/examples/quality_controls_ex04.py @@ -37,4 +37,4 @@ for i in range(len(aBorders)): aGroupF.Add([aBorder.myElemId]) aGroupN.Add([aBorder.myPnt1, aBorder.myPnt2]) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex05.py b/doc/salome/examples/quality_controls_ex05.py index f03456596..cbd217839 100644 --- a/doc/salome/examples/quality_controls_ex05.py +++ b/doc/salome/examples/quality_controls_ex05.py @@ -51,4 +51,4 @@ for i in range(len(anNodeIds)): pass print "" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex06.py b/doc/salome/examples/quality_controls_ex06.py index 861206bb3..1bd007bf6 100644 --- a/doc/salome/examples/quality_controls_ex06.py +++ b/doc/salome/examples/quality_controls_ex06.py @@ -75,4 +75,4 @@ aFaceIds = Mesh_1.GetIdsFromFilter(aFilter) aGroup = Mesh_1.CreateEmptyGroup(SMESH.FACE, "Shared_faces") aGroup.Add(aFaceIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex11.py b/doc/salome/examples/quality_controls_ex11.py index 69352be34..b0b5e3f24 100644 --- a/doc/salome/examples/quality_controls_ex11.py +++ b/doc/salome/examples/quality_controls_ex11.py @@ -47,4 +47,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Faces with length 2D > " + `length_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex12.py b/doc/salome/examples/quality_controls_ex12.py index 4ddcc387d..ba6fb9d7d 100644 --- a/doc/salome/examples/quality_controls_ex12.py +++ b/doc/salome/examples/quality_controls_ex12.py @@ -47,4 +47,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Borders at multi-connection 2D = " + `nb_conn`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex13.py b/doc/salome/examples/quality_controls_ex13.py index 10810c849..3b52dbc12 100644 --- a/doc/salome/examples/quality_controls_ex13.py +++ b/doc/salome/examples/quality_controls_ex13.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Area > " + `area_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex14.py b/doc/salome/examples/quality_controls_ex14.py index 50f87fbf7..b66d9413a 100644 --- a/doc/salome/examples/quality_controls_ex14.py +++ b/doc/salome/examples/quality_controls_ex14.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Taper > " + `taper_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex15.py b/doc/salome/examples/quality_controls_ex15.py index 2c8fe7c6c..0aeedbfa8 100644 --- a/doc/salome/examples/quality_controls_ex15.py +++ b/doc/salome/examples/quality_controls_ex15.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Aspect Ratio > " + `ar_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex16.py b/doc/salome/examples/quality_controls_ex16.py index 5d8bade8a..e80e91f48 100644 --- a/doc/salome/examples/quality_controls_ex16.py +++ b/doc/salome/examples/quality_controls_ex16.py @@ -29,4 +29,4 @@ aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Minimum Angle < " + `min_angle`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex17.py b/doc/salome/examples/quality_controls_ex17.py index bd87eae42..8f7f39c48 100644 --- a/doc/salome/examples/quality_controls_ex17.py +++ b/doc/salome/examples/quality_controls_ex17.py @@ -29,4 +29,4 @@ aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Warp > " + `wa_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex18.py b/doc/salome/examples/quality_controls_ex18.py index 972652c38..ad6dff185 100644 --- a/doc/salome/examples/quality_controls_ex18.py +++ b/doc/salome/examples/quality_controls_ex18.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Skew > " + `skew_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex19.py b/doc/salome/examples/quality_controls_ex19.py index 8b7e89a15..814cb5ba5 100644 --- a/doc/salome/examples/quality_controls_ex19.py +++ b/doc/salome/examples/quality_controls_ex19.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Element Diameter 2D > " + `mel_2d_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex20.py b/doc/salome/examples/quality_controls_ex20.py index 40a7bf155..3a7c44f94 100644 --- a/doc/salome/examples/quality_controls_ex20.py +++ b/doc/salome/examples/quality_controls_ex20.py @@ -29,4 +29,4 @@ aGroup = mesh.CreateEmptyGroup(SMESH.VOLUME, "Aspect Ratio 3D > " + `ar_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex21.py b/doc/salome/examples/quality_controls_ex21.py index 29e384357..1f27eef3a 100644 --- a/doc/salome/examples/quality_controls_ex21.py +++ b/doc/salome/examples/quality_controls_ex21.py @@ -30,4 +30,4 @@ aGroup = mesh.CreateEmptyGroup(SMESH.VOLUME, "Volume < " + `volume_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/quality_controls_ex22.py b/doc/salome/examples/quality_controls_ex22.py index 7cd582366..e43e5c1b8 100644 --- a/doc/salome/examples/quality_controls_ex22.py +++ b/doc/salome/examples/quality_controls_ex22.py @@ -28,4 +28,4 @@ print "" aGroup = mesh.CreateEmptyGroup(SMESH.FACE, "Element Diameter 3D > " + `mel_3d_margin`) aGroup.Add(anIds) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/transforming_meshes_ex06.py b/doc/salome/examples/transforming_meshes_ex06.py index c9c8353d8..47c25b1ea 100644 --- a/doc/salome/examples/transforming_meshes_ex06.py +++ b/doc/salome/examples/transforming_meshes_ex06.py @@ -77,4 +77,4 @@ print "Triangles : ", trias.NbTriangles() print "Quadrangles: ", trias.NbQuadrangles() print "Volumes : ", trias.NbVolumes() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/doc/salome/examples/transforming_meshes_ex11.py b/doc/salome/examples/transforming_meshes_ex11.py index de98b27bb..0abe52013 100644 --- a/doc/salome/examples/transforming_meshes_ex11.py +++ b/doc/salome/examples/transforming_meshes_ex11.py @@ -92,4 +92,4 @@ mesh.DoubleElements([ 1, 2 ]) # Update object browser if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(0) + salome.sg.updateObjBrowser(False) diff --git a/doc/salome/gui/SMESH/images/pref21.png b/doc/salome/gui/SMESH/images/pref21.png old mode 100755 new mode 100644 index 04bacf393..926c78085 Binary files a/doc/salome/gui/SMESH/images/pref21.png and b/doc/salome/gui/SMESH/images/pref21.png differ diff --git a/doc/salome/gui/SMESH/images/radial_prism_mesh.png b/doc/salome/gui/SMESH/images/radial_prism_mesh.png new file mode 100644 index 000000000..6d9a986c1 Binary files /dev/null and b/doc/salome/gui/SMESH/images/radial_prism_mesh.png differ diff --git a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc index 01deffbcd..c4de6317c 100644 --- a/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/1d_meshing_hypo.doc @@ -14,25 +14,25 @@ Basic 1D hypothesis specifies:
  • Constantly increasing or decreasing length of segments:
      -
    • \ref arithmetic_1d_anchor "Arithmetic 1D"
    • +
    • \ref arithmetic_1d_anchor "Arithmetic Progression"
    • \ref geometric_1d_anchor "Geometric Progression"
    • \ref start_and_end_length_anchor "Start and end length"
    • -
    • \ref number_of_segments_anchor "Number of segments" with Scale distribution
    • +
    • \ref number_of_segments_anchor "Number of Segments" with Scale distribution
  • Distribution depending on curvature:
    • \ref adaptive_1d_anchor "Adaptive"
    • -
    • \ref deflection_1d_anchor "Deflection 1D"
    • +
    • \ref deflection_1d_anchor "Deflection"
  • Arbitrary distribution:
      -
    • \ref fixed_points_1d_anchor "Fixed points 1D"
    • -
    • \ref number_of_segments_anchor "Number of segments" with +
    • \ref fixed_points_1d_anchor "Fixed Points"
    • +
    • \ref number_of_segments_anchor "Number of Segments" with \ref analyticdensity_anchor "Analytic Density Distribution" or Table Density Distribution
  • @@ -54,15 +54,15 @@ creation of narrow 2D elements. - Max size parameter defines the length of segments on straight edges. - \b Deflection parameter gives maximal distance of a segment from a curved edge. -\image html adaptive1d_sample_mesh.png "Adaptive hypothesis and Netgen 2D algorithm - the size of mesh segments reflects the size of geometrical features" +\image html adaptive1d_sample_mesh.png "Adaptive hypothesis and NETGEN 2D algorithm - the size of mesh segments reflects the size of geometrical features" See Also a \ref tui_1d_adaptive "sample TUI Script" that uses Adaptive hypothesis.
    \anchor arithmetic_1d_anchor -

    Arithmetic 1D hypothesis

    +

    Arithmetic Progression hypothesis

    -Arithmetic 1D hypothesis allows to split edges into segments with a +Arithmetic Progression hypothesis allows to split edges into segments with a length that changes in arithmetic progression (Lk = Lk-1 + d) beginning from a given starting length and up to a given end length. @@ -82,10 +82,10 @@ defining Reversed Edges parameter. \image html a-arithmetic1d.png -\image html b-ithmetic1d.png "Arithmetic 1D hypothesis - the size of mesh elements gradually increases" +\image html b-ithmetic1d.png "Arithmetic Progression hypothesis - the size of mesh elements gradually increases" See Also a sample TUI Script of a -\ref tui_1d_arithmetic "Defining Arithmetic 1D and Geometric Progression hypothesis" operation. +\ref tui_1d_arithmetic "Defining Arithmetic Progression and Geometric Progression hypothesis" operation.
    \anchor geometric_1d_anchor @@ -112,13 +112,13 @@ defining Reversed Edges parameter. \image html a-geometric1d.png See Also a sample TUI Script of a -\ref tui_1d_arithmetic "Defining Arithmetic 1D and Geometric Progression hypothesis" operation. +\ref tui_1d_arithmetic "Defining Arithmetic Progression and Geometric Progression hypothesis" operation.
    \anchor deflection_1d_anchor -

    Deflection 1D hypothesis

    +

    Deflection hypothesis

    -Deflection 1D hypothesis can be applied for meshing curvilinear edges +Deflection hypothesis can be applied for meshing curvilinear edges composing your geometrical object. It defines only one parameter: the value of deflection (or chord error). @@ -130,10 +130,10 @@ two nodes should not exceed the value of deflection. \image html a-deflection1d.png -\image html b-flection1d.png "Deflection 1D hypothesis - useful for meshing curvilinear edges" +\image html b-flection1d.png "Deflection hypothesis - useful for meshing curvilinear edges" See Also a sample TUI Script of a -\ref tui_deflection_1d "Defining Deflection 1D hypothesis" operation. +\ref tui_deflection_1d "Defining Deflection hypothesis" operation.
    \anchor average_length_anchor @@ -174,7 +174,7 @@ consists of setting the maximal allowed \b length of segments. Use preestimated length check box lets you use \b length automatically calculated basing on size of your geometrical object, namely as diagonal of bounding box divided by ten. The divider can be -changed via "Ratio Bounding Box Diagonal / Max Size" +changed via \ref diagonal_size_ratio_pref "Ratio Bounding Box Diagonal / Max Size" preference parameter. Use preestimated length check box is enabled only if the geometrical object has been selected before hypothesis definition. @@ -183,11 +183,14 @@ geometrical object has been selected before hypothesis definition.
    \anchor number_of_segments_anchor -

    Number of segments hypothesis

    +

    Number of Segments hypothesis

    -Number of segments hypothesis can be applied for approximating +Number of Segments hypothesis can be applied for approximating edges by a definite number of mesh segments with length depending on -the selected type of distribution of nodes. +the selected type of distribution of nodes. The default number of +segments can be set via +\ref nb_segments_pref "Automatic Parameters / Default Number of Segments" +preference parameter. The direction of the splitting is defined by the orientation of the underlying geometrical edge. Reverse Edges list box allows to @@ -302,9 +305,9 @@ minimum and maximum value of this parameter.
    \anchor fixed_points_1d_anchor -

    Fixed points 1D hypothesis

    +

    Fixed Points hypothesis

    -Fixed points 1D hypothesis allows splitting edges through a +Fixed Points hypothesis allows splitting edges through a set of points parametrized on the edge (from 1 to 0) and a number of segments for each interval limited by the points. @@ -326,7 +329,7 @@ Object Browser. defining Reversed Edges parameter. -\image html mesh_fixedpnt.png "Example of a sub-mesh on the edge built using Fixed points 1D hypothesis" +\image html mesh_fixedpnt.png "Example of a sub-mesh on the edge built using Fixed Points hypothesis" See Also a sample TUI Script of a \ref tui_fixed_points "Defining Fixed Points" hypothesis operation. diff --git a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc index 308a6899a..2005ad8d7 100644 --- a/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc +++ b/doc/salome/gui/SMESH/input/2d_meshing_hypo.doc @@ -75,7 +75,7 @@ algorithms are available: \image html reduce_three_to_one.png "The fastest transition pattern: 3 to 1" -Base vertex tab allows using Quadrangle (Mapping) +Base vertex tab allows using Quadrangle: Mapping algorithm for meshing of trilateral faces. In this case it is necessary to select the vertex, which will be used as the forth degenerated side of quadrangle. diff --git a/doc/salome/gui/SMESH/input/about_hypo.doc b/doc/salome/gui/SMESH/input/about_hypo.doc index 12f5c02e1..f40555940 100644 --- a/doc/salome/gui/SMESH/input/about_hypo.doc +++ b/doc/salome/gui/SMESH/input/about_hypo.doc @@ -30,16 +30,16 @@ In \b MESH there are the following Basic Hypotheses:
  • \subpage a1d_meshing_hypo_page "1D Hypotheses" (for meshing of edges):
  • \subpage a2d_meshing_hypo_page "2D Hypotheses" (for meshing of faces):
  • @@ -66,21 +66,21 @@ The \b Local algorithms and hypotheses to be chosen at Scale Factor=3 is assigned to the highlighted edge. -If 3D extrusion algorithm is assigned to a sub-mesh in a mesh +If Extrusion 3D algorithm is assigned to a sub-mesh in a mesh with multiple sub-meshes, the described above approach may not work as expected. For example the bottom face may be meshed by other algorithm -before 3D extrusion have a chance to project a mesh from the +before Extrusion 3D have a chance to project a mesh from the base face. This thing can happen with vertical edges as well. All these can lead to either a meshing failure or to an incorrect meshing. In such a case, it's necessary to explicitly define algorithms -that 3D extrusion implicitly applies in a simple case: +that Extrusion 3D implicitly applies in a simple case: - assign \ref projection_1D2D algorithm to the top face and - assign a 1D algorithm to a group of all vertical edges. -\image html image157.gif "Prism with 3D extrusion meshing. Vertical division is different on neighbor edges because several local 1D hypotheses are assigned." +\image html image157.gif "Prism with Extrusion 3D meshing. Vertical division is different on neighbor edges because several local 1D hypotheses are assigned." \sa a sample TUI Script of -\ref tui_prism_3d_algo "Use 3D extrusion meshing algorithm". +\ref tui_prism_3d_algo "Use Extrusion 3D meshing algorithm". */ diff --git a/doc/salome/gui/SMESH/input/quad_ijk_algo.doc b/doc/salome/gui/SMESH/input/quad_ijk_algo.doc index 90e7eea94..292a300e5 100644 --- a/doc/salome/gui/SMESH/input/quad_ijk_algo.doc +++ b/doc/salome/gui/SMESH/input/quad_ijk_algo.doc @@ -1,8 +1,8 @@ /*! -\page quad_ijk_algo_page Quadrangle (Mapping) meshing algorithm +\page quad_ijk_algo_page Quadrangle: Mapping meshing algorithm -Quadrangle (Mapping) meshing algorithm is intended for creating +Quadrangle: Mapping meshing algorithm is intended for creating all-quadrangle and quad-dominant meshes on faces without holes and bound by at least three edges. diff --git a/doc/salome/gui/SMESH/input/radial_prism_algo.doc b/doc/salome/gui/SMESH/input/radial_prism_algo.doc index 756e0329a..8c3306857 100644 --- a/doc/salome/gui/SMESH/input/radial_prism_algo.doc +++ b/doc/salome/gui/SMESH/input/radial_prism_algo.doc @@ -10,7 +10,9 @@ shell. The meshes of the shells can consist both of triangles and quadrangles. The Radial Prism algorithm would fill the space between the two shells -with meshes. +with prisms. + +\image html radial_prism_mesh.png "Cut-view of a hollow sphere meshed by Radial Prism algorithm" This algorithm also needs the information concerning the number and distribution of mesh layers between the inner and the outer shapes. @@ -21,4 +23,4 @@ Distribution of layers can be set with any of 1D Hypotheses. \image html distribution_of_layers.png -*/ \ No newline at end of file +*/ diff --git a/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc b/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc index 097d217c2..7e49a9a66 100644 --- a/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc +++ b/doc/salome/gui/SMESH/input/radial_quadrangle_1D2D_algo.doc @@ -1,6 +1,6 @@ /*! -\page radial_quadrangle_1D2D_algo_page Radial Quadrangle 1D2D +\page radial_quadrangle_1D2D_algo_page Radial Quadrangle 1D-2D \n This algorithm applies to the meshing of 2D shapes under the following conditions: the face must be a full ellipse or a part of ellipse @@ -21,8 +21,9 @@ end lying on the elliptic curve. If no own hypothesis of the algorithm is assigned, any local or global hypothesis is used by the algorithm to discretize edges. -If no 1D hypothesis is assigned to an edge, "Default Number of -Segments" preferences parameter is used to discretize the edge. +If no 1D hypothesis is assigned to an edge, +\ref nb_segments_pref "Default Number of Segments" preferences +parameter is used to discretize the edge. \image html hypo_radquad_dlg.png diff --git a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc index c19afd1b9..85a3cdf92 100644 --- a/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc +++ b/doc/salome/gui/SMESH/input/tui_defining_hypotheses.doc @@ -8,31 +8,31 @@ This page provides example codes of \ref tui_defining_meshing_algos
  • Wire discretisation 1D algorithm
    • \ref tui_1d_adaptive "Adaptive 1D" hypothesis
    • -
    • \ref tui_1d_arithmetic "Arithmetic 1D" hypothesis
    • +
    • \ref tui_1d_arithmetic "Arithmetic Progression" hypothesis
    • \ref tui_1d_arithmetic "Geometric Progression" hypothesis
    • -
    • \ref tui_deflection_1d "Deflection 1D and Number of Segments" hypotheses
    • +
    • \ref tui_deflection_1d "Deflection and Number of Segments" hypotheses
    • \ref tui_start_and_end_length "Start and End Length" hypotheses
    • \ref tui_average_length "Local Length"
    • \ref tui_propagation "Propagation" additional hypothesis
    • \ref tui_fixed_points "Fixed Points 1D" hypothesis
  • -
  • Triangle (Mefisto) 2D algorithm +
  • Triangle: Mefisto 2D algorithm
    • \ref tui_max_element_area "Max Element Area" hypothesis
    • \ref tui_length_from_edges "Length from Edges" hypothesis
  • -
  • Tetrahedron (Netgen) 3D algorithm +
  • NETGEN 3D algorithm
    • \ref tui_max_element_volume "Max. Element Volume"hypothesis
    • \ref tui_viscous_layers "Viscous layers"
  • \ref tui_projection "Projection Algorithms"
  • -
  • \ref tui_radial_quadrangle "Radial Quadrangle 1D2D" algorithm
  • -
  • Quadrangle (Mapping) 2D algorithm +
  • \ref tui_radial_quadrangle "Radial Quadrangle 1D-2D" algorithm
  • +
  • Quadrangle: Mapping 2D algorithm
    • \ref tui_quadrangle_parameters "Quadrangle Parameters" hypothesis
    @@ -45,7 +45,7 @@ This page provides example codes of \ref tui_defining_meshing_algos
    \anchor tui_1d_arithmetic -

    Arithmetic 1D and Geometric Progression

    +

    Arithmetic Progression and Geometric Progression

    \tui_script{defining_hypotheses_ex01.py}
    @@ -55,7 +55,7 @@ This page provides example codes of \ref tui_defining_meshing_algos
    \anchor tui_deflection_1d -

    Deflection 1D and Number of Segments

    +

    Deflection and Number of Segments

    \tui_script{defining_hypotheses_ex02.py}
    @@ -113,7 +113,7 @@ This page provides example codes of \ref tui_defining_meshing_algos \tui_script{defining_hypotheses_ex12.py} \anchor tui_radial_quadrangle -

    Radial Quadrangle 1D2D example

    +

    Radial Quadrangle 1D-2D example

    \tui_script{defining_hypotheses_ex13.py} \anchor tui_quadrangle_parameters diff --git a/doc/salome/gui/SMESH/input/tui_prism_3d_algo.doc b/doc/salome/gui/SMESH/input/tui_prism_3d_algo.doc index 6ba5e25d3..0bd16a9e3 100644 --- a/doc/salome/gui/SMESH/input/tui_prism_3d_algo.doc +++ b/doc/salome/gui/SMESH/input/tui_prism_3d_algo.doc @@ -1,6 +1,6 @@ /*! -\page tui_prism_3d_algo Use 3D extrusion meshing algorithm +\page tui_prism_3d_algo Use Extrusion 3D meshing algorithm \tui_script{prism_3d_algo.py} The result geometry and mesh is shown below diff --git a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc index 5fbbadb89..c4831c064 100644 --- a/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc +++ b/doc/salome/gui/SMESH/input/viewing_meshes_overview.doc @@ -2,14 +2,23 @@ \page viewing_meshes_overview_page Viewing meshes -\n After definition of algorithms and hypotheses a new mesh is listed -in the Object Browser. Right-click on it and select \b Compute - the -mesh will be automatically displayed in the VTK 3D Viewer. -Alternatively click Display only to hide all other objects at -the same time. +By default a just \ref compute_anchor "computed" mesh will be +automatically displayed in the VTK 3D Viewer. (You can switch +off \ref automatic_update_pref "Automatic Update" preference parameter +to prevent this.) +Click Display only to hide all other objects at the same time. VTK 3D Viewer is described in detail in the documentation on GUI module. -\n After the mesh has appeared in the Viewer, you can select it with + +Use the following \ref mesh_preferences_page "preference parameters" +to adjust how the mesh is displayed by default: +- \ref automatic_update_pref "Automatic Update" +- \ref display_mode_pref "Default display mode" +- \ref quadratic_2d_mode_pref "Representation of the 2D quadratic elements" +- All parameters of \ref mesh_tab_preferences "Mesh" tab page of the +Preferences dialog. + +After the mesh has appeared in the Viewer, you can select it with left mouse click and get information about it, change its presentation parameters and access to other useful options by right-clicking on the selected mesh. @@ -20,21 +29,21 @@ right-clicking on the selected mesh.
  • Rename - allows to rename the object in the Object browser.
  • Hide all - allows to hide all objects in the viewer.
  • Update - refreshes the presentation of your mesh in the -Object Browser, applying all recent changes.
  • + Object Browser, applying all recent changes.
  • \subpage mesh_infos_page "Mesh Information" - provides -information about the mesh.
  • + information about the mesh.
  • \subpage find_element_by_point_page "Find Element by Point" - -allows to find all mesh elements, to which belongs a point with the + allows to find all mesh elements, to which belongs a point with the given coordinates.
  • Auto Color - switch on / off auto-assigning colors for the groups. If switched on, a default color of a new group in \ref creating_groups_page "Create Group" dialog is chosen randomly.
  • \subpage numbering_page "Numbering" - allows to display the ID -numbers of all meshing elements or nodes composing your mesh in the -viewer.
  • + numbers of all meshing elements or nodes composing your mesh in the + viewer.
  • \subpage display_mode_page "Display Mode" - allows to select between -Wireframe, Shading and Nodes presentation.
  • + Wireframe, Shading and Nodes presentation.
  • \subpage display_entity_page "Display Entity" - allows to display entities by types (Faces, Edges, Volumes etc.).
  • \anchor quadratic_2d_mode @@ -44,24 +53,29 @@ Wireframe, Shading and Nodes presentation. Arc representation applies to 1D and 2D elements only.
  • Orientation of faces - shows vectors of orientation of -faces of the selected mesh. The orientation vector is shown for each 2D mesh element -and for each free face of a 3D mesh element. the vector direction is calculated by -the first three nodes of the face produced by vectors n1-n2 and n1-n3.
  • -
  • \subpage colors_size_page "Properties" - allows to define several properties, including color of elements, shrink size, ....
  • + faces of the selected mesh. The orientation vector is shown for each + 2D mesh element and for each free facet of a 3D mesh element. The + vector direction is calculated by the first three nodes of the face + produced by vectors n1-n2 and n1-n3. +
  • \subpage colors_size_page "Properties" - allows to define several + visual properties, including color of elements, shrink size, ...
  • \subpage transparency_page "Transparency" - allows to change the -transparency of mesh elements.
  • -
  • \ref quality_page "Controls" - graphically -presents various information about meshes.
  • + transparency of mesh elements. +
  • \ref quality_page "Controls" - graphically presents various + information about the mesh.
  • Hide - allows to hide the selected mesh from the viewer.
  • -
  • Show Only -allows to display only the selected mesh, hiding all other from the viewer.
  • -
  • \subpage clipping_page "Clipping" - allows to create cross-sections of the selected objects.
  • -
  • Dump view - exports an object from the viewer in bmp, png, jpg or jpeg image format.
  • +
  • Show Only - allows to display only the selected mesh, + hiding all others from the viewer.
  • +
  • \subpage clipping_page "Clipping" - allows to create + cross-sections of the displayed objects.
  • +
  • Dump view - exports an object from the viewer in bmp, png + or jpeg image format.
  • Change background - allows to redefine the background -color. By default it is black.
  • -
  • View Operations checkbox - allows to show/hide the -visualization toolbar in the viewer window.
  • + color. By default it is black. +
  • View Operations - allows to show/hide the + visualization toolbar in the Viewer window.
  • Recording Operations - allows to show/hide the recording -toolbar in the viewer window.
  • + toolbar in the Viewer window. */ diff --git a/resources/StdMeshers.xml.in b/resources/StdMeshers.xml.in index 5c6e8f8ed..5a858500d 100644 --- a/resources/StdMeshers.xml.in +++ b/resources/StdMeshers.xml.in @@ -26,13 +26,39 @@ + + - + gui-lib ="StdMeshersGUI"> @@ -248,9 +295,11 @@ @@ -281,8 +330,10 @@ @@ -445,8 +518,10 @@ @@ -472,6 +549,8 @@ @@ -481,8 +560,10 @@ AddVolumeWithID( iN[0], iN[2], iN[1], iN[3], iN[4], pyrIDShift + i )) + if ( !myMesh->AddVolumeWithID( iN[3], iN[2], iN[1], iN[0], iN[4], pyrIDShift + i )) status = storeBadNodeIds( "GmfPyramids",i, 5, iN[0], iN[1],iN[2], iN[3], iN[4] ); } } diff --git a/src/DriverGMF/DriverGMF_Write.cxx b/src/DriverGMF/DriverGMF_Write.cxx index 27f1ce065..723f73d32 100644 --- a/src/DriverGMF/DriverGMF_Write.cxx +++ b/src/DriverGMF/DriverGMF_Write.cxx @@ -204,10 +204,10 @@ Driver_Mesh::Status DriverGMF_Write::Perform() // pyramids BEGIN_ELEM_WRITE( SMDSEntity_Pyramid, GmfPyramids, pyra ) - node2IdMap[ pyra->GetNode( 0 )], + node2IdMap[ pyra->GetNode( 3 )], node2IdMap[ pyra->GetNode( 2 )], node2IdMap[ pyra->GetNode( 1 )], - node2IdMap[ pyra->GetNode( 3 )], + node2IdMap[ pyra->GetNode( 0 )], node2IdMap[ pyra->GetNode( 4 )], END_ELEM_WRITE( pyra ); diff --git a/src/MEFISTO2/aptrte.cxx b/src/MEFISTO2/aptrte.cxx index 6fd9db1fe..5ee5e167a 100755 --- a/src/MEFISTO2/aptrte.cxx +++ b/src/MEFISTO2/aptrte.cxx @@ -182,10 +182,10 @@ void aptrte( Z nutysu, R aretmx, // majoration empirique du nombre de sommets de la triangulation i = 4*nbarfr/10; mxsomm = Max( 20000, 64*nbpti+i*i ); - MESSAGE( "APTRTE: Debut de la triangulation plane avec " ); - MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx - << " mxsomm=" << mxsomm ); - MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes"); + // MESSAGE( "APTRTE: Debut de la triangulation plane avec " ); + // MESSAGE( "nutysu=" << nutysu << " aretmx=" << aretmx + // << " mxsomm=" << mxsomm ); + // MESSAGE( nbarfr << " sommets sur la frontiere et " << nbpti << " points internes"); NEWDEPART: //mnpxyd( 3, mxsomm ) les coordonnees UV des sommets et la taille d'arete aux sommets @@ -366,9 +366,9 @@ void aptrte( Z nutysu, R aretmx, //fin ajout 9/11/2006 ................................................. - MESSAGE("Sur le bord: arete min=" << aremin << " arete max=" << aremax ); - MESSAGE("Triangulation: arete mx=" << aretmx - << " triangle aire mx=" << airemx ); + // MESSAGE("Sur le bord: arete min=" << aremin << " arete max=" << aremax ); + // MESSAGE("Triangulation: arete mx=" << aretmx + // << " triangle aire mx=" << airemx ); //chainage des aretes frontalieres : la derniere arete frontaliere mnsoar[ mosoar * noar - mosoar + 5 ] = 0; @@ -408,7 +408,7 @@ void aptrte( Z nutysu, R aretmx, mxtree = 2 * mxsomm; NEWTREE: //en cas de saturation de l'un des tableaux, on boucle - MESSAGE( "Debut triangulation avec mxsomm=" << mxsomm ); + //MESSAGE( "Debut triangulation avec mxsomm=" << mxsomm ); if( mntree != NULL ) delete [] mntree; nbsomm = nbarpi; mntree = new Z[motree*(1+mxtree)]; @@ -426,13 +426,13 @@ void aptrte( Z nutysu, R aretmx, //saturation de letree => sa taille est augmentee et relance mxtree = mxtree * 2; ierr = 0; - MESSAGE( "Nouvelle valeur de mxtree=" << mxtree ); + //MESSAGE( "Nouvelle valeur de mxtree=" << mxtree ); goto NEWTREE; } deltacpu_( d ); tcpu += d; - MESSAGE( "Temps de l'ajout arbre-4 des Triangles Equilateraux=" << d << " secondes" ); + //MESSAGE( "Temps de l'ajout arbre-4 des Triangles Equilateraux=" << d << " secondes" ); if( ierr != 0 ) goto ERREUR; //ici le tableau mnpxyd contient les sommets des te et les points frontaliers et internes @@ -452,8 +452,8 @@ void aptrte( Z nutysu, R aretmx, deltacpu_( d ); tcpu += d; - MESSAGE("Temps de l'adaptation et l'homogeneisation de l'arbre-4 des TE=" - << d << " secondes"); + //MESSAGE("Temps de l'adaptation et l'homogeneisation de l'arbre-4 des TE=" + // << d << " secondes"); if( ierr != 0 ) { //destruction du tableau auxiliaire et de l'arbre @@ -461,7 +461,7 @@ void aptrte( Z nutysu, R aretmx, { //letree sature mxtree = mxtree * 2; - MESSAGE( "Redemarrage avec la valeur de mxtree=" << mxtree ); + //MESSAGE( "Redemarrage avec la valeur de mxtree=" << mxtree ); ierr = 0; goto NEWTREE; } @@ -484,7 +484,7 @@ void aptrte( Z nutysu, R aretmx, //Temps calcul deltacpu_( d ); tcpu += d; - MESSAGE( "Temps de la triangulation des TE=" << d << " secondes" ); +//MESSAGE( "Temps de la triangulation des TE=" << d << " secondes" ); // ierr =0 si pas d'erreur // =1 si le tableau mnsoar est sature @@ -506,11 +506,11 @@ void aptrte( Z nutysu, R aretmx, mosoar, mxsoar, n1soar, mnsoar, na, moartr, mxartr, n1artr, mnartr, n ); - MESSAGE( "Nombre d'echanges des diagonales de 2 triangles=" << n ); +//MESSAGE( "Nombre d'echanges des diagonales de 2 triangles=" << n ); deltacpu_( d ); tcpu += d; - MESSAGE("Temps de la triangulation Delaunay par echange des diagonales=" - << d << " secondes"); + // MESSAGE("Temps de la triangulation Delaunay par echange des diagonales=" + // << d << " secondes"); //qualites de la triangulation actuelle qualitetrte( mnpxyd, mosoar, mxsoar, mnsoar, moartr, mxartr, mnartr, @@ -539,11 +539,11 @@ void aptrte( Z nutysu, R aretmx, mxarcf, mn1arcf, mnarcf, mnarcf1, mnarcf2, n, ierr ); - MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere ierr=" << ierr ); +//MESSAGE( "Restauration de " << n << " aretes perdues de la frontiere ierr=" << ierr ); deltacpu_( d ); tcpu += d; - MESSAGE("Temps de la recuperation des aretes perdues de la frontiere=" - << d << " secondes"); +//MESSAGE("Temps de la recuperation des aretes perdues de la frontiere=" +// << d << " secondes"); if( ierr != 0 ) goto ERREUR; @@ -585,7 +585,7 @@ void aptrte( Z nutysu, R aretmx, deltacpu_( d ); tcpu += d; - MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr ); +//MESSAGE( "Temps de la suppression des triangles externes=" << d << "ierr=" << ierr ); if( ierr != 0 ) goto ERREUR; //qualites de la triangulation actuelle @@ -619,7 +619,7 @@ void aptrte( Z nutysu, R aretmx, deltacpu_( d ); tcpu += d; - MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d ); +//MESSAGE( "Temps de l'amelioration de la qualite de la triangulation=" << d ); if( ierr == -13 ) ierr=0; //6/10/2006 arret de l'amelioration apres boucle infinie dans caetoi if( ierr != 0 ) goto ERREUR; @@ -713,11 +713,11 @@ void aptrte( Z nutysu, R aretmx, } } nbt /= nbsttria; //le nombre final de triangles de la surface - MESSAGE( "APTRTE: Fin de la triangulation plane avec "< +#include +#include +#include +#include +#include #ifndef DISABLE_PLOT2DVIEWER #include @@ -117,6 +117,9 @@ SMESH_Actor* SMESH_Actor::New(TVisualObjPtr theVisualObj, SMESH_ActorDef::SMESH_ActorDef() { if(MYDEBUG) MESSAGE("SMESH_ActorDef - "<SetColor( bfc.red() / 255. , bfc.green() / 255. , bfc.blue() / 255. ); my2DActor = SMESH_CellLabelActor::New(); - my2DActor->SetStoreGemetryMapping(true); + my2DActor->SetStoreClippingMapping(true); my2DActor->SetUserMatrix(aMatrix); my2DActor->PickableOff(); my2DActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] ); @@ -255,7 +258,7 @@ SMESH_ActorDef::SMESH_ActorDef() aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); my3DActor = SMESH_CellLabelActor::New(); - my3DActor->SetStoreGemetryMapping(true); + my3DActor->SetStoreClippingMapping(true); my3DActor->SetUserMatrix(aMatrix); my3DActor->PickableOff(); my3DActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] ); @@ -320,8 +323,12 @@ SMESH_ActorDef::SMESH_ActorDef() myEdgeProp->SetColor(anRGB[0],anRGB[1],anRGB[2]); myEdgeProp->SetLineWidth(aLineWidth); + // my1DActor is used to + // - show numbers + // - show controls on all edges (eg Length) + // since edges are shown by myHighlitableActor my1DActor = SMESH_CellLabelActor::New(); - my1DActor->SetStoreGemetryMapping(true); + my1DActor->SetStoreClippingMapping(true); my1DActor->SetUserMatrix(aMatrix); my1DActor->PickableOff(); my1DActor->SetHighlited(true); @@ -347,6 +354,7 @@ SMESH_ActorDef::SMESH_ActorDef() my1DExtProp->SetLineWidth(aLineWidth + aLineWidthInc); my1DExtProp->SetPointSize(aElem0DSize); + // my1DExtActor is used to show filtered edges or links between nodes my1DExtActor = SMESH_DeviceActor::New(); my1DExtActor->SetUserMatrix(aMatrix); my1DExtActor->PickableOff(); @@ -369,7 +377,7 @@ SMESH_ActorDef::SMESH_ActorDef() my0DActor = SMESH_CellLabelActor::New(); my0DActor->SetUserMatrix(aMatrix); - my0DActor->SetStoreGemetryMapping(true); + my0DActor->SetStoreClippingMapping(true); my0DActor->PickableOff(); my0DActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] ); my0DActor->SetVisibility(false); @@ -388,7 +396,7 @@ SMESH_ActorDef::SMESH_ActorDef() myBallActor = SMESH_CellLabelActor::New(); myBallActor->SetUserMatrix(aMatrix); - myBallActor->SetStoreGemetryMapping(true); + myBallActor->SetStoreClippingMapping(true); myBallActor->PickableOff(); myBallActor->SetFontProperties( aFamilyEl, aSizeEl, aBoldEl, anItalicEl, aShadowEl, anRGBEl[0], anRGBEl[1], anRGBEl[2] ); myBallActor->SetVisibility(false); @@ -461,6 +469,8 @@ SMESH_ActorDef::SMESH_ActorDef() //---------------------------------------------- myBaseActor->SetUserMatrix(aMatrix); + myBaseActor->SetStoreIDMapping(true); + myBaseActor->SetStoreClippingMapping(true); myBaseActor->SetStoreGemetryMapping(true); myBaseActor->GetProperty()->SetOpacity(0.0); myPickableActor = myBaseActor; @@ -807,7 +817,8 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) if( !mgr ) return; - myControlMode = eNone; + //myControlMode = eNone; + myControlMode = theMode; theCheckEntityMode &= mgr->booleanValue( "SMESH", "display_entity", false ); my0DActor->GetMapper()->SetScalarVisibility(false); @@ -990,11 +1001,10 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) return; } - vtkUnstructuredGrid* aGrid = myControlActor->GetUnstructuredGrid(); - vtkIdType aNbCells = aGrid->GetNumberOfCells(); + int aNbCells = myFunctor ? myVisualObj->GetNbEntities( myFunctor->GetType() ) : 0; bool aShowOnlyScalarBarTitle = false; if(aNbCells) { - myControlMode = theMode; + //myControlMode = theMode; switch(myControlMode){ case eFreeNodes: case eCoincidentNodes: @@ -1050,25 +1060,13 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) SetEntityMode(eEdges); } else if(myControlActor == my2DActor) { - switch(myControlMode) { - case eLength2D: - case eFreeEdges: - case eFreeFaces: - case eMultiConnection2D: - if (!myIsEntityModeCache){ - myEntityModeCache = GetEntityMode(); - myIsEntityModeCache=true; - } - SetEntityMode(eFaces); - break; - default: - if (!myIsEntityModeCache){ - myEntityModeCache = GetEntityMode(); - myIsEntityModeCache=true; - } - SetEntityMode(eFaces); + if (!myIsEntityModeCache){ + myEntityModeCache = GetEntityMode(); + myIsEntityModeCache=true; } - }else if(myControlActor == my3DActor) { + SetEntityMode(eFaces); + } + else if(myControlActor == my3DActor) { if (!myIsEntityModeCache){ myEntityModeCache = GetEntityMode(); myIsEntityModeCache=true; @@ -1100,7 +1098,7 @@ void SMESH_ActorDef::SetControlMode( eControl theMode, bool theCheckEntityMode ) if (isLogarithmic && range[0] > 1e-07 && range[1] > 1e-07) lookupTable->SetScale(VTK_SCALE_LOG10); - Update(); + //Update(); } int SMESH_ActorDef::GetNumberControlEntities() @@ -1134,6 +1132,11 @@ int SMESH_ActorDef::GetNumberControlEntities() void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer) { + if ( !mySelector || !mySelector->IsSelectionEnabled() ) + { + myBaseActor->SetUnstructuredGrid( NULL ); + //myHighlitableActor->SetUnstructuredGrid( NULL ); + } theRenderer->AddActor(myBaseActor); theRenderer->AddActor(myNodeExtActor); theRenderer->AddActor(my1DExtActor); @@ -1274,7 +1277,9 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, double* SMESH_ActorDef::GetBounds() { - return myNodeActor->GetBounds(); + if ( GetNumberOfClippingPlanes() + myPlaneCollection->GetNumberOfItems() > 0 ) + return myNodeActor->GetBounds(); + return myVisualObj->GetUnstructuredGrid()->GetPoints()->GetBounds(); } @@ -1475,9 +1480,15 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation) case eCoincidentNodes: myNodeExtActor->VisibilityOn(); break; + case eLength: + case eMultiConnection: + my1DActor->VisibilityOn(); + break; case eFreeEdges: case eFreeBorders: case eCoincidentElems1D: + case eLength2D: + case eMultiConnection2D: my1DExtActor->VisibilityOn(); break; case eFreeFaces: @@ -1491,45 +1502,37 @@ void SMESH_ActorDef::SetVisibility(int theMode, bool theIsUpdateRepersentation) case eCoincidentElems3D: my3DExtActor->VisibilityOn(); break; - case eLength2D: - case eMultiConnection2D: - my1DExtActor->VisibilityOn(); - break; default:; } - if(myControlActor->GetUnstructuredGrid()->GetNumberOfCells()) + if ( myFunctor && myVisualObj->GetNbEntities( myFunctor->GetType() )) myScalarBarActor->VisibilityOn(); } - if(myRepresentation != ePoint) - myPickableActor->VisibilityOn(); - else { - myNodeActor->VisibilityOn(); - } - - if(myEntityMode & e0DElements && GetRepresentation() != ePoint ){ - my0DActor->VisibilityOn(); - } - if(myEntityMode & eBallElem && GetRepresentation() != ePoint ){ - myBallActor->VisibilityOn(); - } - - if(myEntityMode & eEdges && GetRepresentation() != ePoint){ - my1DActor->VisibilityOn(); - } - - if(myEntityMode & eFaces && GetRepresentation() != ePoint){ - my2DActor->VisibilityOn(); - } + myPickableActor->VisibilityOn(); - if(myEntityMode & eVolumes && GetRepresentation() != ePoint){ - my3DActor->VisibilityOn(); + if ( GetRepresentation() != ePoint ) + { + if(myEntityMode & e0DElements ){ + my0DActor->VisibilityOn(); + } + if(myEntityMode & eBallElem ){ + myBallActor->VisibilityOn(); + } + if(myEntityMode & eEdges && GetCellsLabeled() ){ // my1DActor shows labels only + my1DActor->VisibilityOn(); + } + if(myEntityMode & eFaces ){ + my2DActor->VisibilityOn(); + } + if(myEntityMode & eVolumes ){ + my3DActor->VisibilityOn(); + } } - if(myNodeActor->GetPointsLabeled()){ + if(myNodeActor->GetPointsLabeled()) { + myNodeActor->UpdateLabels(); myNodeActor->VisibilityOn(); } - if(my0DActor) my0DActor->UpdateLabels(); @@ -1603,97 +1606,108 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode) myBaseActor->myGeomFilter->SetInside(myEntityMode != myEntityState); myEntityMode = theMode; - VTKViewer_ExtractUnstructuredGrid* aFilter = NULL; - aFilter = myBaseActor->GetExtractUnstructuredGrid(); - aFilter->ClearRegisteredCellsWithType(); - aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); + VTKViewer_ExtractUnstructuredGrid* aFilter = myBaseActor->GetExtractUnstructuredGrid(); + aFilter->ClearRegisteredCellsWithType(); VTKViewer_ExtractUnstructuredGrid* aHightFilter = myHighlitableActor->GetExtractUnstructuredGrid(); aHightFilter->ClearRegisteredCellsWithType(); - aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); - if (myEntityMode & e0DElements) { - if (MYDEBUG) MESSAGE("0D ELEMENTS"); - aFilter->RegisterCellsWithType(VTK_VERTEX); - aHightFilter->RegisterCellsWithType(VTK_VERTEX); + bool isPassAll = + (( myEntityMode & e0DElements || myVisualObj->GetNbEntities(SMDSAbs_0DElement) == 0 ) && + ( myEntityMode & eBallElem || myVisualObj->GetNbEntities(SMDSAbs_Ball) == 0 ) && + ( myEntityMode & eEdges || myVisualObj->GetNbEntities(SMDSAbs_Edge) == 0 ) && + ( myEntityMode & eFaces || myVisualObj->GetNbEntities(SMDSAbs_Face) == 0 ) && + ( myEntityMode & eVolumes || myVisualObj->GetNbEntities(SMDSAbs_Volume) == 0 )); + if ( isPassAll && myEntityMode ) + { + aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll); + aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll); } + else + { + aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); + aHightFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding); - if (myEntityMode & eBallElem) { - aFilter->RegisterCellsWithType(VTK_POLY_VERTEX); - } + if (myEntityMode & e0DElements) { + aFilter->RegisterCellsWithType(VTK_VERTEX); + aHightFilter->RegisterCellsWithType(VTK_VERTEX); + } - if (myEntityMode & eEdges) { - if (MYDEBUG) MESSAGE("EDGES"); - aFilter->RegisterCellsWithType(VTK_LINE); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); + if (myEntityMode & eBallElem) { + aFilter->RegisterCellsWithType(VTK_POLY_VERTEX); + } - aHightFilter->RegisterCellsWithType(VTK_LINE); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); - } + if (myEntityMode & eEdges) { + aFilter->RegisterCellsWithType(VTK_LINE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); - if (myEntityMode & eFaces) { - if (MYDEBUG) MESSAGE("FACES"); - aFilter->RegisterCellsWithType(VTK_TRIANGLE); - aFilter->RegisterCellsWithType(VTK_QUAD); - aFilter->RegisterCellsWithType(VTK_POLYGON); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON); - aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); - aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); - - aHightFilter->RegisterCellsWithType(VTK_TRIANGLE); - aHightFilter->RegisterCellsWithType(VTK_QUAD); - aHightFilter->RegisterCellsWithType(VTK_POLYGON); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON); - aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); - aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); - } + aHightFilter->RegisterCellsWithType(VTK_LINE); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_EDGE); + } + + if (myEntityMode & eFaces) { + aFilter->RegisterCellsWithType(VTK_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUAD); + aFilter->RegisterCellsWithType(VTK_POLYGON); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON); + aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); + aFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); + + aHightFilter->RegisterCellsWithType(VTK_TRIANGLE); + aHightFilter->RegisterCellsWithType(VTK_QUAD); + aHightFilter->RegisterCellsWithType(VTK_POLYGON); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TRIANGLE); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_QUAD); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_POLYGON); + aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_QUAD); + aHightFilter->RegisterCellsWithType(VTK_BIQUADRATIC_TRIANGLE); + } - if (myEntityMode & eVolumes) { - if (MYDEBUG) MESSAGE("VOLUMES"); - aFilter->RegisterCellsWithType(VTK_TETRA); - aFilter->RegisterCellsWithType(VTK_VOXEL); - aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); - aFilter->RegisterCellsWithType(VTK_WEDGE); - aFilter->RegisterCellsWithType(VTK_PYRAMID); - aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); - aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); - aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); - aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); - aFilter->RegisterCellsWithType(VTK_POLYHEDRON); - - aHightFilter->RegisterCellsWithType(VTK_TETRA); - aHightFilter->RegisterCellsWithType(VTK_VOXEL); - aHightFilter->RegisterCellsWithType(VTK_HEXAHEDRON); - aHightFilter->RegisterCellsWithType(VTK_WEDGE); - aHightFilter->RegisterCellsWithType(VTK_PYRAMID); - aHightFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); - aHightFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); - aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); - aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); - aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON); + if (myEntityMode & eVolumes) { + aFilter->RegisterCellsWithType(VTK_TETRA); + aFilter->RegisterCellsWithType(VTK_VOXEL); + aFilter->RegisterCellsWithType(VTK_HEXAHEDRON); + aFilter->RegisterCellsWithType(VTK_WEDGE); + aFilter->RegisterCellsWithType(VTK_PYRAMID); + aFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); + aFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); + aFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); + aFilter->RegisterCellsWithType(VTK_POLYHEDRON); + + aHightFilter->RegisterCellsWithType(VTK_TETRA); + aHightFilter->RegisterCellsWithType(VTK_VOXEL); + aHightFilter->RegisterCellsWithType(VTK_HEXAHEDRON); + aHightFilter->RegisterCellsWithType(VTK_WEDGE); + aHightFilter->RegisterCellsWithType(VTK_PYRAMID); + aHightFilter->RegisterCellsWithType(VTK_HEXAGONAL_PRISM); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_TETRA); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_HEXAHEDRON); + aHightFilter->RegisterCellsWithType(VTK_TRIQUADRATIC_HEXAHEDRON); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_WEDGE); + aHightFilter->RegisterCellsWithType(VTK_QUADRATIC_PYRAMID); + aHightFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET); + aHightFilter->RegisterCellsWithType(VTK_POLYHEDRON); + } } - aFilter->Update(); + if ( GetVisibility() ) + aFilter->Update(); if (MYDEBUG) MESSAGE(aFilter->GetOutput()->GetNumberOfCells()); SetVisibility(GetVisibility(),false); } void SMESH_ActorDef::SetRepresentation (int theMode) { - int aNbEdges = myVisualObj->GetNbEntities(SMDSAbs_Edge); - int aNbFaces = myVisualObj->GetNbEntities(SMDSAbs_Face); + int aNbEdges = myVisualObj->GetNbEntities(SMDSAbs_Edge); + int aNbFaces = myVisualObj->GetNbEntities(SMDSAbs_Face); int aNbVolumes = myVisualObj->GetNbEntities(SMDSAbs_Volume); - int aNb0Ds = myVisualObj->GetNbEntities(SMDSAbs_0DElement); - int aNbBalls = myVisualObj->GetNbEntities(SMDSAbs_Ball); + int aNb0Ds = myVisualObj->GetNbEntities(SMDSAbs_0DElement); + int aNbBalls = myVisualObj->GetNbEntities(SMDSAbs_Ball); if (theMode < 0) { myRepresentation = eSurface; @@ -1727,8 +1741,6 @@ void SMESH_ActorDef::SetRepresentation (int theMode) } myPickableActor = myBaseActor; - myNodeActor->SetVisibility(false); - myNodeExtActor->SetVisibility(false); vtkProperty *aProp = NULL, *aBackProp = NULL; vtkProperty *aPropVN = NULL, *aPropVR = NULL; SMESH_DeviceActor::EReperesent aReperesent = SMESH_DeviceActor::EReperesent(-1); @@ -1736,7 +1748,6 @@ void SMESH_ActorDef::SetRepresentation (int theMode) switch (myRepresentation) { case ePoint: myPickableActor = myNodeActor; - myNodeActor->SetVisibility(true); aQuadraticMode = SMESH_Actor::eLines; aProp = aBackProp = aPropVN = aPropVR = myNodeProp; aReperesent = SMESH_DeviceActor::ePoint; @@ -1754,54 +1765,50 @@ void SMESH_ActorDef::SetRepresentation (int theMode) break; } - my2DActor->SetProperty(aProp); - my2DActor->SetBackfaceProperty(aBackProp); - my2DActor->SetRepresentation(aReperesent); + if ( myRepresentation != ePoint ) + { + my2DActor->SetProperty(aProp); + my2DActor->SetBackfaceProperty(aBackProp); + my2DActor->SetRepresentation(aReperesent); - if(aQuadraticMode == SMESH_Actor::eLines) - my2DActor->SetQuadraticArcMode(false); - else if(aQuadraticMode == SMESH_Actor::eArcs) - my2DActor->SetQuadraticArcMode(true); + if(aQuadraticMode == SMESH_Actor::eLines) + my2DActor->SetQuadraticArcMode(false); + else if(aQuadraticMode == SMESH_Actor::eArcs) + my2DActor->SetQuadraticArcMode(true); - my2DExtActor->SetRepresentation(aReperesent); + my2DExtActor->SetRepresentation(aReperesent); - my3DActor->SetProperty(aPropVN); - my3DActor->SetBackfaceProperty(aPropVR); - my3DActor->SetRepresentation(aReperesent); + my3DActor->SetProperty(aPropVN); + my3DActor->SetBackfaceProperty(aPropVR); + my3DActor->SetRepresentation(aReperesent); + my0DActor->SetRepresentation(aReperesent); + myBallActor->SetRepresentation(aReperesent); - my1DExtActor->SetVisibility(false); - my2DExtActor->SetVisibility(false); - my3DExtActor->SetVisibility(false); - - my0DActor->SetRepresentation(aReperesent); - myBallActor->SetRepresentation(aReperesent); - - switch ( myControlMode ) { - case eLength: - case eMultiConnection: - aProp = aBackProp = my1DProp; - if(myRepresentation != ePoint) - aReperesent = SMESH_DeviceActor::eInsideframe; - break; - default:; - } + switch ( myControlMode ) { + case eLength: + case eMultiConnection: + aProp = aBackProp = my1DProp; + if(myRepresentation != ePoint) + aReperesent = SMESH_DeviceActor::eInsideframe; + break; + default:; + } - if(aQuadraticMode == SMESH_Actor::eLines) - my1DActor->SetQuadraticArcMode(false); - else if(aQuadraticMode == SMESH_Actor::eArcs) - my1DActor->SetQuadraticArcMode(true); + if(aQuadraticMode == SMESH_Actor::eLines) + my1DActor->SetQuadraticArcMode(false); + else if(aQuadraticMode == SMESH_Actor::eArcs) + my1DActor->SetQuadraticArcMode(true); - my1DActor->SetProperty(aProp); - my1DActor->SetBackfaceProperty(aBackProp); - my1DActor->SetRepresentation(aReperesent); + my1DActor->SetProperty(aProp); + my1DActor->SetBackfaceProperty(aBackProp); + my1DActor->SetRepresentation(aReperesent); - my1DExtActor->SetRepresentation(aReperesent); + my1DExtActor->SetRepresentation(aReperesent); + } if(myIsPointsVisible) myPickableActor = myNodeActor; - if(GetPointRepresentation()) - myNodeActor->SetVisibility(true); SetMapper(myPickableActor->GetMapper()); @@ -1863,11 +1870,30 @@ void SMESH_ActorDef::UpdateHighlight() } myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint); myNodeActor->GetExtractUnstructuredGrid()->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints); + myNodeActor->GetProperty()->Modified(); break; } } } +void SMESH_ActorDef::EnableSelection( bool enable ) +{ + // selection in the Viewer enabled/disabled + if ( enable && ! myBaseActor->myExtractUnstructuredGrid->GetInput() ) + { + myBaseActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + //myHighlitableActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + myBaseActor->myExtractUnstructuredGrid->Update(); + //myHighlitableActor->myExtractUnstructuredGrid->Update(); + } + if ( !enable && myBaseActor->myExtractUnstructuredGrid->GetInput() ) + { + myBaseActor->SetUnstructuredGrid( NULL ); + //myHighlitableActor->SetUnstructuredGrid( NULL ); + myBaseActor->myExtractUnstructuredGrid->Update(); + //myHighlitableActor->myExtractUnstructuredGrid->Update(); + } +} void SMESH_ActorDef::highlight(bool theHighlight) { @@ -1891,11 +1917,11 @@ void SMESH_ActorDef::SetPreSelected(bool thePreselect) int SMESH_ActorDef::RenderOpaqueGeometry(vtkViewport *vp) { if (myPickableActor->GetIsOpaque()) - { + { vtkRenderer *ren = static_cast(vp); this->Render(ren); return 1; - } + } return 0; } @@ -1903,20 +1929,20 @@ int SMESH_ActorDef::RenderOpaqueGeometry(vtkViewport *vp) int SMESH_ActorDef::RenderTranslucentGeometry(vtkViewport *vp) { if (!myPickableActor->GetIsOpaque()) - { + { vtkRenderer *ren = static_cast(vp); this->Render(ren); return 1; - } + } return 0; } void SMESH_ActorDef::Render(vtkRenderer *ren) { - unsigned long aTime = myTimeStamp->GetMTime(); - unsigned long anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime(); - unsigned long aClippingTime = myImplicitBoolean->GetMTime(); + vtkMTimeType aTime = myTimeStamp->GetMTime(); + vtkMTimeType anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime(); + vtkMTimeType aClippingTime = myImplicitBoolean->GetMTime(); if(anObjTime > aTime || aClippingTime > aTime) Update(); } @@ -1926,6 +1952,8 @@ void SMESH_ActorDef::Update() { if(MYDEBUG) MESSAGE("SMESH_ActorDef::Update"); + myVisualObj->Update(); + if(GetControlMode() != eNone) { unsigned long aTime = myTimeStamp->GetMTime(); unsigned long anObjTime = myVisualObj->GetUnstructuredGrid()->GetMTime(); @@ -2297,6 +2325,11 @@ void SMESH_ActorDef::SetOpenGLClippingPlane() myHighlitableActor->SetPlaneCollection( myPlaneCollection ); myHighlitableActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); + if ( !mySelector || !mySelector->IsSelectionEnabled() ) + { + myBaseActor->SetUnstructuredGrid( NULL ); + //myHighlitableActor->SetUnstructuredGrid( NULL ); + } my1DActor->SetPlaneCollection( myPlaneCollection ); my1DActor->SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h index eb3654ab2..4366a98a6 100644 --- a/src/OBJECT/SMESH_ActorDef.h +++ b/src/OBJECT/SMESH_ActorDef.h @@ -95,6 +95,7 @@ class SMESH_ActorDef : public SMESH_Actor virtual void AddToRender(vtkRenderer* theRenderer); virtual void RemoveFromRender(vtkRenderer* theRenderer); + virtual void EnableSelection( bool enable ); virtual bool hasHighlight() { return true; } virtual void highlight(bool theHighlight); virtual void SetPreSelected(bool thePreselect = false); diff --git a/src/OBJECT/SMESH_CellLabelActor.cxx b/src/OBJECT/SMESH_CellLabelActor.cxx index 5bca6fc0a..7b5e7aec6 100644 --- a/src/OBJECT/SMESH_CellLabelActor.cxx +++ b/src/OBJECT/SMESH_CellLabelActor.cxx @@ -25,6 +25,8 @@ // #include "SMESH_CellLabelActor.h" +#include "SMESH_ExtractGeometry.h" + #include #include #include @@ -47,8 +49,9 @@ vtkStandardNewMacro(SMESH_CellLabelActor); /*! Constructor. */ -SMESH_CellLabelActor::SMESH_CellLabelActor() { - //Definition of cells numbering pipeline +SMESH_CellLabelActor::SMESH_CellLabelActor() +{ + //Definition of cells numbering pipeline //--------------------------------------- myCellsNumDataSet = vtkUnstructuredGrid::New(); @@ -58,18 +61,18 @@ SMESH_CellLabelActor::SMESH_CellLabelActor() { myClsMaskPoints = vtkMaskPoints::New(); myClsMaskPoints->SetInputConnection(myCellCenters->GetOutputPort()); myClsMaskPoints->SetOnRatio(1); - + myClsSelectVisiblePoints = vtkSelectVisiblePoints::New(); myClsSelectVisiblePoints->SetInputConnection(myClsMaskPoints->GetOutputPort()); myClsSelectVisiblePoints->SelectInvisibleOff(); myClsSelectVisiblePoints->SetTolerance(0.1); - + myClsLabeledDataMapper = vtkLabeledDataMapper::New(); myClsLabeledDataMapper->SetInputConnection(myClsSelectVisiblePoints->GetOutputPort()); myClsLabeledDataMapper->SetLabelFormat("%d"); myClsLabeledDataMapper->SetLabelModeToLabelScalars(); - + myClsTextProp = vtkTextProperty::New(); myClsTextProp->SetFontFamilyToTimes(); myClsTextProp->SetFontSize(12); @@ -98,7 +101,8 @@ SMESH_CellLabelActor::SMESH_CellLabelActor() { /*! Destructor. */ -SMESH_CellLabelActor::~SMESH_CellLabelActor() { +SMESH_CellLabelActor::~SMESH_CellLabelActor() +{ //Deleting of cells numbering pipeline //--------------------------------------- myCellsNumDataSet->Delete(); @@ -136,33 +140,39 @@ void SMESH_CellLabelActor::SetFontProperties( SMESH::LabelFont family, int size, myClsTextProp->SetBold( bold ); myClsTextProp->SetItalic( italic ); myClsTextProp->SetShadow( shadow ); - myClsTextProp->SetColor( r, g, b ); + myClsTextProp->SetColor( r, g, b ); } -void SMESH_CellLabelActor::SetCellsLabeled(bool theIsCellsLabeled) { +void SMESH_CellLabelActor::SetCellsLabeled(bool theIsCellsLabeled) +{ + myIsCellsLabeled = theIsCellsLabeled; + + myCellsLabels->SetVisibility(false); + myTransformFilter->Update(); vtkUnstructuredGrid* aGrid = vtkUnstructuredGrid::SafeDownCast(myTransformFilter->GetOutput()); - if(!aGrid) - return; - myIsCellsLabeled = theIsCellsLabeled && aGrid->GetNumberOfPoints(); - if(myIsCellsLabeled){ + if ( myIsCellsLabeled && aGrid ) + { myCellsNumDataSet->ShallowCopy(aGrid); vtkUnstructuredGrid *aDataSet = myCellsNumDataSet; int aNbElem = aDataSet->GetNumberOfCells(); vtkIntArray *anArray = vtkIntArray::New(); anArray->SetNumberOfValues(aNbElem); - for(int anId = 0; anId < aNbElem; anId++){ - vtkIdType id = myExtractUnstructuredGrid->GetInputId(anId); - id = (id >=0) ? id : anId; + myExtractUnstructuredGrid->BuildOut2InMap(); + for(int anId = 0; anId < aNbElem; anId++) + { + vtkIdType id = anId; + if(IsImplicitFunctionUsed()) + id = myExtractGeometry->GetElemObjId(id); + id = myExtractUnstructuredGrid->GetInputId(id); + id = (id >=0) ? id : anId; int aSMDSId = myVisualObj->GetElemObjId(id); anArray->SetValue(anId,aSMDSId); } aDataSet->GetCellData()->SetScalars(anArray); myCellCenters->SetInputData(aDataSet); myCellsLabels->SetVisibility(GetVisibility()); - }else{ - myCellsLabels->SetVisibility(false); } } @@ -187,7 +197,8 @@ void SMESH_CellLabelActor::RemoveFromRender(vtkRenderer* theRenderer) SMESH_DeviceActor::RemoveFromRender(theRenderer); } -void SMESH_CellLabelActor::UpdateLabels() { +void SMESH_CellLabelActor::UpdateLabels() +{ if(myIsCellsLabeled) SetCellsLabeled(myIsCellsLabeled); } @@ -196,7 +207,8 @@ void SMESH_CellLabelActor::UpdateLabels() { void SMESH_CellLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject), unsigned long theEvent, void* theClientData, - void* vtkNotUsed(theCallData)) { + void* vtkNotUsed(theCallData)) +{ SMESH_CellLabelActor* self = reinterpret_cast(theClientData); if(self) self->UpdateLabels(); diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index f9195f19f..2f6ccd06f 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -88,7 +88,7 @@ SMESH_DeviceActor myIsShrunk = false; myIsHighlited = false; - myRepresentation = eSurface; + myRepresentation = SMESH_DeviceActor::EReperesent(-1); myProperty = vtkProperty::New(); myMapper = VTKViewer_PolyDataMapper::New(); @@ -142,7 +142,7 @@ SMESH_DeviceActor if(MYDEBUG) MESSAGE("~SMESH_DeviceActor - "<Delete(); - myPlaneCollection->Delete(); + // myPlaneCollection->Delete(); -- it is vtkSmartPointer myProperty->Delete(); myExtractGeometry->Delete(); @@ -172,7 +172,8 @@ SMESH_DeviceActor ::SetStoreGemetryMapping(bool theStoreMapping) { myGeomFilter->SetStoreMapping(theStoreMapping); - SetStoreClippingMapping(theStoreMapping); + // for optimization, switch the mapping explicitly in each filter/algorithm + //SetStoreClippingMapping(theStoreMapping); } @@ -182,7 +183,10 @@ SMESH_DeviceActor { myStoreClippingMapping = theStoreMapping; myExtractGeometry->SetStoreMapping(theStoreMapping && myIsImplicitFunctionUsed); - SetStoreIDMapping(theStoreMapping); + // EAP, 23315 + // Mapping in myExtractUnstructuredGrid and myGeomFilter is ON in the pickable DeviceActor only. + // To show labels, the mapping is computed explicitly via myExtractUnstructuredGrid->BuildOut2InMap(); + //SetStoreIDMapping(theStoreMapping); } @@ -204,7 +208,6 @@ SMESH_DeviceActor SetUnstructuredGrid(myVisualObj->GetUnstructuredGrid()); } - void SMESH_DeviceActor ::SetImplicitFunctionUsed(bool theIsImplicitFunctionUsed) @@ -224,14 +227,14 @@ void SMESH_DeviceActor ::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid) { - if(theGrid){ - //myIsShrinkable = theGrid->GetNumberOfCells() > 10; - myIsShrinkable = true; + myExtractUnstructuredGrid->SetInputData(theGrid); - myExtractUnstructuredGrid->SetInputData(theGrid); + if ( theGrid ) + { + myIsShrinkable = true; myMergeFilter->SetGeometryConnection(myExtractUnstructuredGrid->GetOutputPort()); - + //Pass diameters of the balls if(myMapper->GetBallEnabled()) { myMergeFilter->SetScalarsConnection(myExtractUnstructuredGrid->GetOutputPort()); @@ -242,7 +245,7 @@ SMESH_DeviceActor int anId = 0; SetImplicitFunctionUsed(myIsImplicitFunctionUsed); myPassFilter[ anId + 1]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() ); - + anId++; // 1 myTransformFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() ); @@ -254,7 +257,7 @@ SMESH_DeviceActor myGeomFilter->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() ); anId++; // 4 - myPassFilter[ anId ]->SetInputConnection( myGeomFilter->GetOutputPort() ); + myPassFilter[ anId ]->SetInputConnection( myGeomFilter->GetOutputPort() ); myPassFilter[ anId + 1 ]->SetInputConnection( myPassFilter[ anId ]->GetOutputPort() ); anId++; // 5 @@ -263,8 +266,8 @@ SMESH_DeviceActor myMapper->SetClippingPlanes( myPlaneCollection ); vtkLODActor::SetMapper( myMapper ); - Modified(); } + Modified(); } void @@ -281,6 +284,7 @@ SMESH_DeviceActor return myExtractUnstructuredGrid; } +#include "SMDS_Mesh.hxx" vtkUnstructuredGrid* SMESH_DeviceActor @@ -301,7 +305,7 @@ SMESH_DeviceActor if(anIsInitialized){ vtkUnstructuredGrid* aDataSet = vtkUnstructuredGrid::New(); - SetStoreIDMapping(true); + // SetStoreIDMapping(true); myExtractUnstructuredGrid->Update(); vtkUnstructuredGrid* aGrid = myExtractUnstructuredGrid->GetOutput(); @@ -318,7 +322,9 @@ SMESH_DeviceActor using namespace SMESH::Controls; if(NumericalFunctor* aNumericalFunctor = dynamic_cast(theFunctor.get())) { - for(vtkIdType i = 0; i < aNbCells; i++){ + myExtractUnstructuredGrid->BuildOut2InMap(); + for(vtkIdType i = 0; i < aNbCells; i++) + { vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i); vtkIdType anObjId = myVisualObj->GetElemObjId(anId); double aValue = aNumericalFunctor->GetValue(anObjId); @@ -334,7 +340,9 @@ SMESH_DeviceActor } else if(Predicate* aPredicate = dynamic_cast(theFunctor.get())) { - for(vtkIdType i = 0; i < aNbCells; i++){ + myExtractUnstructuredGrid->BuildOut2InMap(); + for(vtkIdType i = 0; i < aNbCells; i++) + { vtkIdType anId = myExtractUnstructuredGrid->GetInputId(i); vtkIdType anObjId = myVisualObj->GetElemObjId(anId); bool aValue = aPredicate->IsSatisfy(anObjId); @@ -607,11 +615,32 @@ SMESH_DeviceActor -unsigned long int +vtkMTimeType SMESH_DeviceActor ::GetMTime() { - unsigned long mTime = this->Superclass::GetMTime(); + // cout << "DA " << this + // << " GF " << myGeomFilter; + // if ( this->Property ) + // cout << " P " << this->Property->GetMTime(); + // if ( this->BackfaceProperty != NULL ) + // cout << " BP " << BackfaceProperty->GetMTime(); + // if ( this->Texture != NULL ) + // cout << " T " << this->Texture->GetMTime(); + // cout << " U " << this->GetUserTransformMatrixMTime() + // << " M " << this->MTime.GetMTime() << endl; + + // cout << "DA " << this + // << " GF " << myGeomFilter + // << " " << this->Superclass::GetMTime() + // << " " << myExtractGeometry->GetMTime() + // << " " << myExtractUnstructuredGrid->GetMTime() + // << " " << myMergeFilter->GetMTime() + // << " " << myGeomFilter->GetMTime() + // << " " << myTransformFilter->GetMTime() + // << " " << myFaceOrientationFilter->GetMTime() << endl; + + vtkMTimeType mTime = this->Superclass::GetMTime(); mTime = max(mTime,myExtractGeometry->GetMTime()); mTime = max(mTime,myExtractUnstructuredGrid->GetMTime()); mTime = max(mTime,myMergeFilter->GetMTime()); @@ -718,7 +747,7 @@ SMESH_DeviceActor ::UpdateFaceOrientation() { bool aShowFaceOrientation = myIsFacesOriented; - aShowFaceOrientation &= GetVisibility(); + aShowFaceOrientation &= vtkLODActor::GetVisibility(); //GetVisibility(); -- avoid calling GetUnstructuredGrid() aShowFaceOrientation &= myRepresentation == eSurface; myFaceOrientation->SetVisibility(aShowFaceOrientation); } @@ -728,6 +757,8 @@ void SMESH_DeviceActor ::SetRepresentation(EReperesent theMode) { + if ( myRepresentation == theMode ) + return; switch(theMode){ case ePoint: myGeomFilter->SetInside(true); @@ -762,8 +793,9 @@ void SMESH_DeviceActor ::SetVisibility(int theMode) { - if(!myExtractUnstructuredGrid->GetInput() || - GetUnstructuredGrid()->GetNumberOfCells()) + if(( theMode ) && + ( !myExtractUnstructuredGrid->GetInput() || + GetUnstructuredGrid()->GetNumberOfCells())) { vtkLODActor::SetVisibility(theMode); }else{ @@ -777,10 +809,12 @@ int SMESH_DeviceActor ::GetVisibility() { - if(!GetUnstructuredGrid()->GetNumberOfCells()){ + int visibi = vtkLODActor::GetVisibility(); + if(visibi && !GetUnstructuredGrid()->GetNumberOfCells()){ vtkLODActor::SetVisibility(false); + visibi = 0; } - return vtkLODActor::GetVisibility(); + return visibi; } @@ -821,7 +855,7 @@ SMESH_DeviceActor { vtkDataSet* aDataSet = myMergeFilter->GetOutput(); vtkIdType anID = myVisualObj->GetNodeVTKId(theObjID); - double* aCoord = (anID >=0) ? aDataSet->GetPoint(anID) : NULL; + double* aCoord = (anID >=0 && anID < aDataSet->GetNumberOfPoints()) ? aDataSet->GetPoint(anID) : NULL; if(MYDEBUG) MESSAGE("GetNodeCoord - theObjID = "<SetLabelModeToLabelScalars(); - + myPtsTextProp = vtkTextProperty::New(); myPtsTextProp->SetFontFamilyToTimes(); myPtsTextProp->SetFontSize(10); @@ -90,19 +91,20 @@ SMESH_NodeLabelActor::SMESH_NodeLabelActor() { /*! Destructor */ -SMESH_NodeLabelActor::~SMESH_NodeLabelActor() { +SMESH_NodeLabelActor::~SMESH_NodeLabelActor() +{ //Deleting of points numbering pipeline //--------------------------------------- myPointsNumDataSet->Delete(); - + // commented: porting to vtk 5.0 // myPtsLabeledDataMapper->RemoveAllInputs(); myPtsLabeledDataMapper->Delete(); - + // commented: porting to vtk 5.0 // myPtsSelectVisiblePoints->UnRegisterAllOutputs(); myPtsSelectVisiblePoints->Delete(); - + // commented: porting to vtk 5.0 // myPtsMaskPoints->UnRegisterAllOutputs(); myPtsMaskPoints->Delete(); @@ -130,16 +132,16 @@ void SMESH_NodeLabelActor::SetFontProperties( SMESH::LabelFont family, int size, myPtsTextProp->SetColor( r, g, b ); } -void SMESH_NodeLabelActor::SetPointsLabeled(bool theIsPointsLabeled) { +void SMESH_NodeLabelActor::SetPointsLabeled(bool theIsPointsLabeled) +{ + myIsPointsLabeled = theIsPointsLabeled; + + myPointLabels->SetVisibility( false ); + myTransformFilter->Update(); vtkDataSet* aGrid = vtkUnstructuredGrid::SafeDownCast(myTransformFilter->GetOutput()); - if(!aGrid) - return; - - myIsPointsLabeled = theIsPointsLabeled && aGrid->GetNumberOfPoints(); - - if ( myIsPointsLabeled ) + if ( myIsPointsLabeled && aGrid ) { myPointsNumDataSet->ShallowCopy(aGrid); vtkUnstructuredGrid *aDataSet = myPointsNumDataSet; @@ -160,10 +162,6 @@ void SMESH_NodeLabelActor::SetPointsLabeled(bool theIsPointsLabeled) { myPointLabels->SetVisibility( GetVisibility() ); anArray->Delete(); } - else - { - myPointLabels->SetVisibility( false ); - } } @@ -189,7 +187,8 @@ void SMESH_NodeLabelActor::RemoveFromRender(vtkRenderer* theRenderer) SMESH_DeviceActor::RemoveFromRender(theRenderer); } -void SMESH_NodeLabelActor::UpdateLabels() { +void SMESH_NodeLabelActor::UpdateLabels() +{ if(myIsPointsLabeled) SetPointsLabeled(myIsPointsLabeled); } @@ -198,8 +197,9 @@ void SMESH_NodeLabelActor::UpdateLabels() { void SMESH_NodeLabelActor::ProcessEvents(vtkObject* vtkNotUsed(theObject), unsigned long theEvent, void* theClientData, - void* vtkNotUsed(theCallData)) { - SMESH_NodeLabelActor* self = reinterpret_cast(theClientData); + void* vtkNotUsed(theCallData)) +{ + SMESH_NodeLabelActor* self = reinterpret_cast(theClientData); if(self) self->UpdateLabels(); } diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index 61b36a78c..3b9cd0b8c 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -280,6 +280,7 @@ void SMESH_VisualObjDef::buildPrs(bool buildGrid) myLocalGrid = false; if (!GetMesh()->isCompacted()) { + NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh() if ( MYDEBUG ) MESSAGE("*** buildPrs ==> compactMesh!"); GetMesh()->compactMesh(); } @@ -570,6 +571,7 @@ vtkUnstructuredGrid* SMESH_VisualObjDef::GetUnstructuredGrid() { if ( !myLocalGrid && !GetMesh()->isCompacted() ) { + NulData(); // detach from the SMDS grid to allow immediate memory de-allocation in compactMesh() GetMesh()->compactMesh(); updateEntitiesFlags(); vtkUnstructuredGrid *theGrid = GetMesh()->getGrid(); @@ -717,7 +719,7 @@ bool SMESH_MeshObj::NulData() points->SetNumberOfPoints(0); myEmptyGrid->SetPoints( points ); points->Delete(); - myEmptyGrid->BuildLinks(); + //myEmptyGrid->BuildLinks(); } myGrid->ShallowCopy(myEmptyGrid); return true; diff --git a/src/OBJECT/SMESH_SVTKActor.cxx b/src/OBJECT/SMESH_SVTKActor.cxx index 66c7b738b..a9a549f03 100644 --- a/src/OBJECT/SMESH_SVTKActor.cxx +++ b/src/OBJECT/SMESH_SVTKActor.cxx @@ -119,11 +119,10 @@ SMESH_SVTKActor myBallGrid->Initialize(); myBallGrid->Allocate(); - vtkDataSet *aSourceDataSet = theMapActor->GetInput(); - SVTK::CopyPoints( GetSource(), aSourceDataSet ); - SVTK::CopyPoints( myBallGrid, aSourceDataSet ); - SVTK::CopyPoints( my0DGrid, aSourceDataSet ); - + vtkUnstructuredGrid * aSourceGrid = (vtkUnstructuredGrid *)theMapActor->GetInput(); + GetSource()->SetPoints( aSourceGrid->GetPoints() ); + myBallGrid->SetPoints( aSourceGrid->GetPoints() ); + my0DGrid->SetPoints( aSourceGrid->GetPoints() ); int aNbOfParts = theMapIndex.Extent(); @@ -132,7 +131,7 @@ SMESH_SVTKActor //Copy deamaters of the balls if(myVisualObj) { outputCD = myBallGrid->GetCellData(); - cd = aSourceDataSet->GetCellData(); + cd = aSourceGrid->GetCellData(); } outputCD->CopyAllocate(cd,aNbOfParts,aNbOfParts/2); for(int ind = 1; ind <= aNbOfParts; ind++){ diff --git a/src/SMDS/SMDS_BallElement.cxx b/src/SMDS/SMDS_BallElement.cxx index 22d2d0407..8cf426a91 100644 --- a/src/SMDS/SMDS_BallElement.cxx +++ b/src/SMDS/SMDS_BallElement.cxx @@ -47,10 +47,9 @@ SMDS_BallElement::SMDS_BallElement(vtkIdType nodeId, double diameter, SMDS_Mesh* void SMDS_BallElement::init(vtkIdType nodeId, double diameter, SMDS_Mesh* mesh) { SMDS_MeshCell::init(); - SMDS_UnstructuredGrid* grid = mesh->getGrid(); - myVtkID = grid->InsertNextLinkedCell( GetVtkType(), 1, &nodeId ); myMeshId = mesh->getMeshId(); - grid->SetBallDiameter( myVtkID, diameter ); + myVtkID = mesh->getGrid()->InsertNextLinkedCell( GetVtkType(), 1, &nodeId ); + mesh->getGrid()->SetBallDiameter( myVtkID, diameter ); mesh->setMyModified(); } diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 6582e23f1..13a2aa40f 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -130,7 +130,6 @@ SMDS_Mesh::SMDS_Mesh(): myNodeIDFactory(new SMDS_MeshNodeIDFactory()), myElementIDFactory(new SMDS_MeshElementIDFactory()), myModified(false), myModifTime(0), myCompactTime(0), - myNodeMin(0), myNodeMax(0), myHasConstructionEdges(false), myHasConstructionFaces(false), myHasInverseElements(true), xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0) @@ -160,8 +159,19 @@ SMDS_Mesh::SMDS_Mesh(): points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/); myGrid->SetPoints( points ); points->Delete(); - myGrid->BuildLinks(); + //myGrid->BuildLinks(); this->Modified(); + + // initialize static maps in SMDS_MeshCell, to be thread-safe + if ( myMeshId == 0 ) + { + SMDS_MeshCell::toVtkType( SMDSEntity_Node ); + SMDS_MeshCell::toVtkOrder( SMDSEntity_Node ); + SMDS_MeshCell::reverseSmdsOrder( SMDSEntity_Node ); + SMDS_MeshCell::interlacedSmdsOrder( SMDSEntity_Node ); + SMDS_MeshCell::toSmdsType( VTK_VERTEX ); + SMDS_MeshCell::fromVtkOrder( SMDSEntity_Node ); + } } /////////////////////////////////////////////////////////////////////////////// @@ -2560,6 +2570,13 @@ int SMDS_Mesh::NbNodes() const return myInfo.NbNodes(); } +/////////////////////////////////////////////////////////////////////////////// +/// Return the number of elements +/////////////////////////////////////////////////////////////////////////////// +int SMDS_Mesh::NbElements() const +{ + return myInfo.NbElements(); +} /////////////////////////////////////////////////////////////////////////////// /// Return the number of 0D elements /////////////////////////////////////////////////////////////////////////////// @@ -2661,52 +2678,26 @@ SMDS_Mesh::~SMDS_Mesh() void SMDS_Mesh::Clear() { if (myParent!=NULL) - { + { SMDS_ElemIteratorPtr eIt = elementsIterator(); while ( eIt->more() ) - { - const SMDS_MeshElement *elem = eIt->next(); - myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); - } + { + const SMDS_MeshElement *elem = eIt->next(); + myElementIDFactory->ReleaseID(elem->GetID(), elem->getVtkId()); + } SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - { - const SMDS_MeshNode *node = itn->next(); - myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); - } + { + const SMDS_MeshNode *node = itn->next(); + myNodeIDFactory->ReleaseID(node->GetID(), node->getVtkId()); } + } else - { + { myNodeIDFactory->Clear(); myElementIDFactory->Clear(); - } + } - // SMDS_ElemIteratorPtr itv = elementsIterator(); - // while (itv->more()) - // { - // SMDS_MeshElement* elem = (SMDS_MeshElement*)(itv->next()); - // SMDSAbs_ElementType aType = elem->GetType(); - // switch (aType) - // { - // case SMDSAbs_0DElement: - // delete elem; - // break; - // case SMDSAbs_Edge: - // myEdgePool->destroy(static_cast(elem)); - // break; - // case SMDSAbs_Face: - // myFacePool->destroy(static_cast(elem)); - // break; - // case SMDSAbs_Volume: - // myVolumePool->destroy(static_cast(elem)); - // break; - // case SMDSAbs_Ball: - // myBallPool->destroy(static_cast(elem)); - // break; - // default: - // break; - // } - // } myVolumePool->clear(); myFacePool->clear(); myEdgePool->clear(); @@ -2717,11 +2708,11 @@ void SMDS_Mesh::Clear() SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) - { - SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next()); - node->SetPosition(SMDS_SpacePosition::originSpacePosition()); - //myNodePool->destroy(node); - } + { + SMDS_MeshNode *node = (SMDS_MeshNode*)(itn->next()); + node->SetPosition(SMDS_SpacePosition::originSpacePosition()); + //myNodePool->destroy(node); + } myNodePool->clear(); clearVector( myNodes ); @@ -2743,10 +2734,10 @@ void SMDS_Mesh::Clear() // rnv: to fix bug "21125: EDF 1233 SMESH: Degrardation of precision in a test case for quadratic conversion" // using double type for storing coordinates of nodes instead float. points->SetDataType(VTK_DOUBLE); - points->SetNumberOfPoints(0 /*SMDS_Mesh::chunkSize*/); + points->SetNumberOfPoints( 0 ); myGrid->SetPoints( points ); points->Delete(); - myGrid->BuildLinks(); + myGrid->DeleteLinks(); } /////////////////////////////////////////////////////////////////////////////// @@ -2756,7 +2747,7 @@ void SMDS_Mesh::Clear() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasConstructionEdges() { - return myHasConstructionEdges; + return myHasConstructionEdges; } /////////////////////////////////////////////////////////////////////////////// @@ -2768,7 +2759,7 @@ bool SMDS_Mesh::hasConstructionEdges() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasConstructionFaces() { - return myHasConstructionFaces; + return myHasConstructionFaces; } /////////////////////////////////////////////////////////////////////////////// @@ -2777,7 +2768,7 @@ bool SMDS_Mesh::hasConstructionFaces() /////////////////////////////////////////////////////////////////////////////// bool SMDS_Mesh::hasInverseElements() { - return myHasInverseElements; + return myHasInverseElements; } /////////////////////////////////////////////////////////////////////////////// @@ -2786,7 +2777,7 @@ bool SMDS_Mesh::hasInverseElements() /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::setConstructionEdges(bool b) { - myHasConstructionEdges=b; + myHasConstructionEdges=b; } /////////////////////////////////////////////////////////////////////////////// @@ -2795,7 +2786,7 @@ void SMDS_Mesh::setConstructionEdges(bool b) /////////////////////////////////////////////////////////////////////////////// void SMDS_Mesh::setConstructionFaces(bool b) { - myHasConstructionFaces=b; + myHasConstructionFaces=b; } /////////////////////////////////////////////////////////////////////////////// @@ -3338,14 +3329,14 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) { int elemId = elem->GetID(); - int vtkId = elem->getVtkId(); + int vtkId = elem->getVtkId(); SMDSAbs_ElementType aType = elem->GetType(); - SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem); - if (aType == SMDSAbs_Node) { + SMDS_MeshElement* todest = (SMDS_MeshElement*)(elem); + if ( aType == SMDSAbs_Node ) + { // only free node can be removed by this method const SMDS_MeshNode* n = static_cast(todest); - SMDS_ElemIteratorPtr itFe = n->GetInverseElementIterator(); - if (!itFe->more()) { // free node + if ( n->NbInverseElements() == 0 ) { // free node myNodes[elemId] = 0; myInfo.myNbNodes--; ((SMDS_MeshNode*) n)->SetPosition(SMDS_SpacePosition::originSpacePosition()); @@ -3353,7 +3344,9 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) myNodePool->destroy(static_cast(todest)); myNodeIDFactory->ReleaseID(elemId, vtkId); } - } else { + } + else + { if (hasConstructionEdges() || hasConstructionFaces()) // this methods is only for meshes without descendants return; @@ -3413,7 +3406,7 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem) */ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const { - // we should not imply on validity of *elem, so iterate on containers + // we should not rely on validity of *elem, so iterate on containers // of all types in the hope of finding somewhere there SMDS_NodeIteratorPtr itn = nodesIterator(); while (itn->more()) @@ -3433,7 +3426,7 @@ bool SMDS_Mesh::Contains (const SMDS_MeshElement* elem) const int SMDS_Mesh::MaxNodeID() const { - return myNodeMax; + return myNodeIDFactory->GetMaxID(); } //======================================================================= @@ -3443,7 +3436,7 @@ int SMDS_Mesh::MaxNodeID() const int SMDS_Mesh::MinNodeID() const { - return myNodeMin; + return myNodeIDFactory->GetMinID(); } //======================================================================= @@ -4621,44 +4614,6 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, return volvtk; } - -void SMDS_Mesh::updateNodeMinMax() -{ - myNodeMin = 0; - if (myNodes.size() == 0) - { - myNodeMax=0; - return; - } - while ( !myNodes[myNodeMin] && myNodeMin < (int)myNodes.size() ) - myNodeMin++; - myNodeMax=myNodes.size()-1; - while (!myNodes[myNodeMax] && (myNodeMin>=0)) - myNodeMin--; -} - -void SMDS_Mesh::incrementNodesCapacity(int nbNodes) -{ -// int val = myCellIdSmdsToVtk.size(); -// MESSAGE(" ------------------- resize myCellIdSmdsToVtk " << val << " --> " << val + nbNodes); -// myCellIdSmdsToVtk.resize(val + nbNodes, -1); // fill new elements with -1 - int val = myNodes.size(); - myNodes.resize(val +nbNodes, 0); -} - -void SMDS_Mesh::incrementCellsCapacity(int nbCells) -{ - int val = myCellIdVtkToSmds.size(); - myCellIdVtkToSmds.resize(val + nbCells, -1); // fill new elements with -1 - val = myCells.size(); - myNodes.resize(val +nbCells, 0); -} - -void SMDS_Mesh::adjustStructure() -{ - myGrid->GetPoints()->GetData()->SetNumberOfTuples(myNodeIDFactory->GetMaxID()); -} - void SMDS_Mesh::dumpGrid(string ficdump) { // vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New(); @@ -4691,7 +4646,7 @@ void SMDS_Mesh::dumpGrid(string ficdump) ficcon << endl; } ficcon << "-------------------------------- connectivity " << nbPoints << endl; - vtkCellLinks *links = myGrid->GetCellLinks(); + vtkCellLinks *links = myGrid->GetLinks(); for (int i=0; iGetNcells(i); @@ -4700,8 +4655,8 @@ void SMDS_Mesh::dumpGrid(string ficdump) for (int j=0; jmyCompactTime = this->myModifTime; } int SMDS_Mesh::fromVtkToSmds(int vtkid) @@ -4719,28 +4674,28 @@ int SMDS_Mesh::fromVtkToSmds(int vtkid) throw SALOME_Exception(LOCALIZED ("vtk id out of bounds")); } -void SMDS_Mesh::updateBoundingBox() -{ - xmin = 0; xmax = 0; - ymin = 0; ymax = 0; - zmin = 0; zmax = 0; - vtkPoints *points = myGrid->GetPoints(); - int myNodesSize = this->myNodes.size(); - for (int i = 0; i < myNodesSize; i++) - { - if (SMDS_MeshNode *n = myNodes[i]) - { - double coords[3]; - points->GetPoint(n->myVtkID, coords); - if (coords[0] < xmin) xmin = coords[0]; - else if (coords[0] > xmax) xmax = coords[0]; - if (coords[1] < ymin) ymin = coords[1]; - else if (coords[1] > ymax) ymax = coords[1]; - if (coords[2] < zmin) zmin = coords[2]; - else if (coords[2] > zmax) zmax = coords[2]; - } - } -} +// void SMDS_Mesh::updateBoundingBox() +// { +// xmin = 0; xmax = 0; +// ymin = 0; ymax = 0; +// zmin = 0; zmax = 0; +// vtkPoints *points = myGrid->GetPoints(); +// int myNodesSize = this->myNodes.size(); +// for (int i = 0; i < myNodesSize; i++) +// { +// if (SMDS_MeshNode *n = myNodes[i]) +// { +// double coords[3]; +// points->GetPoint(n->myVtkID, coords); +// if (coords[0] < xmin) xmin = coords[0]; +// else if (coords[0] > xmax) xmax = coords[0]; +// if (coords[1] < ymin) ymin = coords[1]; +// else if (coords[1] > ymax) ymax = coords[1]; +// if (coords[2] < zmin) zmin = coords[2]; +// else if (coords[2] > zmax) zmax = coords[2]; +// } +// } +// } double SMDS_Mesh::getMaxDim() { @@ -4762,17 +4717,12 @@ void SMDS_Mesh::Modified() } //! get last modification timeStamp -unsigned long SMDS_Mesh::GetMTime() const +vtkMTimeType SMDS_Mesh::GetMTime() const { return this->myModifTime; } bool SMDS_Mesh::isCompacted() { - if (this->myModifTime > this->myCompactTime) - { - this->myCompactTime = this->myModifTime; - return false; - } - return true; + return this->myCompactTime == this->myModifTime; } diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index c0dc013b4..814fe9bac 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -73,8 +73,8 @@ public: static std::vector _meshList; //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid - inline SMDS_UnstructuredGrid* getGrid() {return myGrid; } - inline int getMeshId() {return myMeshId; } + inline SMDS_UnstructuredGrid* getGrid() { return myGrid; } + inline int getMeshId() { return myMeshId; } virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const; virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const; @@ -705,6 +705,7 @@ public: const SMDS_MeshInfo& GetMeshInfo() const { return myInfo; } virtual int NbNodes() const; + virtual int NbElements() const; virtual int Nb0DElements() const; virtual int NbBalls() const; virtual int NbEdges() const; @@ -739,14 +740,10 @@ public: typedef std::vector SetOfNodes; typedef std::vector SetOfCells; - void updateNodeMinMax(); - void updateBoundingBox(); + //void updateBoundingBox(); double getMaxDim(); int fromVtkToSmds(int vtkid); - void incrementNodesCapacity(int nbNodes); - void incrementCellsCapacity(int nbCells); - void adjustStructure(); void dumpGrid(std::string ficdump="dumpGrid"); static int chunkSize; @@ -754,7 +751,7 @@ public: inline void setMyModified() { this->myModified = true; } void Modified(); - unsigned long GetMTime() const; + vtkMTimeType GetMTime() const; bool isCompacted(); protected: @@ -809,10 +806,10 @@ protected: int myMeshId; //! actual nodes coordinates, cells definition and reverse connectivity are stored in a vtkUnstructuredGrid - SMDS_UnstructuredGrid* myGrid; + SMDS_UnstructuredGrid* myGrid; //! Small objects like SMDS_MeshNode are allocated by chunks to limit memory costs of new - ObjectPool* myNodePool; + ObjectPool* myNodePool; //! Small objects like SMDS_VtkVolume are allocated by chunks to limit memory costs of new ObjectPool* myVolumePool; @@ -820,32 +817,27 @@ protected: ObjectPool* myEdgePool; ObjectPool* myBallPool; - //! SMDS_MeshNodes refer to vtk nodes (vtk id = index in myNodes),store reference to this mesh, and sub-shape - SetOfNodes myNodes; - - //! SMDS_MeshCells refer to vtk cells (vtk id != index in myCells),store reference to this mesh, and sub-shape - SetOfCells myCells; + //! SMDS_MeshNodes refer to vtk nodes (vtk id != index in myNodes),store reference to this mesh, and sub-shape + SetOfNodes myNodes; + SetOfCells myCells; //! a buffer to speed up elements addition by excluding some memory allocation - std::vector myNodeIds; + std::vector myNodeIds; //! for cells only: index = ID in vtkUnstructuredGrid, value = ID for SMDS users - std::vector myCellIdVtkToSmds; + std::vector myCellIdVtkToSmds; - SMDS_Mesh * myParent; - std::list myChildren; - SMDS_MeshNodeIDFactory *myNodeIDFactory; - SMDS_MeshElementIDFactory *myElementIDFactory; - SMDS_MeshInfo myInfo; + SMDS_Mesh * myParent; + std::list myChildren; + SMDS_MeshNodeIDFactory * myNodeIDFactory; + SMDS_MeshElementIDFactory * myElementIDFactory; + SMDS_MeshInfo myInfo; //! any add, remove or change of node or cell bool myModified; //! use a counter to keep track of modifications unsigned long myModifTime, myCompactTime; - int myNodeMin; - int myNodeMax; - bool myHasConstructionEdges; bool myHasConstructionFaces; bool myHasInverseElements; diff --git a/src/SMDS/SMDS_MeshCell.hxx b/src/SMDS/SMDS_MeshCell.hxx index 803f48622..413b1265a 100644 --- a/src/SMDS/SMDS_MeshCell.hxx +++ b/src/SMDS/SMDS_MeshCell.hxx @@ -33,7 +33,7 @@ public: virtual ~SMDS_MeshCell(); virtual bool ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes)= 0; - virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) {return true; } + virtual bool vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) { return true; } static VTKCellType toVtkType (SMDSAbs_EntityType vtkType); static SMDSAbs_EntityType toSmdsType(VTKCellType vtkType); diff --git a/src/SMDS/SMDS_MeshElement.cxx b/src/SMDS/SMDS_MeshElement.cxx index 3cf56f80f..7150b6c59 100644 --- a/src/SMDS/SMDS_MeshElement.cxx +++ b/src/SMDS/SMDS_MeshElement.cxx @@ -55,13 +55,13 @@ void SMDS_MeshElement::init(int id, ShortType meshId, LongType shapeId ) void SMDS_MeshElement::Print(ostream & OS) const { - OS << "dump of mesh element" << endl; + OS << "dump of mesh element" << endl; } ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) { - ME->Print(OS); - return OS; + ME->Print(OS); + return OS; } /////////////////////////////////////////////////////////////////////////////// @@ -70,7 +70,7 @@ ostream & operator <<(ostream & OS, const SMDS_MeshElement * ME) /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const { - return elementsIterator(SMDSAbs_Node); + return elementsIterator(SMDSAbs_Node); } /////////////////////////////////////////////////////////////////////////////// @@ -79,7 +79,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::nodesIterator() const /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const { - return elementsIterator(SMDSAbs_Edge); + return elementsIterator(SMDSAbs_Edge); } /////////////////////////////////////////////////////////////////////////////// @@ -88,7 +88,7 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::edgesIterator() const /////////////////////////////////////////////////////////////////////////////// SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const { - return elementsIterator(SMDSAbs_Face); + return elementsIterator(SMDSAbs_Face); } /////////////////////////////////////////////////////////////////////////////// @@ -96,14 +96,14 @@ SMDS_ElemIteratorPtr SMDS_MeshElement::facesIterator() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbNodes() const { - int nbnodes=0; - SMDS_ElemIteratorPtr it=nodesIterator(); - while(it->more()) - { - it->next(); - nbnodes++; - } - return nbnodes; + int nbnodes=0; + SMDS_ElemIteratorPtr it=nodesIterator(); + while(it->more()) + { + it->next(); + nbnodes++; + } + return nbnodes; } /////////////////////////////////////////////////////////////////////////////// @@ -111,14 +111,14 @@ int SMDS_MeshElement::NbNodes() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbEdges() const { - int nbedges=0; - SMDS_ElemIteratorPtr it=edgesIterator(); - while(it->more()) - { - it->next(); - nbedges++; - } - return nbedges; + int nbedges=0; + SMDS_ElemIteratorPtr it=edgesIterator(); + while(it->more()) + { + it->next(); + nbedges++; + } + return nbedges; } /////////////////////////////////////////////////////////////////////////////// @@ -126,14 +126,14 @@ int SMDS_MeshElement::NbEdges() const /////////////////////////////////////////////////////////////////////////////// int SMDS_MeshElement::NbFaces() const { - int nbfaces=0; - SMDS_ElemIteratorPtr it=facesIterator(); - while(it->more()) - { - it->next(); - nbfaces++; - } - return nbfaces; + int nbfaces=0; + SMDS_ElemIteratorPtr it=facesIterator(); + while(it->more()) + { + it->next(); + nbfaces++; + } + return nbfaces; } /////////////////////////////////////////////////////////////////////////////// @@ -145,7 +145,7 @@ class SMDS_MeshElement_MyIterator:public SMDS_ElemIterator { const SMDS_MeshElement * myElement; bool myMore; - public: +public: SMDS_MeshElement_MyIterator(const SMDS_MeshElement * element): myElement(element),myMore(true) {} @@ -228,28 +228,28 @@ SMDS_NodeIteratorPtr SMDS_MeshElement::nodeIterator() const bool operator<(const SMDS_MeshElement& e1, const SMDS_MeshElement& e2) { - if(e1.GetType()!=e2.GetType()) return false; - switch(e1.GetType()) - { - case SMDSAbs_Node: - return static_cast(e1) < - static_cast(e2); - - case SMDSAbs_Edge: - return static_cast(e1) < - static_cast(e2); - - case SMDSAbs_Face: - return static_cast(e1) < - static_cast(e2); - - case SMDSAbs_Volume: - return static_cast(e1) < - static_cast(e2); - - default : MESSAGE("Internal Error"); - } - return false; + if(e1.GetType()!=e2.GetType()) return false; + switch(e1.GetType()) + { + case SMDSAbs_Node: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Edge: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Face: + return static_cast(e1) < + static_cast(e2); + + case SMDSAbs_Volume: + return static_cast(e1) < + static_cast(e2); + + default : MESSAGE("Internal Error"); + } + return false; } bool SMDS_MeshElement::IsValidIndex(const int ind) const @@ -291,11 +291,11 @@ int SMDS_MeshElement::NbCornerNodes() const } //================================================================================ - /*! - * \brief Check if a node belongs to the element - * \param node - the node to check - * \retval int - node index within the element, -1 if not found - */ +/*! + * \brief Check if a node belongs to the element + * \param node - the node to check + * \retval int - node index within the element, -1 if not found + */ //================================================================================ int SMDS_MeshElement::GetNodeIndex( const SMDS_MeshNode* node ) const diff --git a/src/SMDS/SMDS_MeshElement.hxx b/src/SMDS/SMDS_MeshElement.hxx index ebbfd9161..d114c02da 100644 --- a/src/SMDS/SMDS_MeshElement.hxx +++ b/src/SMDS/SMDS_MeshElement.hxx @@ -82,13 +82,13 @@ public: inline int GetID() const { return myID; } ///Return the type of the current element - virtual SMDSAbs_ElementType GetType() const = 0; - virtual SMDSAbs_EntityType GetEntityType() const = 0; + virtual SMDSAbs_ElementType GetType() const = 0; + virtual SMDSAbs_EntityType GetEntityType() const = 0; virtual SMDSAbs_GeometryType GetGeomType() const = 0; - virtual vtkIdType GetVtkType() const = 0; + virtual vtkIdType GetVtkType() const = 0; + virtual bool IsPoly() const { return false; } virtual bool IsQuadratic() const; - virtual bool IsMediumNode(const SMDS_MeshNode* node) const; virtual int NbCornerNodes() const; @@ -143,10 +143,14 @@ public: */ virtual int GetNodeIndex( const SMDS_MeshNode* node ) const; - inline ShortType getMeshId() const { return myMeshId; } - inline LongType getshapeId() const { return myShapeId; } - inline int getIdInShape() const { return myIdInShape; } - inline int getVtkId() const { return myVtkID; } + inline ShortType getMeshId() const { return myMeshId; } + inline LongType getshapeId() const { return myShapeId >> BITS_SHIFT; } + inline int getIdInShape() const { return myIdInShape; } + inline int getVtkId() const { return myVtkID; } + + // mark this element; to be used in algos + inline void setIsMarked( bool is ) const; + inline bool isMarked() const; /*! * \brief Filters of elements, to be used with SMDS_SetIterator @@ -180,10 +184,10 @@ public: }; protected: - inline void setId(int id) {myID = id; } - inline void setShapeId(LongType shapeId) {myShapeId = shapeId; } - inline void setIdInShape(int id) { myIdInShape = id; } - inline void setVtkId(int vtkId) { myVtkID = vtkId; } + inline void setId(int id) { myID = id; } + inline void setVtkId(int vtkId) { myVtkID = vtkId; } + inline void setIdInShape(int id) { myIdInShape = id; } + inline void setShapeId(LongType shapeId) { myShapeId = ( shapeId << BITS_SHIFT ) | ( myShapeId & BIT_IS_MARKED ); } SMDS_MeshElement(int ID=-1); SMDS_MeshElement(int id, ShortType meshId, LongType shapeId = 0); virtual void init(int id = -1, ShortType meshId = -1, LongType shapeId = 0); @@ -195,12 +199,25 @@ protected: int myVtkID; //! SMDS_Mesh identification in SMESH ShortType myMeshId; - //! SubShape and SubMesh identification in SMESHDS + //! SubShape and SubMesh identification in SMESHDS; one bit is used to mark the element LongType myShapeId; //! Element index in SMESHDS_SubMesh vector int myIdInShape; + + enum Bits { // use the 1st right bit of myShapeId to set/unset a mark + BIT_IS_MARKED = 1, + BITS_SHIFT = 1 + }; }; +inline void SMDS_MeshElement::setIsMarked( bool is ) const +{ + const_cast< SMDS_MeshElement* >( this )->myShapeId = ( myShapeId & ~BIT_IS_MARKED ) | is; +} +inline bool SMDS_MeshElement::isMarked() const +{ + return myShapeId & BIT_IS_MARKED; +} // ============================================================ /*! diff --git a/src/SMDS/SMDS_MeshElementIDFactory.cxx b/src/SMDS/SMDS_MeshElementIDFactory.cxx index 710be521b..a029b101e 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.cxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.cxx @@ -53,33 +53,29 @@ SMDS_MeshElementIDFactory::SMDS_MeshElementIDFactory(): int SMDS_MeshElementIDFactory::SetInVtkGrid(SMDS_MeshElement * elem) { - // --- retrieve nodes ID + // --- retrieve nodes ID SMDS_MeshCell *cell = dynamic_cast(elem); assert(cell); - vector nodeIds; + vector nodeIds( elem->NbNodes() ); SMDS_ElemIteratorPtr it = elem->nodesIterator(); - while(it->more()) + for( int i = 0; it->more(); ++i ) { - int nodeId = (static_cast(it->next()))->getVtkId(); - MESSAGE(" node in cell " << cell->getVtkId() << " : " << nodeId) - nodeIds.push_back(nodeId); + int nodeId = (static_cast(it->next()))->getVtkId(); + nodeIds[i] = nodeId; } // --- insert cell in vtkUnstructuredGrid - vtkUnstructuredGrid * grid = myMesh->getGrid(); - //int locType = elem->GetType(); - int typ = VTK_VERTEX;//GetVtkCellType(locType); - int cellId = grid->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]); - cell->setVtkId(cellId); - //MESSAGE("SMDS_MeshElementIDFactory::SetInVtkGrid " << cellId); + int typ = VTK_VERTEX; + int cellId = myMesh->getGrid()->InsertNextLinkedCell(typ, nodeIds.size(), &nodeIds[0]); + cell->setVtkId(cellId); return cellId; } //======================================================================= //function : BindID -//purpose : +//purpose : //======================================================================= bool SMDS_MeshElementIDFactory::BindID(int ID, SMDS_MeshElement * elem) @@ -122,17 +118,16 @@ int SMDS_MeshElementIDFactory::GetFreeID() void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId) { if (ID < 1) // TODO check case ID == O - { - MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID); - return; - } - //MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID smdsId vtkId " << ID << " " << vtkId); + { + MESSAGE("~~~~~~~~~~~~~~ SMDS_MeshElementIDFactory::ReleaseID ID = " << ID); + return; + } if (vtkId >= 0) - { - assert(vtkId < (int)myMesh->myCellIdVtkToSmds.size()); - myMesh->myCellIdVtkToSmds[vtkId] = -1; - myMesh->setMyModified(); - } + { + assert(vtkId < (int)myMesh->myCellIdVtkToSmds.size()); + myMesh->myCellIdVtkToSmds[vtkId] = -1; + myMesh->setMyModified(); + } SMDS_MeshIDFactory::ReleaseID(ID); if (ID == myMax) myMax = 0; @@ -142,7 +137,7 @@ void SMDS_MeshElementIDFactory::ReleaseID(int ID, int vtkId) //======================================================================= //function : updateMinMax -//purpose : +//purpose : //======================================================================= void SMDS_MeshElementIDFactory::updateMinMax() const @@ -150,16 +145,16 @@ void SMDS_MeshElementIDFactory::updateMinMax() const myMin = INT_MAX; myMax = 0; for (size_t i = 0; i < myMesh->myCells.size(); i++) + { + if (myMesh->myCells[i]) { - if (myMesh->myCells[i]) - { - int id = myMesh->myCells[i]->GetID(); - if (id > myMax) - myMax = id; - if (id < myMin) - myMin = id; - } + int id = myMesh->myCells[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; } + } if (myMin == INT_MAX) myMin = 0; } @@ -171,12 +166,11 @@ void SMDS_MeshElementIDFactory::updateMinMax() const SMDS_ElemIteratorPtr SMDS_MeshElementIDFactory::elementsIterator() const { - return myMesh->elementsIterator(SMDSAbs_All); + return myMesh->elementsIterator(SMDSAbs_All); } void SMDS_MeshElementIDFactory::Clear() { - //myMesh->myCellIdSmdsToVtk.clear(); myMesh->myCellIdVtkToSmds.clear(); myMin = myMax = 0; SMDS_MeshIDFactory::Clear(); diff --git a/src/SMDS/SMDS_MeshElementIDFactory.hxx b/src/SMDS/SMDS_MeshElementIDFactory.hxx index 16f8ae807..4bd6c638d 100644 --- a/src/SMDS/SMDS_MeshElementIDFactory.hxx +++ b/src/SMDS/SMDS_MeshElementIDFactory.hxx @@ -51,13 +51,12 @@ public: virtual void Clear(); protected: - void updateMinMax() const; + virtual void updateMinMax() const; void updateMinMax(int id) const { if (id > myMax) myMax = id; if (id < myMin) myMin = id; } - }; #endif diff --git a/src/SMDS/SMDS_MeshIDFactory.cxx b/src/SMDS/SMDS_MeshIDFactory.cxx index 74e5e401d..cc765d866 100644 --- a/src/SMDS/SMDS_MeshIDFactory.cxx +++ b/src/SMDS/SMDS_MeshIDFactory.cxx @@ -50,8 +50,8 @@ int SMDS_MeshIDFactory::GetFreeID() else { set::iterator i = myPoolOfID.begin(); - newid = *i;//myPoolOfID.top(); - myPoolOfID.erase( i );//myPoolOfID.pop(); + newid = *i; + myPoolOfID.erase( i ); } return newid; } @@ -77,11 +77,13 @@ void SMDS_MeshIDFactory::ReleaseID(int ID, int vtkId) while ( i != myPoolOfID.begin() && myMaxID == *i ) { --myMaxID; --i; } - if ( myMaxID == *i ) + if ( myMaxID == *i ) { --myMaxID; // begin of myPoolOfID reached - else - ++i; - myPoolOfID.erase( i, myPoolOfID.end() ); + myPoolOfID.clear(); + } + else if ( myMaxID < ID-1 ) { + myPoolOfID.erase( ++i, myPoolOfID.end() ); + } } } } diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index 5499f8b7d..53054f8e4 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -62,16 +62,13 @@ SMDS_MeshNode::SMDS_MeshNode(int id, int meshId, int shapeId, double x, double y void SMDS_MeshNode::init(int id, int meshId, int shapeId, double x, double y, double z) { SMDS_MeshElement::init(id, meshId, shapeId); - myVtkID = id -1; + myVtkID = id - 1; assert(myVtkID >= 0); - //MESSAGE("Node " << myID << " " << myVtkID << " (" << x << ", " << y << ", " << z << ")"); - SMDS_Mesh* mesh = SMDS_Mesh::_meshList[myMeshId]; - SMDS_UnstructuredGrid * grid = mesh->getGrid(); + SMDS_UnstructuredGrid * grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkPoints *points = grid->GetPoints(); points->InsertPoint(myVtkID, x, y, z); - SMDS_CellLinks *cellLinks = dynamic_cast(grid->GetCellLinks()); - assert(cellLinks); - cellLinks->ResizeForPoint( myVtkID ); + if ( grid->HasLinks() ) + grid->GetLinks()->ResizeForPoint( myVtkID ); } SMDS_MeshNode::~SMDS_MeshNode() @@ -86,12 +83,10 @@ SMDS_MeshNode::~SMDS_MeshNode() //purpose : //======================================================================= -void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) +void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem) { - //MESSAGE("RemoveInverseElement " << myID << " " << parent->GetID()); - const SMDS_MeshCell* cell = dynamic_cast(parent); - MYASSERT(cell); - SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, cell->getVtkId()); + if ( SMDS_Mesh::_meshList[myMeshId]->getGrid()->HasLinks() ) + SMDS_Mesh::_meshList[myMeshId]->getGrid()->RemoveReferenceToCell(myVtkID, elem->getVtkId()); } //======================================================================= @@ -149,22 +144,29 @@ public: SMDS_MeshNode_MyInvIterator(SMDS_Mesh *mesh, vtkIdType* cells, int ncells, SMDSAbs_ElementType type) : myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) { - cellList.reserve( ncells ); - if (type == SMDSAbs_All) - cellList.assign( cells, cells + ncells ); - else - for (int i = 0; i < ncells; i++) + if ( ncells ) + { + cellList.reserve( ncells ); + if (type == SMDSAbs_All) + { + cellList.assign( cells, cells + ncells ); + } + else { - int vtkId = cells[i]; - int smdsId = myMesh->fromVtkToSmds(vtkId); - const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); - if (elem->GetType() == type) + for (int i = 0; i < ncells; i++) { - cellList.push_back(vtkId); + int vtkId = cells[i]; + int smdsId = myMesh->fromVtkToSmds(vtkId); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (elem->GetType() == type) + { + cellList.push_back(vtkId); + } } } - myCells = cellList.empty() ? 0 : &cellList[0]; - myNcells = cellList.size(); + myCells = cellList.empty() ? 0 : &cellList[0]; + myNcells = cellList.size(); + } } bool more() @@ -189,68 +191,23 @@ public: SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const { - vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); - return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); -} - -// Same as GetInverseElementIterator but the create iterator only return -// wanted type elements. -class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator -{ -private: - SMDS_Mesh* myMesh; - vtkIdType* myCells; - int myNcells; - SMDSAbs_ElementType myType; - int iter; - vector myFiltCells; - -public: - SMDS_MeshNode_MyIterator(SMDS_Mesh *mesh, - vtkIdType* cells, - int ncells, - SMDSAbs_ElementType type): - myMesh(mesh), myCells(cells), myNcells(ncells), myType(type), iter(0) - { - //MESSAGE("myNcells " << myNcells); - for (; iterfromVtkToSmds(vtkId); - //MESSAGE("vtkId " << vtkId << " smdsId " << smdsId); - const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); - if (elem->GetType() == type) - myFiltCells.push_back((SMDS_MeshElement*)elem); - } - myNcells = myFiltCells.size(); - //MESSAGE("myNcells " << myNcells); - iter = 0; - //MESSAGE("SMDS_MeshNode_MyIterator (filter) " << ncells << " " << myNcells); - } - - bool more() + if ( SMDS_Mesh::_meshList[myMeshId]->NbElements() > 0 ) // avoid building links { - return (iter< myNcells); + vtkCellLinks::Link& l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetLinks()->GetLink(myVtkID); + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); } - - const SMDS_MeshElement* next() + else { - const SMDS_MeshElement* elem = myFiltCells[iter]; - iter++; - return elem; + return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], 0, 0, type)); } -}; +} -SMDS_ElemIteratorPtr SMDS_MeshNode:: -elementsIterator(SMDSAbs_ElementType type) const +SMDS_ElemIteratorPtr SMDS_MeshNode::elementsIterator(SMDSAbs_ElementType type) const { - if(type==SMDSAbs_Node) - return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); + if ( type == SMDSAbs_Node ) + return SMDS_MeshElement::elementsIterator( SMDSAbs_Node ); else - { - vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); - return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); - } + return GetInverseElementIterator( type ); } int SMDS_MeshNode::NbNodes() const @@ -285,12 +242,14 @@ double SMDS_MeshNode::Z() const /*! * \brief thread safe getting coords */ +//================================================================================ + void SMDS_MeshNode::GetXYZ(double xyz[3]) const { return SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetPoint(myVtkID,xyz); } -//* resize the vtkPoints structure every SMDS_Mesh::chunkSize points +//================================================================================ void SMDS_MeshNode::setXYZ(double x, double y, double z) { SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; @@ -316,12 +275,13 @@ vtkIdType SMDS_MeshNode::GetVtkType() const //======================================================================= void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) { - const SMDS_MeshCell *cell = dynamic_cast (ME); - assert(cell); SMDS_UnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); - vtkCellLinks *Links = grid->GetCellLinks(); - Links->ResizeCellList(myVtkID, 1); - Links->AddCellReference(cell->getVtkId(), myVtkID); + if ( grid->HasLinks() ) + { + vtkCellLinks *Links = grid->GetLinks(); + Links->ResizeCellList(myVtkID, 1); + Links->AddCellReference(ME->getVtkId(), myVtkID); + } } //======================================================================= @@ -333,12 +293,6 @@ void SMDS_MeshNode::ClearInverseElements() SMDS_Mesh::_meshList[myMeshId]->getGrid()->ResizeCellList(myVtkID, 0); } -bool SMDS_MeshNode::emptyInverseElements() -{ - vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); - return (l.ncells == 0); -} - //================================================================================ /*! * \brief Count inverse elements of given type @@ -347,35 +301,20 @@ bool SMDS_MeshNode::emptyInverseElements() int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const { - vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); - - if ( type == SMDSAbs_All ) - return l.ncells; - int nb = 0; - SMDS_Mesh *mesh = SMDS_Mesh::_meshList[myMeshId]; - for (int i=0; iNbElements() > 0 ) // avoid building links { - const SMDS_MeshElement* elem = mesh->FindElement(mesh->fromVtkToSmds(l.cells[i])); - if (elem->GetType() == type) - nb++; - } - return nb; -} + vtkCellLinks::Link& l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetLinks()->GetLink(myVtkID); -/////////////////////////////////////////////////////////////////////////////// -/// To be used with STL set -/////////////////////////////////////////////////////////////////////////////// -bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2) -{ - return e1.getVtkId()FindElement( mesh->fromVtkToSmds( l.cells[i] )); + nb += ( elem->GetType() == type ); } - else return false;*/ + } + return nb; } - diff --git a/src/SMDS/SMDS_MeshNode.hxx b/src/SMDS/SMDS_MeshNode.hxx index a61e673f3..43dc9c7f2 100644 --- a/src/SMDS/SMDS_MeshNode.hxx +++ b/src/SMDS/SMDS_MeshNode.hxx @@ -69,7 +69,6 @@ protected: void AddInverseElement(const SMDS_MeshElement * ME); void RemoveInverseElement(const SMDS_MeshElement * parent); void ClearInverseElements(); - bool emptyInverseElements(); SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type) const; diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.cxx b/src/SMDS/SMDS_MeshNodeIDFactory.cxx index bfbd2bf7d..64b7baed1 100644 --- a/src/SMDS/SMDS_MeshNodeIDFactory.cxx +++ b/src/SMDS/SMDS_MeshNodeIDFactory.cxx @@ -126,9 +126,21 @@ int SMDS_MeshNodeIDFactory::GetMinID() const void SMDS_MeshNodeIDFactory::updateMinMax() const { - myMesh->updateNodeMinMax(); - myMin = myMesh->MinNodeID(); - myMax = myMesh->MaxNodeID(); + myMin = INT_MAX; + myMax = 0; + for (size_t i = 0; i < myMesh->myNodes.size(); i++) + { + if (myMesh->myNodes[i]) + { + int id = myMesh->myNodes[i]->GetID(); + if (id > myMax) + myMax = id; + if (id < myMin) + myMin = id; + } + } + if (myMin == INT_MAX) + myMin = 0; } SMDS_ElemIteratorPtr SMDS_MeshNodeIDFactory::elementsIterator() const diff --git a/src/SMDS/SMDS_MeshNodeIDFactory.hxx b/src/SMDS/SMDS_MeshNodeIDFactory.hxx index 52372a851..80c12716b 100644 --- a/src/SMDS/SMDS_MeshNodeIDFactory.hxx +++ b/src/SMDS/SMDS_MeshNodeIDFactory.hxx @@ -49,7 +49,7 @@ public: virtual void emptyPool(int maxId); protected: - void updateMinMax() const; + virtual void updateMinMax() const; void updateMinMax(int id) const { if (id > myMax) diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index b3f743a4f..bf9df36cf 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -53,6 +53,51 @@ void SMDS_CellLinks::ResizeForPoint(vtkIdType vtkID) } } +void SMDS_CellLinks::BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity, vtkUnsignedCharArray* types) +{ + // build links taking into account removed cells + + vtkIdType numPts = data->GetNumberOfPoints(); + vtkIdType j, cellId = 0; + unsigned short *linkLoc; + vtkIdType npts=0; + vtkIdType *pts=0; + vtkIdType loc = Connectivity->GetTraversalLocation(); + + // traverse data to determine number of uses of each point + cellId = 0; + for (Connectivity->InitTraversal(); + Connectivity->GetNextCell(npts,pts); cellId++) + { + if ( types->GetValue( cellId ) != VTK_EMPTY_CELL ) + for (j=0; j < npts; j++) + { + this->IncrementLinkCount(pts[j]); + } + } + + // now allocate storage for the links + this->AllocateLinks(numPts); + this->MaxId = numPts - 1; + + // fill out lists with references to cells + linkLoc = new unsigned short[numPts]; + memset(linkLoc, 0, numPts*sizeof(unsigned short)); + + cellId = 0; + for (Connectivity->InitTraversal(); + Connectivity->GetNextCell(npts,pts); cellId++) + { + if ( types->GetValue( cellId ) != VTK_EMPTY_CELL ) + for (j=0; j < npts; j++) + { + this->InsertCellReference(pts[j], (linkLoc[pts[j]])++, cellId); + } + } + delete [] linkLoc; + Connectivity->SetTraversalLocation(loc); +} + SMDS_CellLinks::SMDS_CellLinks() : vtkCellLinks() { @@ -80,33 +125,26 @@ SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid() { } -unsigned long SMDS_UnstructuredGrid::GetMTime() +vtkMTimeType SMDS_UnstructuredGrid::GetMTime() { - unsigned long mtime = vtkUnstructuredGrid::GetMTime(); + vtkMTimeType mtime = vtkUnstructuredGrid::GetMTime(); return mtime; } -// OUV_PORTING_VTK6: seems to be useless -/* -void SMDS_UnstructuredGrid::Update() -{ - return vtkUnstructuredGrid::Update(); -} -void SMDS_UnstructuredGrid::UpdateInformation() -{ - return vtkUnstructuredGrid::UpdateInformation(); -} -*/ vtkPoints* SMDS_UnstructuredGrid::GetPoints() { // TODO erreur incomprehensible de la macro vtk GetPoints apparue avec la version paraview de fin aout 2010 return this->Points; } -//#ifdef VTK_HAVE_POLYHEDRON int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts) { - if (type != VTK_POLYHEDRON) + if ( !this->Links ) // don't create Links until they are needed + { + return this->InsertNextCell(type, npts, pts); + } + + if ( type != VTK_POLYHEDRON ) return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts); // --- type = VTK_POLYHEDRON @@ -117,26 +155,25 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p int nbfaces = npts; int i = 0; for (int nf = 0; nf < nbfaces; nf++) + { + int nbnodes = pts[i]; + i++; + for (int k = 0; k < nbnodes; k++) { - int nbnodes = pts[i]; + setOfNodes.insert(pts[i]); i++; - for (int k = 0; k < nbnodes; k++) - { - setOfNodes.insert(pts[i]); - i++; - } } + } set::iterator it = setOfNodes.begin(); for (; it != setOfNodes.end(); ++it) - { - this->Links->ResizeCellList(*it, 1); - this->Links->AddCellReference(cellid, *it); - } + { + this->Links->ResizeCellList(*it, 1); + this->Links->AddCellReference(cellid, *it); + } return cellid; } -//#endif void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) { @@ -146,40 +183,58 @@ void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh) void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int newNodeSize, std::vector& idCellsOldToNew, int newCellSize) { - //MESSAGE("------------------------- compactGrid " << newNodeSize << " " << newCellSize);//CHRONO(1); int alreadyCopied = 0; + this->DeleteLinks(); + // --- if newNodeSize, create a new compacted vtkPoints - vtkPoints *newPoints = vtkPoints::New(); - newPoints->SetDataType(VTK_DOUBLE); - newPoints->SetNumberOfPoints(newNodeSize); - if (newNodeSize) - { - // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion" - // using double type for storing coordinates of nodes instead float. - int oldNodeSize = idNodesOldToNew.size(); + if ( newNodeSize ) + { + // rnv: to fix bug "21125: EDF 1233 SMESH: Degradation of precision in a test case for quadratic conversion" + // using double type for storing coordinates of nodes instead float. + vtkPoints *newPoints = vtkPoints::New(); + newPoints->SetDataType(VTK_DOUBLE); + newPoints->SetNumberOfPoints(newNodeSize); - int i = 0; - while ( i < oldNodeSize ) - { - // skip a hole if any - while ( i < oldNodeSize && idNodesOldToNew[i] < 0 ) - ++i; - int startBloc = i; - // look for a block end - while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 ) - ++i; - int endBloc = i; - copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); - } - newPoints->Squeeze(); + int oldNodeSize = idNodesOldToNew.size(); + + int i = 0; + while ( i < oldNodeSize ) + { + // skip a hole if any + while ( i < oldNodeSize && idNodesOldToNew[i] < 0 ) + ++i; + int startBloc = i; + // look for a block end + while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 ) + ++i; + int endBloc = i; + copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc); } + this->SetPoints(newPoints); + newPoints->Delete(); + } + this->Points->Squeeze(); // --- create new compacted Connectivity, Locations and Types int oldCellSize = this->Types->GetNumberOfTuples(); + if ( !newNodeSize && oldCellSize == newCellSize ) // no holes in elements + { + this->Connectivity->Squeeze(); + this->Locations->Squeeze(); + this->Types->Squeeze(); + if ( this->FaceLocations ) + { + this->FaceLocations->Squeeze(); + this->Faces->Squeeze(); + } + for ( int i = 0; i < oldCellSize; ++i ) + idCellsOldToNew[i] = i; + return; + } vtkCellArray *newConnectivity = vtkCellArray::New(); newConnectivity->Initialize(); int oldCellDataSize = this->Connectivity->GetData()->GetSize(); @@ -218,11 +273,6 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n } newConnectivity->Squeeze(); - if (1/*newNodeSize*/) - { - this->SetPoints(newPoints); - } - if (vtkDoubleArray* diameters = vtkDoubleArray::SafeDownCast( vtkDataSet::CellData->GetScalars() )) // Balls { @@ -282,11 +332,9 @@ void SMDS_UnstructuredGrid::compactGrid(std::vector& idNodesOldToNew, int n this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces); } - newPoints->Delete(); newTypes->Delete(); newLocations->Delete(); newConnectivity->Delete(); - this->BuildLinks(); } void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, @@ -299,11 +347,11 @@ void SMDS_UnstructuredGrid::copyNodes(vtkPoints * newPoints, void *source = this->Points->GetVoidPointer(3 * start); int nbPoints = end - start; if (nbPoints > 0) - { - memcpy(target, source, 3 * sizeof(double) * nbPoints); - for (int j = start; j < end; j++) - idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId - } + { + memcpy(target, source, 3 * sizeof(double) * nbPoints); + for (int j = start; j < end; j++) + idNodesOldToNew[j] = alreadyCopied++; // old vtkId --> new vtkId + } } void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, @@ -317,24 +365,24 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, int end) { for (int j = start; j < end; j++) + { + newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); + idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId + vtkIdType oldLoc = this->Locations->GetValue(j); + vtkIdType nbpts; + vtkIdType *oldPtsCell = 0; + this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); + assert(nbpts < NBMAXNODESINCELL); + for (int l = 0; l < nbpts; l++) { - newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); - idCellsOldToNew[j] = alreadyCopied; // old vtkId --> new vtkId - vtkIdType oldLoc = this->Locations->GetValue(j); - vtkIdType nbpts; - vtkIdType *oldPtsCell = 0; - this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell); - assert(nbpts < NBMAXNODESINCELL); - for (int l = 0; l < nbpts; l++) - { - int oldval = oldPtsCell[l]; - pointsCell[l] = idNodesOldToNew[oldval]; - } - /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); - int newLoc = newConnectivity->GetInsertLocation(nbpts); - newLocations->SetValue(alreadyCopied, newLoc); - alreadyCopied++; + int oldval = oldPtsCell[l]; + pointsCell[l] = idNodesOldToNew[oldval]; } + /*int newcnt = */newConnectivity->InsertNextCell(nbpts, pointsCell); + int newLoc = newConnectivity->GetInsertLocation(nbpts); + newLocations->SetValue(alreadyCopied, newLoc); + alreadyCopied++; + } } int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId) @@ -974,17 +1022,34 @@ void SMDS_UnstructuredGrid::BuildLinks() { // Remove the old links if they are already built if (this->Links) - { + { this->Links->UnRegister(this); - } + } - this->Links = SMDS_CellLinks::New(); + SMDS_CellLinks* links; + this->Links = links = SMDS_CellLinks::New(); this->Links->Allocate(this->GetNumberOfPoints()); this->Links->Register(this); - this->Links->BuildLinks(this, this->Connectivity); + links->BuildLinks(this, this->Connectivity,this->GetCellTypesArray() ); this->Links->Delete(); } +void SMDS_UnstructuredGrid::DeleteLinks() +{ + // Remove the old links if they are already built + if (this->Links) + { + this->Links->UnRegister(this); + this->Links = NULL; + } +} +SMDS_CellLinks* SMDS_UnstructuredGrid::GetLinks() +{ + if ( !this->Links ) + BuildLinks(); + return static_cast< SMDS_CellLinks* >( this->Links ); +} + /*! Create a volume (prism or hexahedron) by duplication of a face. * Designed for use in creation of flat elements separating volume domains. * A face separating two domains is shared by two volume cells. diff --git a/src/SMDS/SMDS_UnstructuredGrid.hxx b/src/SMDS/SMDS_UnstructuredGrid.hxx index f2ad6bd57..5936e9759 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.hxx +++ b/src/SMDS/SMDS_UnstructuredGrid.hxx @@ -45,6 +45,14 @@ // allow very huge polyhedrons in tests #define NBMAXNODESINCELL 5000 +// Keep compatibility with paraview 5.0.1 on Linux +#ifndef WIN32 + #ifndef VTK_HAS_MTIME_TYPE + #define VTK_HAS_MTIME_TYPE + typedef unsigned long int vtkMTimeType; + #endif +#endif + class SMDS_Downward; class SMDS_Mesh; class SMDS_MeshCell; @@ -54,6 +62,7 @@ class SMDS_EXPORT SMDS_CellLinks: public vtkCellLinks { public: void ResizeForPoint(vtkIdType vtkID); + void BuildLinks(vtkDataSet *data, vtkCellArray *Connectivity, vtkUnsignedCharArray* types); static SMDS_CellLinks* New(); protected: SMDS_CellLinks(); @@ -68,15 +77,10 @@ public: int newNodeSize, std::vector& idCellsOldToNew, int newCellSize); - virtual unsigned long GetMTime(); - // OUV_PORTING_VTK6: seems to be useless - //virtual void Update(); - //virtual void UpdateInformation(); + virtual vtkMTimeType GetMTime(); virtual vtkPoints *GetPoints(); - //#ifdef VTK_HAVE_POLYHEDRON int InsertNextLinkedCell(int type, int npts, vtkIdType *pts); - //#endif int CellIdToDownId(int vtkCellId); void setCellIdToDownId(int vtkCellId, int downId); @@ -88,15 +92,15 @@ public: void GetNodeIds(std::set& nodeSet, int downId, unsigned char downType); void ModifyCellNodes(int vtkVolId, std::map localClonedNodeIds); int getOrderedNodesOfFace(int vtkVolId, int& dim, std::vector& orderedNodes); - void BuildLinks(); SMDS_MeshCell* extrudeVolumeFromFace(int vtkVolId, int domain1, int domain2, std::set& originalNodes, std::map >& nodeDomains, std::map >& nodeQuadDomains); - vtkCellLinks* GetLinks() - { - return Links; - } + void BuildLinks(); + void DeleteLinks(); + SMDS_CellLinks* GetLinks(); + bool HasLinks() const { return this->Links; } + SMDS_Downward* getDownArray(unsigned char vtkType) { return _downArray[vtkType]; diff --git a/src/SMDS/SMDS_VtkEdge.cxx b/src/SMDS/SMDS_VtkEdge.cxx index f365a30f2..edf40f78f 100644 --- a/src/SMDS/SMDS_VtkEdge.cxx +++ b/src/SMDS/SMDS_VtkEdge.cxx @@ -45,14 +45,10 @@ SMDS_VtkEdge::~SMDS_VtkEdge() void SMDS_VtkEdge::init(std::vector& nodeIds, SMDS_Mesh* mesh) { SMDS_MeshEdge::init(); - vtkUnstructuredGrid* grid = mesh->getGrid(); myMeshId = mesh->getMeshId(); - vtkIdType aType = VTK_LINE; - if (nodeIds.size() == 3) - aType = VTK_QUADRATIC_EDGE; - myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); + vtkIdType aType = ( nodeIds.size() == 3 ) ? VTK_QUADRATIC_EDGE : VTK_LINE; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), &nodeIds[0]); mesh->setMyModified(); - //MESSAGE("SMDS_VtkEdge::init myVtkID " << myVtkID); } bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode * node1, const SMDS_MeshNode * node2) @@ -69,14 +65,14 @@ bool SMDS_VtkEdge::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) vtkIdType* pts = 0; grid->GetCellPoints(myVtkID, npts, pts); if (nbNodes != npts) - { - MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); - return false; - } + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } for (int i = 0; i < nbNodes; i++) - { - pts[i] = nodes[i]->getVtkId(); - } + { + pts[i] = nodes[i]->getVtkId(); + } SMDS_Mesh::_meshList[myMeshId]->setMyModified(); return true; } @@ -87,7 +83,6 @@ bool SMDS_VtkEdge::IsMediumNode(const SMDS_MeshNode* node) const vtkIdType npts = 0; vtkIdType* pts = 0; grid->GetCellPoints(myVtkID, npts, pts); - //MESSAGE("IsMediumNode " << npts << " " << (node->getVtkId() == pts[npts-1])); return ((npts == 3) && (node->getVtkId() == pts[2])); } diff --git a/src/SMDS/SMDS_VtkFace.cxx b/src/SMDS/SMDS_VtkFace.cxx index a8a9b28ff..724a7ec21 100644 --- a/src/SMDS/SMDS_VtkFace.cxx +++ b/src/SMDS/SMDS_VtkFace.cxx @@ -44,53 +44,37 @@ SMDS_VtkFace::~SMDS_VtkFace() void SMDS_VtkFace::init(const std::vector& nodeIds, SMDS_Mesh* mesh) { SMDS_MeshFace::init(); - vtkUnstructuredGrid* grid = mesh->getGrid(); myMeshId = mesh->getMeshId(); vtkIdType aType = VTK_TRIANGLE; switch (nodeIds.size()) { - case 3: - aType = VTK_TRIANGLE; - break; - case 4: - aType = VTK_QUAD; - break; - case 6: - aType = VTK_QUADRATIC_TRIANGLE; - break; - case 8: - aType = VTK_QUADRATIC_QUAD; - break; - case 9: - aType = VTK_BIQUADRATIC_QUAD; - break; - case 7: - aType = VTK_BIQUADRATIC_TRIANGLE; - break; - default: - aType = VTK_POLYGON; - break; + case 3: aType = VTK_TRIANGLE; break; + case 4: aType = VTK_QUAD; break; + case 6: aType = VTK_QUADRATIC_TRIANGLE; break; + case 8: aType = VTK_QUADRATIC_QUAD; break; + case 9: aType = VTK_BIQUADRATIC_QUAD; break; + case 7: aType = VTK_BIQUADRATIC_TRIANGLE;break; + default: aType = VTK_POLYGON; } - myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); mesh->setMyModified(); - //MESSAGE("SMDS_VtkFace::init myVtkID " << myVtkID); } void SMDS_VtkFace::initPoly(const std::vector& nodeIds, SMDS_Mesh* mesh) { SMDS_MeshFace::init(); - vtkUnstructuredGrid* grid = mesh->getGrid(); myMeshId = mesh->getMeshId(); - myVtkID = grid->InsertNextLinkedCell(VTK_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + vtkIdType aType = VTK_POLYGON; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); mesh->setMyModified(); } void SMDS_VtkFace::initQuadPoly(const std::vector& nodeIds, SMDS_Mesh* mesh) { SMDS_MeshFace::init(); - vtkUnstructuredGrid* grid = mesh->getGrid(); myMeshId = mesh->getMeshId(); - myVtkID = grid->InsertNextLinkedCell(VTK_QUADRATIC_POLYGON, nodeIds.size(), (vtkIdType*) &nodeIds[0]); + vtkIdType aType = VTK_QUADRATIC_POLYGON; + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType*) &nodeIds[0]); mesh->setMyModified(); } @@ -101,14 +85,14 @@ bool SMDS_VtkFace::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) vtkIdType* pts = 0; grid->GetCellPoints(myVtkID, npts, pts); if (nbNodes != npts) - { - MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); - return false; - } + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } for (int i = 0; i < nbNodes; i++) - { - pts[i] = nodes[i]->getVtkId(); - } + { + pts[i] = nodes[i]->getVtkId(); + } SMDS_Mesh::_meshList[myMeshId]->setMyModified(); return true; } diff --git a/src/SMDS/SMDS_VtkVolume.cxx b/src/SMDS/SMDS_VtkVolume.cxx index 2b717fc26..8f66ff084 100644 --- a/src/SMDS/SMDS_VtkVolume.cxx +++ b/src/SMDS/SMDS_VtkVolume.cxx @@ -41,57 +41,31 @@ SMDS_VtkVolume::SMDS_VtkVolume(const std::vector& nodeIds, SMDS_Mesh* void SMDS_VtkVolume::init(const std::vector& nodeIds, SMDS_Mesh* mesh) { SMDS_MeshVolume::init(); - vtkUnstructuredGrid* grid = mesh->getGrid(); myMeshId = mesh->getMeshId(); vtkIdType aType = VTK_TETRA; switch (nodeIds.size()) // cases are in order of usage frequency { - case 4: - aType = VTK_TETRA; - break; - case 8: - aType = VTK_HEXAHEDRON; - break; - case 5: - aType = VTK_PYRAMID; - break; - case 6: - aType = VTK_WEDGE; - break; - case 10: - aType = VTK_QUADRATIC_TETRA; - break; - case 20: - aType = VTK_QUADRATIC_HEXAHEDRON; - break; - case 13: - aType = VTK_QUADRATIC_PYRAMID; - break; - case 15: - aType = VTK_QUADRATIC_WEDGE; - break; - case 12: - aType = VTK_HEXAGONAL_PRISM; - break; - case 27: - aType = VTK_TRIQUADRATIC_HEXAHEDRON; - break; - default: - aType = VTK_HEXAHEDRON; - break; + case 4: aType = VTK_TETRA; break; + case 8: aType = VTK_HEXAHEDRON; break; + case 5: aType = VTK_PYRAMID; break; + case 6: aType = VTK_WEDGE; break; + case 10: aType = VTK_QUADRATIC_TETRA; break; + case 20: aType = VTK_QUADRATIC_HEXAHEDRON; break; + case 13: aType = VTK_QUADRATIC_PYRAMID; break; + case 15: aType = VTK_QUADRATIC_WEDGE; break; + case 12: aType = VTK_HEXAGONAL_PRISM; break; + case 27: aType = VTK_TRIQUADRATIC_HEXAHEDRON;break; + default: aType = VTK_HEXAHEDRON; } - myVtkID = grid->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]); + myVtkID = mesh->getGrid()->InsertNextLinkedCell(aType, nodeIds.size(), (vtkIdType *) &nodeIds[0]); mesh->setMyModified(); - //MESSAGE("SMDS_VtkVolume::init myVtkID " << myVtkID); } -//#ifdef VTK_HAVE_POLYHEDRON void SMDS_VtkVolume::initPoly(const std::vector& nodeIds, const std::vector& nbNodesPerFace, SMDS_Mesh* mesh) { SMDS_MeshVolume::init(); - //MESSAGE("SMDS_VtkVolume::initPoly"); SMDS_UnstructuredGrid* grid = mesh->getGrid(); //double center[3]; //this->gravityCenter(grid, &nodeIds[0], nodeIds.size(), ¢er[0]); @@ -99,36 +73,34 @@ void SMDS_VtkVolume::initPoly(const std::vector& nodeIds, vtkIdType nbFaces = nbNodesPerFace.size(); int k = 0; for (int i = 0; i < nbFaces; i++) - { - int nf = nbNodesPerFace[i]; - ptIds.push_back(nf); - // EAP: a right approach is: - // - either the user should care of order of nodes or - // - the user should use a service method arranging nodes if he - // don't want or can't to do it by him-self - // The method below works OK only with planar faces and convex polyhedrones - // - // double a[3]; - // double b[3]; - // double c[3]; - // grid->GetPoints()->GetPoint(nodeIds[k], a); - // grid->GetPoints()->GetPoint(nodeIds[k + 1], b); - // grid->GetPoints()->GetPoint(nodeIds[k + 2], c); - // bool isFaceForward = this->isForward(a, b, c, center); - //MESSAGE("isFaceForward " << i << " " << isFaceForward); - const vtkIdType *facePts = &nodeIds[k]; - //if (isFaceForward) - for (int n = 0; n < nf; n++) - ptIds.push_back(facePts[n]); - // else - // for (int n = nf - 1; n >= 0; n--) - // ptIds.push_back(facePts[n]); - k += nf; - } + { + int nf = nbNodesPerFace[i]; + ptIds.push_back(nf); + // EAP: a right approach is: + // - either the user should care of order of nodes or + // - the user should use a service method arranging nodes if he + // don't want or can't to do it by him-self + // The method below works OK only with planar faces and convex polyhedrones + // + // double a[3]; + // double b[3]; + // double c[3]; + // grid->GetPoints()->GetPoint(nodeIds[k], a); + // grid->GetPoints()->GetPoint(nodeIds[k + 1], b); + // grid->GetPoints()->GetPoint(nodeIds[k + 2], c); + // bool isFaceForward = this->isForward(a, b, c, center); + const vtkIdType *facePts = &nodeIds[k]; + //if (isFaceForward) + for (int n = 0; n < nf; n++) + ptIds.push_back(facePts[n]); + // else + // for (int n = nf - 1; n >= 0; n--) + // ptIds.push_back(facePts[n]); + k += nf; + } myVtkID = grid->InsertNextLinkedCell(VTK_POLYHEDRON, nbFaces, &ptIds[0]); mesh->setMyModified(); } -//#endif bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes) { @@ -137,14 +109,14 @@ bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes vtkIdType* pts = 0; grid->GetCellPoints(myVtkID, npts, pts); if (nbNodes != npts) - { - MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); - return false; - } + { + MESSAGE("ChangeNodes problem: not the same number of nodes " << npts << " -> " << nbNodes); + return false; + } for (int i = 0; i < nbNodes; i++) - { - pts[i] = nodes[i]->getVtkId(); - } + { + pts[i] = nodes[i]->getVtkId(); + } SMDS_Mesh::_meshList[myMeshId]->setMyModified(); return true; } @@ -156,10 +128,10 @@ bool SMDS_VtkVolume::ChangeNodes(const SMDS_MeshNode* nodes[], const int nbNodes bool SMDS_VtkVolume::vtkOrder(const SMDS_MeshNode* nodes[], const int nbNodes) { if (nbNodes != this->NbNodes()) - { - MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes()); - return false; - } + { + MESSAGE("vtkOrder, wrong number of nodes " << nbNodes << " instead of "<< this->NbNodes()); + return false; + } vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myMeshId]->getGrid(); vtkIdType aVtkType = grid->GetCellType(this->myVtkID); const std::vector& interlace = SMDS_MeshCell::toVtkOrder( VTKCellType( aVtkType )); @@ -230,23 +202,23 @@ int SMDS_VtkVolume::NbNodes() const vtkIdType aVtkType = grid->GetCellType(this->myVtkID); vtkIdType nbPoints = 0; if (aVtkType != VTK_POLYHEDRON) - { - vtkIdType *pts; - grid->GetCellPoints( myVtkID, nbPoints, pts ); - } + { + vtkIdType *pts; + grid->GetCellPoints( myVtkID, nbPoints, pts ); + } else + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) { - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - grid->GetFaceStream(this->myVtkID, nFaces, ptIds); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; - nbPoints += nodesInFace; - id += (nodesInFace + 1); - } + int nodesInFace = ptIds[id]; + nbPoints += nodesInFace; + id += (nodesInFace + 1); } + } return nbPoints; } @@ -311,22 +283,22 @@ int SMDS_VtkVolume::NbFaceNodes(const int face_ind) const vtkIdType aVtkType = grid->GetCellType(this->myVtkID); int nbNodes = 0; if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) { - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - grid->GetFaceStream(this->myVtkID, nFaces, ptIds); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; - id += (nodesInFace + 1); - if (i == face_ind - 1) - { - nbNodes = nodesInFace; - break; - } - } + int nodesInFace = ptIds[id]; + id += (nodesInFace + 1); + if (i == face_ind - 1) + { + nbNodes = nodesInFace; + break; + } } + } return nbNodes; } @@ -341,23 +313,23 @@ const SMDS_MeshNode* SMDS_VtkVolume::GetFaceNode(const int face_ind, const int n vtkIdType aVtkType = grid->GetCellType(this->myVtkID); const SMDS_MeshNode* node = 0; if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) { - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - grid->GetFaceStream(this->myVtkID, nFaces, ptIds); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] - if (i == face_ind - 1) // first face is number 1 - { - if ((node_ind > 0) && (node_ind <= nodesInFace)) - node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node - break; - } - id += (nodesInFace + 1); - } + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + if (i == face_ind - 1) // first face is number 1 + { + if ((node_ind > 0) && (node_ind <= nodesInFace)) + node = mesh->FindNodeVtk(ptIds[id + node_ind]); // ptIds[id+1] : first node + break; + } + id += (nodesInFace + 1); } + } return node; } @@ -371,18 +343,18 @@ std::vector SMDS_VtkVolume::GetQuantities() const vtkUnstructuredGrid* grid = mesh->getGrid(); vtkIdType aVtkType = grid->GetCellType(this->myVtkID); if (aVtkType == VTK_POLYHEDRON) + { + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + grid->GetFaceStream(this->myVtkID, nFaces, ptIds); + int id = 0; + for (int i = 0; i < nFaces; i++) { - vtkIdType nFaces = 0; - vtkIdType* ptIds = 0; - grid->GetFaceStream(this->myVtkID, nFaces, ptIds); - int id = 0; - for (int i = 0; i < nFaces; i++) - { - int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] - quantities.push_back(nodesInFace); - id += (nodesInFace + 1); - } + int nodesInFace = ptIds[id]; // nodeIds in ptIds[id+1 .. id+nodesInFace] + quantities.push_back(nodesInFace); + id += (nodesInFace + 1); } + } return quantities; } @@ -539,16 +511,15 @@ bool SMDS_VtkVolume::IsMediumNode(const SMDS_MeshNode* node) const grid->GetCellPoints(myVtkID, npts, pts); vtkIdType nodeId = node->getVtkId(); for (int rank = 0; rank < npts; rank++) + { + if (pts[rank] == nodeId) { - if (pts[rank] == nodeId) - { - if (rank < rankFirstMedium) - return false; - else - return true; - } + if (rank < rankFirstMedium) + return false; + else + return true; } - //throw SALOME_Exception(LOCALIZED("node does not belong to this element")); + } MESSAGE("======================================================"); MESSAGE("= IsMediumNode: node does not belong to this element ="); MESSAGE("======================================================"); @@ -609,11 +580,9 @@ SMDSAbs_EntityType SMDS_VtkVolume::GetEntityType() const case VTK_HEXAGONAL_PRISM: aType = SMDSEntity_Hexagonal_Prism; break; -//#ifdef VTK_HAVE_POLYHEDRON case VTK_POLYHEDRON: aType = SMDSEntity_Polyhedra; break; -//#endif default: aType = SMDSEntity_Polyhedra; break; @@ -649,11 +618,9 @@ SMDSAbs_GeometryType SMDS_VtkVolume::GetGeomType() const case VTK_HEXAGONAL_PRISM: aType = SMDSGeom_HEXAGONAL_PRISM; break; -//#ifdef VTK_HAVE_POLYHEDRON case VTK_POLYHEDRON: aType = SMDSGeom_POLYHEDRA; break; -//#endif default: aType = SMDSGeom_POLYHEDRA; break; @@ -685,7 +652,6 @@ void SMDS_VtkVolume::gravityCenter(SMDS_UnstructuredGrid* grid, } for (int j = 0; j < 3; j++) result[j] = result[j] / nbNodes; - //MESSAGE("center " << result[0] << " " << result[1] << " " << result[2]); return; } @@ -693,16 +659,14 @@ bool SMDS_VtkVolume::isForward(double* a, double* b, double* c, double* d) { double u[3], v[3], w[3]; for (int j = 0; j < 3; j++) - { - //MESSAGE("a,b,c,d " << a[j] << " " << b[j] << " " << c[j] << " " << d[j]); - u[j] = b[j] - a[j]; - v[j] = c[j] - a[j]; - w[j] = d[j] - a[j]; - //MESSAGE("u,v,w " << u[j] << " " << v[j] << " " << w[j]); - } - double prodmixte = (u[1]*v[2] - u[2]*v[1]) * w[0] - + (u[2]*v[0] - u[0]*v[2]) * w[1] - + (u[0]*v[1] - u[1]*v[0]) * w[2]; + { + u[j] = b[j] - a[j]; + v[j] = c[j] - a[j]; + w[j] = d[j] - a[j]; + } + double prodmixte = ((u[1]*v[2] - u[2]*v[1]) * w[0] + + (u[2]*v[0] - u[0]*v[2]) * w[1] + + (u[0]*v[1] - u[1]*v[0]) * w[2] ); return (prodmixte < 0); } @@ -720,6 +684,5 @@ int SMDS_VtkVolume::NbUniqueNodes() const */ SMDS_ElemIteratorPtr SMDS_VtkVolume::uniqueNodesIterator() const { - //MESSAGE("uniqueNodesIterator"); return SMDS_ElemIteratorPtr(new SMDS_VtkCellIterator(SMDS_Mesh::_meshList[myMeshId], myVtkID, GetEntityType())); } diff --git a/src/SMESH/SMESH_Algo.cxx b/src/SMESH/SMESH_Algo.cxx index 84b4dace3..a6806c3d8 100644 --- a/src/SMESH/SMESH_Algo.cxx +++ b/src/SMESH/SMESH_Algo.cxx @@ -584,8 +584,10 @@ bool SMESH_Algo::IsStraight( const TopoDS_Edge & E, */ //================================================================================ -bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E ) +bool SMESH_Algo::isDegenerated( const TopoDS_Edge & E, const bool checkLength ) { + if ( checkLength ) + return EdgeLength( E ) == 0; double f,l; TopLoc_Location loc; Handle(Geom_Curve) C = BRep_Tool::Curve( E, loc, f,l ); diff --git a/src/SMESH/SMESH_Algo.hxx b/src/SMESH/SMESH_Algo.hxx index cee45b12c..e51b2329c 100644 --- a/src/SMESH/SMESH_Algo.hxx +++ b/src/SMESH/SMESH_Algo.hxx @@ -363,7 +363,7 @@ public: /*! * \brief Return true if an edge has no 3D curve */ - static bool isDegenerated( const TopoDS_Edge & E ); + static bool isDegenerated( const TopoDS_Edge & E, const bool checkLength=false ); /*! * \brief Return the node built on a vertex diff --git a/src/SMESH/SMESH_Gen.cxx b/src/SMESH/SMESH_Gen.cxx index ce860fc5e..7ca0a59fa 100644 --- a/src/SMESH/SMESH_Gen.cxx +++ b/src/SMESH/SMESH_Gen.cxx @@ -123,13 +123,16 @@ SMESH_Mesh* SMESH_Gen::CreateMesh(int theStudyId, bool theIsEmbeddedMode) bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool aShapeOnly /*=false*/, - const bool anUpward /*=false*/, + const int aFlags /*= COMPACT_MESH*/, const ::MeshDimension aDim /*=::MeshDim_3D*/, TSetOfInt* aShapesId /*=0*/) { MEMOSTAT; + const bool aShapeOnly = aFlags & SHAPE_ONLY; + const bool anUpward = aFlags & UPWARD; + const bool aCompactMesh = aFlags & COMPACT_MESH; + bool ret = true; SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); @@ -141,10 +144,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, SMESH_subMeshIteratorPtr smIt; // Fix of Issue 22150. Due to !BLSURF->OnlyUnaryInput(), BLSURF computes edges - // that must be computed by Projection 1D-2D when Projection asks to compute + // that must be computed by Projection 1D-2D while the Projection asks to compute // one face only. SMESH_subMesh::compute_event computeEvent = aShapeOnly ? SMESH_subMesh::COMPUTE_SUBMESH : SMESH_subMesh::COMPUTE; + if ( !aMesh.HasShapeToMesh() ) + computeEvent = SMESH_subMesh::COMPUTE_NOGEOM; // if several algos and no geometry if ( anUpward ) // is called from the below code in this method { @@ -331,7 +336,8 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, SMESH_Hypothesis::Hypothesis_Status status; if ( subAlgo->CheckHypothesis( aMesh, aSubShape, status )) // mesh a lower smToCompute starting from vertices - Compute( aMesh, aSubShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId ); + Compute( aMesh, aSubShape, aFlags | SHAPE_ONLY_UPWARD, aDim, aShapesId ); + // Compute( aMesh, aSubShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId ); } } } @@ -362,17 +368,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, // ----------------------------------------------- // mesh the rest sub-shapes starting from vertices // ----------------------------------------------- - ret = Compute( aMesh, aShape, aShapeOnly, /*anUpward=*/true, aDim, aShapesId ); + ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId ); } MEMOSTAT; - SMESHDS_Mesh *myMesh = aMesh.GetMeshDS(); - //MESSAGE("*** compactMesh after compute"); - myMesh->compactMesh(); - // fix quadratic mesh by bending iternal links near concave boundary - if ( aShape.IsSame( aMesh.GetShapeToMesh() ) && + if ( aCompactMesh && // a final compute + aShape.IsSame( aMesh.GetShapeToMesh() ) && !aShapesId && // not preview ret ) // everything is OK { @@ -382,6 +385,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh, aHelper.FixQuadraticElements( sm->GetComputeError() ); } } + + if ( aCompactMesh ) + aMesh.GetMeshDS()->compactMesh(); + return ret; } @@ -1053,7 +1060,8 @@ SMESH_Algo *SMESH_Gen::GetAlgo(SMESH_subMesh * aSubMesh, SMESH_Mesh& aMesh = *aSubMesh->GetFather(); SMESH_HypoFilter filter( SMESH_HypoFilter::IsAlgo() ); - filter.And( filter.IsApplicableTo( aShape )); + if ( aMesh.HasShapeToMesh() ) + filter.And( filter.IsApplicableTo( aShape )); typedef SMESH_Algo::Features AlgoData; diff --git a/src/SMESH/SMESH_Gen.hxx b/src/SMESH/SMESH_Gen.hxx index e047be38f..d01105035 100644 --- a/src/SMESH/SMESH_Gen.hxx +++ b/src/SMESH/SMESH_Gen.hxx @@ -60,7 +60,7 @@ typedef struct studyContextStruct typedef std::set TSetOfInt; -class SMESH_EXPORT SMESH_Gen +class SMESH_EXPORT SMESH_Gen { public: SMESH_Gen(); @@ -69,19 +69,25 @@ public: SMESH_Mesh* CreateMesh(int theStudyId, bool theIsEmbeddedMode) throw(SALOME_Exception); + enum ComputeFlags + { + SHAPE_ONLY = 1, // to ignore algo->OnlyUnaryInput() feature and to compute a given shape only. + UPWARD = 2, // to compute from vertices up to more complex shape (internal usage) + COMPACT_MESH = 4, // to compact the mesh at the end + SHAPE_ONLY_UPWARD = 3 // SHAPE_ONLY | UPWARD + }; /*! * \brief Computes aMesh on aShape - * \param aShapeOnly - if true, algo->OnlyUnaryInput() feature is ignored and - * only \a aShape is computed. - * \param anUpward - compute from vertices up to more complex shape (internal usage) - * \param aDim - upper level dimension of the mesh computation + * \param aMesh - the mesh. + * \param aShape - the shape. + * \param aFlags - ComputeFlags. By default compute the whole mesh and compact at the end. + * \param aDim - upper level dimension of the mesh computation (for preview) * \param aShapesId - list of shapes with computed mesh entities (elements or nodes) - * \retval bool - true if none submesh failed to compute + * \retval bool - true if none sub-mesh failed to compute */ bool Compute(::SMESH_Mesh & aMesh, const TopoDS_Shape & aShape, - const bool aShapeOnly=false, - const bool anUpward=false, + const int aFlags = COMPACT_MESH, const ::MeshDimension aDim=::MeshDim_3D, TSetOfInt* aShapesId=0); diff --git a/src/SMESH/SMESH_Mesh.cxx b/src/SMESH/SMESH_Mesh.cxx index ba8715cb4..ff127dece 100644 --- a/src/SMESH/SMESH_Mesh.cxx +++ b/src/SMESH/SMESH_Mesh.cxx @@ -438,6 +438,7 @@ void SMESH_Mesh::Clear() sm->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); } } + GetMeshDS()->Modified(); _isModified = false; } @@ -1208,49 +1209,67 @@ void SMESH_Mesh::NotifySubMeshesHypothesisModification(const SMESH_Hypothesis* h SMESH_Algo *algo; const SMESH_HypoFilter* compatibleHypoKind; list usedHyps; - - // keep sub-meshes not to miss ones whose state can change due to notifying others vector< SMESH_subMesh* > smToNotify; + bool allMeshedEdgesNotified = true; SMESH_subMeshIteratorPtr smIt( _subMeshHolder->GetIterator() ); while ( smIt->more() ) { SMESH_subMesh* aSubMesh = smIt->next(); + bool toNotify = false; // if aSubMesh meshing depends on hyp, // we call aSubMesh->AlgoStateEngine( MODIF_HYP, hyp ) that causes either // 1) clearing already computed aSubMesh or // 2) changing algo_state from MISSING_HYP to HYP_OK when parameters of hyp becomes valid, // other possible changes are not interesting. (IPAL0052457 - assigning hyp performance pb) - if ( aSubMesh->GetComputeState() != SMESH_subMesh::COMPUTE_OK && - aSubMesh->GetComputeState() != SMESH_subMesh::FAILED_TO_COMPUTE && - aSubMesh->GetAlgoState() != SMESH_subMesh::MISSING_HYP && - !hyp->DataDependOnParams() ) - continue; - - const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); - - if (( aSubMesh->IsApplicableHypotesis( hyp )) && - ( algo = aSubMesh->GetAlgo() ) && - ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) && - ( compatibleHypoKind->IsOk( hyp, aSubShape ))) + if ( aSubMesh->GetComputeState() == SMESH_subMesh::COMPUTE_OK || + aSubMesh->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE || + aSubMesh->GetAlgoState() == SMESH_subMesh::MISSING_HYP || + hyp->DataDependOnParams() ) { - // check if hyp is used by algo - usedHyps.clear(); - if ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) && - find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ) + const TopoDS_Shape & aSubShape = aSubMesh->GetSubShape(); + + if (( aSubMesh->IsApplicableHypotesis( hyp )) && + ( algo = aSubMesh->GetAlgo() ) && + ( compatibleHypoKind = algo->GetCompatibleHypoFilter( !hyp->IsAuxiliary() )) && + ( compatibleHypoKind->IsOk( hyp, aSubShape ))) { - smToNotify.push_back( aSubMesh ); + // check if hyp is used by algo + usedHyps.clear(); + toNotify = ( GetHypotheses( aSubMesh, *compatibleHypoKind, usedHyps, true ) && + std::find( usedHyps.begin(), usedHyps.end(), hyp ) != usedHyps.end() ); } } + if ( toNotify ) + { + smToNotify.push_back( aSubMesh ); + if ( aSubMesh->GetAlgoState() == SMESH_subMesh::MISSING_HYP ) + allMeshedEdgesNotified = false; // update of algo state needed, not mesh clearing + } + else + { + if ( !aSubMesh->IsEmpty() && + aSubMesh->GetSubShape().ShapeType() == TopAbs_EDGE ) + allMeshedEdgesNotified = false; + } } + if ( smToNotify.empty() ) + return; - for ( size_t i = 0; i < smToNotify.size(); ++i ) + // if all meshed EDGEs will be notified then the notification is equivalent + // to the whole mesh clearing, which is usually faster + if ( allMeshedEdgesNotified && NbNodes() > 0 ) { - smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, - const_cast< SMESH_Hypothesis*>( hyp )); + Clear(); + } + else + { + // notify in reverse order to avoid filling the pool of IDs + for ( int i = smToNotify.size()-1; i >= 0; --i ) + smToNotify[i]->AlgoStateEngine(SMESH_subMesh::MODIF_HYP, + const_cast< SMESH_Hypothesis*>( hyp )); } - HasModificationsToDiscard(); // to reset _isModified flag if mesh becomes empty GetMeshDS()->Modified(); } @@ -2349,7 +2368,7 @@ bool SMESH_Mesh::SortByMeshOrder(std::vector& theListToSort) con vector::iterator onlyBIt = onlyOrderedList.begin(); vector::iterator onlyEIt = onlyOrderedList.end(); - // iterate on ordered submeshes and insert them in detected positions + // iterate on ordered sub-meshes and insert them in detected positions map< int, TPosInList >::iterator i_pos = sortedPos.begin(); for ( ; onlyBIt != onlyEIt; ++onlyBIt, ++i_pos ) *(i_pos->second) = *onlyBIt; @@ -2367,18 +2386,27 @@ bool SMESH_Mesh::IsOrderOK( const SMESH_subMesh* smBefore, const SMESH_subMesh* smAfter ) const { TListOfListOfInt::const_iterator listIdsIt = _mySubMeshOrder.begin(); - TListOfInt::const_iterator idBef, idAft; for( ; listIdsIt != _mySubMeshOrder.end(); listIdsIt++) { const TListOfInt& listOfId = *listIdsIt; - idBef = std::find( listOfId.begin(), listOfId.end(), smBefore->GetId() ); - if ( idBef != listOfId.end() ) - idAft = std::find( listOfId.begin(), listOfId.end(), smAfter->GetId() ); - if ( idAft != listOfId.end () ) - return ( std::distance( listOfId.begin(), idBef ) < - std::distance( listOfId.begin(), idAft ) ); + int iB = -1, iA = -1, i = 0; + for ( TListOfInt::const_iterator id = listOfId.begin(); id != listOfId.end(); ++id, ++i ) + { + if ( *id == smBefore->GetId() ) + { + iB = i; + if ( iA > -1 ) + return iB < iA; + } + else if ( *id == smAfter->GetId() ) + { + iA = i; + if ( iB > -1 ) + return iB < iA; + } + } } - return true; // no order imposed to given submeshes + return true; // no order imposed to given sub-meshes } //============================================================================= diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 1f4f42891..056da7050 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -3994,11 +3994,11 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, fToler2 = BRep_Tool::Tolerance( face ); fToler2 *= fToler2 * 10.; isUPeriodic = surface->IsUPeriodic(); - if ( isUPeriodic ) - surface->UPeriod(); + // if ( isUPeriodic ) + // surface->UPeriod(); isVPeriodic = surface->IsVPeriodic(); - if ( isVPeriodic ) - surface->VPeriod(); + // if ( isVPeriodic ) + // surface->VPeriod(); surface->Bounds( u1, u2, v1, v2 ); helper.SetSubShape( face ); } @@ -4057,9 +4057,9 @@ void SMESH_MeshEditor::Smooth (TIDSortedElemSet & theElems, { // check if all faces around the node are on faceSubMesh // because a node on edge may be bound to face - SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); bool all = true; if ( faceSubMesh ) { + SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face); while ( eIt->more() && all ) { const SMDS_MeshElement* e = eIt->next(); all = faceSubMesh->Contains( e ); @@ -11650,7 +11650,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorCleanDownWardConnectivity(); // Mesh has been modified, downward connectivity is no more usable, free memory - grid->BuildLinks(); + grid->DeleteLinks(); CHRONOSTOP(50); counters::stats(); diff --git a/src/SMESH/SMESH_MesherHelper.cxx b/src/SMESH/SMESH_MesherHelper.cxx index 13d072bbb..c6c34ed47 100644 --- a/src/SMESH/SMESH_MesherHelper.cxx +++ b/src/SMESH/SMESH_MesherHelper.cxx @@ -304,6 +304,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) double u2 = uv1.Coord(1); myPar1[0] = Min( u1, u2 ); myPar2[0] = Max( u1, u2 ); + myParIndex |= U_periodic; } else { @@ -313,6 +314,7 @@ void SMESH_MesherHelper::SetSubShape(const TopoDS_Shape& aSh) double v2 = uv1.Coord(2); myPar1[1] = Min( v1, v2 ); myPar2[1] = Max( v1, v2 ); + myParIndex |= V_periodic; } } else //if ( !isSeam ) @@ -2928,7 +2930,7 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace) TopoDS_Shape s0 = GetSubShapeByNode( nn[0], GetMeshDS() ); TopoDS_Shape s1 = GetSubShapeByNode( nn[1], GetMeshDS() ); TopoDS_Shape E = GetCommonAncestor( s0, s1, *myMesh, TopAbs_EDGE ); - if ( !E.IsNull() && !s0.IsSame( s1 )) + if ( !E.IsNull() && !s0.IsSame( s1 ) && E.Orientation() != TopAbs_INTERNAL ) { // is E seam edge? int nb = 0; @@ -2942,10 +2944,16 @@ bool SMESH_MesherHelper::IsReversedSubMesh (const TopoDS_Face& theFace) bool ok = true; double u0 = GetNodeU( TopoDS::Edge( E ), nn[0], nn[1], &ok ); double u1 = GetNodeU( TopoDS::Edge( E ), nn[1], nn[0], &ok ); - // check that the 2 nodes are connected with a segment (IPAL53055) - if ( SMESHDS_SubMesh* sm = GetMeshDS()->MeshElements( E )) - if ( sm->NbElements() > 0 && !GetMeshDS()->FindEdge( nn[0], nn[1] )) - ok = false; + if ( ok ) + { + // check that the 2 nodes are connected with a segment (IPAL53055) + ok = false; + const SMDS_MeshElement* seg; + if ( SMESHDS_SubMesh* sm = GetMeshDS()->MeshElements( E )) + if (( sm->NbElements() > 0 ) && + ( seg = GetMeshDS()->FindEdge( nn[0], nn[1] ))) + ok = sm->Contains( seg ); + } if ( ok ) { isReversed = ( u0 > u1 ); @@ -4627,7 +4635,7 @@ namespace { // Structures used by FixQuadraticElements() SMDS_ElemIteratorPtr faceIter( new TIterOnIter( faceIterVec )); // a seacher to check if a volume is close to a concave face - std::auto_ptr< SMESH_ElementSearcher > faceSearcher + SMESHUtils::Deleter< SMESH_ElementSearcher > faceSearcher ( SMESH_MeshAlgos::GetElementSearcher( *theHelper.GetMeshDS(), faceIter )); // classifier @@ -4729,7 +4737,7 @@ namespace { // Structures used by FixQuadraticElements() gp_Pnt pMedium = SMESH_TNodeXYZ( linkIt->second ); double hMedium = faceNorm * gp_Vec( pOnFace0, pMedium ).XYZ(); double hVol = faceNorm * gp_Vec( pOnFace0, pInSolid ).XYZ(); - isDistorted = ( Abs( hMedium ) > Abs( hVol * 0.5 )); + isDistorted = ( Abs( hMedium ) > Abs( hVol * 0.75 )); } } } diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index c317869bc..6f3c1b076 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -256,7 +256,7 @@ int loadVE( const list< TopoDS_Edge > & eList, //purpose : //======================================================================= -SMESH_Pattern::SMESH_Pattern () +SMESH_Pattern::SMESH_Pattern (): myToKeepNodes(false) { } @@ -565,11 +565,13 @@ static bool isMeshBoundToShape(SMESHDS_Mesh * aMeshDS, bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, const TopoDS_Face& theFace, bool theProject, - TopoDS_Vertex the1stVertex) + TopoDS_Vertex the1stVertex, + bool theKeepNodes) { MESSAGE(" ::Load(face) " ); Clear(); myIs2D = true; + myToKeepNodes = theKeepNodes; SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS(); SMESHDS_SubMesh * fSubMesh = aMeshDS->MeshElements( theFace ); @@ -792,7 +794,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, double u = epos->GetUParameter(); paramNodeMap.insert( make_pair( u, node )); } - if ((int) paramNodeMap.size() != eSubMesh->NbNodes() ) { + if ((int) paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes ) { // wrong U on edge, project Extrema_ExtPC proj; BRepAdaptor_Curve aCurve( edge ); @@ -966,6 +968,19 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, myIsBoundaryPointsFound = true; } + if ( myToKeepNodes ) + { + myInNodes.resize( nodePointIDMap.size() + closeNodePointIDMap.size() ); + + TNodePointIDMap::iterator nIdIt = nodePointIDMap.begin(); + for ( ; nIdIt != nodePointIDMap.end(); nIdIt++ ) + myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first ); + + nIdIt = closeNodePointIDMap.begin(); + for ( ; nIdIt != closeNodePointIDMap.end(); nIdIt++ ) + myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first ); + } + // Assure that U range is proportional to V range Bnd_Box2d bndBox; @@ -3181,11 +3196,13 @@ bool SMESH_Pattern::Apply (std::set & theVolumes, //======================================================================= bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, - const TopoDS_Shell& theBlock) + const TopoDS_Shell& theBlock, + bool theKeepNodes) { MESSAGE(" ::Load(volume) " ); Clear(); myIs2D = false; + myToKeepNodes = theKeepNodes; SMESHDS_SubMesh * aSubMesh; const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC ); @@ -3219,7 +3236,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, SMDS_NodeIteratorPtr nIt = aSubMesh->GetNodes(); if ( !nIt->more() ) continue; - // store a node and a point + // store a node and a point while ( nIt->more() ) { const SMDS_MeshNode* node = smdsNode( nIt->next() ); if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Volume )) @@ -3297,6 +3314,14 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh, myIsBoundaryPointsFound = true; + if ( myToKeepNodes ) + { + myInNodes.resize( nodePointIDMap.size() ); + TNodePointIDMap::iterator nIdIt = nodePointIDMap.begin(); + for ( ; nIdIt != nodePointIDMap.end(); nIdIt++ ) + myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first ); + } + return setErrorCode( ERR_OK ); } @@ -4144,6 +4169,9 @@ bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh, aMeshDS->compactMesh(); + if ( myToKeepNodes ) + myOutNodes.swap( nodesVector ); + // const map& sm = aMeshDS->SubMeshes(); // map::const_iterator i_sm = sm.begin(); // for ( ; i_sm != sm.end(); i_sm++ ) diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index 3bc3684ba..8b405de21 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -71,13 +71,15 @@ class SMESH_EXPORT SMESH_Pattern { bool Load (SMESH_Mesh* theMesh, const TopoDS_Face& theFace, bool theProject = false, - TopoDS_Vertex the1stVertex=TopoDS_Vertex()); + TopoDS_Vertex the1stVertex=TopoDS_Vertex(), + bool theKeepNodes = false ); // Create a pattern from the mesh built on . // ==true makes override nodes positions // on computed by mesher bool Load (SMESH_Mesh* theMesh, - const TopoDS_Shell& theBlock); + const TopoDS_Shell& theBlock, + bool theKeepNodes = false); // Create a pattern from the mesh built on bool Save (std::ostream& theFile); @@ -216,6 +218,11 @@ class SMESH_EXPORT SMESH_Pattern { { return myElemXYZIDs.empty() || !applied ? myElemPointIDs : myElemXYZIDs; } // Return nodal connectivity of the elements of the pattern + void GetInOutNodes( std::vector< const SMDS_MeshNode* > *& inNodes, + std::vector< const SMDS_MeshNode* > *& outNodes ) + { inNodes = & myInNodes; outNodes = & myOutNodes; } + // Return loaded and just created nodes + void DumpPoints() const; // Debug @@ -368,7 +375,11 @@ private: // nb of key-points in each of pattern boundaries std::list< int > myNbKeyPntInBoundary; - + // nodes corresponding to myPoints + bool myToKeepNodes; // to keep these data + std::vector< const SMDS_MeshNode* > myInNodes; // loaded nodes + std::vector< const SMDS_MeshNode* > myOutNodes; // created nodes + // to compute while applying to mesh elements, not to shapes std::vector myXYZ; // XYZ of nodes to create @@ -377,7 +388,7 @@ private: std::vector myElements; // refined elements std::vector myOrderedNodes; - // elements to replace with polygon or polyhedron + // elements to replace with polygon or polyhedron std::vector myPolyElems; // definitions of new poly elements std::list< TElemDef > myPolyElemXYZIDs; diff --git a/src/SMESH/SMESH_ProxyMesh.cxx b/src/SMESH/SMESH_ProxyMesh.cxx index 828b77d1e..f994b83ec 100644 --- a/src/SMESH/SMESH_ProxyMesh.cxx +++ b/src/SMESH/SMESH_ProxyMesh.cxx @@ -533,7 +533,7 @@ int SMESH_ProxyMesh::SubMesh::NbElements() const */ //================================================================================ -SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements() const +SMDS_ElemIteratorPtr SMESH_ProxyMesh::SubMesh::GetElements(bool reverse) const { return SMDS_ElemIteratorPtr ( new SMDS_ElementVectorIterator( _elements.begin(), _elements.end() )); @@ -558,7 +558,7 @@ int SMESH_ProxyMesh::SubMesh::NbNodes() const */ //================================================================================ -SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes() const +SMDS_NodeIteratorPtr SMESH_ProxyMesh::SubMesh::GetNodes(bool reverse) const { if ( !_uvPtStructVec.empty() ) return SMDS_NodeIteratorPtr ( new SMDS_SetIterator diff --git a/src/SMESH/SMESH_ProxyMesh.hxx b/src/SMESH/SMESH_ProxyMesh.hxx index 16513a8eb..a64002e02 100644 --- a/src/SMESH/SMESH_ProxyMesh.hxx +++ b/src/SMESH/SMESH_ProxyMesh.hxx @@ -66,8 +66,8 @@ public: virtual void AddElement(const SMDS_MeshElement * e); virtual int NbElements() const; virtual int NbNodes() const; - virtual SMDS_ElemIteratorPtr GetElements() const; - virtual SMDS_NodeIteratorPtr GetNodes() const; + virtual SMDS_ElemIteratorPtr GetElements(bool reverse=false) const; + virtual SMDS_NodeIteratorPtr GetNodes(bool reverse=false) const; virtual void Clear(); virtual bool Contains(const SMDS_MeshElement * ME) const; diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 128316dcf..b297cf609 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -63,6 +63,11 @@ using namespace std; +#ifdef _DEBUG_ +// enable printing algo + shape id + hypo used while meshing +//#define PRINT_WHO_COMPUTE_WHAT +#endif + //============================================================================= /*! * \brief Allocate some memory at construction and release it at destruction. @@ -510,7 +515,20 @@ bool SMESH_subMesh::CanAddHypothesis(const SMESH_Hypothesis* theHypothesis) cons //======================================================================= //function : IsApplicableHypotesis -//purpose : +//purpose : check if this sub-mesh can be computed using a hypothesis +//======================================================================= + +bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const +{ + if ( !_father->HasShapeToMesh() && _subShape.ShapeType() == TopAbs_SOLID ) + return true; // true for the PseudoShape + + return IsApplicableHypotesis( theHypothesis, _subShape.ShapeType() ); +} + +//======================================================================= +//function : IsApplicableHypotesis +//purpose : compare shape type and hypothesis type //======================================================================= bool SMESH_subMesh::IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, @@ -1272,24 +1290,44 @@ void SMESH_subMesh::DumpAlgoState(bool isMain) static void cleanSubMesh( SMESH_subMesh * subMesh ) { if (subMesh) { - if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) { + if (SMESHDS_SubMesh * subMeshDS = subMesh->GetSubMeshDS()) + { SMESHDS_Mesh * meshDS = subMesh->GetFather()->GetMeshDS(); - SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); - while (ite->more()) { - const SMDS_MeshElement * elt = ite->next(); - //MESSAGE( " RM elt: "<GetID()<<" ( "<NbNodes()<<" )" ); - //meshDS->RemoveElement(elt); - meshDS->RemoveFreeElement(elt, 0); + int nbElems = subMeshDS->NbElements(); + if ( nbElems > 0 ) + { + // start from elem with max ID to avoid filling the pool of IDs + bool rev = true; + SMDS_ElemIteratorPtr ite = subMeshDS->GetElements( rev ); + const SMDS_MeshElement * lastElem = ite->next(); + rev = ( lastElem->GetID() == meshDS->MaxElementID() ); + if ( !rev ) + ite = subMeshDS->GetElements( rev ); + else + meshDS->RemoveFreeElement( lastElem, subMeshDS ); + while (ite->more()) { + const SMDS_MeshElement * elt = ite->next(); + meshDS->RemoveFreeElement( elt, subMeshDS ); + } } - - SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes(); - while (itn->more()) { - const SMDS_MeshNode * node = itn->next(); - //MESSAGE( " RM node: "<GetID()); - if ( node->NbInverseElements() == 0 ) - meshDS->RemoveFreeNode(node, 0); - else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another - meshDS->RemoveNode(node); + int nbNodes = subMeshDS->NbNodes(); + if ( nbNodes > 0 ) + { + bool rev = true; + SMDS_NodeIteratorPtr itn = subMeshDS->GetNodes( rev ); + const SMDS_MeshNode * lastNode = itn->next(); + rev = ( lastNode->GetID() == meshDS->MaxNodeID() ); + if ( !rev ) + itn = subMeshDS->GetNodes( rev ); + else + meshDS->RemoveNode( lastNode ); + while (itn->more()) { + const SMDS_MeshNode * node = itn->next(); + if ( node->NbInverseElements() == 0 ) + meshDS->RemoveFreeNode( node, subMeshDS ); + else // for StdMeshers_CompositeSegment_1D: node in one submesh, edge in another + meshDS->RemoveNode(node); + } } subMeshDS->Clear(); } @@ -1416,6 +1454,31 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) _computeState = READY_TO_COMPUTE; } break; + + case COMPUTE_NOGEOM: // no geometry; can be several algos + if ( !_father->HasShapeToMesh() ) + { + algo = GetAlgo(); // current algo + if ( algo ) + { + // apply algos in the order of increasing dimension + std::list< const SMESHDS_Hypothesis * > algos = _father->GetHypothesisList( _subShape ); + for ( int t = SMESHDS_Hypothesis::ALGO_1D; t <= SMESHDS_Hypothesis::ALGO_3D; ++t ) + { + std::list::iterator al = algos.begin(); + for ( ; al != algos.end(); ++al ) + if ( (*al)->GetType() == t ) + { + _algo = (SMESH_Algo*) *al; + _computeState = READY_TO_COMPUTE; + if ( !ComputeStateEngine( COMPUTE )) + break; + } + } + _algo = algo; // restore + } + break; + } case COMPUTE: case COMPUTE_SUBMESH: { @@ -1499,7 +1562,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) MESSAGE("std::bad_alloc thrown inside algo->Compute()"); if ( _computeError ) { _computeError->myName = COMPERR_MEMORY_PB; - //_computeError->myComment = exc.what(); } cleanSubMesh( this ); throw exc; @@ -1508,7 +1570,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) MESSAGE("Standard_OutOfMemory thrown inside algo->Compute()"); if ( _computeError ) { _computeError->myName = COMPERR_MEMORY_PB; - //_computeError->myComment = exc.what(); } cleanSubMesh( this ); throw std::bad_alloc(); @@ -1549,7 +1610,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) ret = false; // check if anything was built TopExp_Explorer subS(shape, _subShape.ShapeType()); - if (ret) + if ( ret ) { for (; ret && subS.More(); subS.Next()) if ( !_father->GetSubMesh( subS.Current() )->IsMeshComputed() && @@ -1557,10 +1618,27 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) !algo->isDegenerated( TopoDS::Edge( subS.Current() )))) ret = false; } +#ifdef PRINT_WHO_COMPUTE_WHAT + for (subS.ReInit(); subS.More(); subS.Next()) + { + const std::list & hyps = + _algo->GetUsedHypothesis( *_father, _subShape ); + SMESH_Comment hypStr; + if ( !hyps.empty() ) + { + hypStr << hyps.front()->GetName() << " "; + ((SMESHDS_Hypothesis*)hyps.front())->SaveTo( hypStr.Stream() ); + hypStr << " "; + } + cout << _algo->GetName() + << " " << _father->GetSubMesh( subS.Current() )->GetId() + << " " << hypStr << endl; + } +#endif // Set _computeError - if (!ret && !isComputeErrorSet) + if ( !ret && !isComputeErrorSet ) { - for (subS.ReInit(); subS.More(); subS.Next()) + for ( subS.ReInit(); subS.More(); subS.Next() ) { SMESH_subMesh* sm = _father->GetSubMesh( subS.Current() ); if ( !sm->IsMeshComputed() ) @@ -1574,7 +1652,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } } } - if (ret && _computeError && _computeError->myName != COMPERR_WARNING ) + if ( ret && _computeError && _computeError->myName != COMPERR_WARNING ) { _computeError.reset(); } @@ -2139,8 +2217,6 @@ const SMESH_Hypothesis* SMESH_subMesh::getSimilarAttached(const TopoDS_Shape& SMESH_Hypothesis::Hypothesis_Status SMESH_subMesh::CheckConcurentHypothesis (const int theHypType) { - MESSAGE ("SMESH_subMesh::CheckConcurentHypothesis"); - // is there local hypothesis on me? if ( getSimilarAttached( _subShape, 0, theHypType ) ) return SMESH_Hypothesis::HYP_OK; diff --git a/src/SMESH/SMESH_subMesh.hxx b/src/SMESH/SMESH_subMesh.hxx index 05890e8ce..f4cc093b1 100644 --- a/src/SMESH/SMESH_subMesh.hxx +++ b/src/SMESH/SMESH_subMesh.hxx @@ -112,7 +112,7 @@ class SMESH_EXPORT SMESH_subMesh }; enum compute_event { - MODIF_ALGO_STATE, COMPUTE, COMPUTE_SUBMESH, COMPUTE_CANCELED, + MODIF_ALGO_STATE, COMPUTE, COMPUTE_SUBMESH, COMPUTE_NOGEOM, COMPUTE_CANCELED, CLEAN, SUBMESH_COMPUTED, SUBMESH_RESTORED, SUBMESH_LOADED, MESH_ENTITY_REMOVED, CHECK_COMPUTE_STATE }; @@ -241,8 +241,7 @@ public: static bool IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis, const TopAbs_ShapeEnum theShapeType); - bool IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const - { return IsApplicableHypotesis( theHypothesis, _subShape.ShapeType() ); } + bool IsApplicableHypotesis(const SMESH_Hypothesis* theHypothesis) const; // return true if theHypothesis can be used to mesh me: // its shape type is checked diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 7c233db58..e7a10d7fe 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -1374,7 +1374,7 @@ const TopoDS_Shape& SMESHDS_Mesh::IndexToShape(int ShapeIndex) const if ( ShapeIndex > 0 ) return myIndexToShape.FindKey(ShapeIndex); } - catch ( Standard_OutOfRange ) + catch ( ... ) { } static TopoDS_Shape nullShape; @@ -1398,11 +1398,7 @@ int SMESHDS_Mesh::MaxSubMeshIndex() const //======================================================================= int SMESHDS_Mesh::ShapeToIndex(const TopoDS_Shape & S) const { - if (myShape.IsNull()) - MESSAGE("myShape is NULL"); - int index = myIndexToShape.FindIndex(S); - return index; } @@ -2149,16 +2145,15 @@ SMDS_MeshVolume* SMESHDS_Mesh::AddVolumeWithID(const SMDS_MeshNode * n1, void SMESHDS_Mesh::compactMesh() { + if ( isCompacted() ) + return; + SMDS_Mesh::compactMesh(); + int newNodeSize = 0; - int nbNodes = myNodes.size(); - int nbVtkNodes = myGrid->GetNumberOfPoints(); - //MESSAGE("nbNodes=" << nbNodes << " nbVtkNodes=" << nbVtkNodes); - int nbNodeTemp = nbVtkNodes; - if (nbNodes > nbVtkNodes) - nbNodeTemp = nbNodes; - vector idNodesOldToNew; - idNodesOldToNew.clear(); - idNodesOldToNew.resize(nbNodeTemp, -1); // all unused id will be -1 + int nbNodes = myNodes.size(); + int nbVtkNodes = myGrid->GetNumberOfPoints(); + int nbNodeTemp = Max( nbVtkNodes, nbNodes ); + vector idNodesOldToNew(nbNodeTemp, -1); // all unused id will be -1 for (int i = 0; i < nbNodes; i++) { @@ -2169,28 +2164,19 @@ void SMESHDS_Mesh::compactMesh() newNodeSize++; } } - bool areNodesModified = (newNodeSize < nbVtkNodes); - //MESSAGE("------------------------- compactMesh Nodes Modified: " << areNodesModified); + bool areNodesModified = (newNodeSize != nbVtkNodes); areNodesModified = true; int newCellSize = 0; - int nbCells = myCells.size(); - int nbVtkCells = myGrid->GetNumberOfCells(); - //MESSAGE("nbCells=" << nbCells << " nbVtkCells=" << nbVtkCells); - int nbCellTemp = nbVtkCells; - if (nbCells > nbVtkCells) - nbCellTemp = nbCells; - vector idCellsOldToNew; - idCellsOldToNew.clear(); - idCellsOldToNew.resize(nbCellTemp, -1); // all unused id will be -1 + int nbCells = myCells.size(); + int nbVtkCells = myGrid->GetNumberOfCells(); + int nbCellTemp = Max( nbVtkCells, nbCells ); + vector idCellsOldToNew(nbCellTemp, -1); // all unused id will be -1 for (int i = 0; i < nbCells; i++) { if (myCells[i]) { - // //idCellsOldToNew[i] = myCellIdVtkToSmds[i]; // valid vtk indexes are > = 0 - // int vtkid = myCells[i]->getVtkId(); - // idCellsOldToNew[vtkid] = i; // old vtkId --> old smdsId (not used in input) newCellSize++; } } @@ -2212,61 +2198,43 @@ void SMESHDS_Mesh::compactMesh() if (nbVtkCells > newCellSize) newCellSize = nbVtkCells; // several cells with same SMDS Id } - // --- SMDS_MeshNode and myNodes (id in SMDS and in VTK are the same), myNodeIdFactory + // --- SMDS_MeshNode and myNodes, myNodeIdFactory - if (areNodesModified) + if ( true ) { - //MESSAGE("-------------- modify myNodes"); - SetOfNodes newNodes; - newNodes.resize(newNodeSize+1,0); // 0 not used, SMDS numbers 1..n + SetOfNodes newNodes(newNodeSize+1,NULL); // 0 not used, SMDS numbers 1..n int newSmdsId = 0; for (int i = 0; i < nbNodes; i++) { if (myNodes[i]) { - newSmdsId++; // SMDS id start to 1 + newSmdsId++; // SMDS id starts from 1 int oldVtkId = myNodes[i]->getVtkId(); int newVtkId = idNodesOldToNew[oldVtkId]; - //MESSAGE("myNodes["<< i << "] vtkId " << oldVtkId << " --> " << newVtkId); myNodes[i]->setVtkId(newVtkId); myNodes[i]->setId(newSmdsId); newNodes[newSmdsId] = myNodes[i]; - //MESSAGE("myNodes["<< i << "] --> newNodes[" << newSmdsId << "]"); } } myNodes.swap(newNodes); this->myNodeIDFactory->emptyPool(newSmdsId); // newSmdsId = number of nodes - //MESSAGE("myNodes.size " << myNodes.size()); } // --- SMDS_MeshCell, myCellIdVtkToSmds, myCellIdSmdsToVtk, myCells int vtkIndexSize = myCellIdVtkToSmds.size(); - int maxVtkId = -1; for (int oldVtkId = 0; oldVtkId < vtkIndexSize; oldVtkId++) { int oldSmdsId = this->myCellIdVtkToSmds[oldVtkId]; if (oldSmdsId > 0) { int newVtkId = idCellsOldToNew[oldVtkId]; - if (newVtkId > maxVtkId) - maxVtkId = newVtkId; - //MESSAGE("myCells["<< oldSmdsId << "] vtkId " << oldVtkId << " --> " << newVtkId); myCells[oldSmdsId]->setVtkId(newVtkId); } } - // MESSAGE("myCells.size()=" << myCells.size() - // << " myCellIdSmdsToVtk.size()=" << myCellIdSmdsToVtk.size() - // << " myCellIdVtkToSmds.size()=" << myCellIdVtkToSmds.size() ); - - SetOfCells newCells; - //vector newSmdsToVtk; - vector newVtkToSmds; - assert(maxVtkId < newCellSize); - newCells.resize(newCellSize+1, 0); // 0 not used, SMDS numbers 1..n - //newSmdsToVtk.resize(newCellSize+1, -1); - newVtkToSmds.resize(newCellSize+1, -1); + SetOfCells newCells(newCellSize+1, NULL); // 0 not used, SMDS numbers 1..n + vector newVtkToSmds(newCellSize+1, -1); int myCellsSize = myCells.size(); int newSmdsId = 0; @@ -2274,22 +2242,18 @@ void SMESHDS_Mesh::compactMesh() { if ( myCells[i] ) { - newSmdsId++; // SMDS id start to 1 + newSmdsId++; // SMDS id starts from 1 assert(newSmdsId <= newCellSize); newCells[newSmdsId] = myCells[i]; newCells[newSmdsId]->setId(newSmdsId); - //MESSAGE("myCells["<< i << "] --> newCells[" << newSmdsId << "]"); int idvtk = myCells[i]->getVtkId(); - //newSmdsToVtk[newSmdsId] = idvtk; assert(idvtk < newCellSize); newVtkToSmds[idvtk] = newSmdsId; } } myCells.swap(newCells); - //myCellIdSmdsToVtk.swap(newSmdsToVtk); myCellIdVtkToSmds.swap(newVtkToSmds); - //MESSAGE("myCells.size()="<< myCells.size()<<" myCellIdVtkToSmds.size()="<myElementIDFactory->emptyPool(newSmdsId); this->myScript->SetModified(true); // notify GUI client for buildPrs when update diff --git a/src/SMESHDS/SMESHDS_SubMesh.cxx b/src/SMESHDS/SMESHDS_SubMesh.cxx index 21d6da43a..892873016 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.cxx +++ b/src/SMESHDS/SMESHDS_SubMesh.cxx @@ -257,38 +257,44 @@ int SMESHDS_SubMesh::NbNodes() const } /*! - * template class used for iteration on submesh elements. Interface of iterator remains - * unchanged after redesign of SMDS to avoid modification everywhere in SMESH. - * instances are stored in shared_ptr for automatic destruction. - * Container is copied for iteration, because original can be modified - * by addition of elements, for instance, and then reallocated (vector) + * Template class used for iteration on vector of elements which can resize + * during iteration. The iterator returns only elements present upon its creation. */ template class MySetIterator : public SMDS_Iterator { protected: - typename TSET::const_iterator _it, _end; - TSET _table; + int _iCur, _iEnd, _iDelta; + const TSET& _table; public: - MySetIterator(const TSET& table) + MySetIterator(const TSET& table, bool reverse): _table( table ) { - _table = table; - _it = _table.begin(); - _end = _table.end(); - while ((_it != _end) && (*_it == 0)) - _it++; + if ( reverse ) + { + _iCur = _table.size()-1; + _iEnd = -1; + _iDelta = -1; + } + else + { + _iCur = 0; + _iEnd = _table.size(); + _iDelta = 1; + } + if ( more() && !_table[ _iCur ]) + next(); } virtual bool more() { - while ((_it != _end) && (*_it == 0)) - _it++; - return (_it != _end); + return ( _iEnd - _iCur ) * _iDelta > 0; } virtual ELEM next() { - ELEM e = *_it; - _it++; + ELEM e = more() ? _table[ _iCur ] : 0; + _iCur += _iDelta; + while ( more() && !_table[ _iCur ]) + _iCur += _iDelta; return e; } }; @@ -361,13 +367,13 @@ public: //purpose : //======================================================================= -SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const +SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements( bool reverse ) const { if ( IsComplexSubmesh() ) return SMDS_ElemIteratorPtr( new MyElemIterator( mySubMeshes )); - return SMDS_ElemIteratorPtr - (new MySetIterator >(myElements)); + typedef MySetIterator< const SMDS_MeshElement*, std::vector > TIter; + return SMDS_ElemIteratorPtr( new TIter( myElements, reverse )); } //======================================================================= @@ -375,13 +381,13 @@ SMDS_ElemIteratorPtr SMESHDS_SubMesh::GetElements() const //purpose : //======================================================================= -SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes() const +SMDS_NodeIteratorPtr SMESHDS_SubMesh::GetNodes( bool reverse ) const { if ( IsComplexSubmesh() ) return SMDS_NodeIteratorPtr( new MyNodeIterator( mySubMeshes )); - return SMDS_NodeIteratorPtr - (new MySetIterator >(myNodes)); + typedef MySetIterator< const SMDS_MeshNode*, std::vector > TIter; + return SMDS_NodeIteratorPtr( new TIter( myNodes, reverse )); } //======================================================================= @@ -478,7 +484,7 @@ void SMESHDS_SubMesh::RemoveAllSubmeshes() //======================================================================= //function : ContainsSubMesh -//purpose : +//purpose : //======================================================================= bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const @@ -488,7 +494,7 @@ bool SMESHDS_SubMesh::ContainsSubMesh( const SMESHDS_SubMesh* theSubMesh ) const //======================================================================= //function : GetSubMeshIterator -//purpose : +//purpose : //======================================================================= SMESHDS_SubMeshIteratorPtr SMESHDS_SubMesh::GetSubMeshIterator() const @@ -561,6 +567,10 @@ void SMESHDS_SubMesh::compactList() myElements.swap(newElems); myUnusedIdElements = 0; } + else + { + std::vector( myElements ).swap( myElements ); + } if ( myUnusedIdNodes > 0 ) { @@ -576,6 +586,10 @@ void SMESHDS_SubMesh::compactList() myNodes.swap(newNodes); myUnusedIdNodes = 0; } + else + { + std::vector( myNodes ).swap( myNodes ); + } } //======================================================================= diff --git a/src/SMESHDS/SMESHDS_SubMesh.hxx b/src/SMESHDS/SMESHDS_SubMesh.hxx index 58266c0bf..9a9d61f63 100644 --- a/src/SMESHDS/SMESHDS_SubMesh.hxx +++ b/src/SMESHDS/SMESHDS_SubMesh.hxx @@ -65,9 +65,9 @@ class SMESHDS_EXPORT SMESHDS_SubMesh // for both types virtual int NbElements() const; - virtual SMDS_ElemIteratorPtr GetElements() const; + virtual SMDS_ElemIteratorPtr GetElements(bool reverse=false) const; virtual int NbNodes() const; - virtual SMDS_NodeIteratorPtr GetNodes() const; + virtual SMDS_NodeIteratorPtr GetNodes(bool reverse=false) const; virtual bool Contains(const SMDS_MeshElement * ME) const; // check if elem or node is in virtual bool IsQuadratic() const; diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index cd4da8a73..1803c634d 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -975,6 +975,7 @@ namespace aSel->selectedObjects( selected ); if ( selected.Extent() >= 1 ) { + SUIT_OverrideCursor wc; SALOME_ListIteratorOfListIO It( selected ); for( ; It.More(); It.Next()){ Handle(SALOME_InteractiveObject) IObject = It.Value(); @@ -1595,6 +1596,7 @@ namespace return; } // case SMESHOp::OpProperties: } // switch(theCommandID) + SUIT_OverrideCursor wc; SALOME_ListIteratorOfListIO It( selected ); for( ; It.More(); It.Next()){ Handle(SALOME_InteractiveObject) IObject = It.Value(); @@ -2599,6 +2601,7 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) case SMESHOp::OpOrientationOnFaces: { + SUIT_OverrideCursor wc; LightApp_SelectionMgr* mgr = selectionMgr(); SALOME_ListIO selected; mgr->selectedObjects( selected ); @@ -4377,7 +4380,7 @@ void SMESHGUI::initialize( CAM_Application* app ) isNotEmpty("numberOfNodes <> 0"), // has nodes, edges, etc in VISIBLE! actor - hasNodes("(numberOfNodes > 0 )"),//&& isVisible)"), + hasNodes("(numberOfNodes > 0 ) && hasActor"), hasElems("(count( elemTypes ) > 0)"), hasDifferentElems("(count( elemTypes ) > 1)"), hasBalls("({'BallElem'} in elemTypes)"), @@ -4529,7 +4532,7 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( separator(), anId, -1 ); popupMgr()->insert( action( SMESHOp::OpDEChoose ), anId, -1 ); - popupMgr()->setRule( action( SMESHOp::OpDEChoose ), aClient + "&&" + aType + "&&" + isNotEmpty, QtxPopupMgr::VisibleRule ); + popupMgr()->setRule( action( SMESHOp::OpDEChoose ), aClient + "&& $type in {" + mesh + "} &&" + isNotEmpty, QtxPopupMgr::VisibleRule ); popupMgr()->insert( separator(), anId, -1 ); @@ -4998,19 +5001,6 @@ void SMESHGUI::createPreferences() setPreferenceProperty( lim, "special", tr( "PREF_UPDATE_LIMIT_NOLIMIT" ) ); addPreference( tr( "PREF_INCREMENTAL_LIMIT" ), autoUpdate, LightApp_Preferences::Bool, "SMESH", "incremental_limit" ); - int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab ); - setPreferenceProperty( qaGroup, "columns", 2 ); - addPreference( tr( "PREF_DISPLAY_ENTITY" ), qaGroup, LightApp_Preferences::Bool, "SMESH", "display_entity" ); - addPreference( tr( "PREF_PRECISION_USE" ), qaGroup, LightApp_Preferences::Bool, "SMESH", "use_precision" ); - int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), qaGroup, LightApp_Preferences::IntSpin, "SMESH", "controls_precision" ); - setPreferenceProperty( prec, "min", 0 ); - setPreferenceProperty( prec, "max", 100 ); - int doubleNodesTol = addPreference( tr( "PREF_EQUAL_NODES_TOL" ), qaGroup, LightApp_Preferences::DblSpin, "SMESH", "equal_nodes_tolerance" ); - setPreferenceProperty( doubleNodesTol, "precision", 10 ); - setPreferenceProperty( doubleNodesTol, "min", 0.0000000001 ); - setPreferenceProperty( doubleNodesTol, "max", 1000000.0 ); - setPreferenceProperty( doubleNodesTol, "step", 0.0000001 ); - int dispgroup = addPreference( tr( "PREF_DISPLAY_MODE_GROUP" ), genTab ); setPreferenceProperty( dispgroup, "columns", 2 ); int dispmode = addPreference( tr( "PREF_DISPLAY_MODE" ), dispgroup, LightApp_Preferences::Selector, "SMESH", "display_mode" ); @@ -5044,6 +5034,18 @@ void SMESHGUI::createPreferences() setPreferenceProperty( maxAngle, "min", 1 ); setPreferenceProperty( maxAngle, "max", 90 ); + int qaGroup = addPreference( tr( "PREF_GROUP_QUALITY" ), genTab ); + setPreferenceProperty( qaGroup, "columns", 2 ); + addPreference( tr( "PREF_DISPLAY_ENTITY" ), qaGroup, LightApp_Preferences::Bool, "SMESH", "display_entity" ); + addPreference( tr( "PREF_PRECISION_USE" ), qaGroup, LightApp_Preferences::Bool, "SMESH", "use_precision" ); + int prec = addPreference( tr( "PREF_PRECISION_VALUE" ), qaGroup, LightApp_Preferences::IntSpin, "SMESH", "controls_precision" ); + setPreferenceProperty( prec, "min", 0 ); + setPreferenceProperty( prec, "max", 100 ); + int doubleNodesTol = addPreference( tr( "PREF_EQUAL_NODES_TOL" ), qaGroup, LightApp_Preferences::DblSpin, "SMESH", "equal_nodes_tolerance" ); + setPreferenceProperty( doubleNodesTol, "precision", 10 ); + setPreferenceProperty( doubleNodesTol, "min", 0.0000000001 ); + setPreferenceProperty( doubleNodesTol, "max", 1000000.0 ); + setPreferenceProperty( doubleNodesTol, "step", 0.0000001 ); int exportgroup = addPreference( tr( "PREF_GROUP_EXPORT" ), genTab ); diff --git a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx index e1047b874..d7d455b6d 100644 --- a/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ClippingDlg.cxx @@ -231,34 +231,37 @@ SMESH::OrientedPlane::~OrientedPlane() myPlaneSource->Delete(); } -/*! - Definition of class ActorItem - */ -class ActorItem : public QListWidgetItem +namespace { -public: - ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) : - QListWidgetItem( theName, theListWidget ), - myActor( theActor ) {} + /*! + Definition of class ActorItem + */ + class ActorItem : public QListWidgetItem + { + public: + ActorItem( SMESH_Actor* theActor, const QString& theName, QListWidget* theListWidget ) : + QListWidgetItem( theName, theListWidget ), + myActor( theActor ) {} - SMESH_Actor* getActor() const { return myActor; } + SMESH_Actor* getActor() const { return myActor; } -private: - SMESH_Actor* myActor; -}; + private: + SMESH_Actor* myActor; + }; -/*! - Definition of class TSetVisibility - */ -struct TSetVisibility { - // Set visibility of cutting plane - TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){} - void operator()(SMESH::TPlaneData& thePlaneData){ - bool anIsEmpty = thePlaneData.ActorList.empty(); - thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty); - } - int myIsVisible; -}; + /*! + Definition of class TSetVisibility + */ + struct TSetVisibility { + // Set visibility of cutting plane + TSetVisibility(int theIsVisible): myIsVisible(theIsVisible){} + void operator()(SMESH::TPlaneData& thePlaneData){ + bool anIsEmpty = thePlaneData.ActorList.empty(); + thePlaneData.Plane.GetPointer()->myActor->SetVisibility(myIsVisible && !anIsEmpty); + } + int myIsVisible; + }; +} /********************************************************************************* ********************* class SMESHGUI_ClippingDlg ********************* @@ -476,7 +479,7 @@ SMESHGUI_ClippingDlg::SMESHGUI_ClippingDlg( SMESHGUI* theModule, SVTK_ViewWindow QFont fnt = SpinSliderDistance->font(); fnt.setBold( true ); SpinSliderDistance->setFont( fnt ); GroupParametersLayout->addWidget( SpinSliderDistance, 1, 1 ); - QString aUnitRot = "\xB0"; + QString aUnitRot = QString(QChar(0xB0)); TextLabelRotation1 = new QLabel( tr("ROTATION_AROUND_X_Y2Z"), GroupParameters ); TextLabelRotation1->setObjectName( "TextLabelRotation1" ); @@ -713,46 +716,66 @@ vtkImplicitPlaneWidget* SMESHGUI_ClippingDlg::createPreviewWidget() return aPlaneWgt; } -/*! - Translate two angles of plane to normal -*/ -void rotationToNormal ( double theRotation[2], - int theOrientation, - double theNormal[3], - double theDir[2][3] ) +namespace { - static double aCoeff = M_PI/180.0; - - double anU[2] = { cos( aCoeff * theRotation[0] ), cos( aCoeff * theRotation[1] ) }; - double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) }; - aV[0] = theRotation[0] > 0? aV[0]: -aV[0]; - aV[1] = theRotation[1] > 0? aV[1]: -aV[1]; + /*! + Translate two angles of plane to normal + */ + void rotationToNormal ( double theRotation[2], + int theOrientation, + double theNormal[3], + double theDir[2][3] ) + { + static double aCoeff = M_PI/180.0; + + double anU[2] = { cos( aCoeff * theRotation[0] ), cos( aCoeff * theRotation[1] ) }; + double aV[2] = { sqrt( 1.0 - anU[0]*anU[0] ), sqrt( 1.0 - anU[1] * anU[1] ) }; + aV[0] = theRotation[0] > 0? aV[0]: -aV[0]; + aV[1] = theRotation[1] > 0? aV[1]: -aV[1]; + + switch ( theOrientation ) { + case 0: + case 1: + theDir[0][1] = anU[0]; + theDir[0][2] = aV[0]; + theDir[1][0] = anU[1]; + theDir[1][2] = aV[1]; + break; + case 2: + theDir[0][2] = anU[0]; + theDir[0][0] = aV[0]; + theDir[1][1] = anU[1]; + theDir[1][0] = aV[1]; + break; + case 3: + theDir[0][0] = anU[0]; + theDir[0][1] = aV[0]; + theDir[1][2] = anU[1]; + theDir[1][1] = aV[1]; + break; + } - switch ( theOrientation ) { - case 0: - case 1: - theDir[0][1] = anU[0]; - theDir[0][2] = aV[0]; - theDir[1][0] = anU[1]; - theDir[1][2] = aV[1]; - break; - case 2: - theDir[0][2] = anU[0]; - theDir[0][0] = aV[0]; - theDir[1][1] = anU[1]; - theDir[1][0] = aV[1]; - break; - case 3: - theDir[0][0] = anU[0]; - theDir[0][1] = aV[0]; - theDir[1][2] = anU[1]; - theDir[1][1] = aV[1]; - break; + vtkMath::Cross( theDir[1], theDir[0], theNormal ); + vtkMath::Normalize( theNormal ); + vtkMath::Cross( theNormal, theDir[1], theDir[0] ); } - vtkMath::Cross( theDir[1], theDir[0], theNormal ); - vtkMath::Normalize( theNormal ); - vtkMath::Cross( theNormal, theDir[1], theDir[0] ); + /*! + * \brief Return a name of a father mesh if any + */ + QString getFatherName( _PTR(SObject)& theSObj ) + { + _PTR(SComponent) objComponent = theSObj->GetFatherComponent(); + const int theMeshDepth = 1 + objComponent->Depth(); + if ( theSObj->Depth() <= theMeshDepth ) + return QString(); // theSObj is a mesh + + _PTR(SObject) sobj = theSObj->GetFather(); + while ( sobj && sobj->Depth() > theMeshDepth ) + sobj = sobj->GetFather(); + + return sobj ? sobj->GetName().c_str() : ""; + } } /*! @@ -1063,6 +1086,8 @@ void SMESHGUI_ClippingDlg::updateActorList() std::for_each( myPlanes.begin(),myPlanes.end(), TSetVisibility( PreviewCheckBox->isChecked() ) ); aPlaneData.Plane.GetPointer()->myActor->SetVisibility( false ); + std::map< std::string, QListWidgetItem* > itemMap; // used to sort items by entry + VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); vtkActorCollection* anAllActors = aCopy.GetActors(); anAllActors->InitTraversal(); @@ -1084,13 +1109,24 @@ void SMESHGUI_ClippingDlg::updateActorList() } } QString aName = QString( aSObj->GetName().c_str() ); - QListWidgetItem* anItem = new ActorItem( anActor, aName, ActorList ); + QString aFatherName = getFatherName( aSObj ); + if ( !aFatherName.isEmpty() ) + aName = aFatherName + " / " + aName; + aName += QString(" (%1)").arg( aSObj->GetID().c_str() ); + QListWidgetItem* anItem = new ActorItem( anActor, aName, 0 ); anItem->setCheckState( anIsChecked ? Qt::Checked : Qt::Unchecked ); - updateActorItem( anItem, true, false ); + itemMap.insert( std::make_pair( aSObj->GetID(), anItem )); } } } } + std::map< std::string, QListWidgetItem* >::iterator s2i = itemMap.begin(); + for ( ; s2i != itemMap.end(); ++s2i ) + { + QListWidgetItem* anItem = s2i->second; + ActorList->addItem( anItem ); + } + updateActorItem( 0, true, false ); } /*! @@ -1231,16 +1267,19 @@ void SMESHGUI_ClippingDlg::ClickOnNew() SMESH::OrientedPlane* aPlane = SMESH::OrientedPlane::New(myViewWindow); SMESH::TPlane aTPlane(aPlane); aPlane->PlaneMode = CurrentMode; - SMESH::TActorList anActorList; + SMESH::TActorList anActorList, aVisibleActorList; VTK::ActorCollectionCopy aCopy( myViewWindow->getRenderer()->GetActors() ); vtkActorCollection* anAllActors = aCopy.GetActors(); anAllActors->InitTraversal(); while( vtkActor* aVTKActor = anAllActors->GetNextActor() ) if( SMESH_Actor* anActor = SMESH_Actor::SafeDownCast( aVTKActor ) ) + { anActorList.push_back( anActor ); - - SMESH::TPlaneData aPlaneData(aTPlane, anActorList); - + if ( anActor->GetVisibility() ) + aVisibleActorList.push_back( anActor ); + } + SMESH::TPlaneData aPlaneData(aTPlane, + aVisibleActorList.empty() ? anActorList : aVisibleActorList); myPlanes.push_back(aPlaneData); diff --git a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx index 072b48175..752957abd 100644 --- a/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ComputeDlg.cxx @@ -54,6 +54,7 @@ #include #include #include +#include #include // SALOME KERNEL includes @@ -95,6 +96,7 @@ // VTK includes #include +#include // STL includes #include @@ -1008,6 +1010,11 @@ void SMESHGUI_BaseComputeOp::computeMesh() Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject ( (*anIter).second->GetID().c_str(), "SMESH", (*anIter).second->GetName().c_str() ); SMESH::Update(anIO, toDisplay); + if( SVTK_ViewWindow* vtkWnd = SMESH::GetVtkViewWindow(SMESH::GetActiveWindow() ) ) { + if( vtkWnd->getRenderer() ){ + vtkWnd->getRenderer()->ResetCameraClippingRange(); + } + } if ( limitExceeded && !aMesh->_is_nil() ) { diff --git a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx index 240523d4c..d182aa07c 100755 --- a/src/SMESHGUI/SMESHGUI_FilterDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_FilterDlg.cxx @@ -3489,7 +3489,8 @@ void SMESHGUI_FilterDlg::UnRegisterFilters() //======================================================================= void SMESHGUI_FilterDlg::insertFilterInViewer() { - if (SVTK_Selector* aSelector = SMESH::GetSelector()) { + if (SVTK_Selector* aSelector = SMESH::GetSelector()) + { SMESH::ElementType anEntType = (SMESH::ElementType)myTable->GetType(); if (myFilter[ myTable->GetType() ]->_is_nil() || @@ -3499,7 +3500,8 @@ void SMESHGUI_FilterDlg::insertFilterInViewer() { SMESH::RemoveFilter(getFilterId(anEntType), aSelector); } - else { + else + { Handle(SMESHGUI_PredicateFilter) aFilter = new SMESHGUI_PredicateFilter(); aFilter->SetPredicate(myFilter[ myTable->GetType() ]->GetPredicate()); SMESH::RemoveFilter(getFilterId(anEntType), aSelector); //skl for IPAL12631 @@ -3659,7 +3661,7 @@ SMESH_Actor* SMESHGUI_FilterDlg::getActor() //======================================================================= void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QList& theIds) { - if (mySelectionMgr == 0 || myMesh->_is_nil()) + if (mySelectionMgr == 0 || myMesh->_is_nil() ) return; mySelectionMgr->clearFilters(); @@ -3667,7 +3669,8 @@ void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QList& th // Set new selection mode if necessary Selection_Mode aSelMode = getSelMode(theType); SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI ); - if ( aViewWindow && aViewWindow->SelectionMode()!=aSelMode) { + if ( aViewWindow && aViewWindow->SelectionMode() != aSelMode ) + { mySelectionMgr->clearSelected(); mySelectionMgr->clearFilters(); SMESH::SetPointRepresentation( aSelMode == NodeSelection ); @@ -3680,8 +3683,6 @@ void SMESHGUI_FilterDlg::selectInViewer (const int theType, const QList& th return; Handle(SALOME_InteractiveObject) anIO = anActor->getIO(); - //mySelectionMgr->clearSelected(); - //mySelectionMgr->AddIObject(anIO, false); SALOME_ListIO aList; aList.Append(anIO); mySelectionMgr->setSelectedObjects(aList, false); diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx index 9a5e014ff..f313c8ce2 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.cxx +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.cxx @@ -29,6 +29,8 @@ #include "SMESHGUI_HypothesesUtils.h" #include "SMESHGUI_Utils.h" #include "SMESHGUI_SpinBox.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESH_Actor.h" // SALOME KERNEL includes #include @@ -42,6 +44,7 @@ #include #include #include +#include // Qt includes #include @@ -91,7 +94,9 @@ void SMESHGUI_GenericHypothesisCreator::create( SMESH::SMESH_Hypothesis_ptr init void SMESHGUI_GenericHypothesisCreator::create( bool isAlgo, const QString& theHypName, - QWidget* theParent, QObject* obj, const QString& slot ) + QWidget* theParent, + QObject* obj, + const QString& slot ) { myIsCreate = true; @@ -313,6 +318,9 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result ) aMesh = aSubMesh->GetFather(); _PTR(SObject) meshSO = SMESH::FindSObject( aMesh ); SMESH::ModifiedMesh( meshSO, false, aMesh->NbNodes()==0); + SMESH_Actor* actor = SMESH::FindActorByEntry( meshSO->GetID().c_str() ); + if( actor && actor->GetVisibility() ) + actor->Update(); } } SMESHGUI::GetSMESHGUI()->updateObjBrowser( true, 0 ); @@ -324,6 +332,9 @@ void SMESHGUI_GenericHypothesisCreator::onDialogFinished( int result ) myDlg->close(); //delete myDlg; since WA_DeleteOnClose==true myDlg = 0; + if (SVTK_ViewWindow* vf = SMESH::GetCurrentVtkView()) { + vf->Repaint(); + } emit finished( result ); } @@ -732,21 +743,23 @@ void SMESHGUI_HypothesisDlg::setType( const QString& t ) myTypeLabel->setText( t ); } -HypothesisData::HypothesisData( const QString& theTypeName, - const QString& thePluginName, - const QString& theServerLibName, - const QString& theClientLibName, - const QString& theLabel, - const QString& theIconId, - const QString& theContext, - const QList& theDim, - const bool theIsAuxOrNeedHyp, +HypothesisData::HypothesisData( const QString& theTypeName, + const QString& thePluginName, + const QString& theServerLibName, + const QString& theClientLibName, + const QString& theLabel, + const QString& theIconId, + const QString& theContext, + const int theGroupID, + const int thePriority, + const QList& theDim, + const bool theIsAuxOrNeedHyp, const QStringList& theBasicHypos, const QStringList& theOptionalHypos, const QStringList& theInputTypes, const QStringList& theOutputTypes, - const bool theIsNeedGeometry, - const bool supportSub) + const int theIsNeedGeometry, + const bool theSupportSub) : TypeName( theTypeName ), PluginName( thePluginName ), ServerLibName( theServerLibName ), @@ -754,10 +767,12 @@ HypothesisData::HypothesisData( const QString& theTypeName, Label( theLabel ), IconId( theIconId ), Context( theContext ), + GroupID( theGroupID ), + Priority( thePriority ), Dim( theDim ), IsAuxOrNeedHyp( theIsAuxOrNeedHyp ), IsNeedGeometry( theIsNeedGeometry ), - IsSupportSubmeshes( supportSub ), + IsSupportSubmeshes( theSupportSub ), BasicHypos( theBasicHypos ), OptionalHypos( theOptionalHypos ), InputTypes( theInputTypes ), diff --git a/src/SMESHGUI/SMESHGUI_Hypotheses.h b/src/SMESHGUI/SMESHGUI_Hypotheses.h index 6eb03fa9b..f989a49ff 100644 --- a/src/SMESHGUI/SMESHGUI_Hypotheses.h +++ b/src/SMESHGUI/SMESHGUI_Hypotheses.h @@ -72,6 +72,9 @@ public: QString getMainShapeEntry() const { return myMainShapeEntry; } void setMainShapeEntry( const QString& theEntry ) { myMainShapeEntry = theEntry; } + void setNoGeomMesh( const bool noGeom ) { myNoGeomMesh = noGeom; } + bool getNoGeomMesh() const { return myNoGeomMesh; } + signals: void finished( int ); @@ -138,6 +141,7 @@ private: ListOfWidgets myParamWidgets; ListOfWidgets myParamLabels; bool myIsCreate; + bool myNoGeomMesh; //!< true for a mesh not based on geometry QtxDialog* myDlg; QString myShapeEntry; QString myMainShapeEntry; @@ -173,10 +177,11 @@ struct HypothesisData { HypothesisData( const QString&, const QString&, const QString&, const QString&, const QString&, const QString&, - const QString&, const QList&, const bool, + const QString&, const int, const int, + const QList&, const bool, const QStringList&, const QStringList&, const QStringList&, const QStringList&, - const bool=true, const bool supportSub=false ); + const int, const bool supportSub ); QString TypeName; //!< hypothesis type name QString PluginName; //!< plugin name @@ -185,11 +190,15 @@ struct HypothesisData QString Label; //!< label QString IconId; //!< icon identifier QString Context; //!< ["GLOBAL","LOCAL","ANY"(default)] + int GroupID; //!< group ID (staring from zero) + int Priority; //!< integer, priority within the group QList Dim; //!< list of supported dimensions (see SMESH::Dimension enumeration) - bool IsAuxOrNeedHyp; //!< TRUE if given hypothesis is auxiliary one, FALSE otherwise - //!< TRUE if given algorithm can't work w/o hypotheses - bool IsNeedGeometry; //!< TRUE if the algorithm works with shapes only, FALSE otherwise - bool IsSupportSubmeshes; //!< TRUE if the algo building all-dim elems supports submeshes + bool IsAuxOrNeedHyp; //!< TRUE if given HYPOTHESIS is auxiliary one, FALSE otherwise + //!< TRUE if given ALGORITHM can't work w/o hypotheses + int IsNeedGeometry; //!< 1 if the algorithm works with shapes only, + //!< -1 if the algorithm works without shapes only, + //!< 0 if the algorithm works in both cases + bool IsSupportSubmeshes; //!< TRUE if the algorithm building all-dim elems supports sub-meshes // for algorithm only: dependencies algo <-> algo and algo -> hypos QStringList BasicHypos; //!< list of basic hypotheses diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx index fc1f8c5e2..33baabf0b 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx @@ -28,10 +28,13 @@ #include "SMESHGUI_HypothesesUtils.h" #include "SMESHGUI.h" +#include "SMESHGUI_GEOMGenUtils.h" #include "SMESHGUI_Hypotheses.h" -#include "SMESHGUI_XmlHandler.h" #include "SMESHGUI_Utils.h" -#include "SMESHGUI_GEOMGenUtils.h" +#include "SMESHGUI_VTKUtils.h" +#include "SMESHGUI_XmlHandler.h" + +#include "SMESH_Actor.h" // SALOME GUI includes #include @@ -49,9 +52,7 @@ #include // Qt includes -#include #include -//#include // Other includes @@ -68,7 +69,7 @@ #define UnLoadLib( handle ) FreeLibrary( handle ); #else #define LibHandle void* -#define LoadLib( name ) dlopen( name, RTLD_LAZY ) +#define LoadLib( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL ) #define GetProc dlsym #define UnLoadLib( handle ) dlclose( handle ); #endif @@ -180,7 +181,8 @@ namespace SMESH void InitAvailableHypotheses() { SUIT_OverrideCursor wc; - if (myHypothesesMap.empty() && myAlgorithmsMap.empty()) { + if ( myHypothesesMap.empty() && myAlgorithmsMap.empty() ) + { // Resource manager SUIT_ResourceMgr* resMgr = SMESHGUI::resourceMgr(); if (!resMgr) return; @@ -283,14 +285,14 @@ namespace SMESH QStringList GetAvailableHypotheses( const bool isAlgo, const int theDim, const bool isAux, - const bool isNeedGeometry, + const bool hasGeometry, const bool isSubMesh) { QStringList aHypList; // Init list of available hypotheses, if needed InitAvailableHypotheses(); - bool checkGeometry = ( !isNeedGeometry && isAlgo ); + bool checkGeometry = ( isAlgo ); const char* context = isSubMesh ? "LOCAL" : "GLOBAL"; // fill list of hypotheses/algorithms THypothesisDataMap& pMap = isAlgo ? myAlgorithmsMap : myHypothesesMap; @@ -302,7 +304,8 @@ namespace SMESH ( theDim < 0 || aData->Dim.contains( theDim )) && ( isAlgo || aData->IsAuxOrNeedHyp == isAux ) && ( aData->Context == "ANY" || aData->Context == context ) && - ( !checkGeometry || aData->IsNeedGeometry == isNeedGeometry )) + ( !checkGeometry || (!aData->IsNeedGeometry || + ( aData->IsNeedGeometry > 0 ) == hasGeometry))) { aHypList.append(anIter.key()); } @@ -369,6 +372,90 @@ namespace SMESH return aHypData; } + //================================================================================ + /*! + * \brief Return the HypothesisData holding a name of a group of hypotheses + * a given hypothesis belongs to + */ + //================================================================================ + + HypothesisData* GetGroupTitle( const HypothesisData* hyp, const bool isAlgo ) + { + static std::vector< std::vector< HypothesisData > > theGroups; + if ( theGroups.empty() ) + { + theGroups.resize(14); // 14: isAlgo * 10 + dim + + QString dummyS("GROUP"); + QList dummyIL; dummyIL << 1; + QStringList dummySL; + HypothesisData group( dummyS,dummyS,dummyS,dummyS,dummyS,dummyS,dummyS,-1,-1, + dummyIL, 0, dummySL,dummySL,dummySL,dummySL,0,0 ); + // no group + int key = 0; + theGroups[ key ].push_back( group ); + + // 1D algo + key = 11; + // 0: Basic + group.Label = "GROUP:" + QObject::tr( "SMESH_1D_ALGO_GROUP_BASIC" ); + theGroups[ key ].push_back( group ); + // 1: Advanced + group.Label = "GROUP:" + QObject::tr( "SMESH_1D_ALGO_GROUP_ADVANCED" ); + theGroups[ key ].push_back( group ); + + // 1D hypotheses + key = 01; + // 0: Basic + group.Label = "GROUP:" + QObject::tr( "SMESH_1D_HYP_GROUP_BASIC" ); + theGroups[ key ].push_back( group ); + // 1: Progression + group.Label = "GROUP:" + QObject::tr( "SMESH_1D_HYP_GROUP_PROGRESSION" ); + theGroups[ key ].push_back( group ); + // 2: Advanced + group.Label = "GROUP:" + QObject::tr( "SMESH_1D_HYP_GROUP_ADVANCED" ); + theGroups[ key ].push_back( group ); + + // 2D algo + key = 12; + // 0: Regular + group.Label = "GROUP:" + QObject::tr( "SMESH_2D_ALGO_GROUP_REGULAR" ); + theGroups[ key ].push_back( group ); + // 1: Free + group.Label = "GROUP:" + QObject::tr( "SMESH_2D_ALGO_GROUP_FREE" ); + theGroups[ key ].push_back( group ); + // 2: Advanced + group.Label = "GROUP:" + QObject::tr( "SMESH_2D_ALGO_GROUP_ADVANCED" ); + theGroups[ key ].push_back( group ); + + // 3D algo + key = 13; + // 0: Regular + group.Label = "GROUP:" + QObject::tr( "SMESH_3D_ALGO_GROUP_REGULAR" ); + theGroups[ key ].push_back( group ); + // 1: Free + group.Label = "GROUP:" + QObject::tr( "SMESH_3D_ALGO_GROUP_FREE" ); + theGroups[ key ].push_back( group ); + // 2: Advanced + group.Label = "GROUP:" + QObject::tr( "SMESH_3D_ALGO_GROUP_ADVANCED" ); + theGroups[ key ].push_back( group ); + } + + size_t key = 0, groupID = 0; + if ( hyp && !hyp->Dim.isEmpty() ) + { + key = hyp->Dim[0] + isAlgo * 10; + groupID = hyp->GroupID; + } + + if ( key < theGroups.size() && !theGroups[ key ].empty() ) + { + std::vector< HypothesisData > & group = theGroups[ key ]; + return & ( groupID < group.size() ? group[ groupID ] : group.back() ); + } + return & theGroups[ 0 ][ 0 ]; + } + bool IsAvailableHypothesis(const HypothesisData* algoData, const QString& hypType, bool& isAuxiliary) @@ -617,29 +704,29 @@ namespace SMESH _PTR(Study) aStudy = GetActiveStudyDocument(); _PTR(SObject) aHypObj = aStudy->FindObjectID( IObject->getEntry() ); if( aHypObj ) + { + _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj ); + _PTR(SObject) aRealHypo; + if( aHypObj->ReferencedObject( aRealHypo ) ) { - _PTR(SObject) MorSM = SMESH::GetMeshOrSubmesh( aHypObj ); - _PTR(SObject) aRealHypo; - if( aHypObj->ReferencedObject( aRealHypo ) ) - { - SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) ); - RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo ); - } - else - { - SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) ); - SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo ); - for( size_t i = 0; i < meshList.size(); i++ ) - RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo ); - } + SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aRealHypo ) ); + RemoveHypothesisOrAlgorithmOnMesh( MorSM, hypo ); + } + else + { + SMESH_Hypothesis_var hypo = SMESH_Hypothesis::_narrow( SObjectToObject( aHypObj ) ); + SObjectList meshList = GetMeshesUsingAlgoOrHypothesis( hypo ); + for( size_t i = 0; i < meshList.size(); i++ ) + RemoveHypothesisOrAlgorithmOnMesh( meshList[ i ], hypo ); } + } } catch(const SALOME::SALOME_Exception& S_ex) - { - wc.suspend(); - SalomeApp_Tools::QtCatchCorbaException(S_ex); - res = SMESH::HYP_UNKNOWN_FATAL; - } + { + wc.suspend(); + SalomeApp_Tools::QtCatchCorbaException(S_ex); + res = SMESH::HYP_UNKNOWN_FATAL; + } return res < SMESH::HYP_UNKNOWN_FATAL; } @@ -661,26 +748,24 @@ namespace SMESH if (!aMesh->_is_nil()) { if (aMesh->HasShapeToMesh() && !aShapeObject->_is_nil()) { res = aMesh->RemoveHypothesis(aShapeObject, anHyp); - if (res < SMESH::HYP_UNKNOWN_FATAL) { - _PTR(SObject) meshSO = SMESH::FindSObject(aMesh); - if (meshSO) - SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); - } - } else if(!aMesh->HasShapeToMesh()){ res = aMesh->RemoveHypothesis(aShapeObject, anHyp); - if (res < SMESH::HYP_UNKNOWN_FATAL) { - _PTR(SObject) meshSO = SMESH::FindSObject(aMesh); - if (meshSO) - SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); - } } if (res > SMESH::HYP_OK) { wc.suspend(); processHypothesisStatus(res, anHyp, false); wc.resume(); } + if ( _PTR(SObject) meshSO = SMESH::FindSObject(aMesh) ) + { + if ( res < SMESH::HYP_UNKNOWN_FATAL ) + SMESH::ModifiedMesh(meshSO, false, aMesh->NbNodes()==0); + + if ( SMESH_Actor* actor = SMESH::FindActorByEntry( meshSO->GetID().c_str() )) + if( actor->GetVisibility() ) + actor->Update(); + } } } catch(const SALOME::SALOME_Exception& S_ex) { wc.suspend(); diff --git a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h index 70314e2ca..0bf059af1 100644 --- a/src/SMESHGUI/SMESHGUI_HypothesesUtils.h +++ b/src/SMESHGUI/SMESHGUI_HypothesesUtils.h @@ -78,6 +78,9 @@ namespace SMESH SMESHGUI_EXPORT HypothesisData* GetHypothesisData( const QString& ); + SMESHGUI_EXPORT + HypothesisData* GetGroupTitle( const HypothesisData* hyp, const bool isAlgo ); + SMESHGUI_EXPORT bool IsAvailableHypothesis( const HypothesisData*, const QString&, diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx index ad2adb520..0c492b5d7 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.cxx @@ -30,6 +30,7 @@ // SALOME GUI includes #include #include +#include // Qt includes #include @@ -163,19 +164,32 @@ SMESHGUI_MeshTab::~SMESHGUI_MeshTab() * \param [in] txt - item text * \param [in] type - HypType * \param [in] index - index of item in a list of items + * \param [in] isGroup - is the item a group title */ //================================================================================ - -void SMESHGUI_MeshTab::addItem( const QString& txt, const int type, const int index ) +void SMESHGUI_MeshTab::addItem( const QString& txt, + const int type, + const int index, + const bool isGroup ) { + const char* prefix = " "; if ( type <= AddHyp ) { - myHypCombo[ type ]->addItem( txt, QVariant( index )); - myHypCombo[ type ]->setMaxVisibleItems( qMax( 10, myHypCombo[ type ]->count() ) ); + if ( isGroup ) + { + int idx = myHypCombo[ type ]->count(); + myHypCombo[ type ]->addItem( txt.mid( 6 ), QVariant( index )); + myHypCombo[ type ]->setItemData( idx, "separator", Qt::AccessibleDescriptionRole ); + } + else + { + myHypCombo[ type ]->addItem( prefix + txt, QVariant( index )); + } + //myHypCombo[ type ]->setMaxVisibleItems( qMax( 10, myHypCombo[ type ]->count() ) ); } else { - QListWidgetItem* item = new QListWidgetItem( txt, myAddHypList ); + QListWidgetItem* item = new QListWidgetItem( prefix + txt, myAddHypList ); item->setData( Qt::UserRole, QVariant( index )); } } @@ -185,7 +199,6 @@ void SMESHGUI_MeshTab::addItem( const QString& txt, const int type, const int in * \brief Returns index of hyp of a given type */ //================================================================================ - int SMESHGUI_MeshTab::getCurrentIndex( const int type, const bool curByType ) const { if ( type <= AddHyp ) @@ -222,7 +235,7 @@ void SMESHGUI_MeshTab::setAvailableHyps( const int theId, const QStringList& the { addItem( tr( "NONE"), Algo, 0 ); for ( int i = 0, nbHyp = theHyps.count(); i < nbHyp; ++i ) - addItem( theHyps[i], Algo, i+1 ); + addItem( theHyps[i], Algo, i+1, theHyps[i].startsWith( "GROUP:" )); myHypCombo[ Algo ]->setCurrentIndex( 0 ); } } @@ -296,24 +309,6 @@ void SMESHGUI_MeshTab::addHyp( const int theId, const QString& theHyp ) myMoreAddHypBtn->setEnabled( true ); } -//================================================================================ -/*! - * \brief Renames hypothesis - * \param theId - identifier of hypothesis (main or additional, see HypType enumeration) - * \param theIndex - index of hypothesis to be renamed - * \param theNewName - new name of hypothesis to be renamed - * - * Renames hypothesis - */ -//================================================================================ -// void SMESHGUI_MeshTab::renameHyp( const int theId, -// const int theIndex, -// const QString& theNewName ) -// { -// if ( theIndex > 0 && theIndex < myHypCombo[ theId ]->count() ) -// myHypCombo[ theId ]->setItemText( theIndex, theNewName ); -// } - //================================================================================ /*! * \brief Sets current hypothesis @@ -382,7 +377,6 @@ int SMESHGUI_MeshTab::currentHyp( const int theId ) const * range 0 <= i < this->nbAddHypTypes() */ //================================================================================ - int SMESHGUI_MeshTab::nbAddHypTypes() const { return myAddHypList->count(); @@ -400,15 +394,25 @@ void SMESHGUI_MeshTab::onCreateHyp() { bool isMainHyp = ( sender() == myCreateHypBtn[ MainHyp ]); - QMenu aPopup( this ); + QtxMenu aPopup( this ); QStringList aHypNames = isMainHyp ? myAvailableHypTypes[ MainHyp ] : myAvailableHypTypes[ AddHyp ]; QList actions; for ( int i = 0, n = aHypNames.count(); i < n; i++ ) - actions.append( aPopup.addAction( aHypNames[ i ] ) ); - + { + QAction* a = 0; + if ( aHypNames[ i ].startsWith( "GROUP:" )) + { + aPopup.appendGroupTitle( aHypNames[ i ].mid( 6 )); + } + else + { + a = aPopup.addAction( aHypNames[ i ] ); + } + actions.append( a ); + } QAction* a = aPopup.exec( QCursor::pos() ); if ( a ) emit createHyp( isMainHyp ? MainHyp : AddHyp, actions.indexOf( a ) ); @@ -444,7 +448,18 @@ void SMESHGUI_MeshTab::onEditHyp() //================================================================================ void SMESHGUI_MeshTab::onHyp( int theIndex ) { - const QObject* aSender = sender(); + QObject* aSender = sender(); + + if ( QComboBox* cb = qobject_cast< QComboBox* >( aSender )) + { + // don't allow selecting a group title + if ( cb->itemData( theIndex, Qt::AccessibleDescriptionRole ) == "separator" ) + { + cb->setCurrentIndex( theIndex+1 ); + return; + } + } + if ( aSender == myHypCombo[ Algo ] ) { emit selectAlgo( theIndex - 1 ); // - 1 because there is NONE on the top @@ -471,7 +486,6 @@ void SMESHGUI_MeshTab::onHyp( int theIndex ) * SLOT called when myMoreAddHypBtn ("plus") clicked */ //================================================================================ - void SMESHGUI_MeshTab::onMoreAddHyp() { int hypIndex = currentHyp( AddHyp ); @@ -496,7 +510,6 @@ void SMESHGUI_MeshTab::onMoreAddHyp() * SLOT called when myLessAddHypBtn ("minus") clicked */ //================================================================================ - void SMESHGUI_MeshTab::onLessAddHyp() { if ( QListWidgetItem * item = myAddHypList->currentItem() ) @@ -636,7 +649,6 @@ SMESHGUI_MeshDlg::~SMESHGUI_MeshDlg() * \brief Set dialog title */ //================================================================================ - void SMESHGUI_MeshDlg::setTitile( const bool theToCreate, const bool theIsMesh ) { if ( theToCreate ) @@ -695,7 +707,6 @@ void SMESHGUI_MeshDlg::setCurrentTab( const int theId ) * \param int - maximum possible dimention */ //================================================================================ - void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim ) { const int DIM = maxDim; @@ -719,7 +730,6 @@ void SMESHGUI_MeshDlg::setMaxHypoDim( const int maxDim ) * \brief Sets list of available Sets of Hypotheses */ //================================================================================ - void SMESHGUI_MeshDlg::setHypoSets( const QStringList& theSets ) { QMenu* aHypoSetPopup = myHypoSetButton->menu(); @@ -744,7 +754,6 @@ void SMESHGUI_MeshDlg::setHypoSets( const QStringList& theSets ) * signal to notify operation about this event */ //================================================================================ - void SMESHGUI_MeshDlg::onHypoSetPopup( QAction* a ) { emit hypoSet( a->text() ); @@ -789,9 +798,9 @@ void SMESHGUI_MeshDlg::setGeomPopupEnabled( const bool enable ) * \param int - tab ID */ //================================================================================ -void SMESHGUI_MeshDlg::disableTab(const int theTabId) { +void SMESHGUI_MeshDlg::disableTab(const int theTabId) +{ myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), false ); - if ( theTabId == Dim3D ) myHypoSetButton->setEnabled( false ); } //================================================================================ @@ -800,7 +809,8 @@ void SMESHGUI_MeshDlg::disableTab(const int theTabId) { * \param int - tab ID */ //================================================================================ -void SMESHGUI_MeshDlg::enableTab(const int theTabId) { +void SMESHGUI_MeshDlg::enableTab(const int theTabId) +{ myTabWg->setTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ), true ); if ( theTabId == Dim3D ) { QMenu* aHypoSetPopup = myHypoSetButton->menu(); @@ -814,21 +824,37 @@ void SMESHGUI_MeshDlg::enableTab(const int theTabId) { * \param int - tab ID */ //================================================================================ -bool SMESHGUI_MeshDlg::isTabEnabled(const int theTabId) const { +bool SMESHGUI_MeshDlg::isTabEnabled(const int theTabId) const +{ return myTabWg->isTabEnabled( myTabWg->indexOf( myTabs[ theTabId ] ) ); } +//================================================================================ +/*! + * \brief SLOT called when a Geom selection button is clicked + */ +//================================================================================ void SMESHGUI_MeshDlg::onGeomSelectionButton(bool isBtnOn) { if ( myGeomPopup && isBtnOn ) myGeomPopup->exec( QCursor::pos() ); } +//================================================================================ +/*! + * \brief SLOT called when a item of Geom selection popup is choosen + */ +//================================================================================ void SMESHGUI_MeshDlg::onGeomPopup( QAction* a ) { emit geomSelectionByMesh( a->data().toInt() == GEOM_BY_MESH_INDEX ); } +//================================================================================ +/*! + * \brief Return ID of an active selection button + */ +//================================================================================ int SMESHGUI_MeshDlg::getActiveObject() { for (int i = 0; i < 3; ++i ) diff --git a/src/SMESHGUI/SMESHGUI_MeshDlg.h b/src/SMESHGUI/SMESHGUI_MeshDlg.h index 9c0337420..afc499f34 100644 --- a/src/SMESHGUI/SMESHGUI_MeshDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshDlg.h @@ -150,7 +150,7 @@ private slots: private: - void addItem( const QString& txt, const int type, const int index ); + void addItem( const QString& txt, const int type, const int index, const bool isGroup=false ); int getCurrentIndex( const int type, const bool curByType=false) const; QMap myAvailableHypTypes; diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx index 4d7f87a98..b8328b4a6 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.cxx @@ -1956,70 +1956,85 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) QTreeWidgetItem* cntrItem = createItem( elemItem, Bold ); cntrItem->setText( 0, SMESHGUI_ElemInfo::tr( "CONTROLS" ) ); //Length - if( e->GetType()==SMDSAbs_Edge){ + if( e->GetType()==SMDSAbs_Edge){ afunctor.reset( new SMESH::Controls::Length() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); QTreeWidgetItem* lenItem = createItem( cntrItem, Bold ); lenItem->setText( 0, tr( "LENGTH_EDGES" ) ); - lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + lenItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); } if( e->GetType() == SMDSAbs_Face ) { - //Area - afunctor.reset( new SMESH::Controls::Area() ); + //Area + afunctor.reset( new SMESH::Controls::Area() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); QTreeWidgetItem* areaItem = createItem( cntrItem, Bold ); areaItem->setText( 0, tr( "AREA_ELEMENTS" ) ); - areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) ); + areaItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue(id) ) ); //Taper - afunctor.reset( new SMESH::Controls::Taper() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold ); - taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) ); - taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + if ( e->NbNodes() == 4 ) // see SMESH_Controls.cxx + { + afunctor.reset( new SMESH::Controls::Taper() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + afunctor->SetPrecision( cprecision ); + QTreeWidgetItem* taperlItem = createItem( cntrItem, Bold ); + taperlItem->setText( 0, tr( "TAPER_ELEMENTS" ) ); + taperlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + //Wraping angle + afunctor.reset( new SMESH::Controls::Warping() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + afunctor->SetPrecision( cprecision ); + QTreeWidgetItem* warpItem = createItem( cntrItem, Bold ); + warpItem->setText( 0, tr( "WARP_ELEMENTS" )); + warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + } //AspectRatio2D - afunctor.reset( new SMESH::Controls::AspectRatio() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold ); - ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" )); - ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + if ( !e->IsPoly() ) + { + afunctor.reset( new SMESH::Controls::AspectRatio() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + QTreeWidgetItem* ratlItem = createItem( cntrItem, Bold ); + ratlItem->setText( 0, tr( "ASPECTRATIO_ELEMENTS" )); + ratlItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + } //Minimum angle afunctor.reset( new SMESH::Controls::MinimumAngle() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); afunctor->SetPrecision( cprecision ); QTreeWidgetItem* minanglItem = createItem( cntrItem, Bold ); minanglItem->setText( 0, tr( "MINIMUMANGLE_ELEMENTS" ) ); - minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); - //Wraping angle - afunctor.reset( new SMESH::Controls::Warping() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* warpItem = createItem( cntrItem, Bold ); - warpItem->setText( 0, tr( "WARP_ELEMENTS" )); - warpItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); - //Skew - afunctor.reset( new SMESH::Controls::Skew() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - afunctor->SetPrecision( cprecision ); - QTreeWidgetItem* skewItem = createItem( cntrItem, Bold ); - skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) ); - skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); - //ElemDiam2D - afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* diamItem = createItem( cntrItem, Bold ); - diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" )); - diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + minanglItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + //Skew + if ( e->NbNodes() == 3 || e->NbNodes() == 4 ) + { + afunctor.reset( new SMESH::Controls::Skew() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + afunctor->SetPrecision( cprecision ); + QTreeWidgetItem* skewItem = createItem( cntrItem, Bold ); + skewItem->setText( 0, tr( "SKEW_ELEMENTS" ) ); + skewItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + } + //ElemDiam2D + if ( !e->IsPoly() ) + { + afunctor.reset( new SMESH::Controls::MaxElementLength2D() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + QTreeWidgetItem* diamItem = createItem( cntrItem, Bold ); + diamItem->setText( 0, tr( "MAX_ELEMENT_LENGTH_2D" )); + diamItem->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + } } if( e->GetType() == SMDSAbs_Volume ) { - //AspectRatio3D - afunctor.reset( new SMESH::Controls::AspectRatio3D() ); - afunctor->SetMesh( actor()->GetObject()->GetMesh() ); - QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold ); - ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) ); - ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + if ( !e->IsPoly() ) + { + //AspectRatio3D + afunctor.reset( new SMESH::Controls::AspectRatio3D() ); + afunctor->SetMesh( actor()->GetObject()->GetMesh() ); + QTreeWidgetItem* ratlItem3 = createItem( cntrItem, Bold ); + ratlItem3->setText( 0, tr( "ASPECTRATIO_3D_ELEMENTS" ) ); + ratlItem3->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + } //Volume afunctor.reset( new SMESH::Controls::Volume() ); afunctor->SetMesh( actor()->GetObject()->GetMesh() ); @@ -2031,7 +2046,7 @@ void SMESHGUI_TreeElemInfo::information( const QList& ids ) afunctor->SetMesh( actor()->GetObject()->GetMesh() ); QTreeWidgetItem* diam3Item = createItem( cntrItem, Bold ); diam3Item->setText( 0, tr( "MAX_ELEMENT_LENGTH_3D" ) ); - diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); + diam3Item->setText( 1, QString( "%1" ).arg( afunctor->GetValue( id ) ) ); } // gravity center @@ -2919,33 +2934,40 @@ SMESHGUI_MeshInfoDlg::~SMESHGUI_MeshInfoDlg() */ void SMESHGUI_MeshInfoDlg::showInfo( const Handle(SALOME_InteractiveObject)& IO ) { + if ( !IO.IsNull() ) + myIO = IO; + SMESH::SMESH_IDSource_var obj = SMESH::IObjectToInterface( IO ); - if ( !CORBA::is_nil( obj ) ) { + if ( !CORBA::is_nil( obj ) ) + { myAddInfo->showInfo( obj ); // nb of nodes in a group can be computed by myAddInfo, myBaseInfo->showInfo( obj ); // and it will be used by myBaseInfo (IPAL52871) - myCtrlInfo->showInfo( obj ); + if ( myTabWidget->currentIndex() == CtrlInfo ) + myCtrlInfo->showInfo( obj ); - myActor = SMESH::FindActorByEntry( IO->getEntry() ); - SVTK_Selector* selector = SMESH::GetSelector(); - QString ID; - int nb = 0; - if ( myActor && selector ) { - nb = myMode->checkedId() == NodeMode ? - SMESH::GetNameOfSelectedElements( selector, IO, ID ) : - SMESH::GetNameOfSelectedNodes( selector, IO, ID ); - } - myElemInfo->setSource( myActor ) ; - if ( nb > 0 ) { - myID->setText( ID.trimmed() ); - QSet ids; - QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); - foreach ( ID, idTxt ) - ids << ID.trimmed().toLong(); - myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); - } - else { - myID->clear(); - myElemInfo->clear(); + { + myActor = SMESH::FindActorByEntry( IO->getEntry() ); + SVTK_Selector* selector = SMESH::GetSelector(); + QString ID; + int nb = 0; + if ( myActor && selector ) { + nb = myMode->checkedId() == NodeMode ? + SMESH::GetNameOfSelectedElements( selector, IO, ID ) : + SMESH::GetNameOfSelectedNodes( selector, IO, ID ); + } + myElemInfo->setSource( myActor ) ; + if ( nb > 0 ) { + myID->setText( ID.trimmed() ); + QSet ids; + QStringList idTxt = ID.split( " ", QString::SkipEmptyParts ); + foreach ( ID, idTxt ) + ids << ID.trimmed().toLong(); + myElemInfo->showInfo( ids, myMode->checkedId() == ElemMode ); + } + else { + myID->clear(); + myElemInfo->clear(); + } } } } @@ -3049,11 +3071,9 @@ void SMESHGUI_MeshInfoDlg::updateInfo() Handle(SALOME_InteractiveObject) IO = selected.First(); showInfo( IO ); } -// else { -// myBaseInfo->clear(); -// myElemInfo->clear(); -// myAddInfo->clear(); -// } + else { + showInfo( myIO ); + } } /*! diff --git a/src/SMESHGUI/SMESHGUI_MeshInfo.h b/src/SMESHGUI/SMESHGUI_MeshInfo.h index dd1af5c02..2edf2e58a 100644 --- a/src/SMESHGUI/SMESHGUI_MeshInfo.h +++ b/src/SMESHGUI/SMESHGUI_MeshInfo.h @@ -395,6 +395,7 @@ private: SMESHGUI_AddInfo* myAddInfo; SMESHGUI_CtrlInfo* myCtrlInfo; SMESH_Actor* myActor; + Handle(SALOME_InteractiveObject) myIO; }; class SMESHGUI_EXPORT SMESHGUI_CtrlInfoDlg : public QDialog diff --git a/src/SMESHGUI/SMESHGUI_MeshOp.cxx b/src/SMESHGUI/SMESHGUI_MeshOp.cxx index 8677fad56..7319ef4d1 100644 --- a/src/SMESHGUI/SMESHGUI_MeshOp.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshOp.cxx @@ -709,15 +709,14 @@ void SMESHGUI_MeshOp::selectionDone() } } else { // no geometry defined - myDlg->enableTab( SMESH::DIM_3D ); - QStringList hypList; - availableHyps( SMESH::DIM_3D, Algo, hypList, - myAvailableHypData[SMESH::DIM_3D][Algo]); - SMESHGUI_MeshTab* aTab = myDlg->tab( SMESH::DIM_3D ); - aTab->setAvailableHyps( Algo, hypList ); - for (int i = SMESH::DIM_0D;i < SMESH::DIM_3D; ++i) { - myDlg->disableTab(i); + QStringList hypList; + for ( int dim = SMESH::DIM_0D; dim <= SMESH::DIM_3D; dim++ ) + { + availableHyps( dim, Algo, hypList, myAvailableHypData[dim][Algo]); + myDlg->tab( dim )->setAvailableHyps( Algo, hypList ); + if ( hypList.empty() ) myDlg->disableTab( dim ); + else myDlg->enableTab( dim ); } myMaxShapeDim = -1; //Hide labels and fields (Mesh and Geometry) @@ -943,7 +942,6 @@ void SMESHGUI_MeshOp::availableHyps( const int theDim, bool isAux = ( theHypType >= AddHyp ); QStringList aHypTypeNameList = SMESH::GetAvailableHypotheses( isAlgo, theDim, isAux, myIsOnGeometry, !myIsMesh ); - QStringList::const_iterator anIter; GEOM::GEOM_Object_var aGeomVar; QString aCurrentGeomToSelect; if ( !theMeshType.isEmpty() ) { @@ -955,23 +953,50 @@ void SMESHGUI_MeshOp::availableHyps( const int theDim, myHypMapIsApplicable.clear(); } + std::multimap< double, HypothesisData* > sortedHyps; + QStringList::const_iterator anIter; for ( anIter = aHypTypeNameList.begin(); anIter != aHypTypeNameList.end(); ++anIter ) { HypothesisData* aData = SMESH::GetHypothesisData( *anIter ); if ( ( isCompatible ( thePrevAlgoData, aData, theHypType ) && isCompatible ( theNextAlgoData, aData, theHypType ) ) || - ( theMeshType == "ANY" && aData->InputTypes.isEmpty())) { - if ( !theMeshType.isEmpty() && theDim >= SMESH::DIM_2D && + ( theMeshType == "ANY" && aData->InputTypes.isEmpty())) + { + if ( ( !theMeshType.isEmpty() ) && + ( theDim >= SMESH::DIM_2D ) && ( ( theMeshType != "ANY" && !isCompatibleToMeshType( aData, theMeshType )) || - !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar ))) + !isCompatibleToGeometry( aData, aCurrentGeomToSelect, aGeomVar ))) continue; + + int groupID = aData->GroupID; + int priority = aData->Priority; + if ( groupID < 0 || groupID > 9 ) groupID = 9; + if ( priority < 0 || priority > 999 ) priority = 999; + + sortedHyps.insert( std::make_pair( groupID + priority * 1e-3, aData )); + } + } + + if ( !sortedHyps.empty() ) + { + HypothesisData* aPrevGroup = SMESH::GetGroupTitle( sortedHyps.rbegin()->second, isAlgo ); + std::multimap< double, HypothesisData* >::iterator key_hyp = sortedHyps.begin(); + for ( ; key_hyp != sortedHyps.end(); ++key_hyp ) + { + HypothesisData* aData = key_hyp->second; + HypothesisData* aGroup = SMESH::GetGroupTitle( aData, isAlgo ); + if ( aPrevGroup != aGroup ) + { + theDataList.append( aGroup ); + theHyps.append( aGroup->Label ); + aPrevGroup = aGroup; + } theDataList.append( aData ); theHyps.append( aData->Label ); } } - if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() && - myLastGeomToSelect != aCurrentGeomToSelect ) + if ( !theMeshType.isEmpty() && !aCurrentGeomToSelect.isEmpty() ) myLastGeomToSelect = aCurrentGeomToSelect; } @@ -1166,12 +1191,9 @@ void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCrea // Set shapes, of mesh and sub-mesh if any // get Entry of the Geom object - QString aGeomEntry = ""; - QString aMeshEntry = ""; - QString anObjEntry = ""; - aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); - aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); - anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); + QString aGeomEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Geom ); + QString aMeshEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Mesh ); + QString anObjEntry = myDlg->selectedObject( SMESHGUI_MeshDlg::Obj ); if ( myToCreate && myIsMesh ) aMeshEntry = aGeomEntry; @@ -1216,6 +1238,8 @@ void SMESHGUI_MeshOp::initHypCreator( SMESHGUI_GenericHypothesisCreator* theCrea theCreator->setShapeEntry( aGeomEntry ); if ( aMeshEntry != "" ) theCreator->setMainShapeEntry( aMeshEntry ); + + theCreator->setNoGeomMesh( !myIsOnGeometry && myIsMesh && !myToCreate ); } //================================================================================ @@ -1342,7 +1366,8 @@ void SMESHGUI_MeshOp::createHypothesis(const int theDim, aCreator->create(initParamHyp, aHypName, myDlg, this, SLOT( onHypoCreated( int ) ) ); dialog = true; } - else { + else + { SMESH::SMESH_Hypothesis_var aHyp = SMESH::CreateHypothesis(theTypeName, aHypName, false); aHyp.out(); @@ -1479,7 +1504,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, if ( myIgnoreAlgoSelection ) return; - int aDim = theDim < 0 ? getTabDim( sender(), myDlg ): theDim; + int curDim = getTabDim( sender(), myDlg ); + int aDim = theDim < 0 ? curDim : theDim; if (aDim == -1) return; @@ -1561,7 +1587,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, myDlg->tab( dim )->setAvailableHyps( Algo, anAvailable ); noCompatible = anAvailable.isEmpty(); algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo ); - if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) { + if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim == curDim ) { // select the sole compatible algo algoIndex = 0; } @@ -1656,7 +1682,8 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex, hypIndex = this->find( curHyp, myExistingHyps[ dim ][ type ]); else hypIndex = -1; - if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 ) { + if ( !isSubmesh && myToCreate && hypIndex < 0 && anExisting.count() == 1 && dim == curDim ) + { // none is yet selected => select the sole existing if it is not optional CORBA::String_var hypTypeName = myExistingHyps[ dim ][ type ].first().first->GetName(); bool isOptional = true; @@ -2158,7 +2185,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) { // Call hypothesis creation server method (without GUI) SMESH::SMESH_Hypothesis_var aHyp = - SMESH::CreateHypothesis(aHypName, aHypName, true); + SMESH::CreateHypothesis(aHypName, aHypData->Label, true); aHyp.out(); } else @@ -2171,7 +2198,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim ) aCreator->create( true, aHypName, myDlg, 0, QString::null ); else { SMESH::SMESH_Hypothesis_var aHyp = - SMESH::CreateHypothesis(aHypName, aHypName, true); + SMESH::CreateHypothesis(aHypName, aHypData->Label, true); aHyp.out(); } delete aCreator; @@ -2234,7 +2261,7 @@ void SMESHGUI_MeshOp::readMesh() // Get hypotheses and algorithms assigned to the mesh/sub-mesh QStringList anExisting; - const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D; + const int lastDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D; bool algoFound = false; for ( int dim = SMESH::DIM_3D; dim >= lastDim; --dim ) { @@ -2381,7 +2408,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess ) // Set new name QString aName = myDlg->objectText( SMESHGUI_MeshDlg::Obj ); SMESH::SetName( pObj, aName ); - int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_3D; + int aDim = ( myIsOnGeometry ) ? SMESH::DIM_0D : SMESH::DIM_2D; // First, remove old algos in order to avoid messages on algorithm hiding for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ ) @@ -2717,8 +2744,9 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI } if ( !myIsOnGeometry ) for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) { - if ( i < SMESH::DIM_3D ) myDlg->disableTab( i ); - else myDlg->enableTab( i ); + bool disable = myAvailableHypData[i][Algo].isEmpty(); + if ( disable ) myDlg->disableTab( i ); + else myDlg->enableTab( i ); } else for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) { diff --git a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx index 9d4495083..cb3828246 100644 --- a/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_ReorientFacesDlg.cxx @@ -203,9 +203,9 @@ QWidget* SMESHGUI_ReorientFacesDlg::createMainFrame (QWidget* theParent) myDY->SetValue(0); myDZ->SetValue(0); - myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); - myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); - myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 10.0, "length_precision"); + myDX->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision"); + myDY->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision"); + myDZ->RangeStepAndValidator(COORD_MIN, COORD_MAX, 1.0, "length_precision"); width = Max( aFaceBut->fontMetrics().width( tr("SMESH_X")), aFaceBut->fontMetrics().width( tr("SMESH_DX"))); diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 832c51ec1..757238eab 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -118,6 +118,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const QVariant val; if ( p=="client" ) val = QVariant( LightApp_Selection::parameter( p ) ); else if ( p=="type" ) val = QVariant( myTypes[ind] ); + else if ( p=="hasActor" ) val = QVariant( getActor( ind ) != 0 ); else if ( p=="elemTypes" ) val = QVariant( elemTypes( ind ) ); else if ( p=="isAutoColor" ) val = QVariant( isAutoColor( ind ) ); else if ( p=="numberOfNodes" ) val = QVariant( numberOfNodes( ind ) ); diff --git a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx index 390335532..bd52efd4b 100644 --- a/src/SMESHGUI/SMESHGUI_VTKUtils.cxx +++ b/src/SMESHGUI/SMESHGUI_VTKUtils.cxx @@ -349,7 +349,7 @@ namespace SMESH try { OCC_CATCH_SIGNALS; if (nulData) - objModified = aVisualObj->NulData(); + objModified = aVisualObj->NulData(); else objModified = aVisualObj->Update(); } @@ -370,24 +370,24 @@ namespace SMESH int usedMB = aVisualObj->GetUnstructuredGrid()->GetActualMemorySize() / 1024; //MESSAGE("SMESHGUI_VTKUtils::GetVisualObj(), freeMB=" << freeMB << ", usedMB=" < 0 && usedMB * 5 > freeMB ) { - bool continu = false; - if ( usedMB * 3 > freeMB ) - // even dont try to show - SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_NO_MESH_VISUALIZATION")); - else - // there is a chance to succeed - continu = SUIT_MessageBox::warning - (SMESHGUI::desktop(), - QObject::tr("SMESH_WRN_WARNING"), - QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; - if ( !continu ) { - // remove the corresponding actors from all views - RemoveVisualObjectWithActors( theEntry ); - aVisualObj.reset(); - } + bool continu = false; + if ( usedMB * 3 > freeMB ) + // even dont try to show + SUIT_MessageBox::warning(SMESHGUI::desktop(), QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_NO_MESH_VISUALIZATION")); + else + // there is a chance to succeed + continu = SUIT_MessageBox::warning + (SMESHGUI::desktop(), + QObject::tr("SMESH_WRN_WARNING"), + QObject::tr("SMESH_CONTINUE_MESH_VISUALIZATION"), + SUIT_MessageBox::Yes | SUIT_MessageBox::No, + SUIT_MessageBox::Yes ) == SUIT_MessageBox::Yes; + if ( !continu ) { + // remove the corresponding actors from all views + RemoveVisualObjectWithActors( theEntry ); + aVisualObj.reset(); + } } } diff --git a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx index ec8ed41cd..3482d7672 100644 --- a/src/SMESHGUI/SMESHGUI_XmlHandler.cxx +++ b/src/SMESHGUI/SMESHGUI_XmlHandler.cxx @@ -128,10 +128,11 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, bool isAuxOrNeedHyp = ( qName == "hypothesis" ? atts.value("auxiliary") == "true" : atts.value("need-hyp" ) == "true" ); - bool isNeedGeom = true, isSupportSubmeshes = false; + int isNeedGeom = 1; + bool isSupportSubmeshes = false; QString aNeedGeom = atts.value("need-geom"); if ( !aNeedGeom.isEmpty() ) - isNeedGeom = (aNeedGeom == "true"); + isNeedGeom = (aNeedGeom == "true") ? 1 : (aNeedGeom == "never") ? -1 : 0; QString suppSub = atts.value("support-submeshes"); if ( !suppSub.isEmpty() ) isSupportSubmeshes = (suppSub == "true"); @@ -141,11 +142,18 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, else context = context.toUpper(); + bool isOk; + QString groupIDStr = atts.value("group-id"); + int groupID = groupIDStr.toUInt( &isOk ); + if ( !isOk ) groupID = -1; + QString priorityStr = atts.value("priority"); + int priority = priorityStr.toUInt( &isOk ); + if ( !isOk ) priority = -1; + QString aDimStr = atts.value("dim"); aDimStr = aDimStr.remove( ' ' ); QStringList aDimList = aDimStr.split( ',', QString::SkipEmptyParts ); QStringList::iterator anIter; - bool isOk; QList aDim; for ( anIter = aDimList.begin(); anIter != aDimList.end(); ++anIter ) { @@ -170,7 +178,7 @@ bool SMESHGUI_XmlHandler::startElement (const QString&, const QString&, if ( !aHypAlType.contains( BAD_HYP_FLAG ) ) { HypothesisData* aHypData = new HypothesisData (aHypAlType, myPluginName, myServerLib, myClientLib, - aLabel, anIcon, context, aDim, isAuxOrNeedHyp, + aLabel, anIcon, context, groupID, priority, aDim, isAuxOrNeedHyp, attr[ HYPOS ], attr[ OPT_HYPOS ], attr[ INPUT ], attr[ OUTPUT ], isNeedGeom, isSupportSubmeshes ); diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index ad18b5d33..5d052e3dd 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -1132,6 +1132,10 @@ TOP_SPLIT_TO_TETRA Split Volumes + + STB_OVERALL_MESH_QUALITY + Overall Mesh Quality + STB_SPLIT_TO_TETRA Split Volumes @@ -1732,25 +1736,25 @@ Probably, there is not enough space on disk. You can cancel exporting and rename them, otherwise some group names in the resulting file will not match ones in the study. -Do you want to continue ? +Do you want to continue? SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES There are some mesh objects with the same names in the selection. The result file may be incorrect. -Do you want to continue ? +Do you want to continue? SMESH_EXPORT_ONLY_GPOUP - You are going export the group without it's mesh. -Do you want to continue ? + You are going to export the group without its mesh. +Do you want to continue? SMESH_EXPORT_MED_V2_1 During export mesh with name - "%1" to MED 2.1 polygons and polyhedrons elements will be missed For correct export use MED 2.2 -Are you sure want to export to MED 2.1 ? +Are you sure want to export to MED 2.1? SMESH_EXPORT_MED_VERSION_COLLISION @@ -1769,7 +1773,7 @@ Overwrite the file? EXPORT_NOT_SUPPORTED During export mesh with name "%1" to %2 %3 will be missed. -Do you want to continue ? +Do you want to continue? SMESH_EXTRUSION @@ -4385,6 +4389,50 @@ It can't be deleted SMESH_ADVANCED Advanced + + SMESH_1D_ALGO_GROUP_BASIC + Basic + + + SMESH_1D_ALGO_GROUP_ADVANCED + Advanced + + + SMESH_1D_HYP_GROUP_BASIC + Basic + + + SMESH_1D_HYP_GROUP_PROGRESSION + Progression + + + SMESH_1D_HYP_GROUP_ADVANCED + Advanced + + + SMESH_2D_ALGO_GROUP_REGULAR + Regular faces + + + SMESH_2D_ALGO_GROUP_FREE + Free faces + + + SMESH_2D_ALGO_GROUP_ADVANCED + Advanced + + + SMESH_3D_ALGO_GROUP_REGULAR + Regular volumes + + + SMESH_3D_ALGO_GROUP_FREE + Free volumes + + + SMESH_3D_ALGO_GROUP_ADVANCED + Advanced + SMESHGUI_FieldSelectorWdg diff --git a/src/SMESHGUI/SMESH_msg_fr.ts b/src/SMESHGUI/SMESH_msg_fr.ts index 0ca241964..258d8ad78 100755 --- a/src/SMESHGUI/SMESH_msg_fr.ts +++ b/src/SMESHGUI/SMESH_msg_fr.ts @@ -63,9 +63,41 @@ AREA_ELEMENTS Aire + + FREE_NODES + Nœuds isolés + + + NODE_CONNECTIVITY_NB + Nombre de connectivité par nœud + + + FREE_EDGES + Arêtes libres + + + FREE_FACES + Faces libres + + + BARE_BORDER_FACE + Faces avec éléments de peau 1D manquants + + + OVER_CONSTRAINED_FACE + Faces sur-contraintes + + + BARE_BORDER_VOLUME + Volumes avec éléments de peau 2D manquants + + + OVER_CONSTRAINED_VOLUME + Volumes sur-contraints + MIN_DIAG_ELEMENTS - Diagonal minimum + Diagonale minimum ASPECTRATIO_3D_ELEMENTS @@ -256,6 +288,10 @@ MEN_COMPUTE Calculer + + MEN_COMPUTE_SUBMESH + Calculer le sous-maillage + MEN_PRECOMPUTE Prévisualiser @@ -420,6 +456,14 @@ MEN_EDIT_MESHSUBMESH Editer un maillage/sous-maillage + + MEN_EDIT_MESH + Editer un maillage + + + MEN_EDIT_SUBMESH + Editer un sous-maillage + MEN_EXPORT Exporter @@ -584,6 +628,10 @@ MEN_FREE_NODE Nœuds libres + + MEN_NODE_CONNECTIVITY_NB + Nombre de connectivité par nœud + MEN_FREE_FACES Faces libres @@ -1084,6 +1132,10 @@ TOP_SPLIT_TO_TETRA Eclater en tétraèdres + + STB_OVERALL_MESH_QUALITY + Qualité du maillage global + STB_SPLIT_TO_TETRA Eclater en tétraèdres @@ -1193,6 +1245,10 @@ Merci de les corriger, puis essayez de nouveau SMESH_ADD_ELEM0D_TITLE Ajouter un élément 0D + + SMESH_DUPLICATE_0D + Autorise la duplication d'éléments + SMESH_ADD_BALL Ajouter un élément particulaire @@ -1686,6 +1742,11 @@ Voulez-vous continuer ? SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES Il y a des maillages avec les mêmes noms dans la sélection. Il est possible que le fichier résultant soit incorrect. +Voulez-vous continuer ? + + + SMESH_EXPORT_ONLY_GPOUP + Vous allez export le groupe sans son maillage. Voulez-vous continuer ? @@ -2842,6 +2903,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. SMESH_WRN_WARNING Avertissement + + SMESH_WRN_SHOW_DLG_CHECKBOX + Ne plus montrer cet avertissement. + SMESH_X X @@ -2930,6 +2995,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_COMPUTE Calculer + + STB_COMPUTE_SUBMESH + Calculer le sous-maillage + STB_PRECOMPUTE Prévisualiser @@ -3062,6 +3131,14 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_EDIT_MESHSUBMESH Editer un maillage/sous-maillage + + STB_EDIT_MESH + Editer un maillage + + + STB_EDIT_SUBMESH + Editer un sous-maillage + STB_EXPORT_DAT Exporter au format DAT @@ -3130,6 +3207,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. STB_FREE_NODE Nœuds libres + + STB_NODE_CONNECTIVITY_NB + Nombre de connectivité par nœud + STB_FREE_FACES Faces libres @@ -3598,6 +3679,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_COMPUTE Calculer + + TOP_COMPUTE_SUBMESH + Calculer le sous-maillage + TOP_PRECOMPUTE Prévisualiser @@ -3730,6 +3815,14 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_EDIT_MESHSUBMESH Editer un maillage/sous-maillage + + TOP_EDIT_MESH + Editer un maillage + + + TOP_EDIT_SUBMESH + Editer un sous-maillage + TOP_EXPORT_DAT Exporter au format DAT @@ -3790,6 +3883,10 @@ Utilisez le menu "Visualiser une entité" pour les afficher. TOP_FREE_NODE Nœuds libres + + TOP_NODE_CONNECTIVITY_NB + Nombre de connectivité par nœud + TOP_FREE_FACES Faces libres @@ -4289,6 +4386,54 @@ Il ne peut pas être supprimé. STB_SORT_CHILD_ITEMS Trier les items enfants + + SMESH_ADVANCED + Avancé + + + SMESH_1D_ALGO_GROUP_BASIC + Basique + + + SMESH_1D_ALGO_GROUP_ADVANCED + Avancé + + + SMESH_1D_HYP_GROUP_BASIC + Basique + + + SMESH_1D_HYP_GROUP_PROGRESSION + Progression + + + SMESH_1D_HYP_GROUP_ADVANCED + Avancé + + + SMESH_2D_ALGO_GROUP_REGULAR + Faces régulières + + + SMESH_2D_ALGO_GROUP_FREE + Faces libres + + + SMESH_2D_ALGO_GROUP_ADVANCED + Avancé + + + SMESH_3D_ALGO_GROUP_REGULAR + Volumes réguliers + + + SMESH_3D_ALGO_GROUP_FREE + Volumes libres + + + SMESH_3D_ALGO_GROUP_ADVANCED + Avancé + SMESHGUI_FieldSelectorWdg @@ -4297,6 +4442,14 @@ Il ne peut pas être supprimé. Exporter les champs + + SMESHGUI_AddMeshElementDlg + + NB_ADDED + %1 éléments ont été ajoutés car des éléments 0D +étaient déjà présents sur les nœuds séléctionnés. + + SMESHGUI_Dialog @@ -4327,6 +4480,10 @@ Ouvrez une fenêtre VTK et essayez de nouveau PREF_AUTO_GROUPS Créer les groupes automatiquement pour l'export MED + + PREF_SHOW_WARN + Affiche un avertissement quand un groupe est exporté + PREF_GROUP_SEGMENT_LENGTH Paramètres automatiques @@ -5268,7 +5425,19 @@ Choisissez un groupe et essayez de nouveau USE_INPUT_ELEMS_ONLY - Use only input elements + Utilise seulement les éléments d'entrée + + + SMESH_SCALES + Facteurs d'échelle + + + LINEAR_SCALES + Variation linéaire des facteurs d'échelle + + + BASE_POINT + Point de base @@ -5574,6 +5743,10 @@ Vérifiez la validité des informations données CONNECTED_ELEMS Eléments d'un domaine + + NODE_CONN_NUMBER + Nombre de connectivité + NUMBEROFNODESINELEMENT Nombre de noeuds dans l'élément @@ -6123,8 +6296,12 @@ Indiquez-les et essayez de nouveau 3D - EDIT_MESH_SUBMESH - Editer un maillage/sous-maillage + EDIT_MESH + Editer un maillage + + + EDIT_SUBMESH + Editer un sous-maillage GEOMETRY @@ -7620,6 +7797,10 @@ en raison de leurs types incompatibles: NUMBER_OF_THE_FREE_NODES Nombre de nœuds libres + + MAX_NODE_CONNECTIVITY + Nombre maximal d'élément connectés + DOUBLE_NODES_TOLERANCE Tolérance des nœuds doubles @@ -7997,4 +8178,23 @@ en raison de leurs types incompatibles: Au moins une entité devrait être choisie! + + SMESH_AdvOptionsWdg + + ADD_OPTION_BTN + Ajouter une option + + + CHOICE + Choix + + + OPTION_NAME + Nom de l'option + + + OPTION_VALUE + Valeur de l'option' + + diff --git a/src/SMESHGUI/SMESH_msg_ja.ts b/src/SMESHGUI/SMESH_msg_ja.ts index 6b71493f4..d18673c16 100644 --- a/src/SMESHGUI/SMESH_msg_ja.ts +++ b/src/SMESHGUI/SMESH_msg_ja.ts @@ -63,6 +63,38 @@ AREA_ELEMENTS エリア + + FREE_NODES + 自由節点 + + + NODE_CONNECTIVITY_NB + 節点接続番号 + + + FREE_EDGES + フリーエッジ + + + FREE_FACES + フリー面 + + + BARE_BORDER_FACE + むき出しの境界線を持つ面 + + + OVER_CONSTRAINED_FACE + 過拘束面 + + + BARE_BORDER_VOLUME + むき出しの境界を持つボリューム + + + OVER_CONSTRAINED_VOLUME + 過拘束ボリューム + MIN_DIAG_ELEMENTS 最小の対角線 @@ -255,6 +287,10 @@ MEN_COMPUTE メッシュを作成 + + MEN_COMPUTE_SUBMESH + サブメッシュの生成 + MEN_PRECOMPUTE プレビュー @@ -419,6 +455,14 @@ MEN_EDIT_MESHSUBMESH メッシュ/サブメッシュを編集 + + MEN_EDIT_MESH + メッシュの編集 + + + MEN_EDIT_SUBMESH + サブメッシュの編集 + MEN_EXPORT エクスポート... @@ -583,6 +627,10 @@ MEN_FREE_NODE フリーノード + + MEN_NODE_CONNECTIVITY_NB + 節点接続番号 + MEN_FREE_FACES フリーフェース @@ -1083,6 +1131,10 @@ TOP_SPLIT_TO_TETRA 四面体を爆発します。 + + STB_OVERALL_MESH_QUALITY + 全体的なメッシュ品質 + STB_SPLIT_TO_TETRA 四面体を爆発します。 @@ -1187,6 +1239,10 @@ SMESH_ADD_ELEM0D_TITLE D の要素を追加します。 + + SMESH_DUPLICATE_0D + 重複要素の許容 + SMESH_ADD_BALL 粒子要素を追加します。 @@ -1671,6 +1727,10 @@ SMESH_EXPORT_MED_DUPLICATED_MESH_NAMES 選択範囲内の同じ名前を持つメッシュがあります。結果のファイルが正しい可能性が。続行しますか。 + + SMESH_EXPORT_ONLY_GPOUP + そのメッシュなしでグループのエクスポートをしようとしています。続行しますか? + SMESH_EXPORT_MED_V2_1 多角形、多面体要素は正しいエクスポート用 MED 2.1 MED 2.2 にメッシュ '%' のエクスポートの場合省略されます。MED 2.1 をエクスポートしますか。 @@ -1855,6 +1915,10 @@ SMESH_HYP_9 このようなディメンションの前提がジオメトリに既に割り当てられています。 + + SMESH_ID_DIAGONAL + エッジID + SMESH_ID_EDGES エッジID @@ -2799,6 +2863,10 @@ SMESH_WRN_WARNING 警告 + + SMESH_WRN_SHOW_DLG_CHECKBOX + この警告をこれ以上表示してはいけません。 + SMESH_X X @@ -2887,6 +2955,10 @@ STB_COMPUTE メッシュを作成します。 + + STB_COMPUTE_SUBMESH + サブメッシュの生成 + STB_PRECOMPUTE プレビュー @@ -3019,6 +3091,14 @@ STB_EDIT_MESHSUBMESH メッシュ/サブメッシュを編集 + + STB_EDIT_MESH + メッシュの編集 + + + STB_EDIT_SUBMESH + サブメッシュの編集 + STB_EXPORT_DAT DAT形式でエクスポート @@ -3087,6 +3167,10 @@ STB_FREE_NODE フリーノード + + STB_NODE_CONNECTIVITY_NB + 節点接続番号 + STB_FREE_FACES フリーフェース @@ -3295,6 +3379,10 @@ STB_SHOW_DISTRIBUTION 分布を表示します。 + + STB_SHOW_SCALAR_BAR + スカラバーの表示 + STB_REVOLUTION Revolution @@ -3331,10 +3419,6 @@ STB_SHOW 表示 - - STB_SHOW_SCALAR_BAR - スカラバーの表示 - STB_SHRINK 収縮 @@ -3555,6 +3639,10 @@ TOP_COMPUTE メッシュを作成 + + TOP_COMPUTE_SUBMESH + サブメッシュの生成 + TOP_PRECOMPUTE プレビュー @@ -3687,6 +3775,14 @@ TOP_EDIT_MESHSUBMESH メッシュ/サブメッシュを編集 + + TOP_EDIT_MESH + メッシュの編集 + + + TOP_EDIT_SUBMESH + サブメッシュの編集 + TOP_EXPORT_DAT DAT形式でエクスポート @@ -3747,6 +3843,10 @@ TOP_FREE_NODE フリーノード + + TOP_NODE_CONNECTIVITY_NB + 節点接続番号 + TOP_FREE_FACES フリーフェース @@ -4239,6 +4339,54 @@ STB_SORT_CHILD_ITEMS 子アイテムを並べ替える + + SMESH_ADVANCED + 高度な設定 + + + SMESH_1D_ALGO_GROUP_BASIC + ベーシック + + + SMESH_1D_ALGO_GROUP_ADVANCED + アドバンス + + + SMESH_1D_HYP_GROUP_BASIC + ベーシック + + + SMESH_1D_HYP_GROUP_PROGRESSION + 発展的 + + + SMESH_1D_HYP_GROUP_ADVANCED + アドバンス + + + SMESH_2D_ALGO_GROUP_REGULAR + 標準面 + + + SMESH_2D_ALGO_GROUP_FREE + 自由面 + + + SMESH_2D_ALGO_GROUP_ADVANCED + アドバンス + + + SMESH_3D_ALGO_GROUP_REGULAR + 標準ボリューム + + + SMESH_3D_ALGO_GROUP_FREE + 自由ボリューム + + + SMESH_3D_ALGO_GROUP_ADVANCED + アドバンス + SMESHGUI_FieldSelectorWdg @@ -4247,6 +4395,13 @@ 場の出力 + + SMESHGUI_AddMeshElementDlg + + NB_ADDED + 0D要素がすでに選択した節点上に存在するため、%1 の要素が追加されました。 + + SMESHGUI_Dialog @@ -4276,6 +4431,10 @@ PREF_AUTO_GROUPS MEDエクスポート時に自動的にグループ作成 + + PREF_SHOW_WARN + グループをエクスポートする際に警告を表示します。 + PREF_GROUP_SEGMENT_LENGTH 自動設定 @@ -5066,8 +5225,12 @@ 検出 - EDIT_SELECTED_GROUP - 選択したグループを編集します。 + EDIT_SELECTED_NODE_GROUP + 選択された一致節点のグループを編集します。 + + + EDIT_SELECTED_ELEM_GROUP + 選択された一致要素のグループを編集します。 SELECT_ALL @@ -5207,6 +5370,18 @@ USE_INPUT_ELEMS_ONLY 入力要素のみ使用 + + SMESH_SCALES + スケールファクタ + + + LINEAR_SCALES + スケールファクタの直線的変化 + + + BASE_POINT + スケール中心 + SMESHGUI_FilterDlg @@ -5496,6 +5671,10 @@ CONNECTED_ELEMS ドメインの要素 + + NODE_CONN_NUMBER + 接続番号 + NUMBEROFNODESINELEMENT 要素内のノード数 @@ -6036,8 +6215,12 @@ 3D - EDIT_MESH_SUBMESH - メッシュ/サブメッシュを編集 + EDIT_MESH + メッシュの編集 + + + EDIT_SUBMESH + サブメッシュの編集 GEOMETRY @@ -7507,6 +7690,10 @@ NUMBER_OF_THE_FREE_NODES 空きノードの数 + + MAX_NODE_CONNECTIVITY + 接続された要素の最大数 + DOUBLE_NODES_TOLERANCE 重複節点の許容値 @@ -7884,4 +8071,23 @@ 少なくとも一つのエンティティタイプは選択する必要があります! + + SMESH_AdvOptionsWdg + + ADD_OPTION_BTN + 追加オプション + + + CHOICE + 選択 + + + OPTION_NAME + オプション名 + + + OPTION_VALUE + オプション値 + + diff --git a/src/SMESHUtils/CMakeLists.txt b/src/SMESHUtils/CMakeLists.txt index c1322fb3a..c21a8a6d5 100644 --- a/src/SMESHUtils/CMakeLists.txt +++ b/src/SMESHUtils/CMakeLists.txt @@ -44,6 +44,7 @@ SET(_link_LIBRARIES ${CAS_TKGeomBase} ${CAS_TKGeomAlgo} ${CAS_TKTopAlgo} + ${CAS_TKMesh} ${Boost_LIBRARIES} SMDS ) diff --git a/src/SMESHUtils/SMESH_Block.cxx b/src/SMESHUtils/SMESH_Block.cxx index 90bd9bce6..4e6229c30 100644 --- a/src/SMESHUtils/SMESH_Block.cxx +++ b/src/SMESHUtils/SMESH_Block.cxx @@ -1608,7 +1608,6 @@ bool SMESH_Block::LoadMeshBlock(const SMDS_MeshVolume* theVolume, const int theNode001Index, vector& theOrderedNodes) { - MESSAGE(" ::LoadMeshBlock()"); init(); SMDS_VolumeTool vTool; @@ -1736,7 +1735,6 @@ bool SMESH_Block::LoadBlockShapes(const TopoDS_Shell& theShell, const TopoDS_Vertex& theVertex001, TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) { - MESSAGE(" ::LoadBlockShapes()"); return ( FindBlockShapes( theShell, theVertex000, theVertex001, theShapeIDMap ) && LoadBlockShapes( theShapeIDMap )); } @@ -1752,8 +1750,6 @@ bool SMESH_Block::FindBlockShapes(const TopoDS_Shell& theShell, const TopoDS_Vertex& theVertex001, TopTools_IndexedMapOfOrientedShape& theShapeIDMap ) { - MESSAGE(" ::FindBlockShapes()"); - // 8 vertices TopoDS_Shape V000, V100, V010, V110, V001, V101, V011, V111; // 12 edges diff --git a/src/SMESHUtils/SMESH_ControlPnt.hxx b/src/SMESHUtils/SMESH_ControlPnt.hxx index 145baaea1..fa1db79d0 100644 --- a/src/SMESHUtils/SMESH_ControlPnt.hxx +++ b/src/SMESHUtils/SMESH_ControlPnt.hxx @@ -56,19 +56,19 @@ namespace SMESHUtils }; // Functions to get sample point from shapes - void createControlPoints( const TopoDS_Shape& theShape, + SMESHUtils_EXPORT void createControlPoints( const TopoDS_Shape& theShape, const double& theSize, std::vector< ControlPnt >& thePoints ); - void createPointsSampleFromEdge( const TopoDS_Edge& theEdge, + SMESHUtils_EXPORT void createPointsSampleFromEdge( const TopoDS_Edge& theEdge, const double& theSize, std::vector& thePoints ); - void createPointsSampleFromFace( const TopoDS_Face& theFace, + SMESHUtils_EXPORT void createPointsSampleFromFace( const TopoDS_Face& theFace, const double& theSize, std::vector& thePoints ); - void createPointsSampleFromSolid( const TopoDS_Solid& theSolid, + SMESHUtils_EXPORT void createPointsSampleFromSolid( const TopoDS_Solid& theSolid, const double& theSize, std::vector& thePoints ); diff --git a/src/SMESHUtils/SMESH_MAT2d.cxx b/src/SMESHUtils/SMESH_MAT2d.cxx index da57a3148..2c20eb815 100644 --- a/src/SMESHUtils/SMESH_MAT2d.cxx +++ b/src/SMESHUtils/SMESH_MAT2d.cxx @@ -93,8 +93,8 @@ namespace list< const TVDEdge* > _edges; // MA edges in CCW order within _cell InSegment( InPoint * p0, InPoint * p1, size_t iE) - : _p0(p0), _p1(p1), _geomEdgeInd(iE) {} - InSegment() : _p0(0), _p1(0), _geomEdgeInd(0) {} + : _p0(p0), _p1(p1), _geomEdgeInd(iE), _cell(0) {} + InSegment() : _p0(0), _p1(0), _geomEdgeInd(0), _cell(0) {} const InPoint& point0() const { return *_p0; } const InPoint& point1() const { return *_p1; } @@ -662,7 +662,7 @@ namespace // get scale to have the same 2d proportions as in 3d computeProportionScale( face, uvBox, scale ); - // make scale to have coordinates precise enough when converted to int + // make 'scale' such that to have coordinates precise enough when converted to int gp_XY uvMin = uvBox.CornerMin(), uvMax = uvBox.CornerMax(); uvMin.ChangeCoord(1) = uvMin.X() * scale[0]; @@ -672,7 +672,7 @@ namespace double vMax[2] = { Max( Abs( uvMin.X() ), Abs( uvMax.X() )), Max( Abs( uvMin.Y() ), Abs( uvMax.Y() )) }; int iMax = ( vMax[0] > vMax[1] ) ? 0 : 1; - const double precision = 1e-5; + const double precision = Min( 1e-5, minSegLen * 1e-2 ); double preciScale = Min( vMax[iMax] / precision, std::numeric_limits::max() / vMax[iMax] ); preciScale /= scale[iMax]; @@ -703,6 +703,8 @@ namespace { inPoints[ iP++ ] = points[i-1].getInPoint( scale ); inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE )); + if ( inPoints[ iP-2 ] == inPoints[ iP-1 ]) + return false; // too short segment } } } @@ -716,6 +718,8 @@ namespace { inPoints[ iP++ ] = points[i].getInPoint( scale ); inSegments.push_back( InSegment( & inPoints[ iP-2 ], & inPoints[ iP-1 ], iE )); + if ( inPoints[ iP-2 ] == inPoints[ iP-1 ]) + return false; // too short segment } } } diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index e65e20114..1112eb973 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -441,7 +441,8 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher { SMDS_Mesh* _mesh; SMDS_ElemIteratorPtr _meshPartIt; - ElementBndBoxTree* _ebbTree; + ElementBndBoxTree* _ebbTree [SMDSAbs_NbElementTypes]; + int _ebbTreeHeight[SMDSAbs_NbElementTypes]; SMESH_NodeSearcherImpl* _nodeSearcher; SMDSAbs_ElementType _elementType; double _tolerance; @@ -451,10 +452,20 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, double tol=-1, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr()) - : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) {} + : _mesh(&mesh),_meshPartIt(elemIt),_nodeSearcher(0),_tolerance(tol),_outerFacesFound(false) + { + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + { + _ebbTree[i] = NULL; + _ebbTreeHeight[i] = -1; + } + } virtual ~SMESH_ElementSearcherImpl() { - if ( _ebbTree ) delete _ebbTree; _ebbTree = 0; + for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i ) + { + delete _ebbTree[i]; _ebbTree[i] = NULL; + } if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0; } virtual int FindElementsByPoint(const gp_Pnt& point, @@ -479,6 +490,12 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher { return _outerFaces.empty() || _outerFaces.count(face); } + int getTreeHeight() + { + if ( _ebbTreeHeight[ _elementType ] < 0 ) + _ebbTreeHeight[ _elementType ] = _ebbTree[ _elementType ]->getHeight(); + return _ebbTreeHeight[ _elementType ]; + } struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState()) { @@ -521,9 +538,9 @@ double SMESH_ElementSearcherImpl::getTolerance() double boxSize = _nodeSearcher->getTree()->maxSize(); _tolerance = 1e-8 * boxSize/* / meshInfo.NbNodes()*/; } - else if ( _ebbTree && meshInfo.NbElements() > 0 ) + else if ( _ebbTree[_elementType] && meshInfo.NbElements() > 0 ) { - double boxSize = _ebbTree->maxSize(); + double boxSize = _ebbTree[_elementType]->maxSize(); _tolerance = 1e-8 * boxSize/* / meshInfo.NbElements()*/; } if ( _tolerance == 0 ) @@ -544,10 +561,9 @@ double SMESH_ElementSearcherImpl::getTolerance() } else { - SMDS_ElemIteratorPtr elemIt = - _mesh->elementsIterator( SMDSAbs_ElementType( complexType )); + SMDS_ElemIteratorPtr elemIt = _mesh->elementsIterator( SMDSAbs_ElementType( complexType )); const SMDS_MeshElement* elem = elemIt->next(); - SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); + SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator(); SMESH_TNodeXYZ n1( nodeIt->next() ); elemSize = 0; while ( nodeIt->more() ) @@ -716,6 +732,7 @@ FindElementsByPoint(const gp_Pnt& point, vector< const SMDS_MeshElement* >& foundElements) { foundElements.clear(); + _elementType = type; double tolerance = getTolerance(); @@ -749,13 +766,12 @@ FindElementsByPoint(const gp_Pnt& point, // ================================================================================= else // elements more complex than 0D { - if ( !_ebbTree || _elementType != type ) + if ( !_ebbTree[type] ) { - if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt, tolerance ); + _ebbTree[_elementType] = new ElementBndBoxTree( *_mesh, type, _meshPartIt, tolerance ); } TIDSortedElemSet suspectElems; - _ebbTree->getElementsNearPoint( point, suspectElems ); + _ebbTree[ type ]->getElementsNearPoint( point, suspectElems ); TIDSortedElemSet::iterator elem = suspectElems.begin(); for ( ; elem != suspectElems.end(); ++elem ) if ( !SMESH_MeshAlgos::IsOut( *elem, point, tolerance )) @@ -777,29 +793,29 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point, SMDSAbs_ElementType type ) { const SMDS_MeshElement* closestElem = 0; + _elementType = type; if ( type == SMDSAbs_Face || type == SMDSAbs_Volume ) { - if ( !_ebbTree || _elementType != type ) - { - if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt ); - } + ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; + if ( !ebbTree ) + ebbTree = new ElementBndBoxTree( *_mesh, type, _meshPartIt ); + TIDSortedElemSet suspectElems; - _ebbTree->getElementsNearPoint( point, suspectElems ); + ebbTree->getElementsNearPoint( point, suspectElems ); - if ( suspectElems.empty() && _ebbTree->maxSize() > 0 ) + if ( suspectElems.empty() && ebbTree->maxSize() > 0 ) { - gp_Pnt boxCenter = 0.5 * ( _ebbTree->getBox()->CornerMin() + - _ebbTree->getBox()->CornerMax() ); + gp_Pnt boxCenter = 0.5 * ( ebbTree->getBox()->CornerMin() + + ebbTree->getBox()->CornerMax() ); double radius = -1; - if ( _ebbTree->getBox()->IsOut( point.XYZ() )) - radius = point.Distance( boxCenter ) - 0.5 * _ebbTree->maxSize(); + if ( ebbTree->getBox()->IsOut( point.XYZ() )) + radius = point.Distance( boxCenter ) - 0.5 * ebbTree->maxSize(); if ( radius < 0 ) - radius = _ebbTree->maxSize() / pow( 2., _ebbTree->getHeight()) / 2; + radius = ebbTree->maxSize() / pow( 2., getTreeHeight()) / 2; while ( suspectElems.empty() ) { - _ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems ); + ebbTree->getElementsInSphere( point.XYZ(), radius, suspectElems ); radius *= 1.1; } } @@ -863,11 +879,13 @@ SMESH_ElementSearcherImpl::FindClosestTo( const gp_Pnt& point, TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) { double tolerance = getTolerance(); - if ( !_ebbTree || _elementType != SMDSAbs_Face ) - { - if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = SMDSAbs_Face, _meshPartIt ); - } + + _elementType = SMDSAbs_Face; + + ElementBndBoxTree*& ebbTree = _ebbTree[ SMDSAbs_Face ]; + if ( !ebbTree ) + ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); + // Algo: analyse transition of a line starting at the point through mesh boundary; // try three lines parallel to axis of the coordinate system and perform rough // analysis. If solution is not clear perform thorough analysis. @@ -883,7 +901,7 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) gp_Lin line ( lineAxis ); TIDSortedElemSet suspectFaces; // faces possibly intersecting the line - _ebbTree->getElementsNearLine( lineAxis, suspectFaces ); + ebbTree->getElementsNearLine( lineAxis, suspectFaces ); // Intersect faces with the line @@ -987,16 +1005,19 @@ TopAbs_State SMESH_ElementSearcherImpl::GetPointState(const gp_Pnt& point) // skip tangent intersections int nbTgt = 0; - const SMDS_MeshElement* prevFace = u_int1->second._face; - while ( ok && u_int2->second._coincides ) + if ( u_int2 != u2inters.end() ) { - if ( SMESH_MeshAlgos::GetCommonNodes(prevFace , u_int2->second._face).empty() ) - ok = false; - else + const SMDS_MeshElement* prevFace = u_int1->second._face; + while ( ok && u_int2->second._coincides ) { - nbTgt++; - u_int2++; - ok = ( u_int2 != u2inters.end() ); + if ( SMESH_MeshAlgos::GetCommonNodes(prevFace , u_int2->second._face).empty() ) + ok = false; + else + { + nbTgt++; + u_int2++; + ok = ( u_int2 != u2inters.end() ); + } } } if ( !ok ) break; @@ -1088,13 +1109,13 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1& SMDSAbs_ElementType type, vector< const SMDS_MeshElement* >& foundElems) { - if ( !_ebbTree || _elementType != type ) - { - if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt ); - } + _elementType = type; + ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; + if ( !ebbTree ) + ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); + TIDSortedElemSet suspectFaces; // elements possibly intersecting the line - _ebbTree->getElementsNearLine( line, suspectFaces ); + ebbTree->getElementsNearLine( line, suspectFaces ); foundElems.assign( suspectFaces.begin(), suspectFaces.end()); } @@ -1109,13 +1130,13 @@ void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ& SMDSAbs_ElementType type, vector< const SMDS_MeshElement* >& foundElems) { - if ( !_ebbTree || _elementType != type ) - { - if ( _ebbTree ) delete _ebbTree; - _ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt ); - } + _elementType = type; + ElementBndBoxTree*& ebbTree = _ebbTree[ type ]; + if ( !ebbTree ) + ebbTree = new ElementBndBoxTree( *_mesh, _elementType, _meshPartIt ); + TIDSortedElemSet suspectFaces; // elements possibly intersecting the line - _ebbTree->getElementsInSphere( center, radius, suspectFaces ); + ebbTree->getElementsInSphere( center, radius, suspectFaces ); foundElems.assign( suspectFaces.begin(), suspectFaces.end() ); } @@ -1153,8 +1174,8 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin gp_Vec edge2( xyz[i+1], xyz[(i+2)%nbNodes] ); faceNorm += edge1 ^ edge2; } - double normSize = faceNorm.Magnitude(); - if ( normSize <= tol ) + double fNormSize = faceNorm.Magnitude(); + if ( fNormSize <= tol ) { // degenerated face: point is out if it is out of all face edges for ( i = 0; i < nbNodes; ++i ) @@ -1165,7 +1186,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin } return true; } - faceNorm /= normSize; + faceNorm /= fNormSize; // check if the point lays on face plane gp_Vec n2p( xyz[0], point ); @@ -1194,9 +1215,10 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin // to find intersections of the ray with the boundary. gp_Vec ray = n2p; gp_Vec plnNorm = ray ^ faceNorm; - normSize = plnNorm.Magnitude(); - if ( normSize <= tol ) return false; // point coincides with the first node - plnNorm /= normSize; + double n2pSize = plnNorm.Magnitude(); + if ( n2pSize <= tol ) return false; // point coincides with the first node + if ( n2pSize * n2pSize > fNormSize * 100 ) return true; // point is very far + plnNorm /= n2pSize; // for each node of the face, compute its signed distance to the cutting plane vector dist( nbNodes + 1); for ( i = 0; i < nbNodes; ++i ) @@ -1242,7 +1264,7 @@ bool SMESH_MeshAlgos::IsOut( const SMDS_MeshElement* element, const gp_Pnt& poin if ( rClosest > 0. && rClosest < 1. ) // not node intersection return out; - // ray pass through a face node; analyze transition through an adjacent edge + // the ray passes through a face node; analyze transition through an adjacent edge gp_Pnt p1 = xyz[ (rClosest == 0.) ? ((iClosest+nbNodes-1) % nbNodes) : (iClosest+1) ]; gp_Pnt p2 = xyz[ (rClosest == 0.) ? iClosest : ((iClosest+2) % nbNodes) ]; gp_Vec edgeAdjacent( p1, p2 ); diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index d5dadd0e1..17ee75746 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2048,7 +2048,7 @@ void _pyMesh::Process( const Handle(_pyCommand)& theCommand ) { addCmd = *cmd; cmd = addHypCmds.erase( cmd ); - if ( !theGen->IsToKeepAllCommands() && CanClear() ) { + if ( !theGen->IsToKeepAllCommands() /*&& CanClear()*/ ) { addCmd->Clear(); theCommand->Clear(); } @@ -3474,28 +3474,31 @@ bool _pySegmentLengthAroundVertexHyp::Addition2Creation( const Handle(_pyCommand _pyID vertex = theCmd->GetArg( 1 ); - // the problem here is that segment algo will not be found + // the problem here is that segment algo can be not found // by pyHypothesis::Addition2Creation() for , so we try to find // geometry where segment algorithm is assigned - Handle(_pyHypothesis) algo; _pyID geom = vertex; + Handle(_pyHypothesis) algo = theGen->FindAlgo( geom, theMeshID, this ); while ( algo.IsNull() && !geom.IsEmpty()) { // try to find geom as a father of geom = FatherID( geom ); algo = theGen->FindAlgo( geom, theMeshID, this ); } - if ( algo.IsNull() ) + if ( algo.IsNull() || geom.IsEmpty() ) return false; // also possible to find geom as brother of veretex... + // set geom instead of vertex theCmd->SetArg( 1, geom ); - // set vertex as a second arg - if ( myCurCrMethod->myArgs.size() < 1) setCreationArg( 1, "1" ); // :( - setCreationArg( 2, vertex ); - // mesh.AddHypothesis(vertex, SegmentLengthAroundVertex) --> - // theMeshID.LengthNearVertex( length, vertex ) - return _pyHypothesis::Addition2Creation( theCmd, theMeshID ); + // SegmentLengthAroundVertex = Regular_1D.LengthNearVertex( length ) + if ( _pyHypothesis::Addition2Creation( theCmd, theMeshID )) + { + // set vertex as a second arg + theCmd->SetArg( 2, vertex ); + + return true; + } } return false; } diff --git a/src/SMESH_I/SMESH_DumpPython.cxx b/src/SMESH_I/SMESH_DumpPython.cxx index 1beee9b48..e22a87c77 100644 --- a/src/SMESH_I/SMESH_DumpPython.cxx +++ b/src/SMESH_I/SMESH_DumpPython.cxx @@ -162,6 +162,13 @@ namespace SMESH return *this; } + TPythonDump& + TPythonDump:: + operator<<(const std::string& theArg){ + myStream<_is_nil() ) // not a sole mesh { - GEOM::GEOM_Object_var s1 = mesh_i ->GetShapeToMesh(); - GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh(); - if ( ! ( isSole = s1->IsSame( s2 ))) - break; + if ( !foundMesh->HasShapeToMesh() || + !mesh_i ->HasShapeToMesh() ) + { + isSole = ( foundMesh->HasShapeToMesh() == mesh_i->HasShapeToMesh() ); + } + else + { + GEOM::GEOM_Object_var s1 = mesh_i ->GetShapeToMesh(); + GEOM::GEOM_Object_var s2 = foundMesh->GetShapeToMesh(); + isSole = s1->IsSame( s2 ); + } } foundMesh = SMESH::SMESH_Mesh::_narrow( obj ); } @@ -953,7 +960,7 @@ void SMESH_Gen_i::SetOption(const char* name, const char* value) { vector color; string str = value; - // color must be presented as a string of next form: + // color must be presented as a string of following form: if ( str.at(0) == '#' && str.length() == 7 ) { // hexadecimal color ("#ffaa00", for example) str = str.substr(1); for ( size_t i = 0; i < str.length()/2; i++ ) @@ -1917,7 +1924,10 @@ CORBA::Boolean SMESH_Gen_i::Compute( SMESH::SMESH_Mesh_ptr theMesh, // call implementation compute ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); myGen.PrepareCompute( myLocMesh, myLocShape ); - bool ok = myGen.Compute( myLocMesh, myLocShape, myLocShape != myLocMesh.GetShapeToMesh()); + int how = ::SMESH_Gen::COMPACT_MESH; + if ( myLocShape != myLocMesh.GetShapeToMesh() ) // compute a sub-mesh + how |= ::SMESH_Gen::SHAPE_ONLY; + bool ok = myGen.Compute( myLocMesh, myLocShape, how ); meshServant->CreateGroupServants(); // algos can create groups (issue 0020918) myLocMesh.GetMeshDS()->Modified(); return ok; @@ -2001,7 +2011,7 @@ SMESH::MeshPreviewStruct* SMESH_Gen_i::Precompute( SMESH::SMESH_Mesh_ptr theMesh ::SMESH_Mesh& myLocMesh = meshServant->GetImpl(); TSetOfInt shapeIds; ::MeshDimension aDim = (MeshDimension)theDimension; - if ( myGen.Compute( myLocMesh, myLocShape, false, false, aDim, &shapeIds ) ) + if ( myGen.Compute( myLocMesh, myLocShape, ::SMESH_Gen::COMPACT_MESH, aDim, &shapeIds ) ) { int nbShapeId = shapeIds.size(); theShapesId.length( nbShapeId ); diff --git a/src/SMESH_I/SMESH_Gen_i_1.cxx b/src/SMESH_I/SMESH_Gen_i_1.cxx index 346150a0b..86ae35c5f 100644 --- a/src/SMESH_I/SMESH_Gen_i_1.cxx +++ b/src/SMESH_I/SMESH_Gen_i_1.cxx @@ -265,8 +265,7 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr theStudy, SALOMEDS::SObject_wrap SO = SMESH_Gen_i::ObjectToSObject( theStudy, theIOR ); SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder(); SALOMEDS::UseCaseBuilder_wrap useCaseBuilder = theStudy->GetUseCaseBuilder(); - SALOMEDS::SObject_wrap objAfter; - bool isNewSO = false; + bool isNewSO = false, isInUseCaseTree = false; if ( SO->_is_nil() ) { if ( theTag == 0 ) { @@ -277,23 +276,12 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr theStudy, { SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag ); isNewSO = true; - - // define the next tag after given one in the data tree to insert SObject - SALOMEDS::SObject_wrap curObj; - if ( theFatherObject->GetLastChildTag() > theTag ) - { - SALOMEDS::UseCaseIterator_wrap - anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject); - for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) { - curObj = anUseCaseIter->Value(); - if ( curObj->Tag() > theTag ) { - objAfter = curObj; - break; - } - } - } } } + else + { + isInUseCaseTree = useCaseBuilder->IsUseCaseNode( SO ); + } SALOMEDS::GenericAttribute_wrap anAttr; if ( !CORBA::is_nil( theIOR )) @@ -325,13 +313,30 @@ static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr theStudy, selAttr->SetSelectable( false ); } + if ( !isNewSO ) + aStudyBuilder->RemoveReference( SO );// remove garbage reference (23336) + // add object to the use case tree // (to support tree representation customization and drag-n-drop) - if ( isNewSO ) + if ( isNewSO || !isInUseCaseTree ) { - if ( !CORBA::is_nil( objAfter ) ) + // define the next tag after given one in the data tree to insert SObject + SALOMEDS::SObject_wrap curObj, objAfter; + if ( theFatherObject->GetLastChildTag() > theTag && theTag > 0 ) + { + SALOMEDS::UseCaseIterator_wrap + anUseCaseIter = useCaseBuilder->GetUseCaseIterator(theFatherObject); + for ( ; anUseCaseIter->More(); anUseCaseIter->Next() ) { + curObj = anUseCaseIter->Value(); + if ( curObj->Tag() > theTag ) { + objAfter = curObj; + break; + } + } + } + if ( !CORBA::is_nil( objAfter )) useCaseBuilder->InsertBefore( SO, objAfter ); // insert at given tag - else if ( !useCaseBuilder->IsUseCaseNode( SO ) ) + else if ( !isInUseCaseTree ) useCaseBuilder->AppendTo( theFatherObject, SO ); // append to the end of list } return SO._retn(); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index a99acd2f6..a0c252bd3 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -2952,8 +2952,9 @@ SMESH_MeshEditor_i::ExtrusionAlongPathObjects(const SMESH::ListOfIDSources & the } if ( !myIsPreviewMode ) { - aPythonDump << "(" << aGroups << ", error) = " - << this << ".ExtrusionAlongPathObjects( " + if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = "; + else aPythonDump << "(_noGroups, error) = "; + aPythonDump << this << ".ExtrusionAlongPathObjects( " << theNodes << ", " << theEdges << ", " << theFaces << ", " diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index 05043f6f2..44195b8c8 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -299,7 +299,6 @@ void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception) catch(SALOME_Exception & S_ex) { THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM); } - _impl->GetMeshDS()->Modified(); TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()"; } @@ -3283,9 +3282,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, ( !geomAssocFields || !geomAssocFields[0] )) return; - std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 ); - std::vector< int > intVals( meshDS->MaxShapeIndex()+1 ); - std::vector< int > subIdsByDim[ 4 ]; + std::vector< std::vector< double > > dblVals; + std::vector< std::vector< int > > intVals; + std::vector< int > subIdsByDim[ 4 ]; const double noneDblValue = 0.; const double noneIntValue = 0; @@ -3325,6 +3324,9 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, for ( size_t iC = 0; iC < comps->length(); ++iC ) fieldWriter.SetCompName( iC, comps[ iC ].in() ); + dblVals.resize( comps->length() ); + intVals.resize( comps->length() ); + // find sub-shape IDs std::vector< int >& subIds = subIdsByDim[ dim ]; @@ -3350,6 +3352,17 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, fieldWriter.SetDtIt( int( stamp ), int( id )); // fill dblVals or intVals + for ( size_t iC = 0; iC < comps->length(); ++iC ) + if ( dataType == GEOM::FDT_Double ) + { + dblVals[ iC ].clear(); + dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } + else + { + intVals[ iC ].clear(); + intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 ); + } switch ( dataType ) { case GEOM::FDT_Double: @@ -3357,10 +3370,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step ); if ( dblStep->_is_nil() ) continue; GEOM::ListOfDouble_var vv = dblStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - dblVals[ subIds[ i ]] = vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ]; break; } case GEOM::FDT_Int: @@ -3368,10 +3382,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step ); if ( intStep->_is_nil() ) continue; GEOM::ListOfLong_var vv = intStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - intVals[ subIds[ i ]] = (int) vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; break; } case GEOM::FDT_Bool: @@ -3379,10 +3394,11 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step ); if ( boolStep->_is_nil() ) continue; GEOM::short_array_var vv = boolStep->GetValues(); - if ( vv->length() != subIds.size() ) + if ( vv->length() != subIds.size() * comps->length() ) THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR ); - for ( size_t i = 0; i < vv->length(); ++i ) - intVals[ subIds[ i ]] = (int) vv[ i ]; + for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ]; break; } default: continue; @@ -3395,20 +3411,24 @@ void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter, { const SMDS_MeshElement* e = elemIt->next(); const int shapeID = e->getshapeId(); - if ( shapeID < 1 || shapeID >= (int) dblVals.size() ) - fieldWriter.AddValue( noneDblValue ); + if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( noneDblValue ); else - fieldWriter.AddValue( dblVals[ shapeID ]); + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( dblVals[ iC ][ shapeID ]); } else while ( elemIt->more() ) { const SMDS_MeshElement* e = elemIt->next(); const int shapeID = e->getshapeId(); - if ( shapeID < 1 || shapeID >= (int) intVals.size() ) - fieldWriter.AddValue( (double) noneIntValue ); + if ( shapeID < 1 || shapeID >= (int) intVals[0].size() ) + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) noneIntValue ); else - fieldWriter.AddValue( (double) intVals[ shapeID ]); + for ( size_t iC = 0; iC < comps->length(); ++iC ) + fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]); } // write a step diff --git a/src/SMESH_I/SMESH_PythonDump.hxx b/src/SMESH_I/SMESH_PythonDump.hxx index 8f1a79715..7fb82c564 100644 --- a/src/SMESH_I/SMESH_PythonDump.hxx +++ b/src/SMESH_I/SMESH_PythonDump.hxx @@ -234,6 +234,9 @@ namespace SMESH TPythonDump& operator<<(const SMESH::CoincidentFreeBorders& theCFB); + TPythonDump& + operator<<(const std::string& theArg); + static const char* SMESHGenName() { return "smeshgen"; } static const char* MeshEditorName() { return "mesh_editor"; } static const char* NotPublishedObjectName(); diff --git a/src/SMESH_PY/smeshstudytools.py b/src/SMESH_PY/smeshstudytools.py index 949d5b729..3d407f85b 100644 --- a/src/SMESH_PY/smeshstudytools.py +++ b/src/SMESH_PY/smeshstudytools.py @@ -207,7 +207,7 @@ def TEST_createBoxMesh(): smesh.SetName(boxmesh.GetMesh(), 'boxmesh') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) # # Definitions: diff --git a/src/SMESH_SWIG/PAL_MESH_041_mesh.py b/src/SMESH_SWIG/PAL_MESH_041_mesh.py index 31545d1f4..67f0ba76d 100755 --- a/src/SMESH_SWIG/PAL_MESH_041_mesh.py +++ b/src/SMESH_SWIG/PAL_MESH_041_mesh.py @@ -103,5 +103,5 @@ print "---------------------Compute the mesh" ret = mesh.Compute() print ret -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/PAL_MESH_043_2D.py b/src/SMESH_SWIG/PAL_MESH_043_2D.py index d5dc18a9d..a627b543c 100755 --- a/src/SMESH_SWIG/PAL_MESH_043_2D.py +++ b/src/SMESH_SWIG/PAL_MESH_043_2D.py @@ -81,4 +81,4 @@ mesh2.Compute() # ---- udate object browser -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/PAL_MESH_043_3D.py b/src/SMESH_SWIG/PAL_MESH_043_3D.py index a42ccb4e5..5611f172e 100755 --- a/src/SMESH_SWIG/PAL_MESH_043_3D.py +++ b/src/SMESH_SWIG/PAL_MESH_043_3D.py @@ -90,4 +90,4 @@ mesh1.Compute() mesh2.Compute() # ---- update object browser -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_AdvancedEditor.py b/src/SMESH_SWIG/SMESH_AdvancedEditor.py index 73f3b7683..fdea2f137 100644 --- a/src/SMESH_SWIG/SMESH_AdvancedEditor.py +++ b/src/SMESH_SWIG/SMESH_AdvancedEditor.py @@ -217,4 +217,4 @@ for i in range(0,nbrs): oldnodes = newnodes pass -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_BelongToGeom.py b/src/SMESH_SWIG/SMESH_BelongToGeom.py index dd033b894..cc25ccda9 100644 --- a/src/SMESH_SWIG/SMESH_BelongToGeom.py +++ b/src/SMESH_SWIG/SMESH_BelongToGeom.py @@ -63,4 +63,4 @@ print "anIds = ", anIds #anIds = CheckBelongToGeomFilterOld(smesh,mesh.GetMesh(),box,box,anElemType) #print "anIds = ", anIds -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_BuildCompound.py b/src/SMESH_SWIG/SMESH_BuildCompound.py index 4f5c5bc9e..4a197353f 100644 --- a/src/SMESH_SWIG/SMESH_BuildCompound.py +++ b/src/SMESH_SWIG/SMESH_BuildCompound.py @@ -104,4 +104,4 @@ Compound2 = smesh.Concatenate([Mesh_inf.GetMesh(), Mesh_sup.GetMesh()], 1, 0, 1e smesh.SetName(Compound2, 'Compound_with_UniteGrps_and_GrpsOfAllElems') #end -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom.py b/src/SMESH_SWIG/SMESH_GroupFromGeom.py index a0567f42d..b0e936b19 100644 --- a/src/SMESH_SWIG/SMESH_GroupFromGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupFromGeom.py @@ -47,4 +47,4 @@ geompy.addToStudy(aGeomGroup2, "Group on Edges") aSmeshGroup1 = mesh.GroupOnGeom(aGeomGroup1, "SMESHGroup1", SMESH.FACE) aSmeshGroup2 = mesh.GroupOnGeom(aGeomGroup2, "SMESHGroup2", SMESH.EDGE) -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py index f93f10bed..498235198 100755 --- a/src/SMESH_SWIG/SMESH_GroupFromGeom2.py +++ b/src/SMESH_SWIG/SMESH_GroupFromGeom2.py @@ -74,4 +74,4 @@ mesh.Compute() print "aGroupOnShell size =", aGroupOnShell.Size() print "aGroupOnShell ids :", aGroupOnShell.GetListOfID() -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py index 5d8d881a8..4d7f05901 100644 --- a/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py +++ b/src/SMESH_SWIG/SMESH_GroupLyingOnGeom.py @@ -47,4 +47,4 @@ BuildGroupLyingOn(mesh.GetMesh(), SMESH.FACE, "Group of faces lying on edge #1", # Second way mesh.MakeGroup("Group of faces lying on edge #2", SMESH.FACE, SMESH.FT_LyingOnGeom, edge) -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_Nut.py b/src/SMESH_SWIG/SMESH_Nut.py index 6eb015f0b..3e27b57ce 100755 --- a/src/SMESH_SWIG/SMESH_Nut.py +++ b/src/SMESH_SWIG/SMESH_Nut.py @@ -158,4 +158,4 @@ print "Number of quadrangles : ", mesh.NbQuadrangles() print "Number of volumes : ", mesh.NbVolumes() print "Number of tetrahedrons: ", mesh.NbTetras() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_Partition1_tetra.py b/src/SMESH_SWIG/SMESH_Partition1_tetra.py index fe23d77da..aee34bb7e 100644 --- a/src/SMESH_SWIG/SMESH_Partition1_tetra.py +++ b/src/SMESH_SWIG/SMESH_Partition1_tetra.py @@ -184,4 +184,4 @@ if ret != 0: else: print "problem when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_Sphere.py b/src/SMESH_SWIG/SMESH_Sphere.py index 0f876b4b1..faadf285e 100644 --- a/src/SMESH_SWIG/SMESH_Sphere.py +++ b/src/SMESH_SWIG/SMESH_Sphere.py @@ -118,4 +118,4 @@ my_hexa.Quadrangle() my_hexa.Hexahedron() my_hexa.Compute() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_blocks.py b/src/SMESH_SWIG/SMESH_blocks.py index e1b14b11a..b8a4707e3 100644 --- a/src/SMESH_SWIG/SMESH_blocks.py +++ b/src/SMESH_SWIG/SMESH_blocks.py @@ -46,4 +46,4 @@ isMeshTest = 1 # True GEOM_Spanner.MakeSpanner(geompy, math, isBlocksTest, isMeshTest, smesh) -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_box.py b/src/SMESH_SWIG/SMESH_box.py index cfeda429f..1d486f24a 100755 --- a/src/SMESH_SWIG/SMESH_box.py +++ b/src/SMESH_SWIG/SMESH_box.py @@ -70,4 +70,4 @@ alg3D.SetName("algo3D") box_mesh.Compute() -sg.updateObjBrowser(1) +sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_box2_tetra.py b/src/SMESH_SWIG/SMESH_box2_tetra.py index fa582df72..6bba8e165 100644 --- a/src/SMESH_SWIG/SMESH_box2_tetra.py +++ b/src/SMESH_SWIG/SMESH_box2_tetra.py @@ -138,4 +138,4 @@ if ret != 0: else: print "probleme when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_box3_tetra.py b/src/SMESH_SWIG/SMESH_box3_tetra.py index d4c2f043c..6121df448 100644 --- a/src/SMESH_SWIG/SMESH_box3_tetra.py +++ b/src/SMESH_SWIG/SMESH_box3_tetra.py @@ -148,4 +148,4 @@ if ret != 0: else: print "probleme when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_box_tetra.py b/src/SMESH_SWIG/SMESH_box_tetra.py index dbc541e32..4938de61e 100644 --- a/src/SMESH_SWIG/SMESH_box_tetra.py +++ b/src/SMESH_SWIG/SMESH_box_tetra.py @@ -107,4 +107,4 @@ if ret != 0: else: print "probleme when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_controls.py b/src/SMESH_SWIG/SMESH_controls.py index a1aef6dbf..dfefee94c 100644 --- a/src/SMESH_SWIG/SMESH_controls.py +++ b/src/SMESH_SWIG/SMESH_controls.py @@ -141,4 +141,4 @@ print "Criterion: Element Diameter 2D > 10 Nb = ", len( anIds ) #print anIds[ i ] -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py index ed159a5e5..ef6ea57c1 100755 --- a/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py +++ b/src/SMESH_SWIG/SMESH_demo_hexa2_upd.py @@ -176,7 +176,7 @@ for i in range(8): smesh.SetName(algo.GetSubMesh(), "SubMeshEdgeZ_"+str(i+1)) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) print "-------------------------- compute the mesh of the volume" @@ -197,4 +197,4 @@ if ret != 0: else: print "problem when Computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_fixation_hexa.py b/src/SMESH_SWIG/SMESH_fixation_hexa.py index 155d361f7..7d9245c3b 100644 --- a/src/SMESH_SWIG/SMESH_fixation_hexa.py +++ b/src/SMESH_SWIG/SMESH_fixation_hexa.py @@ -99,4 +99,4 @@ if ret != 0: else: print "problem when Computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_fixation_netgen.py b/src/SMESH_SWIG/SMESH_fixation_netgen.py index a002f3c20..ed2c999f4 100644 --- a/src/SMESH_SWIG/SMESH_fixation_netgen.py +++ b/src/SMESH_SWIG/SMESH_fixation_netgen.py @@ -76,4 +76,4 @@ if ret != 0: else: print "problem when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_fixation_tetra.py b/src/SMESH_SWIG/SMESH_fixation_tetra.py index be41476e6..4f578dd01 100644 --- a/src/SMESH_SWIG/SMESH_fixation_tetra.py +++ b/src/SMESH_SWIG/SMESH_fixation_tetra.py @@ -123,4 +123,4 @@ if ret != 0: else: print "problem when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_flight_skin.py b/src/SMESH_SWIG/SMESH_flight_skin.py index 2e327063c..44ca46630 100644 --- a/src/SMESH_SWIG/SMESH_flight_skin.py +++ b/src/SMESH_SWIG/SMESH_flight_skin.py @@ -107,4 +107,4 @@ if ret != 0: else: print "probleme when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_freebord.py b/src/SMESH_SWIG/SMESH_freebord.py index a02e3d8cf..7bd4f3a83 100644 --- a/src/SMESH_SWIG/SMESH_freebord.py +++ b/src/SMESH_SWIG/SMESH_freebord.py @@ -75,4 +75,4 @@ print "Criterion: Free edges Nb = ", len( anIds ) for i in range( len( anIds ) ): print anIds[ i ] -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_hexaedre.py b/src/SMESH_SWIG/SMESH_hexaedre.py index dea48cf54..a2dd15b93 100755 --- a/src/SMESH_SWIG/SMESH_hexaedre.py +++ b/src/SMESH_SWIG/SMESH_hexaedre.py @@ -58,7 +58,7 @@ idblob = geompy.addToStudy(blob,"blob") edgeGroups = geompy.Propagate( blob ) assert len( edgeGroups ) == 3 -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) # ----------------------------------------------------------------------------- @@ -98,4 +98,4 @@ if ok: else: print "problem when Computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_mechanic.py b/src/SMESH_SWIG/SMESH_mechanic.py index 4069b07b4..b04453581 100644 --- a/src/SMESH_SWIG/SMESH_mechanic.py +++ b/src/SMESH_SWIG/SMESH_mechanic.py @@ -188,4 +188,4 @@ print "Number of quadrangles : ", mesh.NbQuadrangles() print "Number of volumes : ", mesh.NbVolumes() print "Number of tetrahedrons: ", mesh.NbTetras() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_mechanic_editor.py b/src/SMESH_SWIG/SMESH_mechanic_editor.py index 7c3f7147c..bb340bc95 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_editor.py +++ b/src/SMESH_SWIG/SMESH_mechanic_editor.py @@ -234,4 +234,4 @@ mesh.RotationSweepObject(GroupRotate, axisXYZ, angle45, 4, 1e-5) #9 reorientation of the submesh1 mesh.ReorientObject(submesh1) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_mechanic_netgen.py b/src/SMESH_SWIG/SMESH_mechanic_netgen.py index 25f8445cb..326348b7c 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_netgen.py +++ b/src/SMESH_SWIG/SMESH_mechanic_netgen.py @@ -135,4 +135,4 @@ if ret != 0: else: print "problem when computing the mesh" -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_mechanic_tetra.py b/src/SMESH_SWIG/SMESH_mechanic_tetra.py index 5d07c831a..18925dac7 100644 --- a/src/SMESH_SWIG/SMESH_mechanic_tetra.py +++ b/src/SMESH_SWIG/SMESH_mechanic_tetra.py @@ -158,4 +158,4 @@ print "Number of quadrangles: ", mesh.NbQuadrangles() print "Number of volumes : ", mesh.NbVolumes() print "Number of tetrahedrons: ", mesh.NbTetras() -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_reg.py b/src/SMESH_SWIG/SMESH_reg.py index 6aa46c3eb..1ce3e6cba 100644 --- a/src/SMESH_SWIG/SMESH_reg.py +++ b/src/SMESH_SWIG/SMESH_reg.py @@ -60,7 +60,7 @@ for f in subShapeList: print name idedge.append( geompy.addToStudyInFather(box, f, name) ) -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) # ---- launch SMESH smeshgui = salome.ImportComponentGUI("SMESH") @@ -115,5 +115,5 @@ algo = mesh.Triangle() algo.MaxElementArea(2500) -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test.py b/src/SMESH_SWIG/SMESH_test.py index 83d1583ff..9b40d7194 100644 --- a/src/SMESH_SWIG/SMESH_test.py +++ b/src/SMESH_SWIG/SMESH_test.py @@ -147,4 +147,4 @@ for a in log: ii = ii+1 print "AddTriangle %i - %i %i %i" % (ind, i1, i2, i3) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test0.py b/src/SMESH_SWIG/SMESH_test0.py index 7b7c8b9ea..23339f35f 100644 --- a/src/SMESH_SWIG/SMESH_test0.py +++ b/src/SMESH_SWIG/SMESH_test0.py @@ -63,4 +63,4 @@ name = geompy.SubShapeName(edge, face) print name idedge = geompy.addToStudyInFather(face, edge, name) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test1.py b/src/SMESH_SWIG/SMESH_test1.py index 824a6759e..ffc08c680 100644 --- a/src/SMESH_SWIG/SMESH_test1.py +++ b/src/SMESH_SWIG/SMESH_test1.py @@ -110,4 +110,4 @@ print hypArea2.GetMaxElementArea() smesh.SetName(hypArea2, "MaxElementArea_500") -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test1_AndDisplay.py b/src/SMESH_SWIG/SMESH_test1_AndDisplay.py index f060cbe8b..0c510a129 100644 --- a/src/SMESH_SWIG/SMESH_test1_AndDisplay.py +++ b/src/SMESH_SWIG/SMESH_test1_AndDisplay.py @@ -111,7 +111,7 @@ smesh.SetName(hypArea2, "MaxElementArea_500") mesh.Compute() -salome.sg.updateObjBrowser(1); +salome.sg.updateObjBrowser(True) sg = salome.ImportComponentGUI('SMESH') if type(sg) != type(salome.salome_ComponentGUI): diff --git a/src/SMESH_SWIG/SMESH_test2.py b/src/SMESH_SWIG/SMESH_test2.py index a74951ea0..c7dc5b14a 100644 --- a/src/SMESH_SWIG/SMESH_test2.py +++ b/src/SMESH_SWIG/SMESH_test2.py @@ -35,4 +35,4 @@ log = mesh.GetLog(0); # no erase trace for linelog in log: print linelog -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test4.py b/src/SMESH_SWIG/SMESH_test4.py index 0bd3a6459..6467319a6 100755 --- a/src/SMESH_SWIG/SMESH_test4.py +++ b/src/SMESH_SWIG/SMESH_test4.py @@ -77,4 +77,4 @@ if len(faces) > 1: group1.Add(faces[:int(len(faces)/2)]) group2.Add(faces[int(len(faces)/2):]) -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/SMESH_test5.py b/src/SMESH_SWIG/SMESH_test5.py index 383d8e1bc..0464598cc 100644 --- a/src/SMESH_SWIG/SMESH_test5.py +++ b/src/SMESH_SWIG/SMESH_test5.py @@ -81,4 +81,4 @@ for iFile in range(len(aListDir)) : ConvertMED2UNV(aPath,aFileName) #break -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/StdMeshersBuilder.py b/src/SMESH_SWIG/StdMeshersBuilder.py index 35e43e551..afcd449fb 100644 --- a/src/SMESH_SWIG/StdMeshersBuilder.py +++ b/src/SMESH_SWIG/StdMeshersBuilder.py @@ -21,6 +21,8 @@ # @package StdMeshersBuilder # Python API for the standard meshing plug-in module. +LIBRARY = "libStdMeshersEngine.so" + from salome.smesh.smesh_algorithm import Mesh_Algorithm import StdMeshers @@ -261,7 +263,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm): # on curve from 0 to 1 (additionally it is neecessary to check # orientation of edges and create list of reversed edges if it is # needed) and sets numbers of segments between given points (default - # values are equals 1 + # values are 1) # @param points defines the list of parameters on curve # @param nbSegs defines the list of numbers of segments # @param reversedEdges is a list of edges to mesh using reversed orientation. @@ -379,6 +381,7 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm): pass # 0D algorithm if self.geom is None: + self.geom = store_geom raise RuntimeError, "Attemp to create SegmentAroundVertex_0D algoritm on None shape" from salome.smesh.smeshBuilder import AssureGeomPublished, GetName, TreatHypoStatus AssureGeomPublished( self.mesh, self.geom ) @@ -961,10 +964,8 @@ class StdMeshersBuilder_Prism3D(Mesh_Algorithm): shape = geom if not shape: shape = mesh.geom - from salome.geom import geomBuilder - nbSolids = len( geomBuilder.geom.SubShapeAll( shape, geomBuilder.geomBuilder.ShapeType["SOLID"] )) - nbShells = len( geomBuilder.geom.SubShapeAll( shape, geomBuilder.geomBuilder.ShapeType["SHELL"] )) - if nbSolids == 0 or nbSolids == nbShells: + isRadial = mesh.smeshpyD.IsApplicable("RadialPrism_3D", LIBRARY, shape, False ) + if not isRadial: self.Create(mesh, geom, "Prism_3D") pass else: diff --git a/src/SMESH_SWIG/ex01_cube2build.py b/src/SMESH_SWIG/ex01_cube2build.py index 5ad812f23..d29303898 100644 --- a/src/SMESH_SWIG/ex01_cube2build.py +++ b/src/SMESH_SWIG/ex01_cube2build.py @@ -323,4 +323,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex02_cube2primitive.py b/src/SMESH_SWIG/ex02_cube2primitive.py index 552a588c9..eca7e708d 100644 --- a/src/SMESH_SWIG/ex02_cube2primitive.py +++ b/src/SMESH_SWIG/ex02_cube2primitive.py @@ -125,4 +125,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex03_cube2partition.py b/src/SMESH_SWIG/ex03_cube2partition.py index 265218a66..4d4205988 100644 --- a/src/SMESH_SWIG/ex03_cube2partition.py +++ b/src/SMESH_SWIG/ex03_cube2partition.py @@ -112,4 +112,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex04_cube5tetraHexa.py b/src/SMESH_SWIG/ex04_cube5tetraHexa.py index 224bc8c96..74709a288 100644 --- a/src/SMESH_SWIG/ex04_cube5tetraHexa.py +++ b/src/SMESH_SWIG/ex04_cube5tetraHexa.py @@ -117,4 +117,4 @@ mixed.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex05_hole1build.py b/src/SMESH_SWIG/ex05_hole1build.py index a8c7ec057..63049972c 100644 --- a/src/SMESH_SWIG/ex05_hole1build.py +++ b/src/SMESH_SWIG/ex05_hole1build.py @@ -152,4 +152,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex06_hole1boolean.py b/src/SMESH_SWIG/ex06_hole1boolean.py index a5008e555..252b4e896 100644 --- a/src/SMESH_SWIG/ex06_hole1boolean.py +++ b/src/SMESH_SWIG/ex06_hole1boolean.py @@ -169,4 +169,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex07_hole1partition.py b/src/SMESH_SWIG/ex07_hole1partition.py index 5eb0b0d33..099204117 100644 --- a/src/SMESH_SWIG/ex07_hole1partition.py +++ b/src/SMESH_SWIG/ex07_hole1partition.py @@ -109,4 +109,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex08_hole2build.py b/src/SMESH_SWIG/ex08_hole2build.py index c2c9d2175..a9d4579c8 100644 --- a/src/SMESH_SWIG/ex08_hole2build.py +++ b/src/SMESH_SWIG/ex08_hole2build.py @@ -142,4 +142,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex09_grid4build.py b/src/SMESH_SWIG/ex09_grid4build.py index 147f50ff0..63222cb36 100644 --- a/src/SMESH_SWIG/ex09_grid4build.py +++ b/src/SMESH_SWIG/ex09_grid4build.py @@ -145,4 +145,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex10_grid4geometry.py b/src/SMESH_SWIG/ex10_grid4geometry.py index bf249d4e7..24cd31d44 100644 --- a/src/SMESH_SWIG/ex10_grid4geometry.py +++ b/src/SMESH_SWIG/ex10_grid4geometry.py @@ -107,4 +107,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex11_grid3partition.py b/src/SMESH_SWIG/ex11_grid3partition.py index db2a74b64..91b6a3d26 100644 --- a/src/SMESH_SWIG/ex11_grid3partition.py +++ b/src/SMESH_SWIG/ex11_grid3partition.py @@ -128,4 +128,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex12_grid17partition.py b/src/SMESH_SWIG/ex12_grid17partition.py index cf311ed61..55164b777 100644 --- a/src/SMESH_SWIG/ex12_grid17partition.py +++ b/src/SMESH_SWIG/ex12_grid17partition.py @@ -143,4 +143,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex13_hole1partial.py b/src/SMESH_SWIG/ex13_hole1partial.py index 2c56896cf..6cb4b1c2d 100644 --- a/src/SMESH_SWIG/ex13_hole1partial.py +++ b/src/SMESH_SWIG/ex13_hole1partial.py @@ -261,4 +261,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex14_cyl1holed.py b/src/SMESH_SWIG/ex14_cyl1holed.py index 374d666ce..f908a3d76 100644 --- a/src/SMESH_SWIG/ex14_cyl1holed.py +++ b/src/SMESH_SWIG/ex14_cyl1holed.py @@ -146,4 +146,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex15_cyl2geometry.py b/src/SMESH_SWIG/ex15_cyl2geometry.py index 8cdf83570..42cfbaad7 100644 --- a/src/SMESH_SWIG/ex15_cyl2geometry.py +++ b/src/SMESH_SWIG/ex15_cyl2geometry.py @@ -205,4 +205,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex16_cyl2complementary.py b/src/SMESH_SWIG/ex16_cyl2complementary.py index 17c2015d1..d7ec0ea1d 100644 --- a/src/SMESH_SWIG/ex16_cyl2complementary.py +++ b/src/SMESH_SWIG/ex16_cyl2complementary.py @@ -149,4 +149,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex17_dome1.py b/src/SMESH_SWIG/ex17_dome1.py index 50b60b558..4d8b06aeb 100644 --- a/src/SMESH_SWIG/ex17_dome1.py +++ b/src/SMESH_SWIG/ex17_dome1.py @@ -107,4 +107,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex18_dome2.py b/src/SMESH_SWIG/ex18_dome2.py index 71f4e657d..3721e9a6b 100644 --- a/src/SMESH_SWIG/ex18_dome2.py +++ b/src/SMESH_SWIG/ex18_dome2.py @@ -145,4 +145,4 @@ hexa.Compute() # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex19_sphereINcube.py b/src/SMESH_SWIG/ex19_sphereINcube.py index b2622b896..4528d5323 100644 --- a/src/SMESH_SWIG/ex19_sphereINcube.py +++ b/src/SMESH_SWIG/ex19_sphereINcube.py @@ -190,4 +190,4 @@ hexa_groupe = hexa.Group(groupe) # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex21_lamp.py b/src/SMESH_SWIG/ex21_lamp.py index cf6b63cc8..034037120 100644 --- a/src/SMESH_SWIG/ex21_lamp.py +++ b/src/SMESH_SWIG/ex21_lamp.py @@ -136,4 +136,4 @@ tetra.Group(group) # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) \ No newline at end of file +salome.sg.updateObjBrowser(True) \ No newline at end of file diff --git a/src/SMESH_SWIG/ex24_cylinder.py b/src/SMESH_SWIG/ex24_cylinder.py index bcb1cd499..87b4cfbe0 100644 --- a/src/SMESH_SWIG/ex24_cylinder.py +++ b/src/SMESH_SWIG/ex24_cylinder.py @@ -134,4 +134,4 @@ hexa.Group(group_1) # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex29_refine.py b/src/SMESH_SWIG/ex29_refine.py index fabbf71d3..938d0eac1 100644 --- a/src/SMESH_SWIG/ex29_refine.py +++ b/src/SMESH_SWIG/ex29_refine.py @@ -229,4 +229,4 @@ MyMesh.ExportMED(path+str(NbCells4)+"_triangles.med", 0) # Update the object browser # ------------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex30_groupsOp.py b/src/SMESH_SWIG/ex30_groupsOp.py index 63328117e..7b9f96c33 100755 --- a/src/SMESH_SWIG/ex30_groupsOp.py +++ b/src/SMESH_SWIG/ex30_groupsOp.py @@ -87,5 +87,5 @@ aIntGrp=Mesh_1.IntersectListOfGroups([aRedGroup, aGreenGroup, aBlueGroup], "IntG # CutListOfGroups() aCutGrp=Mesh_1.CutListOfGroups([aRedGroup],[aGreenGroup,aBlueGroup],"CutGrp") -salome.sg.updateObjBrowser( 1 ) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex30_tepal.py b/src/SMESH_SWIG/ex30_tepal.py index e06a03856..cd8e7bdc1 100644 --- a/src/SMESH_SWIG/ex30_tepal.py +++ b/src/SMESH_SWIG/ex30_tepal.py @@ -94,4 +94,4 @@ else: # Update object browser # --------------------- -salome.sg.updateObjBrowser(1) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/ex31_dimGroup.py b/src/SMESH_SWIG/ex31_dimGroup.py index 61fd89c82..1643ae99a 100755 --- a/src/SMESH_SWIG/ex31_dimGroup.py +++ b/src/SMESH_SWIG/ex31_dimGroup.py @@ -60,5 +60,5 @@ aGrp1D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], SMESH.EDGE, "Edges" ) aGrp0D = Mesh_1.CreateDimGroup( [aGrp3D_1, aGrp3D_2], SMESH.NODE, "Nodes" ) -salome.sg.updateObjBrowser( 1 ) +salome.sg.updateObjBrowser(True) diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index b24167ed2..1b5f9ecfc 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -27,6 +27,10 @@ ## @defgroup l1_creating Creating meshes ## @{ ## @defgroup l2_impexp Importing and exporting meshes +## @{ +## @details +## These are methods of class \ref smeshBuilder.smeshBuilder "smeshBuilder" +## @} ## @defgroup l2_construct Constructing meshes ## @defgroup l2_algorithms Defining Algorithms ## @{ @@ -45,8 +49,7 @@ ## @defgroup l3_hypos_additi Additional Hypotheses ## @} -## @defgroup l2_submeshes Constructing submeshes -## @defgroup l2_compounds Building Compounds +## @defgroup l2_submeshes Constructing sub-meshes ## @defgroup l2_editing Editing Meshes ## @} @@ -55,7 +58,6 @@ ## @defgroup l1_grouping Grouping elements ## @{ ## @defgroup l2_grps_create Creating groups -## @defgroup l2_grps_edit Editing groups ## @defgroup l2_grps_operon Using operations on groups ## @defgroup l2_grps_delete Deleting Groups @@ -67,15 +69,13 @@ ## @defgroup l2_modif_edit Modifying nodes and elements ## @defgroup l2_modif_renumber Renumbering nodes and elements ## @defgroup l2_modif_trsf Transforming meshes (Translation, Rotation, Symmetry, Sewing, Merging) -## @defgroup l2_modif_movenode Moving nodes -## @defgroup l2_modif_throughp Mesh through point ## @defgroup l2_modif_unitetri Uniting triangles ## @defgroup l2_modif_cutquadr Cutting elements ## @defgroup l2_modif_changori Changing orientation of elements ## @defgroup l2_modif_smooth Smoothing ## @defgroup l2_modif_extrurev Extrusion and Revolution -## @defgroup l2_modif_patterns Pattern mapping ## @defgroup l2_modif_tofromqu Convert to/from Quadratic Mesh +## @defgroup l2_modif_duplicat Duplication of nodes and elements (to emulate cracks) ## @} ## @defgroup l1_measurements Measurements @@ -91,6 +91,8 @@ import SALOME import SALOMEDS import os +## Private class used to workaround a problem that sometimes isinstance(m, Mesh) returns False +# class MeshMeta(type): def __instancecheck__(cls, inst): """Implement isinstance(inst, cls).""" @@ -104,7 +106,7 @@ class MeshMeta(type): ## @addtogroup l1_auxiliary ## @{ -## Converts an angle from degrees to radians +## Convert an angle from degrees to radians def DegreesToRadians(AngleInDegrees): from math import pi return AngleInDegrees * pi / 180.0 @@ -145,19 +147,19 @@ def ParseParameters(*args): Result.append( hasVariables ) return Result -# Parse parameters converting variables to radians +## Parse parameters while converting variables to radians def ParseAngles(*args): return ParseParameters( *( args + (DegreesToRadians, ))) -# Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables. -# Parameters are stored in PointStruct.parameters attribute +## Substitute PointStruct.__init__() to create SMESH.PointStruct using notebook variables. +# Parameters are stored in PointStruct.parameters attribute def __initPointStruct(point,*args): point.x, point.y, point.z, point.parameters,hasVars = ParseParameters(*args) pass SMESH.PointStruct.__init__ = __initPointStruct -# Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables. -# Parameters are stored in AxisStruct.parameters attribute +## Substitute AxisStruct.__init__() to create SMESH.AxisStruct using notebook variables. +# Parameters are stored in AxisStruct.parameters attribute def __initAxisStruct(ax,*args): if len( args ) != 6: raise RuntimeError,\ @@ -167,6 +169,7 @@ def __initAxisStruct(ax,*args): SMESH.AxisStruct.__init__ = __initAxisStruct smeshPrecisionConfusion = 1.e-07 +## Compare real values using smeshPrecisionConfusion as tolerance def IsEqual(val1, val2, tol=smeshPrecisionConfusion): if abs(val1 - val2) < tol: return True @@ -174,7 +177,7 @@ def IsEqual(val1, val2, tol=smeshPrecisionConfusion): NO_NAME = "NoName" -## Gets object name +## Return object name def GetName(obj): if obj: # object not null @@ -207,7 +210,7 @@ def GetName(obj): pass raise RuntimeError, "Null or invalid object" -## Prints error message if a hypothesis was not assigned. +## Print error message if a hypothesis was not assigned. def TreatHypoStatus(status, hypName, geomName, isAlgo, mesh): if isAlgo: hypType = "algorithm" @@ -271,7 +274,7 @@ def AssureGeomPublished(mesh, geom, name=''): mesh.geompyD.init_geom( mesh.smeshpyD.GetCurrentStudy()) ## get a name if not name and geom.GetShapeType() != geomBuilder.GEOM.COMPOUND: - # for all groups SubShapeName() returns "Compound_-1" + # for all groups SubShapeName() return "Compound_-1" name = mesh.geompyD.SubShapeName(geom, mesh.geom) if not name: name = "%s_%s"%(geom.GetShapeType(), id(geom)%10000) @@ -376,20 +379,22 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): ## Dump component to the Python script # This method overrides IDL function to allow default values for the parameters. + # @ingroup l1_auxiliary def DumpPython(self, theStudy, theIsPublished=True, theIsMultiFile=True): return SMESH._objref_SMESH_Gen.DumpPython(self, theStudy, theIsPublished, theIsMultiFile) ## Set mode of DumpPython(), \a historical or \a snapshot. - # In the \a historical mode, the Python Dump script includes all commands - # performed by SMESH engine. In the \a snapshot mode, commands - # relating to objects removed from the Study are excluded from the script - # as well as commands not influencing the current state of meshes + # In the \a historical mode, the Python Dump script includes all commands + # performed by SMESH engine. In the \a snapshot mode, commands + # relating to objects removed from the Study are excluded from the script + # as well as commands not influencing the current state of meshes + # @ingroup l1_auxiliary def SetDumpPythonHistorical(self, isHistorical): if isHistorical: val = "true" else: val = "false" SMESH._objref_SMESH_Gen.SetOption(self, "historical_python_dump", val) - ## Sets the current study and Geometry component + ## Set the current study and Geometry component # @ingroup l1_auxiliary def init_smesh(self,theStudy,geompyD = None): #print "init_smesh" @@ -398,7 +403,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): global notebook notebook.myStudy = theStudy - ## Creates a mesh. This can be either an empty mesh, possibly having an underlying geometry, + ## Create a mesh. This can be either an empty mesh, possibly having an underlying geometry, # or a mesh wrapping a CORBA mesh given as a parameter. # @param obj either (1) a CORBA mesh (SMESH._objref_SMESH_Mesh) got e.g. by calling # salome.myStudy.FindObjectID("0:1:2:3").GetObject() or @@ -412,15 +417,15 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): obj,name = name,obj return Mesh(self,self.geompyD,obj,name) - ## Returns a long value from enumeration - # @ingroup l1_controls + ## Return a long value from enumeration + # @ingroup l1_auxiliary def EnumToLong(self,theItem): return theItem._v - ## Returns a string representation of the color. + ## Return a string representation of the color. # To be used with filters. # @param c color value (SALOMEDS.Color) - # @ingroup l1_controls + # @ingroup l1_auxiliary def ColorToString(self,c): val = "" if isinstance(c, SALOMEDS.Color): @@ -431,7 +436,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): raise ValueError, "Color value should be of string or SALOMEDS.Color type" return val - ## Gets PointStruct from vertex + ## Get PointStruct from vertex # @param theVertex a GEOM object(vertex) # @return SMESH.PointStruct # @ingroup l1_auxiliary @@ -439,7 +444,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): [x, y, z] = self.geompyD.PointCoordinates(theVertex) return PointStruct(x,y,z) - ## Gets DirStruct from vector + ## Get DirStruct from vector # @param theVector a GEOM object(vector) # @return SMESH.DirStruct # @ingroup l1_auxiliary @@ -454,7 +459,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): dirst = DirStruct(pnt) return dirst - ## Makes DirStruct from a triplet + ## Make DirStruct from a triplet # @param x,y,z vector components # @return SMESH.DirStruct # @ingroup l1_auxiliary @@ -497,7 +502,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # From SMESH_Gen interface: # ------------------------ - ## Sets the given name to the object + ## Set the given name to the object # @param obj the object to rename # @param name a new object name # @ingroup l1_auxiliary @@ -509,23 +514,20 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): ior = salome.orb.object_to_string(obj) SMESH._objref_SMESH_Gen.SetName(self, ior, name) - ## Sets the current mode + ## Set the current mode # @ingroup l1_auxiliary def SetEmbeddedMode( self,theMode ): - #self.SetEmbeddedMode(theMode) SMESH._objref_SMESH_Gen.SetEmbeddedMode(self,theMode) - ## Gets the current mode + ## Get the current mode # @ingroup l1_auxiliary def IsEmbeddedMode(self): - #return self.IsEmbeddedMode() return SMESH._objref_SMESH_Gen.IsEmbeddedMode(self) - ## Sets the current study. Calling SetCurrentStudy( None ) allows to + ## Set the current study. Calling SetCurrentStudy( None ) allows to # switch OFF automatic pubilishing in the Study of mesh objects. # @ingroup l1_auxiliary def SetCurrentStudy( self, theStudy, geompyD = None ): - #self.SetCurrentStudy(theStudy) if not geompyD: from salome.geom import geomBuilder geompyD = geomBuilder.geom @@ -545,13 +547,12 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): pass pass - ## Gets the current study + ## Get the current study # @ingroup l1_auxiliary def GetCurrentStudy(self): - #return self.GetCurrentStudy() return SMESH._objref_SMESH_Gen.GetCurrentStudy(self) - ## Creates a Mesh object importing data from the given UNV file + ## Create a Mesh object importing data from the given UNV file # @return an instance of Mesh class # @ingroup l2_impexp def CreateMeshesFromUNV( self,theFileName ): @@ -559,7 +560,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMesh = Mesh(self, self.geompyD, aSmeshMesh) return aMesh - ## Creates a Mesh object(s) importing data from the given MED file + ## Create a Mesh object(s) importing data from the given MED file # @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus ) # @ingroup l2_impexp def CreateMeshesFromMED( self,theFileName ): @@ -567,7 +568,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] return aMeshes, aStatus - ## Creates a Mesh object(s) importing data from the given SAUV file + ## Create a Mesh object(s) importing data from the given SAUV file # @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus ) # @ingroup l2_impexp def CreateMeshesFromSAUV( self,theFileName ): @@ -575,7 +576,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] return aMeshes, aStatus - ## Creates a Mesh object importing data from the given STL file + ## Create a Mesh object importing data from the given STL file # @return an instance of Mesh class # @ingroup l2_impexp def CreateMeshesFromSTL( self, theFileName ): @@ -583,7 +584,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMesh = Mesh(self, self.geompyD, aSmeshMesh) return aMesh - ## Creates Mesh objects importing data from the given CGNS file + ## Create Mesh objects importing data from the given CGNS file # @return a tuple ( list of Mesh class instances, SMESH.DriverMED_ReadStatus ) # @ingroup l2_impexp def CreateMeshesFromCGNS( self, theFileName ): @@ -591,7 +592,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aMeshes = [ Mesh(self, self.geompyD, m) for m in aSmeshMeshes ] return aMeshes, aStatus - ## Creates a Mesh object importing data from the given GMF file. + ## Create a Mesh object importing data from the given GMF file. # GMF files must have .mesh extension for the ASCII format and .meshb for # the binary format. # @return [ an instance of Mesh class, SMESH.ComputeError ] @@ -612,7 +613,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # @param allGroups forces creation of groups corresponding to every input mesh # @param name name of a new mesh # @return an instance of Mesh class - # @ingroup l2_compounds + # @ingroup l1_creating def Concatenate( self, meshes, uniteIdenticalGroups, mergeNodesAndElements = False, mergeTolerance = 1e-5, allGroups = False, name = ""): @@ -639,29 +640,30 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # @param toCopyGroups to create in the new mesh groups the copied elements belongs to # @param toKeepIDs to preserve order of the copied elements or not # @return an instance of Mesh class + # @ingroup l1_creating def CopyMesh( self, meshPart, meshName, toCopyGroups=False, toKeepIDs=False): if (isinstance( meshPart, Mesh )): meshPart = meshPart.GetMesh() mesh = SMESH._objref_SMESH_Gen.CopyMesh( self,meshPart,meshName,toCopyGroups,toKeepIDs ) return Mesh(self, self.geompyD, mesh) - ## From SMESH_Gen interface + ## Return IDs of sub-shapes # @return the list of integer values # @ingroup l1_auxiliary def GetSubShapesId( self, theMainObject, theListOfSubObjects ): return SMESH._objref_SMESH_Gen.GetSubShapesId(self,theMainObject, theListOfSubObjects) - ## From SMESH_Gen interface. Creates a pattern + ## Create a pattern mapper. # @return an instance of SMESH_Pattern # # Example of Patterns usage - # @ingroup l2_modif_patterns + # @ingroup l1_modifying def GetPattern(self): return SMESH._objref_SMESH_Gen.GetPattern(self) - ## Sets number of segments per diagonal of boundary box of geometry by which - # default segment length of appropriate 1D hypotheses is defined. - # Default value is 10 + ## Set number of segments per diagonal of boundary box of geometry, by which + # default segment length of appropriate 1D hypotheses is defined in GUI. + # Default value is 10. # @ingroup l1_auxiliary def SetBoundaryBoxSegmentation(self, nbSegments): SMESH._objref_SMESH_Gen.SetBoundaryBoxSegmentation(self,nbSegments) @@ -669,7 +671,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): # Filtering. Auxiliary functions: # ------------------------------ - ## Creates an empty criterion + ## Create an empty criterion # @return SMESH.Filter.Criterion # @ingroup l1_controls def GetEmptyCriterion(self): @@ -686,7 +688,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): return Filter.Criterion(Type, Compare, Threshold, ThresholdStr, ThresholdID, UnaryOp, BinaryOp, Tolerance, TypeOfElement, Precision) - ## Creates a criterion by the given parameters + ## Create a criterion by the given parameters # \n Criterion structures allow to define complex filters by combining them with logical operations (AND / OR) (see example below) # @param elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) # @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.) @@ -874,7 +876,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): return aCriterion - ## Creates a filter with the given parameters + ## Create a filter with the given parameters # @param elementType the type of elements (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) # @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.) # Type SMESH.FunctorType._items in the Python Console to see all values. @@ -908,7 +910,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aFilterMgr.UnRegister() return aFilter - ## Creates a filter from criteria + ## Create a filter from criteria # @param criteria a list of criteria # @param binOp binary operator used when binary operator of criteria is undefined # @return SMESH_Filter @@ -925,7 +927,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aFilterMgr.UnRegister() return aFilter - ## Creates a numerical functor by its type + ## Create a numerical functor by its type # @param theCriterion functor type - an item of SMESH.FunctorType enumeration. # Type SMESH.FunctorType._items in the Python Console to see all items. # Note that not all items correspond to numerical functors. @@ -973,7 +975,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): aFilterMgr.UnRegister() return functor - ## Creates hypothesis + ## Create hypothesis # @param theHType mesh hypothesis type (string) # @param theLibName mesh plug-in library name # @return created hypothesis instance @@ -994,7 +996,7 @@ class smeshBuilder(object, SMESH._objref_SMESH_Gen): return hyp - ## Gets the mesh statistic + ## Get the mesh statistic # @return dictionary "element type" - "count of elements" # @ingroup l1_meshinfo def GetMeshInfo(self, obj): @@ -1207,7 +1209,7 @@ def New( study, instance=None): # It has a set of methods to build a mesh on the given geometry, including the definition of sub-meshes. # It also has methods to define groups of mesh elements, to modify a mesh (by addition of # new nodes and elements and by changing the existing entities), to get information -# about a mesh and to export a mesh into different formats. +# about a mesh and to export a mesh in different formats. class Mesh: __metaclass__ = MeshMeta @@ -1217,7 +1219,7 @@ class Mesh: ## Constructor # - # Creates a mesh on the shape \a obj (or an empty mesh if \a obj is equal to 0) and + # Create a mesh on the shape \a obj (or an empty mesh if \a obj is equal to 0) and # sets the GUI name of this mesh to \a name. # @param smeshpyD an instance of smeshBuilder class # @param geompyD an instance of geomBuilder class @@ -1279,7 +1281,7 @@ class Mesh: pass pass - ## Initializes the Mesh object from an instance of SMESH_Mesh interface + ## Initialize the Mesh object from an instance of SMESH_Mesh interface # @param theMesh a SMESH_Mesh object # @ingroup l2_construct def SetMesh(self, theMesh): @@ -1291,60 +1293,76 @@ class Mesh: self.geom = self.mesh.GetShapeToMesh() pass - ## Returns the mesh, that is an instance of SMESH_Mesh interface + ## Return the mesh, that is an instance of SMESH_Mesh interface # @return a SMESH_Mesh object # @ingroup l2_construct def GetMesh(self): return self.mesh - ## Gets the name of the mesh + ## Get the name of the mesh # @return the name of the mesh as a string # @ingroup l2_construct def GetName(self): name = GetName(self.GetMesh()) return name - ## Sets a name to the mesh + ## Set a name to the mesh # @param name a new name of the mesh # @ingroup l2_construct def SetName(self, name): self.smeshpyD.SetName(self.GetMesh(), name) - ## Gets the subMesh object associated to a \a theSubObject geometrical object. - # The subMesh object gives access to the IDs of nodes and elements. + ## Get a sub-mesh object associated to a \a geom geometrical object. # @param geom a geometrical object (shape) - # @param name a name for the submesh - # @return an object of type SMESH_SubMesh, representing a part of mesh, which lies on the given shape + # @param name a name for the sub-mesh in the Object Browser + # @return an object of type SMESH.SMESH_subMesh, representing a part of mesh, + # which lies on the given shape + # + # The sub-mesh object gives access to the IDs of nodes and elements. + # The sub-mesh object has the following methods: + # - SMESH.SMESH_subMesh.GetNumberOfElements() + # - SMESH.SMESH_subMesh.GetNumberOfNodes( all ) + # - SMESH.SMESH_subMesh.GetElementsId() + # - SMESH.SMESH_subMesh.GetElementsByType( ElementType ) + # - SMESH.SMESH_subMesh.GetNodesId() + # - SMESH.SMESH_subMesh.GetSubShape() + # - SMESH.SMESH_subMesh.GetFather() + # - SMESH.SMESH_subMesh.GetId() + # @note A sub-mesh is implicitly created when a sub-shape is specified at + # creating an algorithm, for example: algo1D = mesh.Segment(geom=Edge_1) + # creates a sub-mesh on @c Edge_1 and assign Wire Discretization algorithm to it. + # The created sub-mesh can be retrieved from the algorithm: + # submesh = algo1D.GetSubMesh() # @ingroup l2_submeshes def GetSubMesh(self, geom, name): AssureGeomPublished( self, geom, name ) submesh = self.mesh.GetSubMesh( geom, name ) return submesh - ## Returns the shape associated to the mesh + ## Return the shape associated to the mesh # @return a GEOM_Object # @ingroup l2_construct def GetShape(self): return self.geom - ## Associates the given shape to the mesh (entails the recreation of the mesh) + ## Associate the given shape to the mesh (entails the recreation of the mesh) # @param geom the shape to be meshed (GEOM_Object) # @ingroup l2_construct def SetShape(self, geom): self.mesh = self.smeshpyD.CreateMesh(geom) - ## Loads mesh from the study after opening the study + ## Load mesh from the study after opening the study def Load(self): self.mesh.Load() - ## Returns true if the hypotheses are defined well + ## Return true if the hypotheses are defined well # @param theSubObject a sub-shape of a mesh shape # @return True or False # @ingroup l2_construct def IsReadyToCompute(self, theSubObject): return self.smeshpyD.IsReadyToCompute(self.mesh, theSubObject) - ## Returns errors of hypotheses definition. + ## Return errors of hypotheses definition. # The list of errors is empty if everything is OK. # @param theSubObject a sub-shape of a mesh shape # @return a list of errors @@ -1352,20 +1370,20 @@ class Mesh: def GetAlgoState(self, theSubObject): return self.smeshpyD.GetAlgoState(self.mesh, theSubObject) - ## Returns a geometrical object on which the given element was built. + ## Return a geometrical object on which the given element was built. # The returned geometrical object, if not nil, is either found in the # study or published by this method with the given name # @param theElementID the id of the mesh element # @param theGeomName the user-defined name of the geometrical object # @return GEOM::GEOM_Object instance - # @ingroup l2_construct + # @ingroup l1_meshinfo def GetGeometryByMeshElement(self, theElementID, theGeomName): return self.smeshpyD.GetGeometryByMeshElement( self.mesh, theElementID, theGeomName ) - ## Returns the mesh dimension depending on the dimension of the underlying shape + ## Return the mesh dimension depending on the dimension of the underlying shape # or, if the mesh is not based on any shape, basing on deimension of elements # @return mesh dimension as an integer value [0,3] - # @ingroup l1_auxiliary + # @ingroup l1_meshinfo def MeshDimension(self): if self.mesh.HasShapeToMesh(): shells = self.geompyD.SubShapeAllIDs( self.geom, self.geompyD.ShapeType["SOLID"] ) @@ -1383,10 +1401,11 @@ class Mesh: if self.NbEdges() > 0: return 1 return 0 - ## Evaluates size of prospective mesh on a shape + ## Evaluate size of prospective mesh on a shape # @return a list where i-th element is a number of elements of i-th SMESH.EntityType # To know predicted number of e.g. edges, inquire it this way # Evaluate()[ EnumToLong( Entity_Edge )] + # @ingroup l2_construct def Evaluate(self, geom=0): if geom == 0 or not isinstance(geom, geomBuilder.GEOM._objref_GEOM_Object): if self.geom == 0: @@ -1396,7 +1415,7 @@ class Mesh: return self.smeshpyD.Evaluate(self.mesh, geom) - ## Computes the mesh and returns the status of the computation + ## Compute the mesh and return the status of the computation # @param geom geomtrical shape on which mesh data should be computed # @param discardModifs if True and the mesh has been edited since # a last total re-compute and that may prevent successful partial re-compute, @@ -1505,11 +1524,12 @@ class Mesh: smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), ok, (self.NbNodes()==0) ) - if refresh: salome.sg.updateObjBrowser(1) + if refresh: salome.sg.updateObjBrowser(True) return ok ## Return a list of error messages (SMESH.ComputeError) of the last Compute() + # @ingroup l2_construct def GetComputeErrors(self, shape=0 ): if shape == 0: shape = self.mesh.GetShapeToMesh() @@ -1522,6 +1542,7 @@ class Mesh: # - FACE #3 (not published sub-shape) # - sub-shape #3 (invalid sub-shape ID) # - #3 (error in this function) + # @ingroup l1_auxiliary def GetSubShapeName(self, subShapeID ): if not self.mesh.HasShapeToMesh(): return "" @@ -1564,6 +1585,7 @@ class Mesh: # error of an algorithm # @param publish if @c True, the returned groups will be published in the study # @return a list of GEOM groups each named after a failed algorithm + # @ingroup l2_construct def GetFailedShapes(self, publish=False): algo2shapes = {} @@ -1614,7 +1636,7 @@ class Mesh: def SetMeshOrder(self, submeshes): return self.mesh.SetMeshOrder(submeshes) - ## Removes all nodes and elements + ## Remove all nodes and elements generated on geometry. Imported elements remain. # @param refresh if @c True, Object browser is automatically updated (when running in GUI) # @ingroup l2_construct def Clear(self, refresh=False): @@ -1624,21 +1646,21 @@ class Mesh: smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) - if refresh: salome.sg.updateObjBrowser(1) + if refresh: salome.sg.updateObjBrowser(True) - ## Removes all nodes and elements of indicated shape + ## Remove all nodes and elements of indicated shape # @param refresh if @c True, Object browser is automatically updated (when running in GUI) # @param geomId the ID of a sub-shape to remove elements on - # @ingroup l2_construct + # @ingroup l2_submeshes def ClearSubMesh(self, geomId, refresh=False): self.mesh.ClearSubMesh(geomId) if salome.sg.hasDesktop(): smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self.mesh ), False, True ) - if refresh: salome.sg.updateObjBrowser(1) + if refresh: salome.sg.updateObjBrowser(True) - ## Computes a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron + ## Compute a tetrahedral mesh using AutomaticLength + MEFISTO + Tetrahedron # @param fineness [0.0,1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic @@ -1655,7 +1677,7 @@ class Mesh: pass return self.Compute() - ## Computes an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron + ## Compute an hexahedral mesh using AutomaticLength + Quadrangle + Hexahedron # @param fineness [0.0, 1.0] defines mesh fineness # @return True or False # @ingroup l3_algos_basic @@ -1672,11 +1694,11 @@ class Mesh: pass return self.Compute() - ## Assigns a hypothesis + ## Assign a hypothesis # @param hyp a hypothesis to assign # @param geom a subhape of mesh geometry # @return SMESH.Hypothesis_Status - # @ingroup l2_hypotheses + # @ingroup l2_editing def AddHypothesis(self, hyp, geom=0): if isinstance( hyp, geomBuilder.GEOM._objref_GEOM_Object ): hyp, geom = geom, hyp @@ -1714,7 +1736,7 @@ class Mesh: # @param hyp a hypothesis to check # @param geom a subhape of mesh geometry # @return True of False - # @ingroup l2_hypotheses + # @ingroup l2_editing def IsUsedHypothesis(self, hyp, geom): if not hyp: # or not geom return False @@ -1727,11 +1749,11 @@ class Mesh: return True return False - ## Unassigns a hypothesis + ## Unassign a hypothesis # @param hyp a hypothesis to unassign # @param geom a sub-shape of mesh geometry # @return SMESH.Hypothesis_Status - # @ingroup l2_hypotheses + # @ingroup l2_editing def RemoveHypothesis(self, hyp, geom=0): if not hyp: return None @@ -1749,15 +1771,15 @@ class Mesh: print "WARNING: RemoveHypothesis() failed as '%s' is not assigned to '%s' shape" % ( hypName, geoName ) return None - ## Gets the list of hypotheses added on a geometry + ## Get the list of hypotheses added on a geometry # @param geom a sub-shape of mesh geometry # @return the sequence of SMESH_Hypothesis - # @ingroup l2_hypotheses + # @ingroup l2_editing def GetHypothesisList(self, geom): return self.mesh.GetHypothesisList( geom ) - ## Removes all global hypotheses - # @ingroup l2_hypotheses + ## Remove all global hypotheses + # @ingroup l2_editing def RemoveGlobalHypotheses(self): current_hyps = self.mesh.GetHypothesisList( self.geom ) for hyp in current_hyps: @@ -1765,7 +1787,7 @@ class Mesh: pass pass - ## Exports the mesh in a file in MED format and chooses the \a version of MED format + ## Export the mesh in a file in MED format and chooses the \a version of MED format ## allowing to overwrite the file if it exists or add the exported data to its contents # @param f is the file name # @param auto_groups boolean parameter for creating/not creating @@ -1799,7 +1821,7 @@ class Mesh: else: self.mesh.ExportToMEDX(f, auto_groups, version, overwrite, autoDimension) - ## Exports the mesh in a file in SAUV format + ## Export the mesh in a file in SAUV format # @param f is the file name # @param auto_groups boolean parameter for creating/not creating # the groups Group_On_All_Nodes, Group_On_All_Faces, ... ; @@ -1808,7 +1830,7 @@ class Mesh: def ExportSAUV(self, f, auto_groups=0): self.mesh.ExportSAUV(f, auto_groups) - ## Exports the mesh in a file in DAT format + ## Export the mesh in a file in DAT format # @param f the file name # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp @@ -1822,7 +1844,7 @@ class Mesh: else: self.mesh.ExportDAT(f) - ## Exports the mesh in a file in UNV format + ## Export the mesh in a file in UNV format # @param f the file name # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh # @ingroup l2_impexp @@ -1851,7 +1873,7 @@ class Mesh: else: self.mesh.ExportSTL(f, ascii) - ## Exports the mesh in a file in CGNS format + ## Export the mesh in a file in CGNS format # @param f is the file name # @param overwrite boolean parameter for overwriting/not overwriting the file # @param meshPart a part of mesh (group, sub-mesh) to export instead of the mesh @@ -1867,7 +1889,7 @@ class Mesh: meshPart = self.mesh self.mesh.ExportCGNS(meshPart, f, overwrite) - ## Exports the mesh in a file in GMF format. + ## Export the mesh in a file in GMF format. # GMF files must have .mesh extension for the ASCII format and .meshb for # the bynary format. Other extensions are not allowed. # @param f is the file name @@ -1885,7 +1907,7 @@ class Mesh: self.mesh.ExportGMF(meshPart, f, True) ## Deprecated, used only for compatibility! Please, use ExportToMEDX() method instead. - # Exports the mesh in a file in MED format and chooses the \a version of MED format + # Export the mesh in a file in MED format and chooses the \a version of MED format ## allowing to overwrite the file if it exists or add the exported data to its contents # @param f the file name # @param version values are SMESH.MED_V2_1, SMESH.MED_V2_2 @@ -1905,7 +1927,7 @@ class Mesh: # Operations with groups: # ---------------------- - ## Creates an empty mesh group + ## Create an empty mesh group # @param elementType the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) # @param name the name of the mesh group @@ -1914,7 +1936,7 @@ class Mesh: def CreateEmptyGroup(self, elementType, name): return self.mesh.CreateGroup(elementType, name) - ## Creates a mesh group based on the geometric object \a grp + ## Create a mesh group based on the geometric object \a grp # and gives a \a name, \n if this parameter is not defined # the name is the same as the geometric group name \n # Note: Works like GroupOnGeom(). @@ -1925,7 +1947,7 @@ class Mesh: def Group(self, grp, name=""): return self.GroupOnGeom(grp, name) - ## Creates a mesh group based on the geometrical object \a grp + ## Create a mesh group based on the geometrical object \a grp # and gives a \a name, \n if this parameter is not defined # the name is the same as the geometrical group name # @param grp a geometrical group, a vertex, an edge, a face or a solid @@ -1964,7 +1986,7 @@ class Mesh: "_groupTypeFromShape(): invalid geometry '%s'" % GetName(shape) return typ - ## Creates a mesh group with given \a name based on the \a filter which + ## Create a mesh group with given \a name based on the \a filter which ## is a special type of group dynamically updating it's contents during ## mesh modification # @param typ the type of elements in the group; either of @@ -1976,7 +1998,7 @@ class Mesh: def GroupOnFilter(self, typ, name, filter): return self.mesh.CreateGroupFromFilter(typ, name, filter) - ## Creates a mesh group by the given ids of elements + ## Create a mesh group by the given ids of elements # @param groupName the name of the mesh group # @param elementType the type of elements in the group; either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME). @@ -1993,7 +2015,7 @@ class Mesh: group.Add(elemIDs) return group - ## Creates a mesh group by the given conditions + ## Create a mesh group by the given conditions # @param groupName the name of the mesh group # @param elementType the type of elements(SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME) # @param CritType the type of criterion (SMESH.FT_Taper, SMESH.FT_Area, etc.) @@ -2018,7 +2040,7 @@ class Mesh: group = self.MakeGroupByCriterion(groupName, aCriterion) return group - ## Creates a mesh group by the given criterion + ## Create a mesh group by the given criterion # @param groupName the name of the mesh group # @param Criterion the instance of Criterion class # @return SMESH_GroupOnFilter @@ -2026,7 +2048,7 @@ class Mesh: def MakeGroupByCriterion(self, groupName, Criterion): return self.MakeGroupByCriteria( groupName, [Criterion] ) - ## Creates a mesh group by the given criteria (list of criteria) + ## Create a mesh group by the given criteria (list of criteria) # @param groupName the name of the mesh group # @param theCriteria the list of criteria # @param binOp binary operator used when binary operator of criteria is undefined @@ -2037,7 +2059,7 @@ class Mesh: group = self.MakeGroupByFilter(groupName, aFilter) return group - ## Creates a mesh group by the given filter + ## Create a mesh group by the given filter # @param groupName the name of the mesh group # @param theFilter the instance of Filter class # @return SMESH_GroupOnFilter @@ -2049,17 +2071,17 @@ class Mesh: group = self.GroupOnFilter( theFilter.GetElementType(), groupName, theFilter ) return group - ## Removes a group + ## Remove a group # @ingroup l2_grps_delete def RemoveGroup(self, group): self.mesh.RemoveGroup(group) - ## Removes a group with its contents + ## Remove a group with its contents # @ingroup l2_grps_delete def RemoveGroupWithContents(self, group): self.mesh.RemoveGroupWithContents(group) - ## Gets the list of groups existing in the mesh in the order + ## Get the list of groups existing in the mesh in the order # of creation (starting from the oldest one) # @param elemType type of elements the groups contain; either of # (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); @@ -2078,13 +2100,13 @@ class Mesh: pass return typedGroups - ## Gets the number of groups existing in the mesh + ## Get the number of groups existing in the mesh # @return the quantity of groups as an integer value # @ingroup l2_grps_create def NbGroups(self): return self.mesh.NbGroups() - ## Gets the list of names of groups existing in the mesh + ## Get the list of names of groups existing in the mesh # @return list of strings # @ingroup l2_grps_create def GetGroupNames(self): @@ -2094,7 +2116,7 @@ class Mesh: names.append(group.GetName()) return names - ## Finds groups by name and type + ## Find groups by name and type # @param name name of the group of interest # @param elemType type of elements the groups contain; either of # (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE, SMESH.VOLUME); @@ -2113,7 +2135,7 @@ class Mesh: groups.append( group ) return groups - ## Produces a union of two groups. + ## Produce a union of two groups. # A new group is created. All mesh elements that are # present in the initial groups are added to the new one # @return an instance of SMESH_Group @@ -2121,7 +2143,7 @@ class Mesh: def UnionGroups(self, group1, group2, name): return self.mesh.UnionGroups(group1, group2, name) - ## Produces a union list of groups. + ## Produce a union list of groups. # New group is created. All mesh elements that are present in # initial groups are added to the new one # @return an instance of SMESH_Group @@ -2129,7 +2151,7 @@ class Mesh: def UnionListOfGroups(self, groups, name): return self.mesh.UnionListOfGroups(groups, name) - ## Prodices an intersection of two groups. + ## Prodice an intersection of two groups. # A new group is created. All mesh elements that are common # for the two initial groups are added to the new one. # @return an instance of SMESH_Group @@ -2137,7 +2159,7 @@ class Mesh: def IntersectGroups(self, group1, group2, name): return self.mesh.IntersectGroups(group1, group2, name) - ## Produces an intersection of groups. + ## Produce an intersection of groups. # New group is created. All mesh elements that are present in all # initial groups simultaneously are added to the new one # @return an instance of SMESH_Group @@ -2145,7 +2167,7 @@ class Mesh: def IntersectListOfGroups(self, groups, name): return self.mesh.IntersectListOfGroups(groups, name) - ## Produces a cut of two groups. + ## Produce a cut of two groups. # A new group is created. All mesh elements that are present in # the main group but are not present in the tool group are added to the new one # @return an instance of SMESH_Group @@ -2153,7 +2175,7 @@ class Mesh: def CutGroups(self, main_group, tool_group, name): return self.mesh.CutGroups(main_group, tool_group, name) - ## Produces a cut of groups. + ## Produce a cut of groups. # A new group is created. All mesh elements that are present in main groups # but do not present in tool groups are added to the new one # @return an instance of SMESH_Group @@ -2189,14 +2211,14 @@ class Mesh: ## Convert group on geom into standalone group - # @ingroup l2_grps_edit + # @ingroup l2_grps_operon def ConvertToStandalone(self, group): return self.mesh.ConvertToStandalone(group) # Get some info about mesh: # ------------------------ - ## Returns the log of nodes and elements added or removed + ## Return the log of nodes and elements added or removed # since the previous clear of the log. # @param clearAfterGet log is emptied after Get (safe if concurrents access) # @return list of log_block structures: @@ -2208,25 +2230,27 @@ class Mesh: def GetLog(self, clearAfterGet): return self.mesh.GetLog(clearAfterGet) - ## Clears the log of nodes and elements added or removed since the previous + ## Clear the log of nodes and elements added or removed since the previous # clear. Must be used immediately after GetLog if clearAfterGet is false. # @ingroup l1_auxiliary def ClearLog(self): self.mesh.ClearLog() - ## Toggles auto color mode on the object. + ## Toggle auto color mode on the object. # @param theAutoColor the flag which toggles auto color mode. - # @ingroup l1_auxiliary + # + # If switched on, a default color of a new group in Create Group dialog is chosen randomly. + # @ingroup l1_grouping def SetAutoColor(self, theAutoColor): self.mesh.SetAutoColor(theAutoColor) - ## Gets flag of object auto color mode. + ## Get flag of object auto color mode. # @return True or False - # @ingroup l1_auxiliary + # @ingroup l1_grouping def GetAutoColor(self): return self.mesh.GetAutoColor() - ## Gets the internal ID + ## Get the internal ID # @return integer value, which is the internal Id of the mesh # @ingroup l1_auxiliary def GetId(self): @@ -2238,14 +2262,14 @@ class Mesh: def GetStudyId(self): return self.mesh.GetStudyId() - ## Checks the group names for duplications. + ## Check the group names for duplications. # Consider the maximum group name length stored in MED file. # @return True or False - # @ingroup l1_auxiliary + # @ingroup l1_grouping def HasDuplicatedGroupNamesMED(self): return self.mesh.HasDuplicatedGroupNamesMED() - ## Obtains the mesh editor tool + ## Obtain the mesh editor tool # @return an instance of SMESH_MeshEditor # @ingroup l1_modifying def GetMeshEditor(self): @@ -2272,44 +2296,44 @@ class Mesh: # Get informations about mesh contents: # ------------------------------------ - ## Gets the mesh stattistic + ## Get the mesh stattistic # @return dictionary type element - count of elements # @ingroup l1_meshinfo def GetMeshInfo(self, obj = None): if not obj: obj = self.mesh return self.smeshpyD.GetMeshInfo(obj) - ## Returns the number of nodes in the mesh + ## Return the number of nodes in the mesh # @return an integer value # @ingroup l1_meshinfo def NbNodes(self): return self.mesh.NbNodes() - ## Returns the number of elements in the mesh + ## Return the number of elements in the mesh # @return an integer value # @ingroup l1_meshinfo def NbElements(self): return self.mesh.NbElements() - ## Returns the number of 0d elements in the mesh + ## Return the number of 0d elements in the mesh # @return an integer value # @ingroup l1_meshinfo def Nb0DElements(self): return self.mesh.Nb0DElements() - ## Returns the number of ball discrete elements in the mesh + ## Return the number of ball discrete elements in the mesh # @return an integer value # @ingroup l1_meshinfo def NbBalls(self): return self.mesh.NbBalls() - ## Returns the number of edges in the mesh + ## Return the number of edges in the mesh # @return an integer value # @ingroup l1_meshinfo def NbEdges(self): return self.mesh.NbEdges() - ## Returns the number of edges with the given order in the mesh + ## Return the number of edges with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2317,13 +2341,13 @@ class Mesh: def NbEdgesOfOrder(self, elementOrder): return self.mesh.NbEdgesOfOrder(elementOrder) - ## Returns the number of faces in the mesh + ## Return the number of faces in the mesh # @return an integer value # @ingroup l1_meshinfo def NbFaces(self): return self.mesh.NbFaces() - ## Returns the number of faces with the given order in the mesh + ## Return the number of faces with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2331,13 +2355,13 @@ class Mesh: def NbFacesOfOrder(self, elementOrder): return self.mesh.NbFacesOfOrder(elementOrder) - ## Returns the number of triangles in the mesh + ## Return the number of triangles in the mesh # @return an integer value # @ingroup l1_meshinfo def NbTriangles(self): return self.mesh.NbTriangles() - ## Returns the number of triangles with the given order in the mesh + ## Return the number of triangles with the given order in the mesh # @param elementOrder is the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2345,19 +2369,19 @@ class Mesh: def NbTrianglesOfOrder(self, elementOrder): return self.mesh.NbTrianglesOfOrder(elementOrder) - ## Returns the number of biquadratic triangles in the mesh + ## Return the number of biquadratic triangles in the mesh # @return an integer value # @ingroup l1_meshinfo def NbBiQuadTriangles(self): return self.mesh.NbBiQuadTriangles() - ## Returns the number of quadrangles in the mesh + ## Return the number of quadrangles in the mesh # @return an integer value # @ingroup l1_meshinfo def NbQuadrangles(self): return self.mesh.NbQuadrangles() - ## Returns the number of quadrangles with the given order in the mesh + ## Return the number of quadrangles with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2365,13 +2389,13 @@ class Mesh: def NbQuadranglesOfOrder(self, elementOrder): return self.mesh.NbQuadranglesOfOrder(elementOrder) - ## Returns the number of biquadratic quadrangles in the mesh + ## Return the number of biquadratic quadrangles in the mesh # @return an integer value # @ingroup l1_meshinfo def NbBiQuadQuadrangles(self): return self.mesh.NbBiQuadQuadrangles() - ## Returns the number of polygons of given order in the mesh + ## Return the number of polygons of given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2379,13 +2403,13 @@ class Mesh: def NbPolygons(self, elementOrder = SMESH.ORDER_ANY): return self.mesh.NbPolygonsOfOrder(elementOrder) - ## Returns the number of volumes in the mesh + ## Return the number of volumes in the mesh # @return an integer value # @ingroup l1_meshinfo def NbVolumes(self): return self.mesh.NbVolumes() - ## Returns the number of volumes with the given order in the mesh + ## Return the number of volumes with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2393,13 +2417,13 @@ class Mesh: def NbVolumesOfOrder(self, elementOrder): return self.mesh.NbVolumesOfOrder(elementOrder) - ## Returns the number of tetrahedrons in the mesh + ## Return the number of tetrahedrons in the mesh # @return an integer value # @ingroup l1_meshinfo def NbTetras(self): return self.mesh.NbTetras() - ## Returns the number of tetrahedrons with the given order in the mesh + ## Return the number of tetrahedrons with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2407,13 +2431,13 @@ class Mesh: def NbTetrasOfOrder(self, elementOrder): return self.mesh.NbTetrasOfOrder(elementOrder) - ## Returns the number of hexahedrons in the mesh + ## Return the number of hexahedrons in the mesh # @return an integer value # @ingroup l1_meshinfo def NbHexas(self): return self.mesh.NbHexas() - ## Returns the number of hexahedrons with the given order in the mesh + ## Return the number of hexahedrons with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2421,19 +2445,19 @@ class Mesh: def NbHexasOfOrder(self, elementOrder): return self.mesh.NbHexasOfOrder(elementOrder) - ## Returns the number of triquadratic hexahedrons in the mesh + ## Return the number of triquadratic hexahedrons in the mesh # @return an integer value # @ingroup l1_meshinfo def NbTriQuadraticHexas(self): return self.mesh.NbTriQuadraticHexas() - ## Returns the number of pyramids in the mesh + ## Return the number of pyramids in the mesh # @return an integer value # @ingroup l1_meshinfo def NbPyramids(self): return self.mesh.NbPyramids() - ## Returns the number of pyramids with the given order in the mesh + ## Return the number of pyramids with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2441,13 +2465,13 @@ class Mesh: def NbPyramidsOfOrder(self, elementOrder): return self.mesh.NbPyramidsOfOrder(elementOrder) - ## Returns the number of prisms in the mesh + ## Return the number of prisms in the mesh # @return an integer value # @ingroup l1_meshinfo def NbPrisms(self): return self.mesh.NbPrisms() - ## Returns the number of prisms with the given order in the mesh + ## Return the number of prisms with the given order in the mesh # @param elementOrder the order of elements: # SMESH.ORDER_ANY, SMESH.ORDER_LINEAR or SMESH.ORDER_QUADRATIC # @return an integer value @@ -2455,31 +2479,31 @@ class Mesh: def NbPrismsOfOrder(self, elementOrder): return self.mesh.NbPrismsOfOrder(elementOrder) - ## Returns the number of hexagonal prisms in the mesh + ## Return the number of hexagonal prisms in the mesh # @return an integer value # @ingroup l1_meshinfo def NbHexagonalPrisms(self): return self.mesh.NbHexagonalPrisms() - ## Returns the number of polyhedrons in the mesh + ## Return the number of polyhedrons in the mesh # @return an integer value # @ingroup l1_meshinfo def NbPolyhedrons(self): return self.mesh.NbPolyhedrons() - ## Returns the number of submeshes in the mesh + ## Return the number of submeshes in the mesh # @return an integer value # @ingroup l1_meshinfo def NbSubMesh(self): return self.mesh.NbSubMesh() - ## Returns the list of mesh elements IDs + ## Return the list of mesh elements IDs # @return the list of integer values # @ingroup l1_meshinfo def GetElementsId(self): return self.mesh.GetElementsId() - ## Returns the list of IDs of mesh elements with the given type + ## Return the list of IDs of mesh elements with the given type # @param elementType the required type of elements, either of # (SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME) # @return list of integer values @@ -2487,7 +2511,7 @@ class Mesh: def GetElementsByType(self, elementType): return self.mesh.GetElementsByType(elementType) - ## Returns the list of mesh nodes IDs + ## Return the list of mesh nodes IDs # @return the list of integer values # @ingroup l1_meshinfo def GetNodesId(self): @@ -2496,29 +2520,29 @@ class Mesh: # Get the information about mesh elements: # ------------------------------------ - ## Returns the type of mesh element + ## Return the type of mesh element # @return the value from SMESH::ElementType enumeration # Type SMESH.ElementType._items in the Python Console to see all possible values. # @ingroup l1_meshinfo def GetElementType(self, id, iselem=True): return self.mesh.GetElementType(id, iselem) - ## Returns the geometric type of mesh element + ## Return the geometric type of mesh element # @return the value from SMESH::EntityType enumeration # Type SMESH.EntityType._items in the Python Console to see all possible values. # @ingroup l1_meshinfo def GetElementGeomType(self, id): return self.mesh.GetElementGeomType(id) - ## Returns the shape type of mesh element + ## Return the shape type of mesh element # @return the value from SMESH::GeometryType enumeration. # Type SMESH.GeometryType._items in the Python Console to see all possible values. # @ingroup l1_meshinfo def GetElementShape(self, id): return self.mesh.GetElementShape(id) - ## Returns the list of submesh elements IDs - # @param Shape a geom object(sub-shape) IOR + ## Return the list of submesh elements IDs + # @param Shape a geom object(sub-shape) # Shape must be the sub-shape of a ShapeToMesh() # @return the list of integer values # @ingroup l1_meshinfo @@ -2529,8 +2553,8 @@ class Mesh: ShapeID = Shape return self.mesh.GetSubMeshElementsId(ShapeID) - ## Returns the list of submesh nodes IDs - # @param Shape a geom object(sub-shape) IOR + ## Return the list of submesh nodes IDs + # @param Shape a geom object(sub-shape) # Shape must be the sub-shape of a ShapeToMesh() # @param all If true, gives all nodes of submesh elements, otherwise gives only submesh nodes # @return the list of integer values @@ -2542,8 +2566,8 @@ class Mesh: ShapeID = Shape return self.mesh.GetSubMeshNodesId(ShapeID, all) - ## Returns type of elements on given shape - # @param Shape a geom object(sub-shape) IOR + ## Return type of elements on given shape + # @param Shape a geom object(sub-shape) # Shape must be a sub-shape of a ShapeToMesh() # @return element type # @ingroup l1_meshinfo @@ -2554,7 +2578,7 @@ class Mesh: ShapeID = Shape return self.mesh.GetSubMeshElementType(ShapeID) - ## Gets the mesh description + ## Get the mesh description # @return string value # @ingroup l1_meshinfo def Dump(self): @@ -2564,72 +2588,72 @@ class Mesh: # Get the information about nodes and elements of a mesh by its IDs: # ----------------------------------------------------------- - ## Gets XYZ coordinates of a node - # \n If there is no nodes for the given ID - returns an empty list + ## Get XYZ coordinates of a node + # \n If there is no nodes for the given ID - return an empty list # @return a list of double precision values # @ingroup l1_meshinfo def GetNodeXYZ(self, id): return self.mesh.GetNodeXYZ(id) - ## Returns list of IDs of inverse elements for the given node - # \n If there is no node for the given ID - returns an empty list + ## Return list of IDs of inverse elements for the given node + # \n If there is no node for the given ID - return an empty list # @return a list of integer values # @ingroup l1_meshinfo def GetNodeInverseElements(self, id): return self.mesh.GetNodeInverseElements(id) - ## @brief Returns the position of a node on the shape + ## Return the position of a node on the shape # @return SMESH::NodePosition # @ingroup l1_meshinfo def GetNodePosition(self,NodeID): return self.mesh.GetNodePosition(NodeID) - ## @brief Returns the position of an element on the shape + ## Return the position of an element on the shape # @return SMESH::ElementPosition # @ingroup l1_meshinfo def GetElementPosition(self,ElemID): return self.mesh.GetElementPosition(ElemID) - ## Returns the ID of the shape, on which the given node was generated. + ## Return the ID of the shape, on which the given node was generated. # @return an integer value > 0 or -1 if there is no node for the given # ID or the node is not assigned to any geometry # @ingroup l1_meshinfo def GetShapeID(self, id): return self.mesh.GetShapeID(id) - ## Returns the ID of the shape, on which the given element was generated. + ## Return the ID of the shape, on which the given element was generated. # @return an integer value > 0 or -1 if there is no element for the given # ID or the element is not assigned to any geometry # @ingroup l1_meshinfo def GetShapeIDForElem(self,id): return self.mesh.GetShapeIDForElem(id) - ## Returns the number of nodes of the given element + ## Return the number of nodes of the given element # @return an integer value > 0 or -1 if there is no element for the given ID # @ingroup l1_meshinfo def GetElemNbNodes(self, id): return self.mesh.GetElemNbNodes(id) - ## Returns the node ID the given (zero based) index for the given element - # \n If there is no element for the given ID - returns -1 - # \n If there is no node for the given index - returns -2 + ## Return the node ID the given (zero based) index for the given element + # \n If there is no element for the given ID - return -1 + # \n If there is no node for the given index - return -2 # @return an integer value # @ingroup l1_meshinfo def GetElemNode(self, id, index): return self.mesh.GetElemNode(id, index) - ## Returns the IDs of nodes of the given element + ## Return the IDs of nodes of the given element # @return a list of integer values # @ingroup l1_meshinfo def GetElemNodes(self, id): return self.mesh.GetElemNodes(id) - ## Returns true if the given node is the medium node in the given quadratic element + ## Return true if the given node is the medium node in the given quadratic element # @ingroup l1_meshinfo def IsMediumNode(self, elementID, nodeID): return self.mesh.IsMediumNode(elementID, nodeID) - ## Returns true if the given node is the medium node in one of quadratic elements + ## Return true if the given node is the medium node in one of quadratic elements # @param nodeID ID of the node # @param elementType the type of elements to check a state of the node, either of # (SMESH.ALL, SMESH.NODE, SMESH.EDGE, SMESH.FACE or SMESH.VOLUME) @@ -2637,55 +2661,55 @@ class Mesh: def IsMediumNodeOfAnyElem(self, nodeID, elementType = SMESH.ALL ): return self.mesh.IsMediumNodeOfAnyElem(nodeID, elementType) - ## Returns the number of edges for the given element + ## Return the number of edges for the given element # @ingroup l1_meshinfo def ElemNbEdges(self, id): return self.mesh.ElemNbEdges(id) - ## Returns the number of faces for the given element + ## Return the number of faces for the given element # @ingroup l1_meshinfo def ElemNbFaces(self, id): return self.mesh.ElemNbFaces(id) - ## Returns nodes of given face (counted from zero) for given volumic element. + ## Return nodes of given face (counted from zero) for given volumic element. # @ingroup l1_meshinfo def GetElemFaceNodes(self,elemId, faceIndex): return self.mesh.GetElemFaceNodes(elemId, faceIndex) - ## Returns three components of normal of given mesh face + ## Return three components of normal of given mesh face # (or an empty array in KO case) # @ingroup l1_meshinfo def GetFaceNormal(self, faceId, normalized=False): return self.mesh.GetFaceNormal(faceId,normalized) - ## Returns an element based on all given nodes. + ## Return an element based on all given nodes. # @ingroup l1_meshinfo def FindElementByNodes(self,nodes): return self.mesh.FindElementByNodes(nodes) - ## Returns true if the given element is a polygon + ## Return true if the given element is a polygon # @ingroup l1_meshinfo def IsPoly(self, id): return self.mesh.IsPoly(id) - ## Returns true if the given element is quadratic + ## Return true if the given element is quadratic # @ingroup l1_meshinfo def IsQuadratic(self, id): return self.mesh.IsQuadratic(id) - ## Returns diameter of a ball discrete element or zero in case of an invalid \a id + ## Return diameter of a ball discrete element or zero in case of an invalid \a id # @ingroup l1_meshinfo def GetBallDiameter(self, id): return self.mesh.GetBallDiameter(id) - ## Returns XYZ coordinates of the barycenter of the given element - # \n If there is no element for the given ID - returns an empty list + ## Return XYZ coordinates of the barycenter of the given element + # \n If there is no element for the given ID - return an empty list # @return a list of three double values # @ingroup l1_meshinfo def BaryCenter(self, id): return self.mesh.BaryCenter(id) - ## Passes mesh elements through the given filter and return IDs of fitting elements + ## Pass mesh elements through the given filter and return IDs of fitting elements # @param theFilter SMESH_Filter # @return a list of ids # @ingroup l1_controls @@ -2693,10 +2717,13 @@ class Mesh: theFilter.SetMesh( self.mesh ) return theFilter.GetIDs() - ## Verifies whether a 2D mesh element has free edges (edges connected to one face only)\n - # Returns a list of special structures (borders). + # Get mesh measurements information: + # ------------------------------------ + + ## Verify whether a 2D mesh element has free edges (edges connected to one face only)\n + # Return a list of special structures (borders). # @return a list of SMESH.FreeEdges.Border structure: edge id and ids of two its nodes. - # @ingroup l1_controls + # @ingroup l1_measurements def GetFreeBorders(self): aFilterMgr = self.smeshpyD.CreateFilterManager() aPredicate = aFilterMgr.CreateFreeEdges() @@ -2705,10 +2732,6 @@ class Mesh: aFilterMgr.UnRegister() return aBorders - - # Get mesh measurements information: - # ------------------------------------ - ## Get minimum distance between two nodes, elements or distance to the origin # @param id1 first node/element id # @param id2 second node/element id (if 0, distance from @a id1 to the origin is computed) @@ -2716,6 +2739,7 @@ class Mesh: # @param isElem2 @c True if @a id2 is element id, @c False if it is node id # @return minimum distance value # @sa GetMinDistance() + # @ingroup l1_measurements def MinDistance(self, id1, id2=0, isElem1=False, isElem2=False): aMeasure = self.GetMinDistance(id1, id2, isElem1, isElem2) return aMeasure.value @@ -2727,6 +2751,7 @@ class Mesh: # @param isElem2 @c True if @a id2 is element id, @c False if it is node id # @return Measure structure # @sa MinDistance() + # @ingroup l1_measurements def GetMinDistance(self, id1, id2=0, isElem1=False, isElem2=False): if isElem1: id1 = self.editor.MakeIDSource([id1], SMESH.FACE) @@ -2752,6 +2777,7 @@ class Mesh: # @c False specifies that @a objects are nodes # @return tuple of six values (minX, minY, minZ, maxX, maxY, maxZ) # @sa GetBoundingBox() + # @ingroup l1_measurements def BoundingBox(self, objects=None, isElem=False): result = self.GetBoundingBox(objects, isElem) if result is None: @@ -2766,6 +2792,7 @@ class Mesh: # @c False specifies that @a objects are nodes # @return Measure structure # @sa BoundingBox() + # @ingroup l1_measurements def GetBoundingBox(self, IDs=None, isElem=False): if IDs is None: IDs = [self.mesh] @@ -2800,21 +2827,21 @@ class Mesh: # Mesh edition (SMESH_MeshEditor functionality): # --------------------------------------------- - ## Removes the elements from the mesh by ids + ## Remove the elements from the mesh by ids # @param IDsOfElements is a list of ids of elements to remove # @return True or False # @ingroup l2_modif_del def RemoveElements(self, IDsOfElements): return self.editor.RemoveElements(IDsOfElements) - ## Removes nodes from mesh by ids + ## Remove nodes from mesh by ids # @param IDsOfNodes is a list of ids of nodes to remove # @return True or False # @ingroup l2_modif_del def RemoveNodes(self, IDsOfNodes): return self.editor.RemoveNodes(IDsOfNodes) - ## Removes all orphan (free) nodes from mesh + ## Remove all orphan (free) nodes from mesh # @return number of the removed nodes # @ingroup l2_modif_del def RemoveOrphanNodes(self): @@ -2828,7 +2855,7 @@ class Mesh: if hasVars: self.mesh.SetParameters(Parameters) return self.editor.AddNode( x, y, z) - ## Creates a 0D element on a node with given number. + ## Create a 0D element on a node with given number. # @param IDOfNode the ID of node for creation of the element. # @param DuplicateElements to add one more 0D element to a node or not # @return the Id of the new 0D element @@ -2857,7 +2884,7 @@ class Mesh: unRegister.set( theObject ) return self.editor.Create0DElementsOnAllNodes( theObject, theGroupName, DuplicateElements ) - ## Creates a ball element on a node with given ID. + ## Create a ball element on a node with given ID. # @param IDOfNode the ID of node for creation of the element. # @param diameter the bal diameter. # @return the Id of the new ball element @@ -2865,7 +2892,7 @@ class Mesh: def AddBall(self, IDOfNode, diameter): return self.editor.AddBall( IDOfNode, diameter ) - ## Creates a linear or quadratic edge (this is determined + ## Create a linear or quadratic edge (this is determined # by the number of given nodes). # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description @@ -2876,7 +2903,7 @@ class Mesh: def AddEdge(self, IDsOfNodes): return self.editor.AddEdge(IDsOfNodes) - ## Creates a linear or quadratic face (this is determined + ## Create a linear or quadratic face (this is determined # by the number of given nodes). # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description @@ -2887,14 +2914,14 @@ class Mesh: def AddFace(self, IDsOfNodes): return self.editor.AddFace(IDsOfNodes) - ## Adds a polygonal face to the mesh by the list of node IDs + ## Add a polygonal face to the mesh by the list of node IDs # @param IdsOfNodes the list of node IDs for creation of the element. # @return the Id of the new face # @ingroup l2_modif_add def AddPolygonalFace(self, IdsOfNodes): return self.editor.AddPolygonalFace(IdsOfNodes) - ## Adds a quadratic polygonal face to the mesh by the list of node IDs + ## Add a quadratic polygonal face to the mesh by the list of node IDs # @param IdsOfNodes the list of node IDs for creation of the element; # corner nodes follow first. # @return the Id of the new face @@ -2902,7 +2929,7 @@ class Mesh: def AddQuadPolygonalFace(self, IdsOfNodes): return self.editor.AddQuadPolygonalFace(IdsOfNodes) - ## Creates both simple and quadratic volume (this is determined + ## Create both simple and quadratic volume (this is determined # by the number of given nodes). # @param IDsOfNodes the list of node IDs for creation of the element. # The order of nodes in this list should correspond to the description @@ -2913,7 +2940,7 @@ class Mesh: def AddVolume(self, IDsOfNodes): return self.editor.AddVolume(IDsOfNodes) - ## Creates a volume of many faces, giving nodes for each face. + ## Create a volume of many faces, giving nodes for each face. # @param IdsOfNodes the list of node IDs for volume creation face by face. # @param Quantities the list of integer values, Quantities[i] # gives the quantity of nodes in face number i. @@ -2922,7 +2949,7 @@ class Mesh: def AddPolyhedralVolume (self, IdsOfNodes, Quantities): return self.editor.AddPolyhedralVolume(IdsOfNodes, Quantities) - ## Creates a volume of many faces, giving the IDs of the existing faces. + ## Create a volume of many faces, giving the IDs of the existing faces. # @param IdsOfFaces the list of face IDs for volume creation. # # Note: The created volume will refer only to the nodes @@ -3018,43 +3045,43 @@ class Mesh: return True - ## Moves the node with the given id + ## Move the node with the given id # @param NodeID the id of the node # @param x a new X coordinate # @param y a new Y coordinate # @param z a new Z coordinate # @return True if succeed else False - # @ingroup l2_modif_movenode + # @ingroup l2_modif_edit def MoveNode(self, NodeID, x, y, z): x,y,z,Parameters,hasVars = ParseParameters(x,y,z) if hasVars: self.mesh.SetParameters(Parameters) return self.editor.MoveNode(NodeID, x, y, z) - ## Finds the node closest to a point and moves it to a point location + ## Find the node closest to a point and moves it to a point location # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point # @param NodeID if specified (>0), the node with this ID is moved, # otherwise, the node closest to point (@a x,@a y,@a z) is moved # @return the ID of a node - # @ingroup l2_modif_throughp + # @ingroup l2_modif_edit def MoveClosestNodeToPoint(self, x, y, z, NodeID): x,y,z,Parameters,hasVars = ParseParameters(x,y,z) if hasVars: self.mesh.SetParameters(Parameters) return self.editor.MoveClosestNodeToPoint(x, y, z, NodeID) - ## Finds the node closest to a point + ## Find the node closest to a point # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point # @return the ID of a node - # @ingroup l2_modif_throughp + # @ingroup l1_meshinfo def FindNodeClosestTo(self, x, y, z): #preview = self.mesh.GetMeshEditPreviewer() #return preview.MoveClosestNodeToPoint(x, y, z, -1) return self.editor.FindNodeClosestTo(x, y, z) - ## Finds the elements where a point lays IN or ON + ## Find the elements where a point lays IN or ON # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point @@ -3063,7 +3090,7 @@ class Mesh: # means elements of any type excluding nodes, discrete and 0D elements. # @param meshPart a part of mesh (group, sub-mesh) to search within # @return list of IDs of found elements - # @ingroup l2_modif_throughp + # @ingroup l1_meshinfo def FindElementsByPoint(self, x, y, z, elementType = SMESH.ALL, meshPart=None): if meshPart: return self.editor.FindAmongElementsByPoint( meshPart, x, y, z, elementType ); @@ -3073,19 +3100,20 @@ class Mesh: ## Return point state in a closed 2D mesh in terms of TopAbs_State enumeration: # 0-IN, 1-OUT, 2-ON, 3-UNKNOWN # UNKNOWN state means that either mesh is wrong or the analysis fails. + # @ingroup l1_meshinfo def GetPointState(self, x, y, z): return self.editor.GetPointState(x, y, z) - ## Finds the node closest to a point and moves it to a point location + ## Find the node closest to a point and moves it to a point location # @param x the X coordinate of a point # @param y the Y coordinate of a point # @param z the Z coordinate of a point # @return the ID of a moved node - # @ingroup l2_modif_throughp + # @ingroup l2_modif_edit def MeshToPassThroughAPoint(self, x, y, z): return self.editor.MoveClosestNodeToPoint(x, y, z, -1) - ## Replaces two neighbour triangles sharing Node1-Node2 link + ## Replace two neighbour triangles sharing Node1-Node2 link # with the triangles built on the same 4 nodes but having other common link. # @param NodeID1 the ID of the first node # @param NodeID2 the ID of the second node @@ -3094,7 +3122,7 @@ class Mesh: def InverseDiag(self, NodeID1, NodeID2): return self.editor.InverseDiag(NodeID1, NodeID2) - ## Replaces two neighbour triangles sharing Node1-Node2 link + ## Replace two neighbour triangles sharing Node1-Node2 link # with a quadrangle built on the same 4 nodes. # @param NodeID1 the ID of the first node # @param NodeID2 the ID of the second node @@ -3103,7 +3131,7 @@ class Mesh: def DeleteDiag(self, NodeID1, NodeID2): return self.editor.DeleteDiag(NodeID1, NodeID2) - ## Reorients elements by ids + ## Reorient elements by ids # @param IDsOfElements if undefined reorients all mesh elements # @return True if succeed else False # @ingroup l2_modif_changori @@ -3112,7 +3140,7 @@ class Mesh: IDsOfElements = self.GetElementsId() return self.editor.Reorient(IDsOfElements) - ## Reorients all elements of the object + ## Reorient all elements of the object # @param theObject mesh, submesh or group # @return True if succeed else False # @ingroup l2_modif_changori @@ -3189,7 +3217,7 @@ class Mesh: unRegister.set( the3DObject ) return self.editor.Reorient2DBy3D( the2DObject, the3DObject, theOutsideNormal ) - ## Fuses the neighbouring triangles into quadrangles. + ## Fuse the neighbouring triangles into quadrangles. # @param IDsOfElements The triangles to be fused. # @param theCriterion a numerical functor, in terms of enum SMESH.FunctorType, used to # applied to possible quadrangles to choose a neighbour to fuse with. @@ -3208,7 +3236,7 @@ class Mesh: Functor = self.smeshpyD.GetFunctor(theCriterion) return self.editor.TriToQuad(IDsOfElements, Functor, MaxAngle) - ## Fuses the neighbouring triangles of the object into quadrangles + ## Fuse the neighbouring triangles of the object into quadrangles # @param theObject is mesh, submesh or group # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, # applied to possible quadrangles to choose a neighbour to fuse with. @@ -3226,7 +3254,7 @@ class Mesh: Functor = self.smeshpyD.GetFunctor(theCriterion) return self.editor.TriToQuadObject(theObject, Functor, MaxAngle) - ## Splits quadrangles into triangles. + ## Split quadrangles into triangles. # @param IDsOfElements the faces to be splitted. # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to # choose a diagonal for splitting. If @a theCriterion is None, which is a default @@ -3243,7 +3271,7 @@ class Mesh: Functor = self.smeshpyD.GetFunctor(theCriterion) return self.editor.QuadToTri(IDsOfElements, Functor) - ## Splits quadrangles into triangles. + ## Split quadrangles into triangles. # @param theObject the object from which the list of elements is taken, # this is mesh, submesh or group # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to @@ -3261,7 +3289,7 @@ class Mesh: Functor = self.smeshpyD.GetFunctor(theCriterion) return self.editor.QuadToTriObject(theObject, Functor) - ## Splits each of given quadrangles into 4 triangles. A node is added at the center of + ## Split each of given quadrangles into 4 triangles. A node is added at the center of # a quadrangle. # @param theElements the faces to be splitted. This can be either mesh, sub-mesh, # group or a list of face IDs. By default all quadrangles are split @@ -3277,7 +3305,7 @@ class Mesh: unRegister.set( theElements ) return self.editor.QuadTo4Tri( theElements ) - ## Splits quadrangles into triangles. + ## Split quadrangles into triangles. # @param IDsOfElements the faces to be splitted # @param Diag13 is used to choose a diagonal for splitting. # @return TRUE in case of success, FALSE otherwise. @@ -3287,7 +3315,7 @@ class Mesh: IDsOfElements = self.GetElementsId() return self.editor.SplitQuad(IDsOfElements, Diag13) - ## Splits quadrangles into triangles. + ## Split quadrangles into triangles. # @param theObject the object from which the list of elements is taken, # this is mesh, submesh or group # @param Diag13 is used to choose a diagonal for splitting. @@ -3298,7 +3326,7 @@ class Mesh: theObject = theObject.GetMesh() return self.editor.SplitQuadObject(theObject, Diag13) - ## Finds a better splitting of the given quadrangle. + ## Find a better splitting of the given quadrangle. # @param IDOfQuad the ID of the quadrangle to be splitted. # @param theCriterion is a numerical functor, in terms of enum SMESH.FunctorType, used to # choose a diagonal for splitting. @@ -3310,7 +3338,7 @@ class Mesh: def BestSplit (self, IDOfQuad, theCriterion): return self.editor.BestSplit(IDOfQuad, self.smeshpyD.GetFunctor(theCriterion)) - ## Splits volumic elements into tetrahedrons + ## Split volumic elements into tetrahedrons # @param elems either a list of elements or a mesh or a group or a submesh or a filter # @param method flags passing splitting method: # smesh.Hex_5Tet, smesh.Hex_6Tet, smesh.Hex_24Tet. @@ -3348,7 +3376,7 @@ class Mesh: elems = [elems] self.editor.SplitBiQuadraticIntoLinear( elems ) - ## Splits hexahedra into prisms + ## Split hexahedra into prisms # @param elems either a list of elements or a mesh or a group or a submesh or a filter # @param startHexPoint a point used to find a hexahedron for which @a facetNormal # gives a normal vector defining facets to split into triangles. @@ -3389,9 +3417,9 @@ class Mesh: self.editor.SplitHexahedraIntoPrisms(elems, startHexPoint, facetNormal, method, allDomains) - ## Splits quadrangle faces near triangular facets of volumes + ## Split quadrangle faces near triangular facets of volumes # - # @ingroup l1_auxiliary + # @ingroup l2_modif_cutquadr def SplitQuadsNearTriangularFacets(self): faces_array = self.GetElementsByType(SMESH.FACE) for face_id in faces_array: @@ -3429,7 +3457,7 @@ class Mesh: # key-point will be mapped into theNode001-th node of each volume. # The (0,0,0) key-point of the used pattern corresponds to a non-split corner. # @return TRUE in case of success, FALSE otherwise. - # @ingroup l1_auxiliary + # @ingroup l2_modif_cutquadr def SplitHexaToTetras (self, theObject, theNode000, theNode001): # Pattern: 5.---------.6 # /|#* /| @@ -3487,7 +3515,7 @@ class Mesh: # will be mapped into the theNode001-th node of each volume. # Edge (0,0,0)-(0,0,1) of used pattern connects two not split corners. # @return TRUE in case of success, FALSE otherwise. - # @ingroup l1_auxiliary + # @ingroup l2_modif_cutquadr def SplitHexaToPrisms (self, theObject, theNode000, theNode001): # Pattern: 5.---------.6 # /|# /| @@ -3526,12 +3554,12 @@ class Mesh: isDone = pattern.MakeMesh(self.mesh, False, False) if not isDone: print 'Pattern.MakeMesh :', pattern.GetErrorCode() - # Splits quafrangle faces near triangular facets of volumes + # Split quafrangle faces near triangular facets of volumes self.SplitQuadsNearTriangularFacets() return isDone - ## Smoothes elements + ## Smooth elements # @param IDsOfElements the list if ids of elements to smooth # @param IDsOfFixedNodes the list of ids of fixed nodes. # Note that nodes built on edges and boundary nodes are always fixed. @@ -3550,7 +3578,7 @@ class Mesh: return self.editor.Smooth(IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) - ## Smoothes elements which belong to the given object + ## Smooth elements which belong to the given object # @param theObject the object to smooth # @param IDsOfFixedNodes the list of ids of fixed nodes. # Note that nodes built on edges and boundary nodes are always fixed. @@ -3567,7 +3595,7 @@ class Mesh: return self.editor.SmoothObject(theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) - ## Parametrically smoothes the given elements + ## Parametrically smooth the given elements # @param IDsOfElements the list if ids of elements to smooth # @param IDsOfFixedNodes the list of ids of fixed nodes. # Note that nodes built on edges and boundary nodes are always fixed. @@ -3586,7 +3614,7 @@ class Mesh: return self.editor.SmoothParametric(IDsOfElements, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) - ## Parametrically smoothes the elements which belong to the given object + ## Parametrically smooth the elements which belong to the given object # @param theObject the object to smooth # @param IDsOfFixedNodes the list of ids of fixed nodes. # Note that nodes built on edges and boundary nodes are always fixed. @@ -3603,13 +3631,14 @@ class Mesh: return self.editor.SmoothParametricObject(theObject, IDsOfFixedNodes, MaxNbOfIterations, MaxAspectRatio, Method) - ## Converts the mesh to quadratic or bi-quadratic, deletes old elements, replacing + ## Convert the mesh to quadratic or bi-quadratic, deletes old elements, replacing # them with quadratic with the same id. # @param theForce3d new node creation method: # 0 - the medium node lies at the geometrical entity from which the mesh element is built # 1 - the medium node lies at the middle of the line segments connecting two nodes of a mesh element # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal # @param theToBiQuad If True, converts the mesh to bi-quadratic + # @return SMESH.ComputeError which can hold a warning # @ingroup l2_modif_tofromqu def ConvertToQuadratic(self, theForce3d=False, theSubMesh=None, theToBiQuad=False): if isinstance( theSubMesh, Mesh ): @@ -3624,8 +3653,9 @@ class Mesh: error = self.editor.GetLastError() if error and error.comment: print error.comment + return error - ## Converts the mesh from quadratic to ordinary, + ## Convert the mesh from quadratic to ordinary, # deletes old quadratic elements, \n replacing # them with ordinary mesh elements with the same id. # @param theSubMesh a group or a sub-mesh to convert; WARNING: in this case the mesh can become not conformal @@ -3636,19 +3666,19 @@ class Mesh: else: return self.editor.ConvertFromQuadratic() - ## Creates 2D mesh as skin on boundary faces of a 3D mesh + ## Create 2D mesh as skin on boundary faces of a 3D mesh # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_add def Make2DMeshFrom3D(self): return self.editor.Make2DMeshFrom3D() - ## Creates missing boundary elements + ## Create missing boundary elements # @param elements - elements whose boundary is to be checked: # mesh, group, sub-mesh or list of elements # if elements is mesh, it must be the mesh whose MakeBoundaryMesh() is called # @param dimension - defines type of boundary elements to create, either of # { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D } - # SMESH.BND_1DFROM3D creates mesh edges on all borders of free facets of 3D cells + # SMESH.BND_1DFROM3D create mesh edges on all borders of free facets of 3D cells # @param groupName - a name of group to store created boundary elements in, # "" means not to create the group # @param meshName - a name of new mesh to store created boundary elements in, @@ -3658,7 +3688,7 @@ class Mesh: # @param toCopyExistingBondary - if true, not only new but also pre-existing # boundary elements will be copied into the new mesh # @return tuple (mesh, group) where boundary elements were added to - # @ingroup l2_modif_edit + # @ingroup l2_modif_add def MakeBoundaryMesh(self, elements, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", toCopyElements=False, toCopyExistingBondary=False): unRegister = genObjUnRegister() @@ -3675,7 +3705,7 @@ class Mesh: return mesh, group ## - # @brief Creates missing boundary elements around either the whole mesh or + # @brief Create missing boundary elements around either the whole mesh or # groups of elements # @param dimension - defines type of boundary elements to create, either of # { SMESH.BND_2DFROM3D, SMESH.BND_1DFROM3D, SMESH.BND_1DFROM2D } @@ -3691,6 +3721,7 @@ class Mesh: # mesh - the mesh where elements were added to # group - the group of boundary elements or None # + # @ingroup l2_modif_add def MakeBoundaryElements(self, dimension=SMESH.BND_2DFROM3D, groupName="", meshName="", toCopyAll=False, groups=[]): nb, mesh, group = self.editor.MakeBoundaryElements(dimension,groupName,meshName, @@ -3722,7 +3753,7 @@ class Mesh: arg = [arg] return arg - ## Generates new elements by rotation of the given elements and nodes around the axis + ## Generate new elements by rotation of the given elements and nodes around the axis # @param nodes - nodes to revolve: a list including ids, groups, sub-meshes or a mesh # @param edges - edges to revolve: a list including ids, groups, sub-meshes or a mesh # @param faces - faces to revolve: a list including ids, groups, sub-meshes or a mesh @@ -3758,7 +3789,7 @@ class Mesh: Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups) - ## Generates new elements by rotation of the elements around the axis + ## Generate new elements by rotation of the elements around the axis # @param IDsOfElements the list of ids of elements to sweep # @param Axis the axis of rotation, AxisStruct or line(geom object) # @param AngleInRadians the angle of Rotation (in radians) or a name of variable which defines angle in degrees @@ -3775,7 +3806,7 @@ class Mesh: AngleInRadians, NbOfSteps, Tolerance, MakeGroups, TotalAngle) - ## Generates new elements by rotation of the elements of object around the axis + ## Generate new elements by rotation of the elements of object around the axis # @param theObject object which elements should be sweeped. # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) @@ -3793,7 +3824,7 @@ class Mesh: AngleInRadians, NbOfSteps, Tolerance, MakeGroups, TotalAngle ) - ## Generates new elements by rotation of the elements of object around the axis + ## Generate new elements by rotation of the elements of object around the axis # @param theObject object which elements should be sweeped. # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) @@ -3811,7 +3842,7 @@ class Mesh: AngleInRadians, NbOfSteps, Tolerance, MakeGroups, TotalAngle) - ## Generates new elements by rotation of the elements of object around the axis + ## Generate new elements by rotation of the elements of object around the axis # @param theObject object which elements should be sweeped. # It can be a mesh, a sub mesh or a group. # @param Axis the axis of rotation, AxisStruct or line(geom object) @@ -3828,7 +3859,7 @@ class Mesh: return self.RotationSweepObjects([],[],theObject, Axis, AngleInRadians, NbOfSteps, Tolerance, MakeGroups, TotalAngle) - ## Generates new elements by extrusion of the given elements and nodes + ## Generate new elements by extrusion of the given elements and nodes # @param nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh # @param edges edges to extrude: a list including ids, groups, sub-meshes or a mesh # @param faces faces to extrude: a list including ids, groups, sub-meshes or a mesh @@ -3878,7 +3909,7 @@ class Mesh: MakeGroups) - ## Generates new elements by extrusion of the elements with given ids + ## Generate new elements by extrusion of the elements with given ids # @param IDsOfElements the list of ids of elements or nodes for extrusion # @param StepVector vector or DirStruct or 3 vector components, defining # the direction and value of extrusion for one step (the total extrusion @@ -3894,7 +3925,7 @@ class Mesh: else : e,f, = IDsOfElements,IDsOfElements return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups) - ## Generates new elements by extrusion along the normal to a discretized surface or wire + ## Generate new elements by extrusion along the normal to a discretized surface or wire # @param Elements elements to extrude - a list including ids, groups, sub-meshes or a mesh. # Only faces can be extruded so far. A sub-mesh should be a sub-mesh on geom faces. # @param StepSize length of one extrusion step (the total extrusion @@ -3932,7 +3963,7 @@ class Mesh: return self.editor.ExtrusionByNormal(Elements, StepSize, NbOfSteps, ByAverageNormal, UseInputElemsOnly, MakeGroups, Dim) - ## Generates new elements by extrusion of the elements or nodes which belong to the object + ## Generate new elements by extrusion of the elements or nodes which belong to the object # @param theObject the object whose elements or nodes should be processed. # It can be a mesh, a sub-mesh or a group. # @param StepVector vector or DirStruct or 3 vector components, defining @@ -3949,7 +3980,7 @@ class Mesh: else : e,f, = theObject,theObject return self.ExtrusionSweepObjects(n,e,f, StepVector, NbOfSteps, MakeGroups) - ## Generates new elements by extrusion of edges which belong to the object + ## Generate new elements by extrusion of edges which belong to the object # @param theObject object whose 1D elements should be processed. # It can be a mesh, a sub-mesh or a group. # @param StepVector vector or DirStruct or 3 vector components, defining @@ -3962,7 +3993,7 @@ class Mesh: def ExtrusionSweepObject1D(self, theObject, StepVector, NbOfSteps, MakeGroups=False): return self.ExtrusionSweepObjects([],theObject,[], StepVector, NbOfSteps, MakeGroups) - ## Generates new elements by extrusion of faces which belong to the object + ## Generate new elements by extrusion of faces which belong to the object # @param theObject object whose 2D elements should be processed. # It can be a mesh, a sub-mesh or a group. # @param StepVector vector or DirStruct or 3 vector components, defining @@ -3975,7 +4006,7 @@ class Mesh: def ExtrusionSweepObject2D(self, theObject, StepVector, NbOfSteps, MakeGroups=False): return self.ExtrusionSweepObjects([],[],theObject, StepVector, NbOfSteps, MakeGroups) - ## Generates new elements by extrusion of the elements with given ids + ## Generate new elements by extrusion of the elements with given ids # @param IDsOfElements is ids of elements # @param StepVector vector or DirStruct or 3 vector components, defining # the direction and value of extrusion for one step (the total extrusion @@ -3996,7 +4027,7 @@ class Mesh: return self.editor.AdvancedExtrusion(IDsOfElements, StepVector, NbOfSteps, ExtrFlags, SewTolerance, MakeGroups) - ## Generates new elements by extrusion of the given elements and nodes along the path. + ## Generate new elements by extrusion of the given elements and nodes along the path. # The path of extrusion must be a meshed edge. # @param Nodes nodes to extrude: a list including ids, groups, sub-meshes or a mesh # @param Edges edges to extrude: a list including ids, groups, sub-meshes or a mesh @@ -4039,7 +4070,7 @@ class Mesh: HasAngles, Angles, LinearVariation, HasRefPoint, RefPoint, MakeGroups) - ## Generates new elements by extrusion of the given elements + ## Generate new elements by extrusion of the given elements # The path of extrusion must be a meshed edge. # @param Base mesh or group, or sub-mesh, or list of ids of elements for extrusion # @param Path - 1D mesh or 1D sub-mesh, along which proceeds the extrusion @@ -4073,7 +4104,7 @@ class Mesh: if MakeGroups: return gr,er return er - ## Generates new elements by extrusion of the given elements + ## Generate new elements by extrusion of the given elements # The path of extrusion must be a meshed edge. # @param IDsOfElements ids of elements # @param PathMesh mesh containing a 1D sub-mesh on the edge, along which proceeds the extrusion @@ -4102,7 +4133,7 @@ class Mesh: if MakeGroups: return gr,er return er - ## Generates new elements by extrusion of the elements which belong to the object + ## Generate new elements by extrusion of the elements which belong to the object # The path of extrusion must be a meshed edge. # @param theObject the object whose elements should be processed. # It can be a mesh, a sub-mesh or a group. @@ -4131,7 +4162,7 @@ class Mesh: if MakeGroups: return gr,er return er - ## Generates new elements by extrusion of mesh segments which belong to the object + ## Generate new elements by extrusion of mesh segments which belong to the object # The path of extrusion must be a meshed edge. # @param theObject the object whose 1D elements should be processed. # It can be a mesh, a sub-mesh or a group. @@ -4160,7 +4191,7 @@ class Mesh: if MakeGroups: return gr,er return er - ## Generates new elements by extrusion of faces which belong to the object + ## Generate new elements by extrusion of faces which belong to the object # The path of extrusion must be a meshed edge. # @param theObject the object whose 2D elements should be processed. # It can be a mesh, a sub-mesh or a group. @@ -4189,7 +4220,7 @@ class Mesh: if MakeGroups: return gr,er return er - ## Creates a symmetrical copy of mesh elements + ## Create a symmetrical copy of mesh elements # @param IDsOfElements list of elements ids # @param Mirror is AxisStruct or geom object(point, line, plane) # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE @@ -4211,7 +4242,7 @@ class Mesh: self.editor.Mirror(IDsOfElements, Mirror, theMirrorType, Copy) return [] - ## Creates a new mesh by a symmetrical copy of mesh elements + ## Create a new mesh by a symmetrical copy of mesh elements # @param IDsOfElements the list of elements ids # @param Mirror is AxisStruct or geom object (point, line, plane) # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE @@ -4232,7 +4263,7 @@ class Mesh: MakeGroups, NewMeshName) return Mesh(self.smeshpyD,self.geompyD,mesh) - ## Creates a symmetrical copy of the object + ## Create a symmetrical copy of the object # @param theObject mesh, submesh or group # @param Mirror AxisStruct or geom object (point, line, plane) # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE @@ -4254,7 +4285,7 @@ class Mesh: self.editor.MirrorObject(theObject, Mirror, theMirrorType, Copy) return [] - ## Creates a new mesh by a symmetrical copy of the object + ## Create a new mesh by a symmetrical copy of the object # @param theObject mesh, submesh or group # @param Mirror AxisStruct or geom object (point, line, plane) # @param theMirrorType smeshBuilder.POINT, smeshBuilder.AXIS or smeshBuilder.PLANE @@ -4275,7 +4306,7 @@ class Mesh: MakeGroups, NewMeshName) return Mesh( self.smeshpyD,self.geompyD,mesh ) - ## Translates the elements + ## Translate the elements # @param IDsOfElements list of elements ids # @param Vector the direction of translation (DirStruct or vector or 3 vector components) # @param Copy allows copying the translated elements @@ -4295,7 +4326,7 @@ class Mesh: self.editor.Translate(IDsOfElements, Vector, Copy) return [] - ## Creates a new mesh of translated elements + ## Create a new mesh of translated elements # @param IDsOfElements list of elements ids # @param Vector the direction of translation (DirStruct or vector or 3 vector components) # @param MakeGroups forces the generation of new groups from existing ones @@ -4313,7 +4344,7 @@ class Mesh: mesh = self.editor.TranslateMakeMesh(IDsOfElements, Vector, MakeGroups, NewMeshName) return Mesh ( self.smeshpyD, self.geompyD, mesh ) - ## Translates the object + ## Translate the object # @param theObject the object to translate (mesh, submesh, or group) # @param Vector direction of translation (DirStruct or geom vector or 3 vector components) # @param Copy allows copying the translated elements @@ -4333,7 +4364,7 @@ class Mesh: self.editor.TranslateObject(theObject, Vector, Copy) return [] - ## Creates a new mesh from the translated object + ## Create a new mesh from the translated object # @param theObject the object to translate (mesh, submesh, or group) # @param Vector the direction of translation (DirStruct or geom vector or 3 vector components) # @param MakeGroups forces the generation of new groups from existing ones @@ -4353,7 +4384,7 @@ class Mesh: - ## Scales the object + ## Scale the object # @param theObject - the object to translate (mesh, submesh, or group) # @param thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates) # @param theScaleFact - list of 1-3 scale factors for axises @@ -4383,7 +4414,7 @@ class Mesh: self.editor.Scale(theObject, thePoint, theScaleFact, Copy) return [] - ## Creates a new mesh from the translated object + ## Create a new mesh from the translated object # @param theObject - the object to translate (mesh, submesh, or group) # @param thePoint - base point for scale (SMESH.PointStruct or list of 3 coordinates) # @param theScaleFact - list of 1-3 scale factors for axises @@ -4411,7 +4442,7 @@ class Mesh: - ## Rotates the elements + ## Rotate the elements # @param IDsOfElements list of elements ids # @param Axis the axis of rotation (AxisStruct or geom line) # @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees @@ -4432,7 +4463,7 @@ class Mesh: self.editor.Rotate(IDsOfElements, Axis, AngleInRadians, Copy) return [] - ## Creates a new mesh of rotated elements + ## Create a new mesh of rotated elements # @param IDsOfElements list of element ids # @param Axis the axis of rotation (AxisStruct or geom line) # @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees @@ -4452,7 +4483,7 @@ class Mesh: MakeGroups, NewMeshName) return Mesh( self.smeshpyD, self.geompyD, mesh ) - ## Rotates the object + ## Rotate the object # @param theObject the object to rotate( mesh, submesh, or group) # @param Axis the axis of rotation (AxisStruct or geom line) # @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees @@ -4473,7 +4504,7 @@ class Mesh: self.editor.RotateObject(theObject, Axis, AngleInRadians, Copy) return [] - ## Creates a new mesh from the rotated object + ## Create a new mesh from the rotated object # @param theObject the object to rotate (mesh, submesh, or group) # @param Axis the axis of rotation (AxisStruct or geom line) # @param AngleInRadians the angle of rotation (in radians) or a name of variable which defines angle in degrees @@ -4493,7 +4524,7 @@ class Mesh: self.mesh.SetParameters(Parameters) return Mesh( self.smeshpyD, self.geompyD, mesh ) - ## Finds groups of adjacent nodes within Tolerance. + ## Find groups of adjacent nodes within Tolerance. # @param Tolerance the value of tolerance # @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts # corner and medium nodes in separate groups thus preventing @@ -4503,7 +4534,7 @@ class Mesh: def FindCoincidentNodes (self, Tolerance, SeparateCornerAndMediumNodes=False): return self.editor.FindCoincidentNodes( Tolerance, SeparateCornerAndMediumNodes ) - ## Finds groups of ajacent nodes within Tolerance. + ## Find groups of ajacent nodes within Tolerance. # @param Tolerance the value of tolerance # @param SubMeshOrGroup SubMesh, Group or Filter # @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search @@ -4525,7 +4556,7 @@ class Mesh: return self.editor.FindCoincidentNodesOnPartBut(SubMeshOrGroup, Tolerance, exceptNodes, SeparateCornerAndMediumNodes) - ## Merges nodes + ## Merge nodes # @param GroupsOfNodes a list of groups of nodes IDs for merging # (e.g. [[1,12,13],[25,4]], then nodes 12, 13 and 4 will be removed and replaced # by nodes 1 and 25 correspondingly in all elements and groups @@ -4537,7 +4568,7 @@ class Mesh: # NodesToKeep are converted to SMESH_IDSource in meshEditor.MergeNodes() self.editor.MergeNodes(GroupsOfNodes,NodesToKeep) - ## Finds the elements built on the same nodes. + ## Find the elements built on the same nodes. # @param MeshOrSubMeshOrGroup Mesh or SubMesh, or Group of elements for searching # @return the list of groups of equal elements IDs (e.g. [[1,12,13],[4,25]]) # @ingroup l2_modif_trsf @@ -4548,7 +4579,7 @@ class Mesh: MeshOrSubMeshOrGroup = MeshOrSubMeshOrGroup.GetMesh() return self.editor.FindEqualElements( MeshOrSubMeshOrGroup ) - ## Merges elements in each given group. + ## Merge elements in each given group. # @param GroupsOfElementsID a list of groups of elements IDs for merging # (e.g. [[1,12,13],[25,4]], then elements 12, 13 and 4 will be removed and # replaced by elements 1 and 25 in all groups) @@ -4556,12 +4587,12 @@ class Mesh: def MergeElements(self, GroupsOfElementsID): self.editor.MergeElements(GroupsOfElementsID) - ## Leaves one element and removes all other elements built on the same nodes. + ## Leave one element and remove all other elements built on the same nodes. # @ingroup l2_modif_trsf def MergeEqualElements(self): self.editor.MergeEqualElements() - ## Returns groups of FreeBorder's coincident within the given tolerance. + ## Return groups of FreeBorder's coincident within the given tolerance. # @param tolerance the tolerance. If the tolerance <= 0.0 then one tenth of an average # size of elements adjacent to free borders being compared is used. # @return SMESH.CoincidentFreeBorders structure @@ -4607,7 +4638,7 @@ class Mesh: return self.editor.SewCoincidentFreeBorders( freeBorders, createPolygons, createPolyhedra ) - ## Sews free borders + ## Sew free borders # @return SMESH::Sew_Error # @ingroup l2_modif_trsf def SewFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1, @@ -4617,7 +4648,7 @@ class Mesh: FirstNodeID2, SecondNodeID2, LastNodeID2, CreatePolygons, CreatePolyedrs) - ## Sews conform free borders + ## Sew conform free borders # @return SMESH::Sew_Error # @ingroup l2_modif_trsf def SewConformFreeBorders (self, FirstNodeID1, SecondNodeID1, LastNodeID1, @@ -4625,7 +4656,7 @@ class Mesh: return self.editor.SewConformFreeBorders(FirstNodeID1, SecondNodeID1, LastNodeID1, FirstNodeID2, SecondNodeID2) - ## Sews border to side + ## Sew border to side # @return SMESH::Sew_Error # @ingroup l2_modif_trsf def SewBorderToSide (self, FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder, @@ -4633,7 +4664,7 @@ class Mesh: return self.editor.SewBorderToSide(FirstNodeIDOnFreeBorder, SecondNodeIDOnFreeBorder, LastNodeIDOnFreeBorder, FirstNodeIDOnSide, LastNodeIDOnSide, CreatePolygons, CreatePolyedrs) - ## Sews two sides of a mesh. The nodes belonging to Side1 are + ## Sew two sides of a mesh. The nodes belonging to Side1 are # merged with the nodes of elements of Side2. # The number of elements in theSide1 and in theSide2 must be # equal and they should have similar nodal connectivity. @@ -4648,36 +4679,36 @@ class Mesh: NodeID1OfSide1ToMerge, NodeID1OfSide2ToMerge, NodeID2OfSide1ToMerge, NodeID2OfSide2ToMerge) - ## Sets new nodes for the given element. + ## Set new nodes for the given element. # @param ide the element id # @param newIDs nodes ids - # @return If the number of nodes does not correspond to the type of element - returns false + # @return If the number of nodes does not correspond to the type of element - return false # @ingroup l2_modif_edit def ChangeElemNodes(self, ide, newIDs): return self.editor.ChangeElemNodes(ide, newIDs) ## If during the last operation of MeshEditor some nodes were - # created, this method returns the list of their IDs, \n - # if new nodes were not created - returns empty list + # created, this method return the list of their IDs, \n + # if new nodes were not created - return empty list # @return the list of integer values (can be empty) - # @ingroup l1_auxiliary + # @ingroup l2_modif_add def GetLastCreatedNodes(self): return self.editor.GetLastCreatedNodes() ## If during the last operation of MeshEditor some elements were - # created this method returns the list of their IDs, \n - # if new elements were not created - returns empty list + # created this method return the list of their IDs, \n + # if new elements were not created - return empty list # @return the list of integer values (can be empty) - # @ingroup l1_auxiliary + # @ingroup l2_modif_add def GetLastCreatedElems(self): return self.editor.GetLastCreatedElems() - ## Clears sequences of nodes and elements created by mesh edition oparations - # @ingroup l1_auxiliary + ## Forget what nodes and elements were created by the last mesh edition operation + # @ingroup l2_modif_add def ClearLastCreated(self): self.editor.ClearLastCreated() - ## Creates duplicates of given elements, i.e. creates new elements based on the + ## Create duplicates of given elements, i.e. create new elements based on the # same nodes as the given ones. # @param theElements - container of elements to duplicate. It can be a Mesh, # sub-mesh, group, filter or a list of element IDs. If \a theElements is @@ -4688,7 +4719,7 @@ class Mesh: # If \a theGroupName is empty, new elements are not added # in any group. # @return a group where the new elements are added. None if theGroupName == "". - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleElements(self, theElements, theGroupName=""): unRegister = genObjUnRegister() if isinstance( theElements, Mesh ): @@ -4698,62 +4729,62 @@ class Mesh: unRegister.set( theElements ) return self.editor.DoubleElements(theElements, theGroupName) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # @param theNodes identifiers of nodes to be doubled # @param theModifiedElems identifiers of elements to be updated by the new (doubled) # nodes. If list of element identifiers is empty then nodes are doubled but # they not assigned to elements # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodes(self, theNodes, theModifiedElems): return self.editor.DoubleNodes(theNodes, theModifiedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theNodeId identifiers of node to be doubled # @param theModifiedElems identifiers of elements to be updated # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNode(self, theNodeId, theModifiedElems): return self.editor.DoubleNode(theNodeId, theModifiedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theNodes group of nodes to be doubled # @param theModifiedElems group of elements to be updated. # @param theMakeGroup forces the generation of a group containing new nodes. # @return TRUE or a created group if operation has been completed successfully, # FALSE or None otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeGroup(self, theNodes, theModifiedElems, theMakeGroup=False): if theMakeGroup: return self.editor.DoubleNodeGroupNew(theNodes, theModifiedElems) return self.editor.DoubleNodeGroup(theNodes, theModifiedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theNodes list of groups of nodes to be doubled # @param theModifiedElems list of groups of elements to be updated. # @param theMakeGroup forces the generation of a group containing new nodes. # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeGroups(self, theNodes, theModifiedElems, theMakeGroup=False): if theMakeGroup: return self.editor.DoubleNodeGroupsNew(theNodes, theModifiedElems) return self.editor.DoubleNodeGroups(theNodes, theModifiedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # @param theElems - the list of elements (edges or faces) to be replicated # The nodes for duplication could be found from these elements # @param theNodesNot - list of nodes to NOT replicate # @param theAffectedElems - the list of elements (cells and edges) to which the # replicated nodes should be associated to. # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElem(self, theElems, theNodesNot, theAffectedElems): return self.editor.DoubleNodeElem(theElems, theNodesNot, theAffectedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # @param theElems - the list of elements (edges or faces) to be replicated # The nodes for duplication could be found from these elements # @param theNodesNot - list of nodes to NOT replicate @@ -4761,11 +4792,11 @@ class Mesh: # located on or inside shape). # The replicated nodes should be associated to affected elements. # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElemInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemInRegion(theElems, theNodesNot, theShape) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theElems - group of of elements (edges or faces) to be replicated # @param theNodesNot - group of nodes not to replicated @@ -4775,7 +4806,7 @@ class Mesh: # @param theMakeNodeGroup forces the generation of a group containing new nodes. # @return TRUE or created groups (one or two) if operation has been completed successfully, # FALSE or None otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElemGroup(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False, theMakeNodeGroup=False): if theMakeGroup or theMakeNodeGroup: @@ -4788,18 +4819,18 @@ class Mesh: return twoGroups[ int(theMakeNodeGroup) ] return self.editor.DoubleNodeElemGroup(theElems, theNodesNot, theAffectedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theElems - group of of elements (edges or faces) to be replicated # @param theNodesNot - group of nodes not to replicated # @param theShape - shape to detect affected elements (element which geometric center # located on or inside shape). # The replicated nodes should be associated to affected elements. - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElemGroupInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemGroupInRegion(theElems, theNodesNot, theShape) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theElems - list of groups of elements (edges or faces) to be replicated # @param theNodesNot - list of groups of nodes not to replicated @@ -4809,7 +4840,7 @@ class Mesh: # @param theMakeNodeGroup forces the generation of a group containing new nodes. # @return TRUE or created groups (one or two) if operation has been completed successfully, # FALSE or None otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElemGroups(self, theElems, theNodesNot, theAffectedElems, theMakeGroup=False, theMakeNodeGroup=False): if theMakeGroup or theMakeNodeGroup: @@ -4822,7 +4853,7 @@ class Mesh: return twoGroups[ int(theMakeNodeGroup) ] return self.editor.DoubleNodeElemGroups(theElems, theNodesNot, theAffectedElems) - ## Creates a hole in a mesh by doubling the nodes of some particular elements + ## Create a hole in a mesh by doubling the nodes of some particular elements # This method provided for convenience works as DoubleNodes() described above. # @param theElems - list of groups of elements (edges or faces) to be replicated # @param theNodesNot - list of groups of nodes not to replicated @@ -4830,7 +4861,7 @@ class Mesh: # located on or inside shape). # The replicated nodes should be associated to affected elements. # @return TRUE if operation has been completed successfully, FALSE otherwise - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def DoubleNodeElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.DoubleNodeElemGroupsInRegion(theElems, theNodesNot, theShape) @@ -4842,30 +4873,32 @@ class Mesh: # located on or inside shape). # The replicated nodes should be associated to affected elements. # @return groups of affected elements - # @ingroup l2_modif_edit + # @ingroup l2_modif_duplicat def AffectedElemGroupsInRegion(self, theElems, theNodesNot, theShape): return self.editor.AffectedElemGroupsInRegion(theElems, theNodesNot, theShape) ## Double nodes on shared faces between groups of volumes and create flat elements on demand. - # The list of groups must describe a partition of the mesh volumes. - # The nodes of the internal faces at the boundaries of the groups are doubled. - # In option, the internal faces are replaced by flat elements. - # Triangles are transformed in prisms, and quadrangles in hexahedrons. - # @param theDomains - list of groups of volumes - # @param createJointElems - if TRUE, create the elements - # @param onAllBoundaries - if TRUE, the nodes and elements are also created on - # the boundary between \a theDomains and the rest mesh - # @return TRUE if operation has been completed successfully, FALSE otherwise + # The list of groups must describe a partition of the mesh volumes. + # The nodes of the internal faces at the boundaries of the groups are doubled. + # In option, the internal faces are replaced by flat elements. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theDomains - list of groups of volumes + # @param createJointElems - if TRUE, create the elements + # @param onAllBoundaries - if TRUE, the nodes and elements are also created on + # the boundary between \a theDomains and the rest mesh + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_duplicat def DoubleNodesOnGroupBoundaries(self, theDomains, createJointElems, onAllBoundaries=False ): return self.editor.DoubleNodesOnGroupBoundaries( theDomains, createJointElems, onAllBoundaries ) ## Double nodes on some external faces and create flat elements. - # Flat elements are mainly used by some types of mechanic calculations. - # - # Each group of the list must be constituted of faces. - # Triangles are transformed in prisms, and quadrangles in hexahedrons. - # @param theGroupsOfFaces - list of groups of faces - # @return TRUE if operation has been completed successfully, FALSE otherwise + # Flat elements are mainly used by some types of mechanic calculations. + # + # Each group of the list must be constituted of faces. + # Triangles are transformed in prisms, and quadrangles in hexahedrons. + # @param theGroupsOfFaces - list of groups of faces + # @return TRUE if operation has been completed successfully, FALSE otherwise + # @ingroup l2_modif_duplicat def CreateFlatElementsOnFacesGroups(self, theGroupsOfFaces ): return self.editor.CreateFlatElementsOnFacesGroups( theGroupsOfFaces ) @@ -4882,12 +4915,13 @@ class Mesh: self.functors[ funcType._v ] = fn return fn - ## Returns value of a functor for a given element + ## Return value of a functor for a given element # @param funcType an item of SMESH.FunctorType enum # Type "SMESH.FunctorType._items" in the Python Console to see all items. # @param elemId element or node ID # @param isElem @a elemId is ID of element or node # @return the functor value or zero in case of invalid arguments + # @ingroup l1_measurements def FunctorValue(self, funcType, elemId, isElem=True): fn = self._getFunctor( funcType ) if fn.GetElementType() == self.GetElementType(elemId, isElem): @@ -5010,7 +5044,7 @@ class Mesh: pass # end of Mesh class -## Class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility +## Private class used to compensate change of CORBA API of SMESH_Mesh for backward compatibility # with old dump scripts which call SMESH_Mesh directly and not via smeshBuilder.Mesh # class meshProxy(SMESH._objref_SMESH_Mesh): @@ -5027,7 +5061,7 @@ class meshProxy(SMESH._objref_SMESH_Mesh): omniORB.registerObjref(SMESH._objref_SMESH_Mesh._NP_RepositoryId, meshProxy) -## Class wrapping SMESH_SubMesh in order to add Compute() +## Private class wrapping SMESH.SMESH_SubMesh in order to add Compute() # class submeshProxy(SMESH._objref_SMESH_subMesh): def __init__(self): @@ -5037,10 +5071,13 @@ class submeshProxy(SMESH._objref_SMESH_subMesh): new = self.__class__() return new - ## Computes the sub-mesh and returns the status of the computation + ## Compute the sub-mesh and return the status of the computation # @param refresh if @c True, Object browser is automatically updated (when running in GUI) # @return True or False - # @ingroup l2_construct + # + # This is a method of SMESH.SMESH_submesh that can be obtained via Mesh.GetSubMesh() or + # @ref smesh_algorithm.Mesh_Algorithm.GetSubMesh() "Mesh_Algorithm.GetSubMesh()". + # @ingroup l2_submeshes def Compute(self,refresh=False): if not self.mesh: self.mesh = Mesh( smeshBuilder(), None, self.GetMesh()) @@ -5051,7 +5088,7 @@ class submeshProxy(SMESH._objref_SMESH_subMesh): smeshgui = salome.ImportComponentGUI("SMESH") smeshgui.Init(self.mesh.GetStudyId()) smeshgui.SetMeshIcon( salome.ObjectToID( self ), ok, (self.GetNumberOfElements()==0) ) - if refresh: salome.sg.updateObjBrowser(1) + if refresh: salome.sg.updateObjBrowser(True) pass return ok @@ -5059,8 +5096,9 @@ class submeshProxy(SMESH._objref_SMESH_subMesh): omniORB.registerObjref(SMESH._objref_SMESH_subMesh._NP_RepositoryId, submeshProxy) -## Class used to compensate change of CORBA API of SMESH_MeshEditor for backward compatibility -# with old dump scripts which call SMESH_MeshEditor directly and not via smeshBuilder.Mesh +## Private class used to compensate change of CORBA API of SMESH_MeshEditor for backward +# compatibility with old dump scripts which call SMESH_MeshEditor directly and not via +# smeshBuilder.Mesh # class meshEditor(SMESH._objref_SMESH_MeshEditor): def __init__(self): @@ -5098,7 +5136,8 @@ class meshEditor(SMESH._objref_SMESH_MeshEditor): pass omniORB.registerObjref(SMESH._objref_SMESH_MeshEditor._NP_RepositoryId, meshEditor) -## Helper class for wrapping of SMESH.SMESH_Pattern CORBA class +## Private class wrapping SMESH.SMESH_Pattern CORBA class in order to treat Notebook +# variables in some methods # class Pattern(SMESH._objref_SMESH_Pattern): @@ -5137,7 +5176,7 @@ class algoCreator: self.defaultAlgoType = "" self.algoTypeToClass = {} - # Stores a python class of algorithm + # Store a python class of algorithm def add(self, algoClass): if type( algoClass ).__name__ == 'classobj' and \ hasattr( algoClass, "algoType"): @@ -5147,7 +5186,7 @@ class algoCreator: self.defaultAlgoType = algoClass.algoType #print "Add",algoClass.algoType, "dflt",self.defaultAlgoType - # creates a copy of self and assign mesh to the copy + # Create a copy of self and assign mesh to the copy def copy(self, mesh): other = algoCreator() other.defaultAlgoType = self.defaultAlgoType @@ -5155,7 +5194,7 @@ class algoCreator: other.mesh = mesh return other - # creates an instance of algorithm + # Create an instance of algorithm def __call__(self,algo="",geom=0,*args): algoType = self.defaultAlgoType for arg in args + (algo,geom): @@ -5202,7 +5241,7 @@ class hypMethodWrapper: return result pass -## A helper class that call UnRegister() of SALOME.GenericObj'es stored in it +## A helper class that calls UnRegister() of SALOME.GenericObj'es stored in it # class genObjUnRegister: diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index 3a2939151..fc48e7ba2 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -183,7 +183,7 @@ class Mesh_Algorithm: ## Private method. def Create(self, mesh, geom, hypo, so="libStdMeshersEngine.so"): if geom is None and mesh.mesh.HasShapeToMesh(): - raise RuntimeError, "Attemp to create " + hypo + " algoritm on None shape" + raise RuntimeError, "Attemp to create " + hypo + " algorithm on None shape" algo = self.FindAlgorithm(hypo, mesh.smeshpyD) if algo is None: algo = mesh.smeshpyD.CreateHypothesis(hypo, so) @@ -195,7 +195,7 @@ class Mesh_Algorithm: def Assign(self, algo, mesh, geom): from salome.smesh.smeshBuilder import AssureGeomPublished, TreatHypoStatus, GetName if geom is None and mesh.mesh.HasShapeToMesh(): - raise RuntimeError, "Attemp to create " + algo + " algoritm on None shape" + raise RuntimeError, "Attemp to create " + algo + " algorithm on None shape" self.mesh = mesh if not geom or geom.IsSame( mesh.geom ): self.geom = mesh.geom @@ -288,6 +288,8 @@ class Mesh_Algorithm: raise TypeError, "ViscousLayers are supported by 3D algorithms only" if not "ViscousLayers" in self.GetCompatibleHypothesis(): raise TypeError, "ViscousLayers are not supported by %s"%self.algo.GetName() + if faces and isinstance( faces, geomBuilder.GEOM._objref_GEOM_Object ): + faces = [ faces ] if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ): faceIDs = [] for shape in faces: @@ -324,6 +326,8 @@ class Mesh_Algorithm: raise TypeError, "ViscousLayers2D are supported by 2D algorithms only" if not "ViscousLayers2D" in self.GetCompatibleHypothesis(): raise TypeError, "ViscousLayers2D are not supported by %s"%self.algo.GetName() + if edges and not isinstance( edges, list ) and not isinstance( edges, tuple ): + edges = [edges] if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ): edgeIDs = [] for shape in edges: diff --git a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx index 1adb3d4f0..cb9e5ae6f 100644 --- a/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx +++ b/src/SMESH_SWIG_WITHIHM/libSMESH_Swig.cxx @@ -302,7 +302,7 @@ SMESH_Swig::SMESH_Swig() } }; - MESSAGE("Constructeur"); + //MESSAGE("Constructeur"); if(CORBA::is_nil(anORB)) ProcessVoidEvent(new TEvent(anORB)); @@ -402,7 +402,7 @@ SMESH_Swig::Init(int theStudyID) } }; - MESSAGE("Init"); + //MESSAGE("Init"); ProcessVoidEvent(new TEvent(theStudyID, myStudy, @@ -414,7 +414,7 @@ SMESH_Swig::Init(int theStudyID) //=============================================================== SMESH_Swig::~SMESH_Swig() { - MESSAGE("Destructeur"); + //MESSAGE("Destructeur"); } diff --git a/src/StdMeshers/CMakeLists.txt b/src/StdMeshers/CMakeLists.txt index 3a1348297..c0097c64a 100644 --- a/src/StdMeshers/CMakeLists.txt +++ b/src/StdMeshers/CMakeLists.txt @@ -29,7 +29,6 @@ INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ${VTK_INCLUDE_DIRS} ${KERNEL_INCLUDE_DIRS} - ${GUI_INCLUDE_DIRS} ${GEOM_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/SMESHUtils ${PROJECT_SOURCE_DIR}/src/SMESH diff --git a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx index 70fe2368d..138755ab0 100644 --- a/src/StdMeshers/StdMeshers_Cartesian_3D.cxx +++ b/src/StdMeshers/StdMeshers_Cartesian_3D.cxx @@ -3167,7 +3167,7 @@ namespace const F_IntersectPoint* firstIntPnt = 0; if ( link._nodes[0]->Node() ) // 1st node is a hexa corner { - curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0]; + curIntPnt._paramOnLine = coords[ ijk[ iDir ]] - coords[0] + _grid->_tol; const GridLine& line = _grid->_lines[ iDir ][ lineIndex[ iL ]]; multiset< F_IntersectPoint >::const_iterator ip = line._intPoints.upper_bound( curIntPnt ); diff --git a/src/StdMeshers/StdMeshers_FaceSide.cxx b/src/StdMeshers/StdMeshers_FaceSide.cxx index 66bae01e0..0c7c334f2 100644 --- a/src/StdMeshers/StdMeshers_FaceSide.cxx +++ b/src/StdMeshers/StdMeshers_FaceSide.cxx @@ -448,8 +448,11 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons if ((int) u2node.size() + nbProxyNodes != myNbPonits && (int) u2node.size() + nbProxyNodes != NbPoints( /*update=*/true )) { - MESSAGE("Wrong node parameters on edges, u2node.size():" - < 0 ) && + ( u2node.begin()->first < 0 || u2node.rbegin()->first > 1 )) + { return myPoints; } @@ -466,25 +469,39 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons if ( proxySubMesh[ iE ] ) // copy data from a proxy sub-mesh { const UVPtStructVec& edgeUVPtStruct = proxySubMesh[iE]->GetUVPtStructVec(); - std::copy( edgeUVPtStruct.begin(), edgeUVPtStruct.end(), & points[iPt] ); + UVPtStruct* pointsPtr = & points[iPt]; + std::copy( edgeUVPtStruct.begin(), edgeUVPtStruct.end(), pointsPtr ); // check orientation double du1 = edgeUVPtStruct.back().param - edgeUVPtStruct[0].param; double du2 = myLast[iE] - myFirst[iE]; if ( du1 * du2 < 0 ) { - std::reverse( & points[iPt], & points[iPt + edgeUVPtStruct.size()]); + std::reverse( pointsPtr, pointsPtr + edgeUVPtStruct.size()); for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) - points[iPt+i].normParam = 1. - points[iPt+i].normParam; + pointsPtr[i].normParam = 1. - pointsPtr[i].normParam; } // update normalized params if ( myEdge.size() > 1 ) { - for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i, ++iPt ) + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) { - UVPtStruct & uvPt = points[iPt]; + UVPtStruct & uvPt = pointsPtr[i]; uvPt.normParam = prevNormPar + uvPt.normParam * paramSize; uvPt.x = uvPt.y = uvPt.normParam; } - --iPt; // to point to the 1st VERTEX of the next EDGE + iPt += edgeUVPtStruct.size() - 1; // to point to the 1st VERTEX of the next EDGE + } + // update UV on a seam EDGE + if ( fHelper.IsRealSeam( myEdgeID[ iE ])) + { + // check if points lye on the EDGE + const UVPtStruct& pm = edgeUVPtStruct[ edgeUVPtStruct.size()/2 ]; + gp_Pnt pNode = SMESH_TNodeXYZ( pm.node ); + gp_Pnt pCurv = myC3dAdaptor[ iE ].Value( pm.param ); + double tol = BRep_Tool::Tolerance( myEdge[ iE ]) * 10; + bool isPointOnEdge = ( pNode.SquareDistance( pCurv ) < tol * tol ); + if ( isPointOnEdge ) + for ( size_t i = 0; i < edgeUVPtStruct.size(); ++i ) + pointsPtr[i].SetUV( myC2d[ iE ]->Value( pointsPtr[i].param ).XY() ); } } else @@ -492,7 +509,7 @@ const std::vector& StdMeshers_FaceSide::GetUVPtStruct(bool isXCons for ( ; u_node != u2node.end(); ++u_node, ++iPt ) { if ( myNormPar[ iE ]-eps < u_node->first ) - break; // u_node is at VERTEX of the next EDGE + break; // u_node is at VERTEX of the next EDGE UVPtStruct & uvPt = points[iPt]; uvPt.node = u_node->second; diff --git a/src/StdMeshers/StdMeshers_FixedPoints1D.cxx b/src/StdMeshers/StdMeshers_FixedPoints1D.cxx index 04290a6d4..e316cb11a 100644 --- a/src/StdMeshers/StdMeshers_FixedPoints1D.cxx +++ b/src/StdMeshers/StdMeshers_FixedPoints1D.cxx @@ -27,16 +27,6 @@ #include "SMESH_Algo.hxx" #include "SMESH_Mesh.hxx" -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include - using namespace std; //============================================================================= @@ -50,14 +40,14 @@ StdMeshers_FixedPoints1D::StdMeshers_FixedPoints1D(int hypId, int studyId, :SMESH_Hypothesis(hypId, studyId, gen) { _name = "FixedPoints1D"; - _param_algo_dim = 1; + _param_algo_dim = 1; _nbsegs.reserve( 1 ); _nbsegs.push_back( 1 ); } //============================================================================= /*! - * + * */ //============================================================================= @@ -72,7 +62,7 @@ StdMeshers_FixedPoints1D::~StdMeshers_FixedPoints1D() //============================================================================= void StdMeshers_FixedPoints1D::SetPoints(std::vector& listParams) - throw(SALOME_Exception) + throw(SALOME_Exception) { _params = listParams; NotifySubMeshesHypothesisModification(); @@ -85,7 +75,7 @@ void StdMeshers_FixedPoints1D::SetPoints(std::vector& listParams) //============================================================================= void StdMeshers_FixedPoints1D::SetNbSegments(std::vector& listNbSeg) - throw(SALOME_Exception) + throw(SALOME_Exception) { _nbsegs = listNbSeg; NotifySubMeshesHypothesisModification(); @@ -140,7 +130,7 @@ ostream & StdMeshers_FixedPoints1D::SaveTo(ostream & save) //============================================================================= /*! - * + * */ //============================================================================= @@ -185,28 +175,6 @@ istream & StdMeshers_FixedPoints1D::LoadFrom(istream & load) return load; } -//============================================================================= -/*! - * - */ -//============================================================================= - -ostream & operator <<(ostream & save, StdMeshers_FixedPoints1D & hyp) -{ - return hyp.SaveTo( save ); -} - -//============================================================================= -/*! - * - */ -//============================================================================= - -istream & operator >>(istream & load, StdMeshers_FixedPoints1D & hyp) -{ - return hyp.LoadFrom( load ); -} - //================================================================================ /*! * \brief Initialize start and end length by the mesh built on the geometry diff --git a/src/StdMeshers/StdMeshers_FixedPoints1D.hxx b/src/StdMeshers/StdMeshers_FixedPoints1D.hxx index bb3901118..4855f0307 100644 --- a/src/StdMeshers/StdMeshers_FixedPoints1D.hxx +++ b/src/StdMeshers/StdMeshers_FixedPoints1D.hxx @@ -61,14 +61,12 @@ public: virtual std::ostream & SaveTo(std::ostream & save); virtual std::istream & LoadFrom(std::istream & load); - friend std::ostream& operator << (std::ostream & save, StdMeshers_FixedPoints1D & hyp); - friend std::istream& operator >> (std::istream & load, StdMeshers_FixedPoints1D & hyp); /*! * \brief Initialize start and end length by the mesh built on the geometry - * \param theMesh - the built mesh - * \param theShape - the geometry of interest - * \retval bool - true if parameter values have been successfully defined + * \param theMesh - the built mesh + * \param theShape - the geometry of interest + * \retval bool - true if parameter values have been successfully defined */ virtual bool SetParametersByMesh(const SMESH_Mesh* theMesh, const TopoDS_Shape& theShape); diff --git a/src/StdMeshers/StdMeshers_Hexa_3D.cxx b/src/StdMeshers/StdMeshers_Hexa_3D.cxx index 0dfff42b9..4e1ee652d 100644 --- a/src/StdMeshers/StdMeshers_Hexa_3D.cxx +++ b/src/StdMeshers/StdMeshers_Hexa_3D.cxx @@ -73,7 +73,6 @@ static bool EvaluatePentahedralMesh(SMESH_Mesh &, const TopoDS_Shape &, StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen) :SMESH_3D_Algo(hypId, studyId, gen) { - MESSAGE("StdMeshers_Hexa_3D::StdMeshers_Hexa_3D"); _name = "Hexa_3D"; _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID); // 1 bit /shape type _requireShape = false; @@ -88,7 +87,6 @@ StdMeshers_Hexa_3D::StdMeshers_Hexa_3D(int hypId, int studyId, SMESH_Gen * gen) StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D() { - MESSAGE("StdMeshers_Hexa_3D::~StdMeshers_Hexa_3D"); } //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Prism_3D.cxx b/src/StdMeshers/StdMeshers_Prism_3D.cxx index fe5276b39..b3f34cadb 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.cxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.cxx @@ -162,6 +162,12 @@ namespace { { return _src2tgtNodes; } + void SetEventListener( SMESH_subMesh* tgtSubMesh ) + { + NSProjUtils::SetEventListener( tgtSubMesh, + _sourceHypo->GetSourceFace(), + _sourceHypo->GetSourceMesh() ); + } }; //======================================================================= /*! @@ -938,11 +944,10 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, std::list< int >::iterator nbE = thePrism.myNbEdgesInWires.begin(); std::list< int > nbQuadsPerWire; int iE = 0; - double f,l; while ( edge != thePrism.myBottomEdges.end() ) { ++iE; - if ( BRep_Tool::Curve( *edge, f,l ).IsNull() ) + if ( SMESH_Algo::isDegenerated( *edge )) { edge = thePrism.myBottomEdges.erase( edge ); --iE; @@ -950,12 +955,14 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, } else { + bool hasWallFace = false; TopTools_ListIteratorOfListOfShape faceIt( edgeToFaces.FindFromKey( *edge )); for ( ; faceIt.More(); faceIt.Next() ) { const TopoDS_Face& face = TopoDS::Face( faceIt.Value() ); if ( !thePrism.myBottom.IsSame( face )) { + hasWallFace = true; Prism_3D::TQuadList quadList( 1, quadAlgo->CheckNbEdges( *mesh, face )); if ( !quadList.back() ) return toSM( error(TCom("Side face #") << shapeID( face ) @@ -974,7 +981,16 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism, break; } } - ++edge; + if ( hasWallFace ) + { + ++edge; + } + else // seam edge (IPAL53561) + { + edge = thePrism.myBottomEdges.erase( edge ); + --iE; + --(*nbE); + } } if ( iE == *nbE ) { @@ -1204,7 +1220,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism) for ( ; bot_column != myBotToColumnMap.end(); ++bot_column ) { const Prism_3D::TNode& tBotNode = bot_column->first; // bottom TNode - if ( tBotNode.GetPositionType() != SMDS_TOP_FACE ) + if ( tBotNode.GetPositionType() != SMDS_TOP_FACE && + myBlock.HasNodeColumn( tBotNode.myNode )) continue; // node is not inside the FACE // column nodes; middle part of the column are zero pointers @@ -1308,16 +1325,17 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism) for ( int i = 0; i < nbNodes; ++i ) { const SMDS_MeshNode* n = face->GetNode( i ); - if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) { + columns[ i ] = NULL; + + if ( n->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE ) + columns[ i ] = myBlock.GetNodeColumn( n ); + + if ( !columns[ i ] ) + { TNode2ColumnMap::iterator bot_column = myBotToColumnMap.find( n ); if ( bot_column == myBotToColumnMap.end() ) - return toSM( error(TCom("No nodes found above node ") << n->GetID() )); - columns[ i ] = & bot_column->second; - } - else { - columns[ i ] = myBlock.GetNodeColumn( n ); - if ( !columns[ i ] ) return toSM( error(TCom("No side nodes found above node ") << n->GetID() )); + columns[ i ] = & bot_column->second; } } // create prisms @@ -2068,7 +2086,8 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf { const SMDS_MeshNode* botNode = bN_tN->first; const SMDS_MeshNode* topNode = bN_tN->second; - if ( botNode->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE ) + if ( botNode->GetPosition()->GetTypeOfPosition() != SMDS_TOP_FACE && + myBlock.HasNodeColumn( botNode )) continue; // wall columns are contained in myBlock // create node column Prism_3D::TNode bN( botNode ); @@ -2265,29 +2284,39 @@ bool StdMeshers_Prism_3D::projectBottomToTop( const gp_Trsf & bottom Handle(Geom_Surface) surface = BRep_Tool::Surface( topFace, loc ); bool isPlanar = GeomLib_IsPlanarSurface( surface ).IsPlanar(); - bool isFixed = false; set fixedNodes; - for ( int iAttemp = 0; !isFixed && iAttemp < 10; ++iAttemp ) - { - TIDSortedElemSet faces; - for ( faceIt = topSMDS->GetElements(); faceIt->more(); ) - faces.insert( faces.end(), faceIt->next() ); + TIDSortedElemSet faces; + for ( faceIt = topSMDS->GetElements(); faceIt->more(); ) + faces.insert( faces.end(), faceIt->next() ); + bool isOk = false; + for ( int isCentroidal = 0; isCentroidal < 2; ++isCentroidal ) + { SMESH_MeshEditor::SmoothMethod algo = - iAttemp ? SMESH_MeshEditor::CENTROIDAL : SMESH_MeshEditor::LAPLACIAN; + isCentroidal ? SMESH_MeshEditor::CENTROIDAL : SMESH_MeshEditor::LAPLACIAN; + + int nbAttempts = isCentroidal ? 1 : 10; + for ( int iAttemp = 0; iAttemp < nbAttempts; ++iAttemp ) + { + TIDSortedElemSet workFaces = faces; - // smoothing - editor.Smooth( faces, fixedNodes, algo, /*nbIterations=*/ 10, - /*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar); + // smoothing + editor.Smooth( workFaces, fixedNodes, algo, /*nbIterations=*/ 10, + /*theTgtAspectRatio=*/1.0, /*the2D=*/!isPlanar); - isFixed = !topHelper.IsDistorted2D( topSM, /*checkUV=*/true ); + if (( isOk = !topHelper.IsDistorted2D( topSM, /*checkUV=*/true )) && + ( !isCentroidal )) + break; + } } - if ( !isFixed ) + if ( !isOk ) return toSM( error( TCom("Projection from face #") << botSM->GetId() << " to face #" << topSM->GetId() << " failed: inverted elements created")); } + TProjction2dAlgo::instance( this )->SetEventListener( topSM ); + return true; } @@ -2371,6 +2400,9 @@ double StdMeshers_Prism_3D::getSweepTolerance( const Prism_3D::TPrismTopo& thePr bool StdMeshers_Prism_3D::isSimpleBottom( const Prism_3D::TPrismTopo& thePrism ) { + if ( thePrism.myBottomEdges.size() != 4 ) + return false; + // analyse angles between edges double nbConcaveAng = 0, nbConvexAng = 0; TopoDS_Face reverseBottom = TopoDS::Face( thePrism.myBottom.Reversed() ); // see initPrism() @@ -2426,6 +2458,8 @@ bool StdMeshers_Prism_3D::project2dMesh(const TopoDS_Face& theSrcFace, tgtSM->ComputeStateEngine ( SMESH_subMesh::CHECK_COMPUTE_STATE ); tgtSM->ComputeSubMeshStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE ); + projector2D->SetEventListener( tgtSM ); + return ok; } @@ -2505,13 +2539,15 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() struct EdgeWithNeighbors { TopoDS_Edge _edge; - int _iL, _iR; - EdgeWithNeighbors(const TopoDS_Edge& E, int iE, int nbE, int shift = 0 ): - _edge( E ), - _iL( SMESH_MesherHelper::WrapIndex( iE-1, nbE ) + shift ), - _iR( SMESH_MesherHelper::WrapIndex( iE+1, nbE ) + shift ) + int _iBase; /* index in a WIRE with non-base EDGEs excluded */ + int _iL, _iR; /* used to connect edges in a base FACE */ + bool _isBase; /* is used in a base FACE */ + EdgeWithNeighbors(const TopoDS_Edge& E, int iE, int nbE, int shift, bool isBase ): + _edge( E ), _iBase( iE + shift ), + _iL( SMESH_MesherHelper::WrapIndex( iE-1, Max( 1, nbE )) + shift ), + _iR( SMESH_MesherHelper::WrapIndex( iE+1, Max( 1, nbE )) + shift ), + _isBase( isBase ) { - //_edge.Orientation( TopAbs_FORWARD ); // for operator==() to work } EdgeWithNeighbors() {} bool IsInternal() const { return !_edge.IsNull() && _edge.Orientation() == TopAbs_INTERNAL; } @@ -2553,13 +2589,29 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() return false; } }; + //-------------------------------------------------------------------------------- + /*! + * \brief Return another faces sharing an edge + */ + const TopoDS_Face & getAnotherFace( const TopoDS_Face& face, + const TopoDS_Edge& edge, + TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge) + { + TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edge )); + for ( ; faceIt.More(); faceIt.Next() ) + if ( !face.IsSame( faceIt.Value() )) + return TopoDS::Face( faceIt.Value() ); + return face; + } + //-------------------------------------------------------------------------------- /*! * \brief Return ordered edges of a face */ - bool getEdges( const TopoDS_Face& face, - vector< EdgeWithNeighbors > & edges, - const bool noHolesAllowed) + bool getEdges( const TopoDS_Face& face, + vector< EdgeWithNeighbors > & edges, + TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge, + const bool noHolesAllowed) { TopoDS_Face f = face; if ( f.Orientation() != TopAbs_FORWARD && @@ -2571,26 +2623,40 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() if ( nbW > 1 && noHolesAllowed ) return false; - int iE, nbTot = 0; + int iE, nbTot = 0, nbBase, iBase; list< TopoDS_Edge >::iterator e = ee.begin(); list< int >::iterator nbE = nbEdgesInWires.begin(); for ( ; nbE != nbEdgesInWires.end(); ++nbE ) for ( iE = 0; iE < *nbE; ++e, ++iE ) - if ( SMESH_Algo::isDegenerated( *e )) + if ( SMESH_Algo::isDegenerated( *e )) // degenerated EDGE is never used { e = --ee.erase( e ); --(*nbE); --iE; } + vector isBase; edges.clear(); e = ee.begin(); for ( nbE = nbEdgesInWires.begin(); nbE != nbEdgesInWires.end(); ++nbE ) { - for ( iE = 0; iE < *nbE; ++e, ++iE ) - edges.push_back( EdgeWithNeighbors( *e, iE, *nbE, nbTot )); - nbTot += *nbE; + nbBase = 0; + isBase.resize( *nbE ); + list< TopoDS_Edge >::iterator eIt = e; + for ( iE = 0; iE < *nbE; ++eIt, ++iE ) + { + isBase[ iE ] = ( getAnotherFace( face, *eIt, facesOfEdge ) != face ); + nbBase += isBase[ iE ]; + } + for ( iBase = 0, iE = 0; iE < *nbE; ++e, ++iE ) + { + edges.push_back( EdgeWithNeighbors( *e, iBase, nbBase, nbTot, isBase[ iE ] )); + iBase += isBase[ iE ]; + } + nbTot += nbBase; } + if ( nbTot == 0 ) + return false; // IPAL53099. Set correct neighbors to INTERNAL EDGEs, which can be connected to // EDGEs of the outer WIRE but this fact can't be detected by their order. @@ -2605,16 +2671,19 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() bool isConnectOk = ( vv[0].IsSame( vv[1] )); if ( !isConnectOk ) { - // look for an EDGE of the outer WIRE connected to vv + edges[ iFirst ]._iL = edges[ iFirst ]._iBase; // connect to self + edges[ iLast ]._iR = edges[ iLast ]._iBase; + + // look for an EDGE of the outer WIREs connected to vv TopoDS_Vertex v0, v1; - for ( iE = 0; iE < nbEdgesInWires.front(); ++iE ) + for ( iE = 0; iE < iFirst; ++iE ) { v0 = SMESH_MesherHelper::IthVertex( 0, edges[ iE ]._edge ); v1 = SMESH_MesherHelper::IthVertex( 1, edges[ iE ]._edge ); if ( vv[0].IsSame( v0 ) || vv[0].IsSame( v1 )) - edges[ iFirst ]._iL = iE; + edges[ iFirst ]._iL = edges[ iE ]._iBase; if ( vv[1].IsSame( v0 ) || vv[1].IsSame( v1 )) - edges[ iLast ]._iR = iE; + edges[ iLast ]._iR = edges[ iE ]._iBase; } } iFirst += *nbE; @@ -2622,21 +2691,7 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable() } return edges.size(); } - //-------------------------------------------------------------------------------- - /*! - * \brief Return another faces sharing an edge - */ - const TopoDS_Face & getAnotherFace( const TopoDS_Face& face, - const TopoDS_Edge& edge, - TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge) - { - TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edge )); - for ( ; faceIt.More(); faceIt.Next() ) - if ( !face.IsSame( faceIt.Value() )) - return TopoDS::Face( faceIt.Value() ); - return face; - } - + //-------------------------------------------------------------------------------- /*! * \brief Return number of faces sharing given edges @@ -2676,10 +2731,10 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA // check nb shells TopoDS_Shape shell; TopExp_Explorer shExp( sExp.Current(), TopAbs_SHELL ); - if ( shExp.More() ) { + while ( shExp.More() ) { shell = shExp.Current(); shExp.Next(); - if ( shExp.More() ) + if ( shExp.More() && BRep_Tool::IsClosed( shExp.Current() )) shell.Nullify(); } if ( shell.IsNull() ) { @@ -2688,7 +2743,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA } // get all faces TopTools_IndexedMapOfShape allFaces; - TopExp::MapShapes( shell, TopAbs_FACE, allFaces ); + TopExp::MapShapes( sExp.Current(), TopAbs_FACE, allFaces ); if ( allFaces.Extent() < 3 ) { if ( toCheckAll ) return false; continue; @@ -2705,7 +2760,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA } } #ifdef _DEBUG_ - TopTools_IndexedMapOfShape allShapes; + TopTools_IndexedMapOfShape allShapes; // usage: allShapes.FindIndex( s ) TopExp::MapShapes( shape, allShapes ); #endif @@ -2732,23 +2787,32 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA TEdgeWithNeighborsVec& botEdges = faceEdgesVec[ iF ]; if ( botEdges.empty() ) - if ( !getEdges( botF, botEdges, /*noHoles=*/false )) + if ( !getEdges( botF, botEdges, facesOfEdge, /*noHoles=*/false )) break; - if ( allFaces.Extent()-1 <= (int) botEdges.size() ) + + int nbBase = 0; + for ( size_t iS = 0; iS < botEdges.size(); ++iS ) + nbBase += botEdges[ iS ]._isBase; + + if ( allFaces.Extent()-1 <= nbBase ) continue; // all faces are adjacent to botF - no top FACE // init data of side FACEs sides.clear(); - sides.resize( botEdges.size() ); - for ( size_t iS = 0; iS < botEdges.size(); ++iS ) + sides.resize( nbBase ); + size_t iS = 0; + for ( size_t iE = 0; iE < botEdges.size(); ++iE ) { - sides[ iS ]._topEdge = botEdges[ iS ]._edge; + if ( !botEdges[ iE ]._isBase ) + continue; + sides[ iS ]._topEdge = botEdges[ iE ]._edge; sides[ iS ]._face = botF; - sides[ iS ]._leftSide = & sides[ botEdges[ iS ]._iR ]; - sides[ iS ]._rightSide = & sides[ botEdges[ iS ]._iL ]; - sides[ iS ]._isInternal = botEdges[ iS ].IsInternal(); + sides[ iS ]._leftSide = & sides[ botEdges[ iE ]._iR ]; + sides[ iS ]._rightSide = & sides[ botEdges[ iE ]._iL ]; + sides[ iS ]._isInternal = botEdges[ iE ].IsInternal(); sides[ iS ]._faces = & facesOfSide[ iS ]; sides[ iS ]._faces->Clear(); + ++iS; } bool isOK = true; // ok for a current botF @@ -2843,7 +2907,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA int faceID = allFaces.FindIndex( side._face ); side._edges = & faceEdgesVec[ faceID ]; if ( side._edges->empty() ) - if ( !getEdges( side._face, * side._edges, /*noHoles=*/true )) + if ( !getEdges( side._face, * side._edges, facesOfEdge, /*noHoles=*/true )) break; const int nbE = side._edges->size(); if ( nbE >= 4 ) @@ -4828,8 +4892,8 @@ bool StdMeshers_Sweeper::ComputeNodes( SMESH_MesherHelper& helper, } } - //centerIntErrorIsSmall = true; - //bndErrorIsSmall = true; + centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3 + bndErrorIsSmall = true; if ( !centerIntErrorIsSmall ) { // Compensate the central error; continue adding projection diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index c113fd1e8..ddfbff96a 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -185,6 +185,16 @@ class STDMESHERS_EXPORT StdMeshers_PrismAsBlock: public SMESH_Block return col_frw.first; } + /*! + * \brief Return pointer to column of nodes + * \param node - bottom node from which the returned column goes up + * \retval const TNodeColumn* - the found column + */ + bool HasNodeColumn(const SMDS_MeshNode* node) const + { + return myShapeIndex2ColumnMap.count( node->getshapeId() ); + } + /*! * \brief Return transformations to get coordinates of nodes of each internal layer * by nodes of the bottom. Layer is a set of nodes at a certain step diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index d81ade633..c13ea9fcb 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -414,9 +414,8 @@ namespace { const gp_Pnt2d& uv, const double& tol2d ) { - TopoDS_Vertex VV[2]; - TopExp::Vertices( edge, VV[0], VV[1], true); - gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face); + TopoDS_Vertex V = SMESH_MesherHelper::IthVertex( vIndex, edge, /*CumOri=*/true ); + gp_Pnt2d v1UV = BRep_Tool::Parameters( V, face); double dist2d = v1UV.Distance( uv ); return dist2d < tol2d; } @@ -1111,8 +1110,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { InsertAssociation( *eIt1, *eIt2, theMap ); - VV1[0] = TopExp::FirstVertex( *eIt1, true ); - VV2[0] = TopExp::FirstVertex( *eIt2, true ); + VV1[0] = SMESH_MesherHelper::IthVertex( 0, *eIt1, true ); + VV2[0] = SMESH_MesherHelper::IthVertex( 0, *eIt2, true ); InsertAssociation( VV1[0], VV2[0], theMap ); } InsertAssociation( theShape1, theShape2, theMap ); @@ -2325,7 +2324,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter string algoType = algo->GetName(); if ( algoType.substr(0, 11) != "Projection_") - return gen->Compute( *mesh, shape, /*shapeOnly=*/true ); + return gen->Compute( *mesh, shape, SMESH_Gen::SHAPE_ONLY ); // try to compute source mesh @@ -2366,7 +2365,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter srcMesh = mesh; if ( MakeComputed( srcMesh->GetSubMesh( srcShape ), iterationNb + 1 ) && - gen->Compute( *mesh, shape, /*shapeOnly=*/true )) + gen->Compute( *mesh, shape, SMESH_Gen::SHAPE_ONLY )) return sm->IsMeshComputed(); return false; diff --git a/src/StdMeshers/StdMeshers_Projection_2D.cxx b/src/StdMeshers/StdMeshers_Projection_2D.cxx index b44115663..10f862696 100644 --- a/src/StdMeshers/StdMeshers_Projection_2D.cxx +++ b/src/StdMeshers/StdMeshers_Projection_2D.cxx @@ -41,18 +41,22 @@ #include "SMESH_Comment.hxx" #include "SMESH_Gen.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_MeshAlgos.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_Pattern.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "utilities.h" +#include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -68,6 +72,10 @@ using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } +#ifdef _DEBUG_ +// enable printing algo + projection shapes while meshing +//#define PRINT_WHO_COMPUTE_WHAT +#endif namespace TAssocTool = StdMeshers_ProjectionUtils; //typedef StdMeshers_ProjectionUtils TAssocTool; @@ -260,7 +268,7 @@ namespace { //================================================================================ /*! * \brief find new nodes belonging to one free border of mesh on face - * \param sm - submesh on edge or vertex containg nodes to choose from + * \param sm - submesh on edge or vertex containing nodes to choose from * \param face - the face bound by the submesh * \param u2nodes - map to fill with nodes * \param seamNodes - set of found nodes @@ -432,7 +440,11 @@ namespace { if (( err && !err->IsOK() ) || ( srcWires.empty() )) return err; - +#ifdef PRINT_WHO_COMPUTE_WHAT + cout << "Projection_2D" << " F " + << tgtMesh->GetMeshDS()->ShapeToIndex( tgtFace ) << " <- " + << srcMesh->GetMeshDS()->ShapeToIndex( srcFace ) << endl; +#endif SMESH_MesherHelper srcHelper( *srcMesh ); srcHelper.SetSubShape( srcFace ); @@ -488,6 +500,11 @@ namespace { for ( int iE = 0; iE < srcWire->NbEdges(); ++iE ) { +#ifdef PRINT_WHO_COMPUTE_WHAT + if ( tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() ) + cout << "Projection_2D" << " E " + << tgtWire->EdgeID(iE) << " <- " << srcWire->EdgeID(iE) << endl; +#endif if ( srcMesh->GetSubMesh( srcWire->Edge(iE) )->IsEmpty() || tgtMesh->GetSubMesh( tgtWire->Edge(iE) )->IsEmpty() ) { @@ -654,6 +671,8 @@ namespace { SMESH_MesherHelper srcHelper( *srcMesh ); srcHelper.SetSubShape( srcFace ); + SMESH_MesherHelper edgeHelper( *tgtMesh ); + edgeHelper.ToFixNodeParameters( true ); const SMDS_MeshNode* nullNode = 0; TAssocTool::TNodeNodeMap::iterator srcN_tgtN; @@ -692,10 +711,29 @@ namespace { } case SMDS_TOP_EDGE: { - const TopoDS_Shape & srcE = srcMeshDS->IndexToShape( srcNode->getshapeId() ); - const TopoDS_Shape & tgtE = shape2ShapeMap( srcE, /*isSrc=*/true ); - double srcU = srcHelper.GetNodeU( TopoDS::Edge( srcE ), srcNode ); - tgtMeshDS->SetNodeOnEdge( n, TopoDS::Edge( tgtE ), srcU ); + const TopoDS_Edge& srcE = TopoDS::Edge( srcMeshDS->IndexToShape( srcNode->getshapeId())); + const TopoDS_Edge& tgtE = TopoDS::Edge( shape2ShapeMap( srcE, /*isSrc=*/true )); + double srcU = srcHelper.GetNodeU( srcE, srcNode ); + tgtMeshDS->SetNodeOnEdge( n, tgtE, srcU ); + if ( !tgtFace.IsPartner( srcFace )) + { + edgeHelper.SetSubShape( tgtE ); + double tol = BRep_Tool::Tolerance( tgtE ); + bool isOk = edgeHelper.CheckNodeU( tgtE, n, srcU, 2 * tol, /*force=*/true ); + if ( !isOk ) // projection of n to tgtE failed (23395) + { + double sF, sL, tF, tL; + BRep_Tool::Range( srcE, sF, sL ); + BRep_Tool::Range( tgtE, tF, tL ); + double srcR = ( srcU - sF ) / ( sL - sF ); + double tgtU = tF + srcR * ( tL - tF ); + tgtMeshDS->SetNodeOnEdge( n, tgtE, tgtU ); + gp_Pnt newP = BRepAdaptor_Curve( tgtE ).Value( tgtU ); + double dist = newP.Distance( tgtP ); + if ( tol < dist && dist < 1000*tol ) + tgtMeshDS->MoveNode( n, newP.X(), newP.Y(), newP.Z() ); + } + } break; } case SMDS_TOP_VERTEX: @@ -726,12 +764,9 @@ namespace { if ( !tgtFace.IsPartner( srcFace ) ) { - SMESH_MesherHelper edgeHelper( *tgtMesh ); - edgeHelper.ToFixNodeParameters( true ); helper.ToFixNodeParameters( true ); int nbOkPos = 0; - bool toCheck = true; const double tol2d = 1e-12; srcN_tgtN = src2tgtNodes.begin(); for ( ; srcN_tgtN != src2tgtNodes.end(); ++srcN_tgtN ) @@ -752,9 +787,9 @@ namespace { } case SMDS_TOP_EDGE: { - const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() )); - edgeHelper.SetSubShape( tgtE ); - edgeHelper.GetNodeU( tgtE, n, 0, &toCheck ); + // const TopoDS_Edge & tgtE = TopoDS::Edge( tgtMeshDS->IndexToShape( n->getshapeId() )); + // edgeHelper.SetSubShape( tgtE ); + // edgeHelper.GetNodeU( tgtE, n, 0, &toCheck ); break; } default:; @@ -1102,7 +1137,7 @@ namespace { { SMESH_subMesh* faceSM = helper.GetMesh()->GetSubMesh( helper.GetSubShape() ); - if ( helper.IsDistorted2D( faceSM, /*checkUV=*/false )) + if ( helper.IsDistorted2D( faceSM, /*checkUV=*/true )) { SMESH_MeshEditor editor( helper.GetMesh() ); SMESHDS_SubMesh* smDS = faceSM->GetSubMeshDS(); @@ -1148,6 +1183,240 @@ namespace { return true; } + typedef list< pair< const SMDS_MeshNode*, const BRepMesh_Triangle* > > TNodeTriaList; + + //================================================================================ + /*! + * \brief Add in-FACE nodes surrounding a given node to a queue + */ + //================================================================================ + + void addCloseNodes( const SMDS_MeshNode* srcNode, + const BRepMesh_Triangle* bmTria, + const int srcFaceID, + TNodeTriaList & noTriQueue ) + { + // find in-FACE nodes + SMDS_ElemIteratorPtr elems = srcNode->GetInverseElementIterator(SMDSAbs_Face); + while ( elems->more() ) + { + const SMDS_MeshElement* elem = elems->next(); + if ( elem->getshapeId() == srcFaceID ) + { + for ( int i = 0, nb = elem->NbNodes(); i < nb; ++i ) + { + const SMDS_MeshNode* n = elem->GetNode( i ); + if ( !n->isMarked() ) + noTriQueue.push_back( make_pair( n, bmTria )); + } + } + } + } + + //================================================================================ + /*! + * \brief Find a delauney triangle containing a given 2D point and return + * barycentric coordinates within the found triangle + */ + //================================================================================ + + const BRepMesh_Triangle* findTriangle( const gp_XY& uv, + const BRepMesh_Triangle* bmTria, + Handle(BRepMesh_DataStructureOfDelaun)& triaDS, + double bc[3] ) + { + int nodeIDs[3]; + gp_XY nodeUVs[3]; + int linkIDs[3]; + Standard_Boolean ori[3]; + + while ( bmTria ) + { + // check bmTria + + triaDS->ElementNodes( *bmTria, nodeIDs ); + nodeUVs[0] = triaDS->GetNode( nodeIDs[0] ).Coord(); + nodeUVs[1] = triaDS->GetNode( nodeIDs[1] ).Coord(); + nodeUVs[2] = triaDS->GetNode( nodeIDs[2] ).Coord(); + + SMESH_MeshAlgos::GetBarycentricCoords( uv, + nodeUVs[0], nodeUVs[1], nodeUVs[2], + bc[0], bc[1] ); + if ( bc[0] >= 0 && bc[1] >= 0 && bc[0] + bc[1] <= 1 ) + { + bc[2] = 1 - bc[0] - bc[1]; + return bmTria; + } + + // look for a neighbor triangle, which is adjacent to a link intersected + // by a segment( triangle center -> uv ) + + gp_XY gc = ( nodeUVs[0] + nodeUVs[1] + nodeUVs[2] ) / 3.; + gp_XY seg = uv - gc; + + bmTria->Edges( linkIDs, ori ); + int triaID = triaDS->IndexOf( *bmTria ); + bmTria = 0; + + for ( int i = 0; i < 3; ++i ) + { + const BRepMesh_PairOfIndex & triIDs = triaDS->ElementsConnectedTo( linkIDs[i] ); + if ( triIDs.Extent() < 2 ) + continue; // no neighbor triangle + + // check if a link intersects gc2uv + const BRepMesh_Edge & link = triaDS->GetLink( linkIDs[i] ); + const BRepMesh_Vertex & n1 = triaDS->GetNode( link.FirstNode() ); + const BRepMesh_Vertex & n2 = triaDS->GetNode( link.LastNode() ); + gp_XY uv1 = n1.Coord(); + gp_XY lin = n2.Coord() - uv1; // link direction + + double crossSegLin = seg ^ lin; + if ( Abs( crossSegLin ) < std::numeric_limits::min() ) + continue; // parallel + + double uSeg = ( uv1 - gc ) ^ lin / crossSegLin; + if ( 0. <= uSeg && uSeg <= 1. ) + { + bmTria = & triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID ))); + break; + } + } + } + return bmTria; + } + + //================================================================================ + /*! + * \brief Morph mesh on the target face to lie within FACE boundary w/o distortion + * + * algo: + * - make a CDT on the src FACE + * - find a triangle containing a src node and get its barycentric coordinates + * - move the node to a point with the same barycentric coordinates in a corresponding + * tgt triangle + */ + //================================================================================ + + bool morph( SMESH_MesherHelper& tgtHelper, + const TopoDS_Face& tgtFace, + const TopoDS_Face& srcFace, + const TSideVector& tgtWires, + const TSideVector& srcWires, + const TAssocTool::TNodeNodeMap& src2tgtNodes ) + { + if ( srcWires.size() != tgtWires.size() ) return false; + if ( srcWires.size() == 1 ) return false; // tmp + + // count boundary points + int iP = 1, nbP = 0; + for ( size_t iW = 0; iW < srcWires.size(); ++iW ) + nbP += srcWires[iW]->NbPoints() - 1; // 1st and last points coincide + + // fill boundary points + BRepMesh::Array1OfVertexOfDelaun srcVert( 1, 1 + nbP ), tgtVert( 1, 1 + nbP ); + vector< const SMDS_MeshNode* > bndSrcNodes( nbP + 1 ); bndSrcNodes[0] = 0; + BRepMesh_Vertex v( 0, 0, BRepMesh_Frontier ); + for ( size_t iW = 0; iW < srcWires.size(); ++iW ) + { + const UVPtStructVec& srcPnt = srcWires[iW]->GetUVPtStruct(); + const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct(); + if ( srcPnt.size() != tgtPnt.size() ) return false; + + for ( int i = 0, nb = srcPnt.size() - 1; i < nb; ++i, ++iP ) + { + bndSrcNodes[ iP ] = srcPnt[i].node; + srcPnt[i].node->setIsMarked( true ); + + v.ChangeCoord() = srcPnt[i].UV(); + srcVert( iP ) = v; + v.ChangeCoord() = tgtPnt[i].UV(); + tgtVert( iP ) = v; + } + } + // triangulate the srcFace in 2D + BRepMesh_Delaun delauney( srcVert ); + Handle(BRepMesh_DataStructureOfDelaun) triaDS = delauney.Result(); + + Handle(ShapeAnalysis_Surface) tgtSurface = tgtHelper.GetSurface( tgtFace ); + SMESHDS_Mesh* srcMesh = srcWires[0]->GetMesh()->GetMeshDS(); + SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS(); + const SMDS_MeshNode *srcNode, *tgtNode; + const BRepMesh_Triangle *bmTria; + + // un-mark internal src nodes; later we will mark moved nodes + SMDS_NodeIteratorPtr nIt = srcMesh->MeshElements( srcFace )->GetNodes(); + if ( !nIt || !nIt->more() ) return true; + while ( nIt->more() ) + ( srcNode = nIt->next() )->setIsMarked( false ); + + // initialize a queue of nodes with starting triangles + const int srcFaceID = srcNode->getshapeId(); + TNodeTriaList noTriQueue; + size_t iBndSrcN = 1; + for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN ) + { + // get a triangle + const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN ); + const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() ); + const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) ); + + addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue ); + } + + // Move tgt nodes + + double bc[3]; // barycentric coordinates + int nodeIDs[3]; + bool checkUV = true; + const SMDS_FacePosition* pos; + + while ( !noTriQueue.empty() ) + { + srcNode = noTriQueue.front().first; + bmTria = noTriQueue.front().second; + noTriQueue.pop_front(); + if ( srcNode->isMarked() ) + continue; + srcNode->setIsMarked( true ); + + // find a delauney triangle containing the src node + gp_XY uv = tgtHelper.GetNodeUV( srcFace, srcNode, NULL, &checkUV ); + bmTria = findTriangle( uv, bmTria, triaDS, bc ); + if ( !bmTria ) + continue; + + // compute new coordinates for a corresponding tgt node + gp_XY uvNew( 0., 0. ), nodeUV; + triaDS->ElementNodes( *bmTria, nodeIDs ); + for ( int i = 0; i < 3; ++i ) + uvNew += bc[i] * tgtVert( nodeIDs[i]).Coord(); + gp_Pnt xyz = tgtSurface->Value( uvNew ); + + // find and move tgt node + TAssocTool::TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode ); + if ( n2n == src2tgtNodes.end() ) continue; + tgtNode = n2n->second; + tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() ); + + if (( pos = dynamic_cast< const SMDS_FacePosition* >( tgtNode->GetPosition() ))) + const_cast( pos )->SetParameters( uvNew.X(), uvNew.Y() ); + + addCloseNodes( srcNode, bmTria, srcFaceID, noTriQueue ); + + // assure that all src nodes are visited + for ( ; iBndSrcN < bndSrcNodes.size() && noTriQueue.empty(); ++iBndSrcN ) + { + const BRepMesh::ListOfInteger & linkIds = triaDS->LinksConnectedTo( iBndSrcN ); + const BRepMesh_PairOfIndex & triaIds = triaDS->ElementsConnectedTo( linkIds.First() ); + const BRepMesh_Triangle& tria = triaDS->GetElement( triaIds.Index(1) ); + addCloseNodes( bndSrcNodes[ iBndSrcN ], &tria, srcFaceID, noTriQueue ); + } + } + + return true; + } + //======================================================================= /* * Set initial association of VERTEXes for the case of projection @@ -1246,23 +1515,6 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& } TopoDS_Face srcFace = TopoDS::Face( shape2ShapeMap( tgtFace ).Oriented(TopAbs_FORWARD)); - // orient faces - // if ( srcMesh == tgtMesh ) - // { - // TopoDS_Shape solid = - // helper.GetCommonAncestor( srcFace, tgtFace, *tgtMesh, TopAbs_SOLID ); - // if ( !solid.IsNull() ) - // { - // srcFace.Orientation( helper.GetSubShapeOri( solid, srcFace )); - // tgtFace.Orientation( helper.GetSubShapeOri( solid, tgtFace )); - // } - // else if ( helper.NbAncestors( srcFace, *tgtMesh, TopAbs_SOLID ) == 1 && - // helper.NbAncestors( tgtFace, *tgtMesh, TopAbs_SOLID ) == 1 ) - // { - // srcFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), srcFace )); - // tgtFace.Orientation( helper.GetSubShapeOri( tgtMesh->GetShapeToMesh(), tgtFace )); - // } - // } // ---------------------------------------------- // Assure that mesh on a source Face is computed // ---------------------------------------------- @@ -1461,7 +1713,7 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // Load pattern from the source face SMESH_Pattern mapper; - mapper.Load( srcMesh, srcFace, toProjectNodes, srcV1 ); + mapper.Load( srcMesh, srcFace, toProjectNodes, srcV1, /*keepNodes=*/true ); if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) return error(COMPERR_BAD_INPUT_MESH,"Can't load mesh pattern from the source face"); @@ -1485,6 +1737,15 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& if ( mapper.GetErrorCode() != SMESH_Pattern::ERR_OK ) return error("Can't make mesh by source mesh pattern"); + // fill _src2tgtNodes + std::vector< const SMDS_MeshNode* > *srcNodes, *tgtNodes; + mapper.GetInOutNodes( srcNodes, tgtNodes ); + size_t nbN = std::min( srcNodes->size(), tgtNodes->size() ); + for ( size_t i = 0; i < nbN; ++i ) + if ( (*srcNodes)[i] && (*tgtNodes)[i] ) + _src2tgtNodes.insert( make_pair( (*srcNodes)[i], (*tgtNodes)[i] )); + + } // end of projection using Pattern mapping { @@ -1674,9 +1935,13 @@ bool StdMeshers_Projection_2D::Compute(SMESH_Mesh& theMesh, const TopoDS_Shape& // boundary, also bad face can be created if EDGEs already discretized // --> fix bad faces by smoothing // ---------------------------------------------------------------- - if ( !fixDistortedFaces( helper, tgtWires )) - return error("Invalid mesh generated"); + if ( helper.IsDistorted2D( tgtSubMesh, /*checkUV=*/false )) + { + morph( helper, tgtFace, srcFace, tgtWires, srcWires, _src2tgtNodes ); + if ( !fixDistortedFaces( helper, tgtWires )) + return error("Invalid mesh generated"); + } // --------------------------- // Check elements orientation // --------------------------- diff --git a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx index 2fcf21902..76f3a31f2 100644 --- a/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_QuadFromMedialAxis_1D2D.cxx @@ -383,7 +383,7 @@ namespace tmpMesh.ShapeToMesh( theEdges[i] ); try { if ( !mesh->GetGen() ) continue; // tmp mesh - mesh->GetGen()->Compute( tmpMesh, theEdges[i], true, true ); // make nodes on VERTEXes + mesh->GetGen()->Compute( tmpMesh, theEdges[i], SMESH_Gen::SHAPE_ONLY_UPWARD ); // make nodes on VERTEXes if ( !algo->Compute( tmpMesh, theEdges[i] )) continue; } @@ -868,7 +868,7 @@ namespace TmpMesh tmpMesh; tmpMesh.ShapeToMesh( branchEdge ); try { - mesh->GetGen()->Compute( tmpMesh, branchEdge, true, true ); // make nodes on VERTEXes + mesh->GetGen()->Compute( tmpMesh, branchEdge, SMESH_Gen::SHAPE_ONLY_UPWARD ); // make nodes on VERTEXes if ( !algo->Compute( tmpMesh, branchEdge )) return false; } @@ -1930,7 +1930,8 @@ namespace { if ( !theHasRadialHyp ) // use global hyps - theHelper.GetGen()->Compute( *theHelper.GetMesh(), theShortEdges[i], true, true ); + theHelper.GetGen()->Compute( *theHelper.GetMesh(), theShortEdges[i], + SMESH_Gen::SHAPE_ONLY_UPWARD ); SMESH_subMesh* sm = theHelper.GetMesh()->GetSubMesh(theShortEdges[i] ); if ( sm->IsEmpty() ) diff --git a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx index a03ed6a82..2e4ea50b8 100644 --- a/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx +++ b/src/StdMeshers/StdMeshers_QuadToTriaAdaptor.cxx @@ -485,9 +485,6 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, gp_XYZ vert1 = P2.XYZ(); gp_XYZ vert2 = P3.XYZ(); - /* calculate distance from vert0 to ray origin */ - gp_XYZ tvec = orig - vert0; - gp_XYZ edge1 = vert1 - vert0; gp_XYZ edge2 = vert2 - vert0; @@ -497,9 +494,13 @@ static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, /* if determinant is near zero, ray lies in plane of triangle */ double det = edge1 * pvec; - if (det > -EPSILON && det < EPSILON) + const double ANGL_EPSILON = 1e-12; + if ( det > -ANGL_EPSILON && det < ANGL_EPSILON ) return false; + /* calculate distance from vert0 to ray origin */ + gp_XYZ tvec = orig - vert0; + /* calculate U parameter and test bounds */ double u = ( tvec * pvec ) / det; //if (u < 0.0 || u > 1.0) @@ -1012,6 +1013,8 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) groupDS = 0; } + const bool toFindVolumes = aMesh.NbVolumes() > 0; + vector myPyramids; SMESH_MesherHelper helper(aMesh); helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh()); @@ -1023,6 +1026,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) if ( !myElemSearcher ) myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS ); SMESH_ElementSearcher* searcher = const_cast(myElemSearcher); + SMESHUtils::Deleter + volSearcher( SMESH_MeshAlgos::GetElementSearcher( *meshDS )); + vector< const SMDS_MeshElement* > suspectFaces, foundVolumes; TColgp_Array1OfPnt PN(1,5); TColgp_Array1OfVec VN(1,4); @@ -1042,7 +1048,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) if ( what == NOT_QUAD ) continue; if ( volumes[0] && volumes[1] ) - continue; // face is shared by two volumes - no space for a pyramid + continue; // face is shared by two volumes - no room for a pyramid if ( what == DEGEN_QUAD ) { @@ -1143,6 +1149,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) } // Restrict pyramid height by intersection with other faces + gp_Vec tmpDir(PC,PCbest); tmpDir.Normalize(); double tmp = PN(1).Distance(PN(3)) + PN(2).Distance(PN(4)); // far points: in (PC, PCbest) direction and vice-versa @@ -1154,8 +1161,24 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh) gp_Pnt intPnt [2]; int intFaceInd [2] = { 0, 0 }; + if ( toFindVolumes && 0 ) // non-conformal mesh is not suitable for any mesher so far + { + // there are volumes in the mesh, in a non-conformal mesh an neighbor + // volume can be not found yet + for ( int isRev = 0; isRev < 2; ++isRev ) + { + if ( volumes[isRev] ) continue; + gp_Pnt testPnt = PC.XYZ() + tmpDir.XYZ() * height * ( isRev ? -0.1: 0.1 ); + foundVolumes.clear(); + if ( volSearcher->FindElementsByPoint( testPnt, SMDSAbs_Volume, foundVolumes )) + volumes[isRev] = foundVolumes[0]; + } + if ( volumes[0] && volumes[1] ) + continue; // no room for a pyramid + } + gp_Ax1 line( PC, tmpDir ); - vector< const SMDS_MeshElement* > suspectFaces; + suspectFaces.clear(); searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectFaces); for ( size_t iF = 0; iF < suspectFaces.size(); ++iF ) diff --git a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx index 2be343242..d72434501 100644 --- a/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx +++ b/src/StdMeshers/StdMeshers_Quadrangle_2D.cxx @@ -94,7 +94,6 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, myQuadType(QUAD_STANDARD), myHelper( NULL ) { - MESSAGE("StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D"); _name = "Quadrangle_2D"; _shapeType = (1 << TopAbs_FACE); _compatibleHypothesis.push_back("QuadrangleParams"); @@ -111,7 +110,6 @@ StdMeshers_Quadrangle_2D::StdMeshers_Quadrangle_2D (int hypId, int studyId, StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D() { - MESSAGE("StdMeshers_Quadrangle_2D::~StdMeshers_Quadrangle_2D"); } //============================================================================= @@ -161,7 +159,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis } else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ isFirstParams = false; - myTrianglePreference = true; + myTrianglePreference = true; } else { isFirstParams = false; @@ -174,18 +172,18 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis if (isFirstParams) { if (strcmp("QuadranglePreference", aHyp->GetName()) == 0) { myQuadranglePreference = true; - myTrianglePreference = false; + myTrianglePreference = false; myQuadType = QUAD_STANDARD; } else if (strcmp("TrianglePreference", aHyp->GetName()) == 0){ myQuadranglePreference = false; - myTrianglePreference = true; + myTrianglePreference = true; myQuadType = QUAD_STANDARD; } } - else { - const StdMeshers_QuadrangleParams* aHyp2 = - (const StdMeshers_QuadrangleParams*)aHyp; + else if (const StdMeshers_QuadrangleParams* aHyp2 = + dynamic_cast( aHyp )) + { myTriaVertexID = aHyp2->GetTriaVertex(); if (!myQuadranglePreference && !myTrianglePreference) { // priority of hypos @@ -206,7 +204,7 @@ bool StdMeshers_Quadrangle_2D::CheckHypothesis //============================================================================= /*! - * + * */ //============================================================================= diff --git a/src/StdMeshers/StdMeshers_Regular_1D.cxx b/src/StdMeshers/StdMeshers_Regular_1D.cxx index 1b2ba291f..c3430af05 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.cxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.cxx @@ -294,6 +294,10 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh, _hypType = MAX_LENGTH; aStatus = SMESH_Hypothesis::HYP_OK; } + else if ( !_mainEdge.IsNull() && _hypType == DISTRIB_PROPAGATION ) // !!! before "Adaptive1D" + { + aStatus = SMESH_Hypothesis::HYP_OK; + } else if ( hypName == "Adaptive1D" ) { _adaptiveHyp = dynamic_cast < const StdMeshers_Adaptive1D* >(theHyp); @@ -672,10 +676,10 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, // Propagation Of Distribution // - if ( !_mainEdge.IsNull() && _isPropagOfDistribution ) + if ( !_mainEdge.IsNull() && _hypType == DISTRIB_PROPAGATION ) { TopoDS_Edge mainEdge = TopoDS::Edge( _mainEdge ); // should not be a reference! - _gen->Compute( theMesh, mainEdge, /*aShapeOnly=*/true, /*anUpward=*/true); + _gen->Compute( theMesh, mainEdge, SMESH_Gen::SHAPE_ONLY_UPWARD ); SMESHDS_SubMesh* smDS = theMesh.GetMeshDS()->MeshElements( mainEdge ); if ( !smDS ) @@ -992,8 +996,6 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, { const std::vector& aPnts = _fpHyp->GetPoints(); std::vector nbsegs = _fpHyp->GetNbSegments(); - if ( theReverse ) - std::reverse( nbsegs.begin(), nbsegs.end() ); // sort normalized params, taking into account theReverse TColStd_SequenceOfReal Params; @@ -1031,6 +1033,16 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh, uVec.back() = theLastU; // divide segments + if ( theReverse ) + { + if ((int) nbsegs.size() > Params.Length() + 1 ) + nbsegs.resize( Params.Length() + 1 ); + std::reverse( nbsegs.begin(), nbsegs.end() ); + } + if ( nbsegs.empty() ) + { + nbsegs.push_back( 1 ); + } Params.InsertBefore( 1, 0.0 ); Params.Append( 1.0 ); double eltSize, segmentSize, par1, par2; @@ -1120,15 +1132,14 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t ASSERT(!VFirst.IsNull()); ASSERT(!VLast.IsNull()); - const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); - const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS ); - if (!idFirst || !idLast) + const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS ); + const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS ); + if ( !nFirst || !nLast ) return error( COMPERR_BAD_INPUT_MESH, "No node on vertex"); // remove elements created by e.g. patern mapping (PAL21999) // CLEAN event is incorrectly ptopagated seemingly due to Propagation hyp // so TEMPORARY solution is to clean the submesh manually - //theMesh.GetSubMesh(theShape)->ComputeStateEngine( SMESH_subMesh::CLEAN ); if (SMESHDS_SubMesh * subMeshDS = meshDS->MeshElements(theShape)) { SMDS_ElemIteratorPtr ite = subMeshDS->GetElements(); @@ -1144,7 +1155,8 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t } } - if (!Curve.IsNull()) + double length = EdgeLength( E ); + if ( !Curve.IsNull() && length > 0 ) { list< double > params; bool reversed = false; @@ -1156,7 +1168,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // take into account reversing the edge the hypothesis is propagated from // (_mainEdge.Orientation() marks mutual orientation of EDGEs in propagation chain) reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED ); - if ( !_isPropagOfDistribution ) { + if ( _hypType != DISTRIB_PROPAGATION ) { int mainID = meshDS->ShapeToIndex(_mainEdge); if ( std::find( _revEdgesIDs.begin(), _revEdgesIDs.end(), mainID) != _revEdgesIDs.end()) reversed = !reversed; @@ -1167,7 +1179,6 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t reversed = !reversed; BRepAdaptor_Curve C3d( E ); - double length = EdgeLength( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) { return false; } @@ -1176,19 +1187,10 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t // edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex) // only internal nodes receive an edge position with param on curve - const SMDS_MeshNode * idPrev = idFirst; + const SMDS_MeshNode * nPrev = nFirst; double parPrev = f; double parLast = l; - /* NPAL18025 - if (reversed) { - idPrev = idLast; - idLast = idFirst; - idFirst = idPrev; - parPrev = l; - parLast = f; - } - */ for (list::iterator itU = params.begin(); itU != params.end(); itU++) { double param = *itU; gp_Pnt P = Curve->Value(param); @@ -1200,18 +1202,18 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t if(_quadraticMesh) { // create medium node double prm = ( parPrev + param )/2; - gp_Pnt PM = Curve->Value(prm); + gp_Pnt PM = Curve->Value(prm); SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); meshDS->SetNodeOnEdge(NM, shapeID, prm); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node); meshDS->SetMeshElementOnShape(edge, shapeID); } - idPrev = node; + nPrev = node; parPrev = param; } if(_quadraticMesh) { @@ -1219,11 +1221,11 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t gp_Pnt PM = Curve->Value(prm); SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z()); meshDS->SetNodeOnEdge(NM, shapeID, prm); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast); + SMDS_MeshEdge* edge = meshDS->AddEdge(nPrev, nLast); meshDS->SetMeshElementOnShape(edge, shapeID); } } @@ -1236,7 +1238,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t gp_Pnt P = BRep_Tool::Pnt(VFirst); - const SMDS_MeshNode * idPrev = idFirst; + const SMDS_MeshNode * nPrev = nFirst; for (int i = 2; i < NbPoints; i++) { double param = f + (i - 1) * du; SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z()); @@ -1245,26 +1247,26 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t double prm = param - du/2.; SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnEdge(NM, shapeID, prm); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, node); meshDS->SetMeshElementOnShape(edge, shapeID); } meshDS->SetNodeOnEdge(node, shapeID, param); - idPrev = node; + nPrev = node; } if(_quadraticMesh) { // create medium node double prm = l - du/2.; SMDS_MeshNode * NM = meshDS->AddNode(P.X(), P.Y(), P.Z()); meshDS->SetNodeOnEdge(NM, shapeID, prm); - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast, NM); meshDS->SetMeshElementOnShape(edge, shapeID); } else { - SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast); + SMDS_MeshEdge * edge = meshDS->AddEdge(nPrev, nLast); meshDS->SetMeshElementOnShape(edge, shapeID); } } @@ -1306,11 +1308,11 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, std::vector aVec(SMDSEntity_Last,0); - if (!Curve.IsNull()) { + double length = EdgeLength( E ); + if ( !Curve.IsNull() && length > 0 ) + { list< double > params; - BRepAdaptor_Curve C3d( E ); - double length = EdgeLength( E ); if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, false, true )) { SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); aResMap.insert(std::make_pair(sm,aVec)); @@ -1328,7 +1330,7 @@ bool StdMeshers_Regular_1D::Evaluate(SMESH_Mesh & theMesh, aVec[SMDSEntity_Node] = params.size(); aVec[SMDSEntity_Edge] = params.size() + 1; } - + } else { // Edge is a degenerated Edge : We put n = 5 points on the edge. @@ -1372,10 +1374,13 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh, if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE) { // Check, if propagated from some other edge + bool isPropagOfDistribution = false; _mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape, - _isPropagOfDistribution ); + isPropagOfDistribution ); if ( !_mainEdge.IsNull() ) { + if ( isPropagOfDistribution ) + _hypType = DISTRIB_PROPAGATION; // Propagation of 1D hypothesis from on this edge; // get non-auxiliary assigned to _mainEdge nbHyp = aMesh.GetHypotheses( _mainEdge, *compatibleFilter, _usedHypList, true ); diff --git a/src/StdMeshers/StdMeshers_Regular_1D.hxx b/src/StdMeshers/StdMeshers_Regular_1D.hxx index 7786f4ac7..d2af675f7 100644 --- a/src/StdMeshers/StdMeshers_Regular_1D.hxx +++ b/src/StdMeshers/StdMeshers_Regular_1D.hxx @@ -104,7 +104,7 @@ protected: StdMeshers_SegmentLengthAroundVertex* getVertexHyp(SMESH_Mesh & theMesh, const TopoDS_Vertex & theV); - enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, ADAPTIVE, GEOMETRIC_1D, NONE }; + enum HypothesisType { LOCAL_LENGTH, MAX_LENGTH, NB_SEGMENTS, BEG_END_LENGTH, DEFLECTION, ARITHMETIC_1D, FIXED_POINTS_1D, ADAPTIVE, GEOMETRIC_1D, DISTRIB_PROPAGATION, NONE }; enum ValueIndex { SCALE_FACTOR_IND = 0, @@ -142,7 +142,6 @@ protected: // a source of propagated hypothesis, is set by CheckHypothesis() // always called before Compute() TopoDS_Shape _mainEdge; - bool _isPropagOfDistribution; }; #endif diff --git a/src/StdMeshers/StdMeshers_ViscousLayers.cxx b/src/StdMeshers/StdMeshers_ViscousLayers.cxx index 27afe5d02..1a117aff2 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers.cxx @@ -95,8 +95,9 @@ #include #ifdef _DEBUG_ -//#define __myDEBUG +#define __myDEBUG //#define __NOT_INVALIDATE_BAD_SMOOTH +//#define __NODES_AT_POS #endif #define INCREMENTAL_SMOOTH // smooth only if min angle is too small @@ -424,24 +425,25 @@ namespace VISCOUS_3D // data for smoothing of _LayerEdge's based on the EDGE _2NearEdges* _2neibors; - enum EFlags { TO_SMOOTH = 1, - MOVED = 2, // set by _neibors[i]->SetNewLength() - SMOOTHED = 4, // set by this->Smooth() - DIFFICULT = 8, // near concave VERTEX - ON_CONCAVE_FACE = 16, - BLOCKED = 32, // not to inflate any more - INTERSECTED = 64, // close intersection with a face found - NORMAL_UPDATED = 128, - MARKED = 256, // local usage - MULTI_NORMAL = 512, // a normal is invisible by some of surrounding faces - NEAR_BOUNDARY = 1024,// is near FACE boundary forcing smooth - SMOOTHED_C1 = 2048,// is on _eosC1 - DISTORTED = 4096,// was bad before smoothing - RISKY_SWOL = 8192 // SWOL is parallel to a source FACE + enum EFlags { TO_SMOOTH = 0x0000001, + MOVED = 0x0000002, // set by _neibors[i]->SetNewLength() + SMOOTHED = 0x0000004, // set by this->Smooth() + DIFFICULT = 0x0000008, // near concave VERTEX + ON_CONCAVE_FACE = 0x0000010, + BLOCKED = 0x0000020, // not to inflate any more + INTERSECTED = 0x0000040, // close intersection with a face found + NORMAL_UPDATED = 0x0000080, + MARKED = 0x0000100, // local usage + MULTI_NORMAL = 0x0000200, // a normal is invisible by some of surrounding faces + NEAR_BOUNDARY = 0x0000400, // is near FACE boundary forcing smooth + SMOOTHED_C1 = 0x0000800, // is on _eosC1 + DISTORTED = 0x0001000, // was bad before smoothing + RISKY_SWOL = 0x0002000, // SWOL is parallel to a source FACE + UNUSED_FLAG = 0x0100000 }; - bool Is ( EFlags f ) const { return _flags & f; } - void Set ( EFlags f ) { _flags |= f; } - void Unset( EFlags f ) { _flags &= ~f; } + bool Is ( int flag ) const { return _flags & flag; } + void Set ( int flag ) { _flags |= flag; } + void Unset( int flag ) { _flags &= ~flag; } void SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelper& helper ); bool SetNewLength2d( Handle(Geom_Surface)& surface, @@ -457,6 +459,7 @@ namespace VISCOUS_3D void ChooseSmooFunction(const set< TGeomID >& concaveVertices, const TNode2Edge& n2eMap); void SmoothPos( const vector< double >& segLen, const double tol ); + int GetSmoothedPos( const double tol ); int Smooth(const int step, const bool isConcaveFace, bool findBest); int Smooth(const int step, bool findBest, vector< _LayerEdge* >& toSmooth ); int CheckNeiborsOnBoundary(vector< _LayerEdge* >* badNeibors = 0, bool * needSmooth = 0 ); @@ -490,7 +493,7 @@ namespace VISCOUS_3D dist, epsilon ); } const gp_XYZ& PrevPos() const { return _pos[ _pos.size() - 2 ]; } - const gp_XYZ& PrevCheckPos() const { return _pos[ Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0 ]; } + gp_XYZ PrevCheckPos( _EdgesOnShape* eos=0 ) const; gp_Ax1 LastSegment(double& segLen, _EdgesOnShape& eos) const; gp_XY LastUV( const TopoDS_Face& F, _EdgesOnShape& eos ) const; bool IsOnEdge() const { return _2neibors; } @@ -782,10 +785,10 @@ namespace VISCOUS_3D SMESH_MesherHelper& GetHelper() const { return *_helper; } - void UnmarkEdges() { + void UnmarkEdges( int flag = _LayerEdge::MARKED ) { for ( size_t i = 0; i < _edgesOnShape.size(); ++i ) for ( size_t j = 0; j < _edgesOnShape[i]._edges.size(); ++j ) - _edgesOnShape[i]._edges[j]->Unset( _LayerEdge::MARKED ); + _edgesOnShape[i]._edges[j]->Unset( flag ); } void AddShapesToSmooth( const set< _EdgesOnShape* >& shape, const set< _EdgesOnShape* >* edgesNoAnaSmooth=0 ); @@ -806,8 +809,10 @@ namespace VISCOUS_3D _OffsetPlane() { _isLineOK[0] = _isLineOK[1] = false; _faceIndexNext[0] = _faceIndexNext[1] = -1; } - void ComputeIntersectionLine( _OffsetPlane& pln ); - gp_XYZ GetCommonPoint(bool& isFound) const; + void ComputeIntersectionLine( _OffsetPlane& pln, + const TopoDS_Edge& E, + const TopoDS_Vertex& V ); + gp_XYZ GetCommonPoint(bool& isFound, const TopoDS_Vertex& V) const; int NbLines() const { return _isLineOK[0] + _isLineOK[1]; } }; //-------------------------------------------------------------------------------- @@ -907,7 +912,8 @@ namespace VISCOUS_3D gp_XYZ getWeigthedNormal( const _LayerEdge* edge ); gp_XYZ getNormalByOffset( _LayerEdge* edge, std::pair< TopoDS_Face, gp_XYZ > fId2Normal[], - int nbFaces ); + int nbFaces, + bool lastNoOffset = false); bool findNeiborsOnEdge(const _LayerEdge* edge, const SMDS_MeshNode*& n1, const SMDS_MeshNode*& n2, @@ -930,8 +936,14 @@ namespace VISCOUS_3D vector< _EdgesOnShape* >& eosC1, const int infStep ); void makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& ); - void putOnOffsetSurface( _EdgesOnShape& eos, int infStep, int smooStep=0, bool moveAll=false ); + void putOnOffsetSurface( _EdgesOnShape& eos, int infStep, + vector< _EdgesOnShape* >& eosC1, + int smooStep=0, bool moveAll=false ); void findCollisionEdges( _SolidData& data, SMESH_MesherHelper& helper ); + void limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper ); + void limitMaxLenByCurvature( _LayerEdge* e1, _LayerEdge* e2, + _EdgesOnShape& eos1, _EdgesOnShape& eos2, + SMESH_MesherHelper& helper ); bool updateNormals( _SolidData& data, SMESH_MesherHelper& helper, int stepNb, double stepSize ); bool updateNormalsOfConvexFaces( _SolidData& data, SMESH_MesherHelper& helper, @@ -1004,12 +1016,14 @@ namespace VISCOUS_3D double _len; // length reached at previous inflation step double _param; // on EDGE _2NearEdges _2edges; // 2 neighbor _LayerEdge's + gp_XYZ _edgeDir;// EDGE tangent at _param double Distance( const OffPnt& p ) const { return ( _xyz - p._xyz ).Modulus(); } }; vector< OffPnt > _offPoints; vector< double > _leParams; // normalized param of _eos._edges on EDGE Handle(Geom_Curve) _anaCurve; // for analytic smooth _LayerEdge _leOnV[2]; // _LayerEdge's holding normal to the EDGE at VERTEXes + gp_XYZ _edgeDir[2]; // tangent at VERTEXes size_t _iSeg[2]; // index of segment where extreme tgt node is projected _EdgesOnShape& _eos; double _curveLen; // length of the EDGE @@ -1048,8 +1062,8 @@ namespace VISCOUS_3D const TopoDS_Face& F, SMESH_MesherHelper& helper); - void setNormalOnV( const bool is2nd, - SMESH_MesherHelper& helper); + gp_XYZ getNormalNormal( const gp_XYZ & normal, + const gp_XYZ& edgeDir); _LayerEdge* getLEdgeOnV( bool is2nd ) { @@ -2538,7 +2552,7 @@ bool _ViscousBuilder::makeLayer(_SolidData& data) if ( data._stepSize < 1. ) data._epsilon *= data._stepSize; - if ( !findShapesToSmooth( data )) + if ( !findShapesToSmooth( data )) // _LayerEdge::_maxLen is computed here return false; // limit data._stepSize depending on surface curvature and fill data._convexFaces @@ -2680,11 +2694,11 @@ void _ViscousBuilder::limitStepSize( _SolidData& data, const double minSize ) void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) { + SMESH_MesherHelper helper( *_mesh ); + const int nbTestPnt = 5; // on a FACE sub-shape BRepLProp_SLProps surfProp( 2, 1e-6 ); - SMESH_MesherHelper helper( *_mesh ); - data._convexFaces.clear(); for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) @@ -2747,6 +2761,42 @@ void _ViscousBuilder::limitStepSizeByCurvature( _SolidData& data ) convFace._face = F; convFace._normalsFixed = false; + // skip a closed surface (data._convexFaces is useful anyway) + bool isClosedF = false; + helper.SetSubShape( F ); + if ( helper.HasRealSeam() ) + { + // in the closed surface there must be a closed EDGE + for ( TopExp_Explorer eIt( F, TopAbs_EDGE ); eIt.More() && !isClosedF; eIt.Next() ) + isClosedF = helper.IsClosedEdge( TopoDS::Edge( eIt.Current() )); + } + if ( isClosedF ) + { + // limit _LayerEdge::_maxLen on the FACE + const double minCurvature = + 1. / ( eof._hyp.GetTotalThickness() * ( 1 + theThickToIntersection )); + map< TGeomID, _EdgesOnShape* >::iterator id2eos = cnvFace._subIdToEOS.find( faceID ); + if ( id2eos != cnvFace._subIdToEOS.end() ) + { + _EdgesOnShape& eos = * id2eos->second; + for ( size_t i = 0; i < eos._edges.size(); ++i ) + { + _LayerEdge* ledge = eos._edges[ i ]; + gp_XY uv = helper.GetNodeUV( F, ledge->_nodes[0] ); + surfProp.SetParameters( uv.X(), uv.Y() ); + if ( !surfProp.IsCurvatureDefined() ) + continue; + + if ( surfProp.MaxCurvature() * oriFactor > minCurvature ) + ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MaxCurvature() * oriFactor ); + + if ( surfProp.MinCurvature() * oriFactor > minCurvature ) + ledge->_maxLen = Min( ledge->_maxLen, 1. / surfProp.MinCurvature() * oriFactor ); + } + } + continue; + } + // Fill _ConvexFace::_simplexTestEdges. These _LayerEdge's are used to detect // prism distortion. map< TGeomID, _EdgesOnShape* >::iterator id2eos = convFace._subIdToEOS.find( faceID ); @@ -3300,7 +3350,11 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, // find _normal if ( useGeometry ) { - if ( onShrinkShape ) // one of faces the node is on has no layers + bool fromVonF = ( eos.ShapeType() == TopAbs_VERTEX && + eos.SWOLType() == TopAbs_FACE && + totalNbFaces > 1 ); + + if ( onShrinkShape && !fromVonF ) // one of faces the node is on has no layers { if ( eos.SWOLType() == TopAbs_EDGE ) { @@ -3320,12 +3374,15 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, node, helper, normOK); } } - else // layers are on all FACEs of SOLID the node is on + else // layers are on all FACEs of SOLID the node is on (or fromVonF) { + if ( fromVonF ) + face2Norm[ totalNbFaces++ ].first = TopoDS::Face( eos._sWOL ); + int nbOkNorms = 0; - for ( int iF = 0; iF < totalNbFaces; ++iF ) + for ( int iF = totalNbFaces - 1; iF >= 0; --iF ) { - F = TopoDS::Face( face2Norm[ iF ].first ); + F = face2Norm[ iF ].first; geomNorm = getFaceNormal( node, F, helper, normOK ); if ( !normOK ) continue; nbOkNorms++; @@ -3338,11 +3395,16 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, if ( nbOkNorms == 0 ) return error(SMESH_Comment("Can't get normal to node ") << node->GetID(), data._index); + if ( totalNbFaces >= 3 ) + { + edge._normal = getNormalByOffset( &edge, face2Norm, totalNbFaces, fromVonF ); + } + if ( edge._normal.Modulus() < 1e-3 && nbOkNorms > 1 ) { // opposite normals, re-get normals at shifted positions (IPAL 52426) edge._normal.SetCoord( 0,0,0 ); - for ( int iF = 0; iF < totalNbFaces; ++iF ) + for ( int iF = 0; iF < totalNbFaces - fromVonF; ++iF ) { const TopoDS_Face& F = face2Norm[iF].first; geomNorm = getFaceNormal( node, F, helper, normOK, /*shiftInside=*/true ); @@ -3353,11 +3415,6 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, edge._normal += face2Norm[ iF ].second; } } - - if ( totalNbFaces >= 3 ) - { - edge._normal = getNormalByOffset( &edge, face2Norm, totalNbFaces ); - } } } else // !useGeometry - get _normal using surrounding mesh faces @@ -3397,7 +3454,8 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, break; } case TopAbs_VERTEX: { - if ( eos.SWOLType() != TopAbs_FACE ) { // else _cosin is set by getFaceDir() + //if ( eos.SWOLType() != TopAbs_FACE ) // else _cosin is set by getFaceDir() + { TopoDS_Vertex V = TopoDS::Vertex( eos._shape ); gp_Vec inFaceDir = getFaceDir( F, V, node, helper, normOK ); double angle = inFaceDir.Angle( edge._normal ); // [0,PI] @@ -3410,7 +3468,7 @@ bool _ViscousBuilder::setEdgeData(_LayerEdge& edge, if ( normOK ) { double angle = inFaceDir.Angle( edge._normal ); double cosin = Cos( angle ); - if ( Abs( cosin ) > edge._cosin ) + if ( Abs( cosin ) > Abs( edge._cosin )) edge._cosin = cosin; } } @@ -3733,7 +3791,8 @@ gp_XYZ _ViscousBuilder::getWeigthedNormal( const _LayerEdge* edge ) gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge, std::pair< TopoDS_Face, gp_XYZ > f2Normal[], - int nbFaces ) + int nbFaces, + bool lastNoOffset) { SMESH_TNodeXYZ p0 = edge->_nodes[0]; @@ -3748,11 +3807,16 @@ gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge // prepare _OffsetPlane's vector< _OffsetPlane > pln( nbFaces ); - for ( int i = 0; i < nbFaces; ++i ) + for ( int i = 0; i < nbFaces - lastNoOffset; ++i ) { pln[i]._faceIndex = i; pln[i]._plane = gp_Pln( p0 + f2Normal[i].second, f2Normal[i].second ); } + if ( lastNoOffset ) + { + pln[ nbFaces - 1 ]._faceIndex = nbFaces - 1; + pln[ nbFaces - 1 ]._plane = gp_Pln( p0, f2Normal[ nbFaces - 1 ].second ); + } // intersect neighboring OffsetPlane's PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( V, *_mesh, TopAbs_EDGE ); @@ -3764,7 +3828,7 @@ gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge (( f1 < 0 ) ? f1 : f2 ) = i; if ( f2 >= 0 ) - pln[ f1 ].ComputeIntersectionLine( pln[ f2 ]); + pln[ f1 ].ComputeIntersectionLine( pln[ f2 ], TopoDS::Edge( *edge ), TopoDS::Vertex( V )); } // get a common point @@ -3773,7 +3837,7 @@ gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge bool isPointFound; for ( int i = 0; i < nbFaces; ++i ) { - commonPnt += pln[ i ].GetCommonPoint( isPointFound ); + commonPnt += pln[ i ].GetCommonPoint( isPointFound, TopoDS::Vertex( V )); nbPoints += isPointFound; } gp_XYZ wgtNorm = getWeigthedNormal( edge ); @@ -3782,13 +3846,15 @@ gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge commonPnt /= nbPoints; resNorm = commonPnt - p0; + if ( lastNoOffset ) + return resNorm; // choose the best among resNorm and wgtNorm resNorm.Normalize(); wgtNorm.Normalize(); double resMinDot = std::numeric_limits::max(); double wgtMinDot = std::numeric_limits::max(); - for ( int i = 0; i < nbFaces; ++i ) + for ( int i = 0; i < nbFaces - lastNoOffset; ++i ) { resMinDot = Min( resMinDot, resNorm * f2Normal[i].second ); wgtMinDot = Min( wgtMinDot, wgtNorm * f2Normal[i].second ); @@ -3808,7 +3874,9 @@ gp_XYZ _ViscousBuilder::getNormalByOffset( _LayerEdge* edge */ //================================================================================ -void _OffsetPlane::ComputeIntersectionLine( _OffsetPlane& pln ) +void _OffsetPlane::ComputeIntersectionLine( _OffsetPlane& pln, + const TopoDS_Edge& E, + const TopoDS_Vertex& V ) { int iNext = bool( _faceIndexNext[0] >= 0 ); _faceIndexNext[ iNext ] = pln._faceIndex; @@ -3832,31 +3900,37 @@ void _OffsetPlane::ComputeIntersectionLine( _OffsetPlane& pln ) else cooMax = 3; } - if ( Abs( lineDir.Coord( cooMax )) < 0.05 ) - return; - gp_Pnt linePos; - // the constants in the 2 plane equations - double d1 = - ( _plane.Axis().Direction().XYZ() * _plane.Location().XYZ() ); - double d2 = - ( pln._plane.Axis().Direction().XYZ() * pln._plane.Location().XYZ() ); - - switch ( cooMax ) { - case 1: - linePos.SetX( 0 ); - linePos.SetY(( d2*n1.Z() - d1*n2.Z()) / lineDir.X() ); - linePos.SetZ(( d1*n2.Y() - d2*n1.Y()) / lineDir.X() ); - break; - case 2: - linePos.SetX(( d1*n2.Z() - d2*n1.Z()) / lineDir.Y() ); - linePos.SetY( 0 ); - linePos.SetZ(( d2*n1.X() - d1*n2.X()) / lineDir.Y() ); - break; - case 3: - linePos.SetX(( d2*n1.Y() - d1*n2.Y()) / lineDir.Z() ); - linePos.SetY(( d1*n2.X() - d2*n1.X()) / lineDir.Z() ); - linePos.SetZ( 0 ); + if ( Abs( lineDir.Coord( cooMax )) < 0.05 ) + { + // parallel planes - intersection is an offset of the common EDGE + gp_Pnt p = BRep_Tool::Pnt( V ); + linePos = 0.5 * (( p.XYZ() + n1 ) + ( p.XYZ() + n2 )); + lineDir = getEdgeDir( E, V ); } + else + { + // the constants in the 2 plane equations + double d1 = - ( _plane.Axis().Direction().XYZ() * _plane.Location().XYZ() ); + double d2 = - ( pln._plane.Axis().Direction().XYZ() * pln._plane.Location().XYZ() ); + switch ( cooMax ) { + case 1: + linePos.SetX( 0 ); + linePos.SetY(( d2*n1.Z() - d1*n2.Z()) / lineDir.X() ); + linePos.SetZ(( d1*n2.Y() - d2*n1.Y()) / lineDir.X() ); + break; + case 2: + linePos.SetX(( d1*n2.Z() - d2*n1.Z()) / lineDir.Y() ); + linePos.SetY( 0 ); + linePos.SetZ(( d2*n1.X() - d1*n2.X()) / lineDir.Y() ); + break; + case 3: + linePos.SetX(( d2*n1.Y() - d1*n2.Y()) / lineDir.Z() ); + linePos.SetY(( d1*n2.X() - d2*n1.X()) / lineDir.Z() ); + linePos.SetZ( 0 ); + } + } gp_Lin& line = _lines[ iNext ]; line.SetDirection( lineDir ); line.SetLocation ( linePos ); @@ -3876,7 +3950,8 @@ void _OffsetPlane::ComputeIntersectionLine( _OffsetPlane& pln ) */ //================================================================================ -gp_XYZ _OffsetPlane::GetCommonPoint(bool& isFound) const +gp_XYZ _OffsetPlane::GetCommonPoint(bool& isFound, + const TopoDS_Vertex & V) const { gp_XYZ p( 0,0,0 ); isFound = false; @@ -3885,13 +3960,22 @@ gp_XYZ _OffsetPlane::GetCommonPoint(bool& isFound) const { gp_Vec lPerp0 = _lines[0].Direction().XYZ() ^ _plane.Axis().Direction().XYZ(); double dot01 = lPerp0 * _lines[1].Direction().XYZ(); - if ( Abs( dot01 ) > std::numeric_limits::min() ) + if ( Abs( dot01 ) > 0.05 ) { gp_Vec l0l1 = _lines[1].Location().XYZ() - _lines[0].Location().XYZ(); double u1 = - ( lPerp0 * l0l1 ) / dot01; p = ( _lines[1].Location().XYZ() + _lines[1].Direction().XYZ() * u1 ); isFound = true; } + else + { + gp_Pnt pV ( BRep_Tool::Pnt( V )); + gp_Vec lv0( _lines[0].Location(), pV ), lv1(_lines[1].Location(), pV ); + double dot0( lv0 * _lines[0].Direction() ), dot1( lv1 * _lines[1].Direction() ); + p += 0.5 * ( _lines[0].Location().XYZ() + _lines[0].Direction().XYZ() * dot0 ); + p += 0.5 * ( _lines[1].Location().XYZ() + _lines[1].Direction().XYZ() * dot1 ); + isFound = true; + } } return p; @@ -4266,6 +4350,8 @@ bool _ViscousBuilder::inflate(_SolidData& data) findCollisionEdges( data, helper ); + limitMaxLenByCurvature( data, helper ); + // limit length of _LayerEdge's around MULTI_NORMAL _LayerEdge's for ( size_t i = 0; i < data._edgesOnShape.size(); ++i ) if ( data._edgesOnShape[i].ShapeType() == TopAbs_VERTEX && @@ -4449,20 +4535,30 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, { // smooth disabled by the user; check validy only if ( !isFace ) continue; + badEdges.clear(); for ( size_t i = 0; i < eos._edges.size(); ++i ) { _LayerEdge* edge = eos._edges[i]; for ( size_t iF = 0; iF < edge->_simplices.size(); ++iF ) if ( !edge->_simplices[iF].IsForward( edge->_nodes[0], edge->_pos.back(), vol )) { - debugMsg( "-- Stop inflation. Bad simplex (" - << " "<< edge->_nodes[0]->GetID() - << " "<< edge->_nodes.back()->GetID() - << " "<< edge->_simplices[iF]._nPrev->GetID() - << " "<< edge->_simplices[iF]._nNext->GetID() << " ) "); - return false; + // debugMsg( "-- Stop inflation. Bad simplex (" + // << " "<< edge->_nodes[0]->GetID() + // << " "<< edge->_nodes.back()->GetID() + // << " "<< edge->_simplices[iF]._nPrev->GetID() + // << " "<< edge->_simplices[iF]._nNext->GetID() << " ) "); + // return false; + badEdges.push_back( edge ); } } + if ( !badEdges.empty() ) + { + eosC1.resize(1); + eosC1[0] = &eos; + int nbBad = invalidateBadSmooth( data, helper, badEdges, eosC1, infStep ); + if ( nbBad > 0 ) + return false; + } continue; // goto the next EDGE or FACE } @@ -4609,7 +4705,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, if (( step % 3 == 1 ) || ( nbBad > 0 && step >= stepLimit / 2 )) for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS ) { - putOnOffsetSurface( *eosC1[ iEOS ], infStep, step, /*moveAll=*/step == 1 ); + putOnOffsetSurface( *eosC1[ iEOS ], infStep, eosC1, step, /*moveAll=*/step == 1 ); } } // smoothing steps @@ -4618,10 +4714,10 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS ) { if ( ! eosC1[ iEOS ]->_eosConcaVer.empty() || nbBad > 0 ) - putOnOffsetSurface( *eosC1[ iEOS ], infStep ); + putOnOffsetSurface( *eosC1[ iEOS ], infStep, eosC1 ); } - if ( !badEdges.empty() ) + //if ( !badEdges.empty() ) { badEdges.clear(); for ( size_t iEOS = 0; iEOS < eosC1.size(); ++iEOS ) @@ -4632,10 +4728,11 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, _LayerEdge* edge = eosC1[ iEOS ]->_edges[i]; edge->CheckNeiborsOnBoundary( & badEdges ); - if ( nbBad > 0 ) + if (( nbBad > 0 ) || + ( edge->Is( _LayerEdge::BLOCKED ) && edge->Is( _LayerEdge::NEAR_BOUNDARY ))) { SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); - const gp_XYZ& prevXYZ = edge->PrevCheckPos(); + gp_XYZ prevXYZ = edge->PrevCheckPos(); for ( size_t j = 0; j < edge->_simplices.size(); ++j ) if ( !edge->_simplices[j].IsForward( &prevXYZ, &tgtXYZ, vol )) { @@ -4677,7 +4774,7 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, _LayerEdge* edge = eos._edges[i]; if ( edge->_nodes.size() < 2 ) continue; SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); - const gp_XYZ& prevXYZ = edge->PrevCheckPos(); + gp_XYZ prevXYZ = edge->PrevCheckPos( &eos ); //const gp_XYZ& prevXYZ = edge->PrevPos(); for ( size_t j = 0; j < edge->_simplices.size(); ++j ) if ( !edge->_simplices[j].IsForward( &prevXYZ, &tgtXYZ, vol )) @@ -4858,16 +4955,16 @@ bool _ViscousBuilder::smoothAndCheck(_SolidData& data, } // loop on eos._edges } // loop on data._edgesOnShape -#ifdef __myDEBUG - if ( closestFace ) + if ( closestFace && le ) { +#ifdef __myDEBUG SMDS_MeshElement::iterator nIt = closestFace->begin_nodes(); cout << "Shortest distance: _LayerEdge nodes: tgt " << le->_nodes.back()->GetID() << " src " << le->_nodes[0]->GetID()<< ", intersection with face (" << (*nIt++)->GetID()<<" "<< (*nIt++)->GetID()<<" "<< (*nIt++)->GetID() << ") distance = " << distToIntersection<< endl; - } #endif + } return true; } @@ -4890,53 +4987,119 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data, dumpFunction(SMESH_Comment("invalidateBadSmooth")<<"_S"<_shapeID<<"_InfStep"<Set( ADDED ); + bool invalidated = false; + if ( edge->Is( TO_INVALIDATE ) && edge->NbSteps() > 1 ) + { + edge->InvalidateStep( edge->NbSteps(), *eos, /*restoreLength=*/true ); + edge->Block( data ); + edge->Set( INVALIDATED ); + edge->Unset( TO_INVALIDATE ); + invalidated = true; + haveInvalidated = true; + } + + // look for _LayerEdge's of bad _simplices + int nbBad = 0; + SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); + gp_XYZ prevXYZ1 = edge->PrevCheckPos( eos ); + //const gp_XYZ& prevXYZ2 = edge->PrevPos(); + for ( size_t j = 0; j < edge->_simplices.size(); ++j ) + { + if (( edge->_simplices[j].IsForward( &prevXYZ1, &tgtXYZ, vol ))/* && + ( &prevXYZ1 == &prevXYZ2 || edge->_simplices[j].IsForward( &prevXYZ2, &tgtXYZ, vol ))*/) + continue; + + bool isBad = true; + _LayerEdge* ee[2] = { 0,0 }; + for ( size_t iN = 0; iN < edge->_neibors.size() && !ee[1] ; ++iN ) + if ( edge->_simplices[j].Includes( edge->_neibors[iN]->_nodes.back() )) + ee[ ee[0] != 0 ] = edge->_neibors[iN]; + + int maxNbSteps = Max( ee[0]->NbSteps(), ee[1]->NbSteps() ); + while ( maxNbSteps > edge->NbSteps() && isBad ) + { + --maxNbSteps; + for ( int iE = 0; iE < 2; ++iE ) + { + if ( ee[ iE ]->NbSteps() > maxNbSteps && + ee[ iE ]->NbSteps() > 1 ) + { + _EdgesOnShape* eos = data.GetShapeEdges( ee[ iE ] ); + ee[ iE ]->InvalidateStep( ee[ iE ]->NbSteps(), *eos, /*restoreLength=*/true ); + ee[ iE ]->Block( data ); + ee[ iE ]->Set( INVALIDATED ); + haveInvalidated = true; + } + } + if (( edge->_simplices[j].IsForward( &prevXYZ1, &tgtXYZ, vol )) /*&& + ( &prevXYZ1 == &prevXYZ2 || edge->_simplices[j].IsForward( &prevXYZ2, &tgtXYZ, vol ))*/) + isBad = false; + } + nbBad += isBad; + if ( !ee[0]->Is( ADDED )) badSmooEdges.push_back( ee[0] ); + if ( !ee[1]->Is( ADDED )) badSmooEdges.push_back( ee[1] ); + ee[0]->Set( ADDED ); + ee[1]->Set( ADDED ); + if ( isBad ) + { + ee[0]->Set( TO_INVALIDATE ); + ee[1]->Set( TO_INVALIDATE ); + } + } + + if ( !invalidated && nbBad > 0 && edge->NbSteps() > 1 ) + { + _EdgesOnShape* eos = data.GetShapeEdges( edge ); + edge->InvalidateStep( edge->NbSteps(), *eos, /*restoreLength=*/true ); + edge->Block( data ); + edge->Set( INVALIDATED ); + edge->Unset( TO_INVALIDATE ); + haveInvalidated = true; + } + } // loop on badSmooEdges + } // while ( haveInvalidated ) + + // re-smooth on analytical EDGEs for ( size_t i = 0; i < badSmooEdges.size(); ++i ) { _LayerEdge* edge = badSmooEdges[i]; - if ( edge->NbSteps() < 2 /*|| edge->Is( _LayerEdge::MARKED )*/) - continue; + if ( !edge->Is( INVALIDATED )) continue; _EdgesOnShape* eos = data.GetShapeEdges( edge ); - edge->InvalidateStep( edge->NbSteps(), *eos, /*restoreLength=*/true ); - edge->Block( data ); - //edge->Set( _LayerEdge::MARKED ); - - // look for _LayerEdge's of bad _simplices - SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); - const gp_XYZ& prevXYZ1 = edge->PrevCheckPos(); - const gp_XYZ& prevXYZ2 = edge->PrevPos(); - for ( size_t j = 0; j < edge->_simplices.size(); ++j ) - { - if (( edge->_simplices[j].IsForward( &prevXYZ1, &tgtXYZ, vol )) && - ( &prevXYZ1 == &prevXYZ2 || edge->_simplices[j].IsForward( &prevXYZ2, &tgtXYZ, vol ))) - continue; - for ( size_t iN = 0; iN < edge->_neibors.size(); ++iN ) - if ( edge->_simplices[j].Includes( edge->_neibors[iN]->_nodes.back() )) - badSmooEdges.push_back( edge->_neibors[iN] ); - } - if ( eos->ShapeType() == TopAbs_VERTEX ) { - // re-smooth on analytical EDGEs PShapeIteratorPtr eIt = helper.GetAncestors( eos->_shape, *_mesh, TopAbs_EDGE ); while ( const TopoDS_Shape* e = eIt->next() ) if ( _EdgesOnShape* eoe = data.GetShapeEdges( *e )) if ( eoe->_edgeSmoother && eoe->_edgeSmoother->isAnalytic() ) { - TopoDS_Face F; Handle(ShapeAnalysis_Surface) surface; - if ( eoe->SWOLType() == TopAbs_FACE ) { - F = TopoDS::Face( eoe->_sWOL ); - surface = helper.GetSurface( F ); - } - eoe->_edgeSmoother->Perform( data, surface, F, helper ); + // TopoDS_Face F; Handle(ShapeAnalysis_Surface) surface; + // if ( eoe->SWOLType() == TopAbs_FACE ) { + // F = TopoDS::Face( eoe->_sWOL ); + // surface = helper.GetSurface( F ); + // } + // eoe->_edgeSmoother->Perform( data, surface, F, helper ); + eoe->_edgeSmoother->_anaCurve.Nullify(); } - } - } // loop on badSmooEdges + } // check result of invalidation @@ -4949,7 +5112,7 @@ int _ViscousBuilder::invalidateBadSmooth( _SolidData& data, if ( !eosC1[ iEOS ]->_sWOL.IsNull() ) continue; _LayerEdge* edge = eosC1[ iEOS ]->_edges[i]; SMESH_TNodeXYZ tgtXYZ = edge->_nodes.back(); - const gp_XYZ& prevXYZ = edge->PrevCheckPos(); + gp_XYZ prevXYZ = edge->PrevCheckPos( eosC1[ iEOS ]); for ( size_t j = 0; j < edge->_simplices.size(); ++j ) if ( !edge->_simplices[j].IsForward( &prevXYZ, &tgtXYZ, vol )) { @@ -4983,7 +5146,7 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& // find offset gp_Pnt tgtP = SMESH_TNodeXYZ( eos._edgeForOffset->_nodes.back() ); - gp_Pnt2d uv = baseSurface->ValueOfUV( tgtP, Precision::Confusion() ); + /*gp_Pnt2d uv=*/baseSurface->ValueOfUV( tgtP, Precision::Confusion() ); double offset = baseSurface->Gap(); eos._offsetSurf.Nullify(); @@ -5013,18 +5176,35 @@ void _ViscousBuilder::makeOffsetSurface( _EdgesOnShape& eos, SMESH_MesherHelper& */ //================================================================================ -void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape& eos, - int infStep, - int smooStep, - bool moveAll ) +void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape& eos, + int infStep, + vector< _EdgesOnShape* >& eosC1, + int smooStep, + bool moveAll ) { - if ( eos._offsetSurf.IsNull() || - eos.ShapeType() != TopAbs_FACE || - eos._edgeForOffset == 0 || - eos._edgeForOffset->Is( _LayerEdge::BLOCKED )) + _EdgesOnShape * eof = & eos; + if ( eos.ShapeType() != TopAbs_FACE ) // eos is a boundary of C1 FACE, look for the FACE eos + { + eof = 0; + for ( size_t i = 0; i < eosC1.size() && !eof; ++i ) + { + if ( eosC1[i]->_offsetSurf.IsNull() || + eosC1[i]->ShapeType() != TopAbs_FACE || + eosC1[i]->_edgeForOffset == 0 || + eosC1[i]->_edgeForOffset->Is( _LayerEdge::BLOCKED )) + continue; + if ( SMESH_MesherHelper::IsSubShape( eos._shape, eosC1[i]->_shape )) + eof = eosC1[i]; + } + } + if ( !eof || + eof->_offsetSurf.IsNull() || + eof->ShapeType() != TopAbs_FACE || + eof->_edgeForOffset == 0 || + eof->_edgeForOffset->Is( _LayerEdge::BLOCKED )) return; - double preci = BRep_Tool::Tolerance( TopoDS::Face( eos._shape )), vol; + double preci = BRep_Tool::Tolerance( TopoDS::Face( eof->_shape )), vol; for ( size_t i = 0; i < eos._edges.size(); ++i ) { _LayerEdge* edge = eos._edges[i]; @@ -5041,12 +5221,12 @@ void _ViscousBuilder::putOnOffsetSurface( _EdgesOnShape& eos, continue; gp_Pnt tgtP = SMESH_TNodeXYZ( edge->_nodes.back() ); - gp_Pnt2d uv = eos._offsetSurf->NextValueOfUV( edge->_curvature->_uv, tgtP, preci ); - if ( eos._offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug + gp_Pnt2d uv = eof->_offsetSurf->NextValueOfUV( edge->_curvature->_uv, tgtP, preci ); + if ( eof->_offsetSurf->Gap() > edge->_len ) continue; // NextValueOfUV() bug edge->_curvature->_uv = uv; - if ( eos._offsetSurf->Gap() < 10 * preci ) continue; // same pos + if ( eof->_offsetSurf->Gap() < 10 * preci ) continue; // same pos - gp_XYZ newP = eos._offsetSurf->Value( uv ).XYZ(); + gp_XYZ newP = eof->_offsetSurf->Value( uv ).XYZ(); gp_XYZ prevP = edge->PrevCheckPos(); bool ok = true; if ( !moveAll ) @@ -5202,22 +5382,27 @@ bool _Smoother1D::smoothAnalyticEdge( _SolidData& data, SMESH_TNodeXYZ p1 ( _eos._edges[iTo-1]->_2neibors->tgtNode(1) ); SMESH_TNodeXYZ pSrc0( _eos._edges[iFrom]->_2neibors->srcNode(0) ); SMESH_TNodeXYZ pSrc1( _eos._edges[iTo-1]->_2neibors->srcNode(1) ); - gp_XYZ newPos; + gp_XYZ newPos, lineDir = pSrc1 - pSrc0; + _LayerEdge* vLE0 = _eos._edges[iFrom]->_2neibors->_edges[0]; + _LayerEdge* vLE1 = _eos._edges[iTo-1]->_2neibors->_edges[1]; + bool shiftOnly = ( vLE0->Is( _LayerEdge::NORMAL_UPDATED ) || + vLE0->Is( _LayerEdge::BLOCKED ) || + vLE1->Is( _LayerEdge::NORMAL_UPDATED ) || + vLE1->Is( _LayerEdge::BLOCKED )); for ( size_t i = iFrom; i < iTo; ++i ) { _LayerEdge* edge = _eos._edges[i]; SMDS_MeshNode* tgtNode = const_cast( edge->_nodes.back() ); newPos = p0 * ( 1. - _leParams[i] ) + p1 * _leParams[i]; - if ( _eos._edges[i]->Is( _LayerEdge::NORMAL_UPDATED )) + if ( shiftOnly || edge->Is( _LayerEdge::NORMAL_UPDATED )) { - gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode ); - gp_XYZ lineDir = pSrc1 - pSrc0; - double shift = ( lineDir * ( newPos - pSrc0 ) - - lineDir * ( curPos - pSrc0 )); + gp_XYZ curPos = SMESH_TNodeXYZ ( tgtNode ); + double shift = ( lineDir * ( newPos - pSrc0 ) - + lineDir * ( curPos - pSrc0 )); newPos = curPos + lineDir * shift / lineDir.SquareModulus(); } - if ( _eos._edges[i]->Is( _LayerEdge::BLOCKED )) + if ( edge->Is( _LayerEdge::BLOCKED )) { SMESH_TNodeXYZ pSrc( edge->_nodes[0] ); double curThick = pSrc.SquareDistance( tgtNode ); @@ -5370,11 +5555,13 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, if ( _offPoints.empty() ) return false; - // move _offPoints to positions along normals of _LayerEdge's + // move _offPoints along normals of _LayerEdge's _LayerEdge* e[2] = { getLEdgeOnV(0), getLEdgeOnV(1) }; - if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) setNormalOnV( 0, helper ); - if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) setNormalOnV( 1, helper ); + if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) + _leOnV[0]._normal = getNormalNormal( e[0]->_normal, _edgeDir[0] ); + if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) + _leOnV[1]._normal = getNormalNormal( e[1]->_normal, _edgeDir[1] ); _leOnV[0]._len = e[0]->_len; _leOnV[1]._len = e[1]->_len; for ( size_t i = 0; i < _offPoints.size(); i++ ) @@ -5386,6 +5573,9 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, gp_XYZ avgNorm = ( e0->_normal * w0 + e1->_normal * w1 ).Normalized(); double avgLen = ( e0->_len * w0 + e1->_len * w1 ); double avgFact = ( e0->_lenFactor * w0 + e1->_lenFactor * w1 ); + if ( e0->Is( _LayerEdge::NORMAL_UPDATED ) || + e1->Is( _LayerEdge::NORMAL_UPDATED )) + avgNorm = getNormalNormal( avgNorm, _offPoints[i]._edgeDir ); _offPoints[i]._xyz += avgNorm * ( avgLen - _offPoints[i]._len ) * avgFact; _offPoints[i]._len = avgLen; @@ -5411,6 +5601,9 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, // project tgt nodes of extreme _LayerEdge's to the offset segments + if ( e[0]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[0] = 0; + if ( e[1]->Is( _LayerEdge::NORMAL_UPDATED )) _iSeg[1] = _offPoints.size()-2; + gp_Pnt pExtreme[2], pProj[2]; for ( int is2nd = 0; is2nd < 2; ++is2nd ) { @@ -5418,26 +5611,26 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, int i = _iSeg[ is2nd ]; int di = is2nd ? -1 : +1; bool projected = false; - double uOnSeg, uOnSegDiff, uOnSegBestDiff = Precision::Infinite(), uOnSegPrevDiff = 0; + double uOnSeg, distMin = Precision::Infinite(), dist, distPrev = 0; int nbWorse = 0; do { gp_Vec v0p( _offPoints[i]._xyz, pExtreme[ is2nd ] ); gp_Vec v01( _offPoints[i]._xyz, _offPoints[i+1]._xyz ); - uOnSeg = ( v0p * v01 ) / v01.SquareMagnitude(); - uOnSegDiff = Abs( uOnSeg - 0.5 ); - projected = ( uOnSegDiff <= 0.5 ); - if ( uOnSegDiff < uOnSegBestDiff ) + uOnSeg = ( v0p * v01 ) / v01.SquareMagnitude(); // param [0,1] along v01 + projected = ( Abs( uOnSeg - 0.5 ) <= 0.5 ); + dist = pExtreme[ is2nd ].SquareDistance( _offPoints[ i + ( uOnSeg > 0.5 )]._xyz ); + if ( dist < distMin || projected ) { _iSeg[ is2nd ] = i; pProj[ is2nd ] = _offPoints[i]._xyz + ( v01 * uOnSeg ).XYZ(); - uOnSegBestDiff = uOnSegDiff; + distMin = dist; } - else if ( uOnSegDiff > uOnSegPrevDiff ) + else if ( dist > distPrev ) { if ( ++nbWorse > 3 ) // avoid projection to the middle of a closed EDGE break; } - uOnSegPrevDiff = uOnSegDiff; + distPrev = dist; i += di; } while ( !projected && @@ -5460,20 +5653,30 @@ bool _Smoother1D::smoothComplexEdge( _SolidData& data, return false; } + // adjust length of extreme LE (test viscous_layers_01/B7) + gp_Vec vDiv0( pExtreme[0], pProj[0] ); + gp_Vec vDiv1( pExtreme[1], pProj[1] ); + double d0 = vDiv0.Magnitude(); + double d1 = vDiv1.Magnitude(); + if ( e[0]->_normal * vDiv0.XYZ() < 0 ) e[0]->_len += d0; + else e[0]->_len -= d0; + if ( e[1]->_normal * vDiv1.XYZ() < 0 ) e[1]->_len += d1; + else e[1]->_len -= d1; + // compute normalized length of the offset segments located between the projections size_t iSeg = 0, nbSeg = _iSeg[1] - _iSeg[0] + 1; vector< double > len( nbSeg + 1 ); len[ iSeg++ ] = 0; - len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz ); + len[ iSeg++ ] = pProj[ 0 ].Distance( _offPoints[ _iSeg[0]+1 ]._xyz )/* * e[0]->_lenFactor*/; for ( size_t i = _iSeg[0]+1; i <= _iSeg[1]; ++i, ++iSeg ) { len[ iSeg ] = len[ iSeg-1 ] + _offPoints[i].Distance( _offPoints[i+1] ); } - len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz ); + len[ nbSeg ] -= pProj[ 1 ].Distance( _offPoints[ _iSeg[1]+1 ]._xyz )/* * e[1]->_lenFactor*/; - double d0 = pProj[0].Distance( pExtreme[0]); - double d1 = pProj[1].Distance( pExtreme[1]); + // d0 *= e[0]->_lenFactor; + // d1 *= e[1]->_lenFactor; double fullLen = len.back() - d0 - d1; for ( iSeg = 0; iSeg < len.size(); ++iSeg ) len[iSeg] = ( len[iSeg] - d0 ) / fullLen; @@ -5533,64 +5736,24 @@ void _Smoother1D::prepare(_SolidData& data) // sort _LayerEdge's by position on the EDGE data.SortOnEdge( E, _eos._edges ); - SMESH_MesherHelper& helper = data.GetHelper(); - // compute normalized param of _eos._edges on EDGE _leParams.resize( _eos._edges.size() + 1 ); { - double curLen, prevLen = _leParams[0] = 1.0; + double curLen; gp_Pnt pPrev = SMESH_TNodeXYZ( getLEdgeOnV( 0 )->_nodes[0] ); _leParams[0] = 0; for ( size_t i = 0; i < _eos._edges.size(); ++i ) { - gp_Pnt p = SMESH_TNodeXYZ( _eos._edges[i]->_nodes[0] ); - //curLen = prevLen * _eos._edges[i]->_2neibors->_wgt[1] / _eos._edges[i]->_2neibors->_wgt[0]; - curLen = p.Distance( pPrev ); + gp_Pnt p = SMESH_TNodeXYZ( _eos._edges[i]->_nodes[0] ); + curLen = p.Distance( pPrev ); _leParams[i+1] = _leParams[i] + curLen; - prevLen = curLen; - pPrev = p; + pPrev = p; } double fullLen = _leParams.back() + pPrev.Distance( SMESH_TNodeXYZ( getLEdgeOnV(1)->_nodes[0])); for ( size_t i = 0; i < _leParams.size()-1; ++i ) _leParams[i] = _leParams[i+1] / fullLen; } - // find intersection of neighbor _LayerEdge's to limit _maxLen - // according to EDGE curvature (IPAL52648) - _LayerEdge* e0 = _eos._edges[0]; - for ( size_t i = 1; i < _eos._edges.size(); ++i ) - { - _LayerEdge* ei = _eos._edges[i]; - gp_XYZ plnNorm = e0->_normal ^ ei->_normal; - gp_XYZ perp0 = e0->_normal ^ plnNorm; - double dot0i = perp0 * ei->_normal; - if ( Abs( dot0i ) > std::numeric_limits::min() ) - { - SMESH_TNodeXYZ srci( ei->_nodes[0] ), src0( e0->_nodes[0] ); - double ui = ( perp0 * ( src0 - srci )) / dot0i; - if ( ui > 0 ) - { - ei->_maxLen = Min( ei->_maxLen, 0.75 * ui / ei->_lenFactor ); - if ( ei->_maxLen < ei->_len ) - { - ei->InvalidateStep( ei->NbSteps(), _eos, /*restoreLength=*/true ); - ei->SetNewLength( ei->_maxLen, _eos, helper ); - ei->Block( data ); - } - gp_Pnt pi = srci + ei->_normal * ui; - double u0 = pi.Distance( src0 ); - e0->_maxLen = Min( e0->_maxLen, 0.75 * u0 / e0->_lenFactor ); - if ( e0->_maxLen < e0->_len ) - { - e0->InvalidateStep( e0->NbSteps(), _eos, /*restoreLength=*/true ); - e0->SetNewLength( e0->_maxLen, _eos, helper ); - e0->Block( data ); - } - } - } - e0 = ei; - } - if ( isAnalytic() ) return; @@ -5605,15 +5768,16 @@ void _Smoother1D::prepare(_SolidData& data) return; } - const double edgeLen = SMESH_Algo::EdgeLength( E ); - const double u0 = c3dAdaptor.FirstParameter(); + const double u0 = c3dAdaptor.FirstParameter(); + gp_Pnt p; gp_Vec tangent; _offPoints.resize( discret.NbPoints() ); for ( size_t i = 0; i < _offPoints.size(); i++ ) { - _offPoints[i]._xyz = discret.Value( i+1 ).XYZ(); - // use OffPnt::_len to TEMPORARY store normalized param of an offset point double u = discret.Parameter( i+1 ); - _offPoints[i]._len = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / edgeLen; + c3dAdaptor.D1( u, p, tangent ); + _offPoints[i]._xyz = p.XYZ(); + _offPoints[i]._edgeDir = tangent.XYZ(); + _offPoints[i]._param = GCPnts_AbscissaPoint::Length( c3dAdaptor, u0, u ) / _curveLen; } _LayerEdge* leOnV[2] = { getLEdgeOnV(0), getLEdgeOnV(1) }; @@ -5631,7 +5795,7 @@ void _Smoother1D::prepare(_SolidData& data) { // find _LayerEdge's located before and after an offset point // (_eos._edges[ iLE ] is next after ePrev) - while ( iLE < _eos._edges.size() && _offPoints[i]._len > _leParams[ iLE ] ) + while ( iLE < _eos._edges.size() && _offPoints[i]._param > _leParams[ iLE ] ) ePrev = _eos._edges[ iLE++ ]; eNext = ePrev->_2neibors->_edges[1]; @@ -5641,27 +5805,25 @@ void _Smoother1D::prepare(_SolidData& data) _offPoints[i]._2edges.set( ePrev, eNext, 1-r, r ); } - int iLBO = _offPoints.size() - 2; // last but one - _offPoints[iLBO]._2edges._edges[1] = & _leOnV[1]; + // replace _LayerEdge's on VERTEX by _leOnV in _offPoints._2edges + for ( size_t i = 0; i < _offPoints.size(); i++ ) + if ( _offPoints[i]._2edges._edges[0] == leOnV[0] ) + _offPoints[i]._2edges._edges[0] = & _leOnV[0]; + else break; + for ( size_t i = _offPoints.size()-1; i > 0; i-- ) + if ( _offPoints[i]._2edges._edges[1] == leOnV[1] ) + _offPoints[i]._2edges._edges[1] = & _leOnV[1]; + else break; - // { - // TopoDS_Face face[2]; // FACEs sharing the EDGE - // PShapeIteratorPtr fIt = helper.GetAncestors( _eos._shape, *helper.GetMesh(), TopAbs_FACE ); - // while ( const TopoDS_Shape* F = fIt->next() ) - // { - // TGeomID fID = helper.GetMeshDS()->ShapeToIndex( *F ); - // if ( ! data._ignoreFaceIds.count( fID )) - // face[ !face[0].IsNull() ] = *F; - // } - // if ( face[0].IsNull() ) return; - // if ( face[1].IsNull() ) face[1] = face[0]; - // } + // set _normal of _leOnV[0] and _leOnV[1] to be normal to the EDGE + int iLBO = _offPoints.size() - 2; // last but one - // set _normal of _leOnV[0] and _leOnV[1] to be normal to the EDGE + _edgeDir[0] = getEdgeDir( E, leOnV[0]->_nodes[0], data.GetHelper() ); + _edgeDir[1] = getEdgeDir( E, leOnV[1]->_nodes[0], data.GetHelper() ); - setNormalOnV( 0, data.GetHelper() ); - setNormalOnV( 1, data.GetHelper() ); + _leOnV[ 0 ]._normal = getNormalNormal( leOnV[0]->_normal, _edgeDir[0] ); + _leOnV[ 1 ]._normal = getNormalNormal( leOnV[1]->_normal, _edgeDir[1] ); _leOnV[ 0 ]._len = 0; _leOnV[ 1 ]._len = 0; _leOnV[ 0 ]._lenFactor = _offPoints[1 ]._2edges._edges[1]->_lenFactor; @@ -5699,18 +5861,14 @@ void _Smoother1D::prepare(_SolidData& data) */ //================================================================================ -void _Smoother1D::setNormalOnV( const bool is2nd, - SMESH_MesherHelper& helper) +gp_XYZ _Smoother1D::getNormalNormal( const gp_XYZ & normal, + const gp_XYZ& edgeDir) { - _LayerEdge* leOnV = getLEdgeOnV( is2nd ); - const TopoDS_Edge& E = TopoDS::Edge( _eos._shape ); - TopoDS_Shape V = helper.GetSubShapeByNode( leOnV->_nodes[0], helper.GetMeshDS() ); - gp_XYZ eDir = getEdgeDir( E, TopoDS::Vertex( V )); - gp_XYZ cross = leOnV->_normal ^ eDir; - gp_XYZ norm = eDir ^ cross; - double size = norm.Modulus(); + gp_XYZ cross = normal ^ edgeDir; + gp_XYZ norm = edgeDir ^ cross; + double size = norm.Modulus(); - _leOnV[ is2nd ]._normal = norm / size; + return norm / size; } //================================================================================ @@ -5960,6 +6118,94 @@ void _SolidData::AddShapesToSmooth( const set< _EdgesOnShape* >& eosToSmooth, } } +//================================================================================ +/*! + * \brief Limit _LayerEdge::_maxLen according to local curvature + */ +//================================================================================ + +void _ViscousBuilder::limitMaxLenByCurvature( _SolidData& data, SMESH_MesherHelper& helper ) +{ + // find intersection of neighbor _LayerEdge's to limit _maxLen + // according to local curvature (IPAL52648) + + // This method must be called after findCollisionEdges() where _LayerEdge's + // get _lenFactor initialized in the case of eos._hyp.IsOffsetMethod() + + for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) + { + _EdgesOnShape& eosI = data._edgesOnShape[iS]; + if ( eosI._edges.empty() ) continue; + if ( !eosI._hyp.ToSmooth() ) + { + for ( size_t i = 0; i < eosI._edges.size(); ++i ) + { + _LayerEdge* eI = eosI._edges[i]; + for ( size_t iN = 0; iN < eI->_neibors.size(); ++iN ) + { + _LayerEdge* eN = eI->_neibors[iN]; + if ( eI->_nodes[0]->GetID() < eN->_nodes[0]->GetID() ) // treat this pair once + { + _EdgesOnShape* eosN = data.GetShapeEdges( eN ); + limitMaxLenByCurvature( eI, eN, eosI, *eosN, helper ); + } + } + } + } + else if ( eosI.ShapeType() == TopAbs_EDGE ) + { + const TopoDS_Edge& E = TopoDS::Edge( eosI._shape ); + if ( SMESH_Algo::IsStraight( E, /*degenResult=*/true )) continue; + + _LayerEdge* e0 = eosI._edges[0]; + for ( size_t i = 1; i < eosI._edges.size(); ++i ) + { + _LayerEdge* eI = eosI._edges[i]; + limitMaxLenByCurvature( eI, e0, eosI, eosI, helper ); + e0 = eI; + } + } + } +} + +//================================================================================ +/*! + * \brief Limit _LayerEdge::_maxLen according to local curvature + */ +//================================================================================ + +void _ViscousBuilder::limitMaxLenByCurvature( _LayerEdge* e1, + _LayerEdge* e2, + _EdgesOnShape& eos1, + _EdgesOnShape& eos2, + SMESH_MesherHelper& helper ) +{ + gp_XYZ plnNorm = e1->_normal ^ e2->_normal; + double norSize = plnNorm.SquareModulus(); + if ( norSize < std::numeric_limits::min() ) + return; // parallel normals + + // find closest points of skew _LayerEdge's + SMESH_TNodeXYZ src1( e1->_nodes[0] ), src2( e2->_nodes[0] ); + gp_XYZ dir12 = src2 - src1; + gp_XYZ perp1 = e1->_normal ^ plnNorm; + gp_XYZ perp2 = e2->_normal ^ plnNorm; + double dot1 = perp2 * e1->_normal; + double dot2 = perp1 * e2->_normal; + double u1 = ( perp2 * dir12 ) / dot1; + double u2 = - ( perp1 * dir12 ) / dot2; + if ( u1 > 0 && u2 > 0 ) + { + double ovl = ( u1 * e1->_normal * dir12 - + u2 * e2->_normal * dir12 ) / dir12.SquareModulus(); + if ( ovl > theSmoothThickToElemSizeRatio ) + { + e1->_maxLen = Min( e1->_maxLen, 0.75 * u1 / e1->_lenFactor ); + e2->_maxLen = Min( e2->_maxLen, 0.75 * u2 / e2->_lenFactor ); + } + } +} + //================================================================================ /*! * \brief Fill data._collisionEdges @@ -6038,10 +6284,10 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& SMESHUtils::Deleter searcher ( SMESH_MeshAlgos::GetElementSearcher( *getMeshDS(), fIt )); - double dist1, dist2, segLen, eps; + double dist1, dist2, segLen, eps = 0.5; _CollisionEdges collEdges; vector< const SMDS_MeshElement* > suspectFaces; - const double angle30 = Cos( 30. * M_PI / 180. ); + const double angle45 = Cos( 45. * M_PI / 180. ); for ( size_t iS = 0; iS < data._edgesOnShape.size(); ++iS ) { @@ -6070,9 +6316,9 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& // find intersecting _LayerEdge's for ( size_t i = 0; i < eos._edges.size(); ++i ) { + if ( eos._edges[i]->Is( _LayerEdge::MULTI_NORMAL )) continue; _LayerEdge* edge = eos._edges[i]; gp_Ax1 lastSegment = edge->LastSegment( segLen, eos ); - eps = 0.5 * edge->_len; segLen *= 1.2; gp_Vec eSegDir0, eSegDir1; @@ -6083,7 +6329,7 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& eSegDir1 = SMESH_TNodeXYZ( edge->_2neibors->srcNode(1) ) - eP; } suspectFaces.clear(); - searcher->GetElementsInSphere( SMESH_TNodeXYZ( edge->_nodes.back()), edge->_len, + searcher->GetElementsInSphere( SMESH_TNodeXYZ( edge->_nodes.back()), edge->_len * 2, SMDSAbs_Face, suspectFaces ); collEdges._intEdges.clear(); for ( size_t j = 0 ; j < suspectFaces.size(); ++j ) @@ -6112,10 +6358,10 @@ void _ViscousBuilder::findCollisionEdges( _SolidData& data, SMESH_MesherHelper& { // skip perpendicular EDGEs gp_Vec fSegDir = SMESH_TNodeXYZ( f->_nn[0] ) - SMESH_TNodeXYZ( f->_nn[3] ); - bool isParallel = ( isLessAngle( eSegDir0, fSegDir, angle30 ) || - isLessAngle( eSegDir1, fSegDir, angle30 ) || - isLessAngle( eSegDir0, fSegDir.Reversed(), angle30 ) || - isLessAngle( eSegDir1, fSegDir.Reversed(), angle30 )); + bool isParallel = ( isLessAngle( eSegDir0, fSegDir, angle45 ) || + isLessAngle( eSegDir1, fSegDir, angle45 ) || + isLessAngle( eSegDir0, fSegDir.Reversed(), angle45 ) || + isLessAngle( eSegDir1, fSegDir.Reversed(), angle45 )); if ( !isParallel ) continue; } @@ -6187,7 +6433,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, set< _EdgesOnShape* > shapesToSmooth, edgesNoAnaSmooth; - double segLen, dist1, dist2; + double segLen, dist1, dist2, dist; vector< pair< _LayerEdge*, double > > intEdgesDist; _TmpMeshFaceOnEdge quad( &zeroEdge, &zeroEdge, 0 ); @@ -6199,19 +6445,20 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, { _CollisionEdges& ce = data._collisionEdges[iE]; _LayerEdge* edge1 = ce._edge; - if ( !edge1 || edge1->Is( _LayerEdge::BLOCKED )) continue; + if ( !edge1 /*|| edge1->Is( _LayerEdge::BLOCKED )*/) continue; _EdgesOnShape* eos1 = data.GetShapeEdges( edge1 ); if ( !eos1 ) continue; // detect intersections gp_Ax1 lastSeg = edge1->LastSegment( segLen, *eos1 ); - double testLen = 1.5 * edge1->_maxLen; //2 + edge1->_len * edge1->_lenFactor; - double eps = 0.5 * edge1->_len; + double testLen = 1.5 * edge1->_maxLen * edge1->_lenFactor; + double eps = 0.5; intEdgesDist.clear(); double minIntDist = Precision::Infinite(); for ( size_t i = 0; i < ce._intEdges.size(); i += 2 ) { - if ( ce._intEdges[i ]->Is( _LayerEdge::BLOCKED ) || + if ( edge1->Is( _LayerEdge::BLOCKED ) && + ce._intEdges[i ]->Is( _LayerEdge::BLOCKED ) && ce._intEdges[i+1]->Is( _LayerEdge::BLOCKED )) continue; double dot = edge1->_normal * quad.GetDir( ce._intEdges[i], ce._intEdges[i+1] ); @@ -6221,16 +6468,18 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, gp_XYZ pLast0 = pSrc0 + ( pTgt0 - pSrc0 ) * fact; gp_XYZ pLast1 = pSrc1 + ( pTgt1 - pSrc1 ) * fact; dist1 = dist2 = Precision::Infinite(); - if ( !edge1->SegTriaInter( lastSeg, pSrc0, pTgt0, pSrc1, dist1, eps ) && - !edge1->SegTriaInter( lastSeg, pSrc1, pTgt1, pTgt0, dist2, eps )) - continue; - if (( dist1 > testLen || dist1 < 0 ) && - ( dist2 > testLen || dist2 < 0 )) + if ( !edge1->SegTriaInter( lastSeg, pSrc0, pLast0, pSrc1, dist1, eps ) && + !edge1->SegTriaInter( lastSeg, pSrc1, pLast1, pLast0, dist2, eps )) continue; - + dist = dist1; + if ( dist > testLen || dist <= 0 ) + { + dist = dist2; + if ( dist > testLen || dist <= 0 ) + continue; + } // choose a closest edge - gp_Pnt intP( lastSeg.Location().XYZ() + - lastSeg.Direction().XYZ() * ( Min( dist1, dist2 ) + segLen )); + gp_Pnt intP( lastSeg.Location().XYZ() + lastSeg.Direction().XYZ() * ( dist + segLen )); double d1 = intP.SquareDistance( pSrc0 ); double d2 = intP.SquareDistance( pSrc1 ); int iClose = i + ( d2 < d1 ); @@ -6249,15 +6498,14 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, ( d1 < d2 ? edgeJ : edge2 )->Set( _LayerEdge::MARKED ); } } - intEdgesDist.push_back( make_pair( edge2, Min( dist1, dist2 ))); + intEdgesDist.push_back( make_pair( edge2, dist )); // if ( Abs( d2 - d1 ) / Max( d2, d1 ) < 0.5 ) // { // iClose = i + !( d2 < d1 ); // intEdges.push_back( ce._intEdges[iClose] ); // ce._intEdges[iClose]->Unset( _LayerEdge::MARKED ); // } - minIntDist = Min( edge1->_len * edge1->_lenFactor - segLen + dist1, minIntDist ); - minIntDist = Min( edge1->_len * edge1->_lenFactor - segLen + dist2, minIntDist ); + minIntDist = Min( edge1->_len * edge1->_lenFactor - segLen + dist, minIntDist ); } //ce._edge = 0; @@ -6267,6 +6515,8 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, { _LayerEdge* edge2 = intEdgesDist[i].first; double distWgt = edge1->_len / intEdgesDist[i].second; + // if ( edge1->Is( _LayerEdge::BLOCKED ) && + // edge2->Is( _LayerEdge::BLOCKED )) continue; if ( edge2->Is( _LayerEdge::MARKED )) continue; edge2->Set( _LayerEdge::MARKED ); @@ -6324,6 +6574,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, for ( e2neIt = edge2newEdge.begin(); e2neIt != edge2newEdge.end(); ++e2neIt ) { _LayerEdge* edge = e2neIt->first; + if ( edge->Is( _LayerEdge::BLOCKED )) continue; _LayerEdge& newEdge = e2neIt->second; _EdgesOnShape* eos = data.GetShapeEdges( edge ); @@ -6394,7 +6645,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, edge1->SetDataByNeighbors( n1, n2, *eos1, helper ); } - if ( !edge1->_2neibors ) + if ( !edge1->_2neibors || !eos1->_sWOL.IsNull() ) continue; for ( int j = 0; j < 2; ++j ) // loop on 2 neighbors { @@ -6418,7 +6669,7 @@ bool _ViscousBuilder::updateNormals( _SolidData& data, if ( nextEdge == prevEdge ) nextEdge = neighbor->_2neibors->_edges[ ++iNext ]; } - double r = double(step-1)/nbSteps; + double r = double(step-1)/nbSteps/(iter+1); if ( !nextEdge->_2neibors ) r = Min( r, 0.5 ); @@ -6482,14 +6733,16 @@ bool _ViscousBuilder::isNewNormalOk( _SolidData& data, newMinDot = Min( newNormal * normFace, newMinDot ); curMinDot = Min( edge._normal * normFace, curMinDot ); } + bool ok = true; if ( newMinDot < 0.5 ) { - return ( newMinDot >= curMinDot * 0.9 ); + ok = ( newMinDot >= curMinDot * 0.9 ); //return ( newMinDot >= ( curMinDot * ( 0.8 + 0.1 * edge.NbSteps() ))); // double initMinDot2 = 1. - edge._cosin * edge._cosin; // return ( newMinDot * newMinDot ) >= ( 0.8 * initMinDot2 ); } - return true; + + return ok; } //================================================================================ @@ -6572,6 +6825,7 @@ void _ViscousBuilder::updateNormalsOfC1Vertices( _SolidData& data ) oppV = SMESH_MesherHelper::IthVertex( 1, e ); _EdgesOnShape* eovOpp = data.GetShapeEdges( oppV ); if ( !eovOpp || eovOpp->_edges.empty() ) continue; + if ( eov._edges[0]->Is( _LayerEdge::BLOCKED )) continue; double curThickOpp = eovOpp->_edges[0]->_len * eovOpp->_edges[0]->_lenFactor; if ( curThickOpp + curThick < eLen ) @@ -7168,6 +7422,28 @@ bool _LayerEdge::FindIntersection( SMESH_ElementSearcher& searcher, return segmentIntersected; } +//================================================================================ +/*! + * \brief Returns a point used to check orientation of _simplices + */ +//================================================================================ + +gp_XYZ _LayerEdge::PrevCheckPos( _EdgesOnShape* eos ) const +{ + size_t i = Is( NORMAL_UPDATED ) ? _pos.size()-2 : 0; + + if ( !eos || eos->_sWOL.IsNull() ) + return _pos[ i ]; + + if ( eos->SWOLType() == TopAbs_EDGE ) + { + return BRepAdaptor_Curve( TopoDS::Edge( eos->_sWOL )).Value( _pos[i].X() ).XYZ(); + } + //else // TopAbs_FACE + + return BRepAdaptor_Surface( TopoDS::Face( eos->_sWOL )).Value(_pos[i].X(), _pos[i].Y() ).XYZ(); +} + //================================================================================ /*! * \brief Returns size and direction of the last segment @@ -7270,7 +7546,7 @@ bool _LayerEdge::SegTriaInter( const gp_Ax1& lastSegment, const gp_Dir& dir = lastSegment.Direction(); /* calculate distance from vert0 to ray origin */ - gp_XYZ tvec = orig.XYZ() - vert0; + //gp_XYZ tvec = orig.XYZ() - vert0; //if ( tvec * dir > EPSILON ) // intersected face is at back side of the temporary face this _LayerEdge belongs to @@ -7289,6 +7565,9 @@ bool _LayerEdge::SegTriaInter( const gp_Ax1& lastSegment, if ( det > -ANGL_EPSILON && det < ANGL_EPSILON ) return false; + /* calculate distance from vert0 to ray origin */ + gp_XYZ tvec = orig.XYZ() - vert0; + /* calculate U parameter and test bounds */ double u = ( tvec * pvec ) / det; //if (u < 0.0 || u > 1.0) @@ -7577,7 +7856,9 @@ int _LayerEdge::CheckNeiborsOnBoundary( vector< _LayerEdge* >* badNeibors, bool if ( eN->_nodes[0]->getshapeId() == _nodes[0]->getshapeId() ) continue; if ( needSmooth ) - *needSmooth |= ( eN->Is( _LayerEdge::BLOCKED ) || eN->Is( _LayerEdge::NORMAL_UPDATED )); + *needSmooth |= ( eN->Is( _LayerEdge::BLOCKED ) || + eN->Is( _LayerEdge::NORMAL_UPDATED ) || + eN->_pos.size() != _pos.size() ); SMESH_TNodeXYZ curPosN ( eN->_nodes.back() ); SMESH_TNodeXYZ prevPosN( eN->_nodes[0] ); @@ -7623,7 +7904,7 @@ int _LayerEdge::Smooth(const int step, bool findBest, vector< _LayerEdge* >& toS findBest = true; const gp_XYZ& curPos = _pos.back(); - const gp_XYZ& prevPos = PrevCheckPos(); + const gp_XYZ& prevPos = _pos[0]; //PrevPos(); // quality metrics (orientation) of tetras around _tgtNode int nbOkBefore = 0; @@ -7767,7 +8048,7 @@ int _LayerEdge::Smooth(const int step, const bool isConcaveFace, bool findBest ) return 0; // not inflated const gp_XYZ& curPos = _pos.back(); - const gp_XYZ& prevPos = PrevCheckPos(); + const gp_XYZ& prevPos = _pos[0]; //PrevCheckPos(); // quality metrics (orientation) of tetras around _tgtNode int nbOkBefore = 0; @@ -8584,13 +8865,14 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe // find point of intersection of the face plane located at baryCenter // and _normal located at newXYZ - double d = -( faceNorm.XYZ() * baryCenter ); // d of plane equation ax+by+cz+d=0 - double dot = ( faceNorm.XYZ() * _normal ); + double d = -( faceNorm.XYZ() * baryCenter ); // d of plane equation ax+by+cz+d=0 + double dot = ( faceNorm.XYZ() * _normal ); if ( dot < std::numeric_limits::min() ) dot = lenDelta * 1e-3; double step = -( faceNorm.XYZ() * newXYZ + d ) / dot; newXYZ += step * _normal; } + _lenFactor = _normal * ( newXYZ - oldXYZ ) / lenDelta; // _lenFactor is used in InvalidateStep() } else { @@ -8664,7 +8946,7 @@ void _LayerEdge::SetNewLength( double len, _EdgesOnShape& eos, SMESH_MesherHelpe void _LayerEdge::Block( _SolidData& data ) { - if ( Is( BLOCKED )) return; + //if ( Is( BLOCKED )) return; Set( BLOCKED ); _maxLen = _len; @@ -8680,8 +8962,7 @@ void _LayerEdge::Block( _SolidData& data ) for ( size_t iN = 0; iN < edge->_neibors.size(); ++iN ) { _LayerEdge* neibor = edge->_neibors[iN]; - if ( neibor->Is( BLOCKED ) || - neibor->_maxLen < edge->_maxLen ) + if ( neibor->_maxLen < edge->_maxLen * 1.01 ) continue; pSrcN = SMESH_TNodeXYZ( neibor->_nodes[0] ); pTgtN = SMESH_TNodeXYZ( neibor->_nodes.back() ); @@ -8704,6 +8985,7 @@ void _LayerEdge::Block( _SolidData& data ) neibor->NbSteps() > 1 ) neibor->InvalidateStep( neibor->NbSteps(), *eos, /*restoreLength=*/true ); neibor->SetNewLength( neibor->_maxLen, *eos, data.GetHelper() ); + //neibor->Block( data ); } queue.push( neibor ); } @@ -8758,17 +9040,12 @@ void _LayerEdge::InvalidateStep( size_t curStep, const _EdgesOnShape& eos, bool //================================================================================ /*! - * \brief Smooth a path formed by _pos of a _LayerEdge smoothed on FACE + * \brief Return index of a _pos distant from _normal */ //================================================================================ -void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) +int _LayerEdge::GetSmoothedPos( const double tol ) { - //return; - if ( /*Is( NORMAL_UPDATED ) ||*/ _pos.size() <= 2 ) - return; - - // find the 1st smoothed _pos int iSmoothed = 0; for ( size_t i = 1; i < _pos.size() && !iSmoothed; ++i ) { @@ -8776,12 +9053,26 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) if ( normDist > tol * tol ) iSmoothed = i; } + return iSmoothed; +} + +//================================================================================ +/*! + * \brief Smooth a path formed by _pos of a _LayerEdge smoothed on FACE + */ +//================================================================================ + +void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) +{ + if ( /*Is( NORMAL_UPDATED ) ||*/ _pos.size() <= 2 ) + return; + + // find the 1st smoothed _pos + int iSmoothed = GetSmoothedPos( tol ); if ( !iSmoothed ) return; - if ( 1 || Is( DISTORTED )) + //if ( 1 || Is( DISTORTED )) { - // if ( segLen[ iSmoothed ] / segLen.back() < 0.5 ) - // return; gp_XYZ normal = _normal; if ( Is( NORMAL_UPDATED )) for ( size_t i = 1; i < _pos.size(); ++i ) @@ -8795,7 +9086,7 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) } } const double r = 0.2; - for ( int iter = 0; iter < 3; ++iter ) + for ( int iter = 0; iter < 50; ++iter ) { double minDot = 1; for ( size_t i = Max( 1, iSmoothed-1-iter ); i < _pos.size()-1; ++i ) @@ -8808,11 +9099,11 @@ void _LayerEdge::SmoothPos( const vector< double >& segLen, const double tol ) const_cast< double& >( segLen[i] ) = newLen; // check angle between normal and (_pos[i+1], _pos[i] ) gp_XYZ posDir = _pos[i+1] - _pos[i]; - double size = posDir.Modulus(); + double size = posDir.SquareModulus(); if ( size > RealSmall() ) - minDot = Min( minDot, ( normal * posDir ) / size ); + minDot = Min( minDot, ( normal * posDir ) * ( normal * posDir ) / size ); } - if ( minDot > 0.5 ) + if ( minDot > 0.5 * 0.5 ) break; } } @@ -8912,11 +9203,10 @@ bool _ViscousBuilder::refine(_SolidData& data) bool useNormal = true; bool usePos = false; bool smoothed = false; - const double preci = 0.1 * edge._len; - if ( eos._toSmooth ) + double preci = 0.1 * edge._len; + if ( eos._toSmooth && edge._pos.size() > 2 ) { - gp_Pnt tgtExpected = edge._pos[0] + edge._normal * edge._len; - smoothed = tgtExpected.SquareDistance( edge._pos.back() ) > preci * preci; + smoothed = edge.GetSmoothedPos( preci ); } if ( smoothed ) { @@ -8935,13 +9225,15 @@ bool _ViscousBuilder::refine(_SolidData& data) } } } - else + else if ( !edge.Is( _LayerEdge::NORMAL_UPDATED )) { +#ifndef __NODES_AT_POS useNormal = usePos = false; edge._pos[1] = edge._pos.back(); edge._pos.resize( 2 ); segLen.resize( 2 ); segLen[ 1 ] = edge._len; +#endif } if ( useNormal && edge.Is( _LayerEdge::NORMAL_UPDATED )) { @@ -8970,11 +9262,12 @@ bool _ViscousBuilder::refine(_SolidData& data) while ( swapped ) { swapped = false; - for ( size_t j = 1; j < edge._pos.size(); ++j ) + for ( size_t j = 1; j < edge._pos.size()-1; ++j ) if ( segLen[j] > segLen.back() ) { segLen.erase( segLen.begin() + j ); edge._pos.erase( edge._pos.begin() + j ); + --j; } else if ( segLen[j] < segLen[j-1] ) { @@ -8985,9 +9278,11 @@ bool _ViscousBuilder::refine(_SolidData& data) } } // smooth a path formed by edge._pos +#ifndef __NODES_AT_POS if (( smoothed ) /*&& ( eos.ShapeType() == TopAbs_FACE || edge.Is( _LayerEdge::SMOOTHED_C1 ))*/) edge.SmoothPos( segLen, preci ); +#endif } else if ( eos._isRegularSWOL ) // usual SWOL { @@ -9008,7 +9303,12 @@ bool _ViscousBuilder::refine(_SolidData& data) const SMDS_MeshNode* tgtNode = edge._nodes.back(); if ( edge._nodes.size() == 2 ) { - edge._nodes.resize( eos._hyp.GetNumberLayers() + 1, 0 ); +#ifdef __NODES_AT_POS + int nbNodes = edge._pos.size(); +#else + int nbNodes = eos._hyp.GetNumberLayers() + 1; +#endif + edge._nodes.resize( nbNodes, 0 ); edge._nodes[1] = 0; edge._nodes.back() = tgtNode; } @@ -9068,7 +9368,9 @@ bool _ViscousBuilder::refine(_SolidData& data) --iPrevSeg; double r = ( segLen[iSeg] - hSum ) / ( segLen[iSeg] - segLen[iPrevSeg] ); gp_Pnt pos = r * edge._pos[iPrevSeg] + (1-r) * edge._pos[iSeg]; - +#ifdef __NODES_AT_POS + pos = edge._pos[ iStep ]; +#endif SMDS_MeshNode*& node = const_cast< SMDS_MeshNode*& >( edge._nodes[ iStep ]); if ( !eos._sWOL.IsNull() ) { diff --git a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx index 32cf255ec..2de6e474c 100644 --- a/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx +++ b/src/StdMeshers/StdMeshers_ViscousLayers2D.cxx @@ -1744,11 +1744,13 @@ bool _ViscousBuilder2D::shrink() } } // loop on FACEs sharing E + // Check if L is an already shrinked seam + if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) + if ( L._wire->Edge( L._edgeInd ).Orientation() == TopAbs_FORWARD ) + continue; // Commented as a case with a seam EDGE (issue 0052461) is hard to support // because SMESH_ProxyMesh can't hold different sub-meshes for two // 2D representations of the seam. But such a case is not a real practice one. - // Check if L is an already shrinked seam - // if ( adjFace.IsNull() && _helper.IsRealSeam( edgeID )) // { // for ( int iL2 = iL1-1; iL2 > -1; --iL2 ) // { @@ -2438,6 +2440,19 @@ bool _ViscousBuilder2D::refine() nodeDataVec.front().param = L._wire->FirstU( L._edgeInd ); nodeDataVec.back() .param = L._wire->LastU ( L._edgeInd ); + if (( nodeDataVec[0].node == nodeDataVec.back().node ) && + ( _helper.GetPeriodicIndex() == 1 || _helper.GetPeriodicIndex() == 2 )) // closed EDGE + { + const int iCoord = _helper.GetPeriodicIndex(); + gp_XY uv = nodeDataVec[0].UV(); + uv.SetCoord( iCoord, L._lEdges[0]._uvOut.Coord( iCoord )); + nodeDataVec[0].SetUV( uv ); + + uv = nodeDataVec.back().UV(); + uv.SetCoord( iCoord, L._lEdges.back()._uvOut.Coord( iCoord )); + nodeDataVec.back().SetUV( uv ); + } + _ProxyMeshOfFace::_EdgeSubMesh* edgeSM = getProxyMesh()->GetEdgeSubMesh( L._wire->EdgeID( L._edgeInd )); edgeSM->SetUVPtStructVec( nodeDataVec ); diff --git a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx index 3390e8b59..823331951 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_ObjectReferenceParamWdg.cxx @@ -55,12 +55,10 @@ //================================================================================ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg -( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection - /*, bool stretch */) +( SUIT_SelectionFilter* f, QWidget* parent, bool multiSelection ) : QWidget( parent ), myMultiSelection( multiSelection ) { myFilter = f; - // myStretchActivated = stretch; init(); } @@ -78,6 +76,7 @@ StdMeshersGUI_ObjectReferenceParamWdg::StdMeshersGUI_ObjectReferenceParamWdg myFilter = new SMESH_TypeFilter( objType ); init(); } + //================================================================================ /*! * \brief Destructor @@ -93,7 +92,6 @@ StdMeshersGUI_ObjectReferenceParamWdg::~StdMeshersGUI_ObjectReferenceParamWdg() } } - //================================================================================ /*! * \brief Create a leayout, initialize fields @@ -128,9 +126,6 @@ void StdMeshersGUI_ObjectReferenceParamWdg::init() aHBox->addWidget( mySelButton ); aHBox->addWidget( myObjNameLineEdit ); - //if (myStretchActivated){ - // aHBox->addStretch(); - //} connect( mySelButton, SIGNAL(clicked()), SLOT(activateSelection())); } diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx index ef3dbe164..03eeb4082 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.cxx @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -70,41 +71,72 @@ //================================================================================ StdMeshersGUI_SubShapeSelectorWdg -::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent, TopAbs_ShapeEnum aSubShType ): +::StdMeshersGUI_SubShapeSelectorWdg( QWidget * parent, + TopAbs_ShapeEnum subShType, + const bool toShowList, + const bool toShowActivateBtn ): QWidget( parent ), myMaxSize( -1 ), myPreviewActor( 0 ) { QPixmap image0( SMESH::GetResourceMgr( mySMESHGUI )->loadPixmap( "SMESH", tr( "ICON_SELECT" ) ) ); - QGridLayout* edgesLayout = new QGridLayout( this ); - edgesLayout->setMargin( MARGIN ); - edgesLayout->setSpacing( SPACING ); - - myListWidget = new QListWidget( this ); - myAddButton = new QPushButton( tr( "SMESH_BUT_ADD" ), this ); - myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this ); + QGridLayout* layout = new QGridLayout( this ); + layout->setMargin( MARGIN ); + layout->setSpacing( SPACING ); + + if ( toShowList ) + { + QPixmap iconSelect (SUIT_Session::session()->resourceMgr()->loadPixmap("SMESH", tr("ICON_SELECT"))); + myListWidget = new QListWidget( this ); + myActivateButton = new QPushButton( iconSelect, "", this ); + myAddButton = new QPushButton( tr( "SMESH_BUT_ADD" ), this ); + myRemoveButton = new QPushButton( tr( "SMESH_BUT_REMOVE" ), this ); + myListWidget->setSelectionMode( QListWidget::ExtendedSelection ); + myListWidget->setMinimumWidth(300); + myListWidget->setWrapping(true); + myActivateButton->setCheckable( true ); + } + else + { + myListWidget = 0; + myActivateButton = 0; + myAddButton = 0; + myRemoveButton = 0; + } myInfoLabel = new QLabel( this ); myPrevButton = new QPushButton( "<<", this ); myNextButton = new QPushButton( ">>", this ); - myListWidget->setSelectionMode( QListWidget::ExtendedSelection ); - - edgesLayout->addWidget(myListWidget, 0, 0, 3, 3); - edgesLayout->addWidget(myAddButton, 0, 3); - edgesLayout->addWidget(myRemoveButton, 1, 3); - edgesLayout->addWidget(myInfoLabel, 3, 0, 1, 3); - edgesLayout->addWidget(myPrevButton, 4, 0); - edgesLayout->addWidget(myNextButton, 4, 2); - - edgesLayout->setRowStretch(2, 5); - edgesLayout->setColumnStretch(1, 5); - myListWidget->setMinimumWidth(300); - myInfoLabel->setMinimumWidth(300); - myInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + if ( myListWidget ) + { + int row = 0; + layout->addWidget(myListWidget, row, 0, 3+toShowActivateBtn, 3); + if ( toShowActivateBtn ) + layout->addWidget( myActivateButton, row++, 3 ); + else + myActivateButton->hide(); + layout->addWidget(myAddButton, row, 3); + layout->addWidget(myRemoveButton, ++row, 3); + ++row; + layout->addWidget(myInfoLabel, ++row, 0, 1, 3); + layout->addWidget(myPrevButton, ++row, 0); + layout->addWidget(myNextButton, row, 2); + + layout->setRowStretch(row-2, 5); + layout->setColumnStretch(1, 5); + } + else // show only Prev and Next buttons + { + layout->addWidget(myInfoLabel, 0, 0, 1, 2); + layout->addWidget(myPrevButton, 1, 0); + layout->addWidget(myNextButton, 1, 1); + } + //myInfoLabel->setMinimumWidth(300); + //myInfoLabel->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); myInfoLabel->setAlignment(Qt::AlignCenter); - mySubShType = aSubShType; + mySubShType = subShType; init(); } @@ -150,30 +182,32 @@ StdMeshersGUI_SubShapeSelectorWdg::~StdMeshersGUI_SubShapeSelectorWdg() void StdMeshersGUI_SubShapeSelectorWdg::init() { myParamValue = ""; - myIsNotCorrected = true; // to dont call the GetCorrectedValue method twice myListOfIDs.clear(); mySelectedIDs.clear(); - myAddButton->setEnabled( false ); - myRemoveButton->setEnabled( false ); - mySMESHGUI = SMESHGUI::GetSMESHGUI(); mySelectionMgr = SMESH::GetSelectionMgr( mySMESHGUI ); - mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); + mySelector = (SMESH::GetViewWindow( mySMESHGUI ))->GetSelector(); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->SetSelectionMode( ActorSelection ); myFilter=0; - //setFilter(); - connect( myAddButton, SIGNAL(clicked()), SLOT(onAdd())); - connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove())); + if ( myListWidget ) + { + myAddButton->setEnabled( false ); + myRemoveButton->setEnabled( false ); + + connect( myListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); + connect( myActivateButton, SIGNAL( toggled(bool) ), SLOT( ActivateSelection(bool))); + connect( myAddButton, SIGNAL(clicked()), SLOT(onAdd())); + connect( myRemoveButton, SIGNAL(clicked()), SLOT(onRemove())); + } connect( myPrevButton, SIGNAL(clicked()), SLOT(onPrevious())); connect( myNextButton, SIGNAL(clicked()), SLOT(onNext())); - + connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(selectionIntoArgument())); - connect( myListWidget, SIGNAL(itemSelectionChanged()), this, SLOT(onListSelectionChanged())); updateState(); } @@ -186,14 +220,17 @@ void StdMeshersGUI_SubShapeSelectorWdg::init() void StdMeshersGUI_SubShapeSelectorWdg::setFilter() { - SalomeApp_Study* study = mySMESHGUI->activeStudy(); - GEOM_TypeFilter* typeFilter = new GEOM_TypeFilter(study, mySubShType, /*isShapeType=*/true ); - GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study); - gpoupFilter->addSubType( mySubShType ); - myGeomFilters.append( typeFilter ); - myGeomFilters.append( gpoupFilter ); - myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR ); - mySelectionMgr->installFilter( myFilter ); + // if ( !myFilter ) + // { + // SalomeApp_Study* study = mySMESHGUI->activeStudy(); + // GEOM_TypeFilter* typeFilter = new GEOM_TypeFilter(study, mySubShType, /*isShapeType=*/true ); + // GEOM_CompoundFilter* gpoupFilter = new GEOM_CompoundFilter(study); + // gpoupFilter->addSubType( mySubShType ); + // myGeomFilters.append( typeFilter ); + // myGeomFilters.append( gpoupFilter ); + // myFilter = new SMESH_LogicalFilter( myGeomFilters, SMESH_LogicalFilter::LO_OR ); + // } + // mySelectionMgr->installFilter( myFilter ); } //================================================================================ @@ -217,6 +254,38 @@ void StdMeshersGUI_SubShapeSelectorWdg::ShowPreview( bool visible) } } +//================================================================================ +/*! + * \brief Connect/disconnect to change of selection + */ +//================================================================================ + +void StdMeshersGUI_SubShapeSelectorWdg::ActivateSelection( bool toActivate ) +{ + // adjust state of myActivateButton + if ( myActivateButton && + myActivateButton != sender() && + myActivateButton->isChecked() != toActivate ) + { + myActivateButton->toggle(); + return; + } + + if ( !mySelectionMgr ) return; + + if ( toActivate ) + { + connect( mySelectionMgr, SIGNAL(currentSelectionChanged()), this, SLOT(selectionIntoArgument())); + } + else + { + disconnect(mySelectionMgr, 0, this, 0 ); + } + + if ( sender() == myActivateButton ) + ShowPreview( toActivate ); +} + //================================================================================ /*! * \brief Clears selected IDs. This is a workaround of a bug that @@ -232,7 +301,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::ClearSelected() //================================================================================= // function : selectionIntoArgument() -// purpose : Called when selection as changed or other case +// purpose : Called when selection has changed or in other cases //================================================================================= void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument() { @@ -291,7 +360,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument() } else if ( aGeomObj->GetType() == 28 /*GEOM_SUBSHAPE*/ || myEntry == IO->getEntry() ) { - GEOMBase::GetShape(aGeomObj, shape); + GEOMBase::GetShape(aGeomObj, shape); if ( !shape.IsNull() && shape.ShapeType() == mySubShType ) { int index = myPreviewActor->GetIndexByShape( shape ); if ( index ) { @@ -313,23 +382,28 @@ void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument() } } // update add button - myAddButton->setEnabled( ( myListWidget->count() < myMaxSize || myMaxSize == -1 ) && - mySelectedIDs.size() > 0 && - ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) ); - - //Connect Selected Ids in viewer and dialog's Ids list - bool signalsBlocked = myListWidget->blockSignals( true ); - myListWidget->clearSelection(); - if ( mySelectedIDs.size() > 0 ) { - for (int i = 0; i < mySelectedIDs.size(); i++) { - QString anID = QString(" %1").arg( mySelectedIDs.at(i) ); - QList anItems = myListWidget->findItems ( anID, Qt::MatchExactly ); - QListWidgetItem* item; - foreach(item, anItems) - item->setSelected(true); + if ( myListWidget ) + { + myAddButton->setEnabled(( myListWidget->count() < myMaxSize || myMaxSize == -1 ) && + ( mySelectedIDs.size() > 0 ) && + ( mySelectedIDs.size() <= myMaxSize || myMaxSize == -1 ) ); + + //Connect Selected Ids in viewer and dialog's Ids list + bool signalsBlocked = myListWidget->blockSignals( true ); + myListWidget->clearSelection(); + if ( mySelectedIDs.size() > 0 ) { + for (int i = 0; i < mySelectedIDs.size(); i++) { + QString anID = QString(" %1").arg( mySelectedIDs.at(i) ); + QList anItems = myListWidget->findItems ( anID, Qt::MatchExactly ); + QListWidgetItem* item; + foreach(item, anItems) + item->setSelected(true); + } } + myListWidget->blockSignals( signalsBlocked ); } - myListWidget->blockSignals( signalsBlocked ); + + emit shapeSelected(); } //================================================================================= @@ -338,7 +412,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::selectionIntoArgument() //================================================================================= void StdMeshersGUI_SubShapeSelectorWdg::onAdd() { - if ( mySelectedIDs.size() < 1 ) + if ( mySelectedIDs.size() < 1 || !myListWidget ) return; myListWidget->blockSignals( true ); @@ -365,7 +439,7 @@ void StdMeshersGUI_SubShapeSelectorWdg::onAdd() //================================================================================= void StdMeshersGUI_SubShapeSelectorWdg::onRemove() { - if ( myListWidget->count() < 1 ) + if ( myListWidget->count() < 1 || !myListWidget ) return; myListWidget->blockSignals( true ); @@ -390,7 +464,8 @@ void StdMeshersGUI_SubShapeSelectorWdg::onPrevious() { if ( myPreviewActor ) { myPreviewActor->previous(); - myListWidget->clearSelection(); + if ( myListWidget ) + myListWidget->clearSelection(); updateButtons(); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->Repaint(); @@ -401,7 +476,8 @@ void StdMeshersGUI_SubShapeSelectorWdg::onNext() { if ( myPreviewActor ) { myPreviewActor->next(); - myListWidget->clearSelection(); + if ( myListWidget ) + myListWidget->clearSelection(); updateButtons(); if ( SVTK_ViewWindow* aViewWindow = SMESH::GetViewWindow( mySMESHGUI )) aViewWindow->Repaint(); @@ -417,7 +493,6 @@ void StdMeshersGUI_SubShapeSelectorWdg::onListSelectionChanged() if ( !myPreviewActor ) return; - //mySelectionMgr->clearSelected(); myPreviewActor->HighlightAll( false ); QList selItems = myListWidget->selectedItems(); QListWidgetItem* anItem; @@ -458,7 +533,6 @@ void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEnt else myMainShape = GetTopoDSByEntry( myMainEntry.c_str() ); updateState(); - myIsNotCorrected = true; } } @@ -468,19 +542,21 @@ void StdMeshersGUI_SubShapeSelectorWdg::SetGeomShapeEntry( const QString& theEnt //================================================================================= void StdMeshersGUI_SubShapeSelectorWdg::updateState() { - bool state = false; - if ( !myGeomShape.IsNull() ) - state = true; - myInfoLabel->setVisible( false ); + bool state = ( !myGeomShape.IsNull() ); + + myInfoLabel ->setVisible( false ); myPrevButton->setVisible( false ); myNextButton->setVisible( false ); - - myListWidget->setEnabled( state ); - myAddButton->setEnabled( mySelectedIDs.size() > 0 ); - - if (state) { + + if ( myListWidget ) + { + myListWidget->setEnabled( state ); + myAddButton->setEnabled( mySelectedIDs.size() > 0 ); + } + if ( state ) { SUIT_OverrideCursor wc; - myPreviewActor = new SMESH_PreviewActorsCollection(); + if ( !myPreviewActor ) + myPreviewActor = new SMESH_PreviewActorsCollection(); myPreviewActor->SetSelector( mySelector ); myPreviewActor->Init( myGeomShape, myMainShape, mySubShType, myEntry.c_str() ); myPreviewActor->SetShown( false ); @@ -555,9 +631,12 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI for ( int i = 0; i < size; i++ ) mySelectedIDs.append( theIds[ i ] ); - myListWidget->blockSignals( true ); - myListWidget->clear(); - myListWidget->blockSignals( false ); + if ( myListWidget ) + { + myListWidget->blockSignals( true ); + myListWidget->clear(); + myListWidget->blockSignals( false ); + } bool isOk = true; if ( myPreviewActor ) @@ -572,7 +651,6 @@ bool StdMeshersGUI_SubShapeSelectorWdg::SetListOfIDs( SMESH::long_array_var theI for ( int i = 0; i < size && isOk; i++ ) isOk = ( theIds[ i ] > 0 && theIds[ i ] <= aMainMap.Extent() ); } - // mySelectedIDs = GetCorrectedListOfIDs( false, &isOk ); onAdd(); return isOk; } diff --git a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h index d8974fd23..577d31041 100644 --- a/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h +++ b/src/StdMeshersGUI/StdMeshersGUI_SubShapeSelectorWdg.h @@ -50,26 +50,23 @@ class STDMESHERSGUI_EXPORT StdMeshersGUI_SubShapeSelectorWdg : public QWidget Q_OBJECT public: - StdMeshersGUI_SubShapeSelectorWdg( QWidget* parent = 0, - TopAbs_ShapeEnum aSubShType = TopAbs_EDGE ); + StdMeshersGUI_SubShapeSelectorWdg( QWidget* parent = 0, + TopAbs_ShapeEnum subShType = TopAbs_EDGE, + const bool toShowList = true, + const bool toShowActivateBtn = false); ~StdMeshersGUI_SubShapeSelectorWdg(); SMESH::long_array_var GetListOfIDs(); bool SetListOfIDs( SMESH::long_array_var ); + const QList& GetSelectedIDs() const { return mySelectedIDs; } void SetGeomShapeEntry( const QString& theEntry, const QString& theMainShapeEntry); - //QString GetGeomShapeEntry() { return myEntry; } - - // void SetMainShapeEntry( const QString& theEntry ); const char* GetMainShapeEntry(); TopoDS_Shape GetGeomShape() { return myGeomShape; } TopoDS_Shape GetMainShape() { return myMainShape; } - // QList GetCorrectedListOfIDs( bool fromSubshapeToMainshape, - // bool* isOK=0); - static GEOM::GEOM_Object_var GetGeomObjectByEntry( const QString& ); static TopoDS_Shape GetTopoDSByEntry( const QString& ); @@ -85,8 +82,12 @@ public: SMESH_PreviewActorsCollection* GetActorCollection() { return myPreviewActor; } void ClearSelected(); +public slots: + void ActivateSelection( bool ); + signals: - void selectionChanged(); + void selectionChanged(); // in the list + void shapeSelected(); // globally private: void updateState(); @@ -116,6 +117,7 @@ private: vtkRenderer* myRenderer; QListWidget* myListWidget; + QPushButton* myActivateButton; QPushButton* myAddButton; QPushButton* myRemoveButton; QLabel* myInfoLabel; @@ -126,7 +128,6 @@ private: QString myParamValue; bool myIsShown; - bool myIsNotCorrected; // for manage possible size of myListOfIDs int myMaxSize; diff --git a/src/StdMeshersGUI/StdMeshers_images.ts b/src/StdMeshersGUI/StdMeshers_images.ts index 0f56903ef..4bfcece28 100644 --- a/src/StdMeshersGUI/StdMeshers_images.ts +++ b/src/StdMeshersGUI/StdMeshers_images.ts @@ -135,6 +135,10 @@ ICON_SMESH_TREE_ALGO_Projection_2D mesh_tree_algo_projection_2d.png + + ICON_SMESH_TREE_ALGO_Projection_1D2D + mesh_tree_algo_projection_2d.png + ICON_SMESH_TREE_ALGO_Projection_3D mesh_tree_hypo_projection_3d.png @@ -251,6 +255,10 @@ ICON_SMESH_TREE_HYPO_QuadranglePreference mesh_tree_algo_quad.png + + ICON_SMESH_TREE_HYPO_QuadrangleParams + mesh_tree_algo_quad.png + ICON_SMESH_TREE_HYPO_TrianglePreference mesh_tree_algo_mefisto.png diff --git a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx index 580ccb653..d532e3935 100644 --- a/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx +++ b/src/StdMeshers_I/StdMeshers_AutomaticLength_i.cxx @@ -52,7 +52,6 @@ StdMeshers_AutomaticLength_i::StdMeshers_AutomaticLength_i( PortableServer::POA_ : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { - MESSAGE( "StdMeshers_AutomaticLength_i::StdMeshers_AutomaticLength_i" ); myBaseImpl = new ::StdMeshers_AutomaticLength( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -68,7 +67,6 @@ StdMeshers_AutomaticLength_i::StdMeshers_AutomaticLength_i( PortableServer::POA_ StdMeshers_AutomaticLength_i::~StdMeshers_AutomaticLength_i() { - MESSAGE( "StdMeshers_AutomaticLength_i::~StdMeshers_AutomaticLength_i" ); } //============================================================================= diff --git a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx index 739bda3ea..88e418edf 100644 --- a/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Hexa_3D_i.cxx @@ -50,7 +50,6 @@ StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, SMESH_Algo_i( thePOA ), SMESH_3D_Algo_i( thePOA ) { - MESSAGE( "StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i" ); myBaseImpl = new ::StdMeshers_Hexa_3D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -66,7 +65,6 @@ StdMeshers_Hexa_3D_i::StdMeshers_Hexa_3D_i( PortableServer::POA_ptr thePOA, StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i() { - MESSAGE( "StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i" ); } //============================================================================= @@ -79,7 +77,6 @@ StdMeshers_Hexa_3D_i::~StdMeshers_Hexa_3D_i() ::StdMeshers_Hexa_3D* StdMeshers_Hexa_3D_i::GetImpl() { - MESSAGE( "StdMeshers_Hexa_3D_i::GetImpl" ); return ( ::StdMeshers_Hexa_3D* )myBaseImpl; } diff --git a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx index e512a74b5..5a75bf78e 100644 --- a/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx +++ b/src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx @@ -51,7 +51,6 @@ StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::PO : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { - MESSAGE( "StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i" ); myBaseImpl = new ::StdMeshers_NumberOfSegments( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -67,7 +66,6 @@ StdMeshers_NumberOfSegments_i::StdMeshers_NumberOfSegments_i( PortableServer::PO StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i() { - MESSAGE( "StdMeshers_NumberOfSegments_i::~StdMeshers_NumberOfSegments_i" ); } //============================================================================= @@ -247,7 +245,6 @@ char* StdMeshers_NumberOfSegments_i::GetObjectEntry() SMESH::long_array* StdMeshers_NumberOfSegments_i::GetReversedEdges() { - MESSAGE( "StdMeshers_NumberOfSegments_i::GetReversedEdges" ); ASSERT( myBaseImpl ); SMESH::long_array_var anArray = new SMESH::long_array; std::vector ids = this->GetImpl()->GetReversedEdges(); diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx index 279e556f3..8c0d9778b 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource1D_i.cxx @@ -287,11 +287,14 @@ void StdMeshers_ProjectionSource1D_i::LoadFrom( const char* theStream ) } myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->SetSourceMesh ( meshImpl ); - GetImpl()->SetSourceEdge ( shapes[ SRC_EDGE ] ); - GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX ], - shapes[ TGT_VERTEX ]); - + try { + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSourceEdge ( shapes[ SRC_EDGE ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX ], + shapes[ TGT_VERTEX ]); + } + catch (...) { + } myBaseImpl->LoadFrom( is ); std::istringstream str( theStream ); diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx index 93cd392c0..369cc29df 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource2D_i.cxx @@ -52,7 +52,6 @@ StdMeshers_ProjectionSource2D_i::StdMeshers_ProjectionSource2D_i ::SMESH_Gen* theGenImpl ) : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { - MESSAGE( "StdMeshers_ProjectionSource2D_i::StdMeshers_ProjectionSource2D_i" ); myBaseImpl = new ::StdMeshers_ProjectionSource2D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -68,7 +67,6 @@ StdMeshers_ProjectionSource2D_i::StdMeshers_ProjectionSource2D_i StdMeshers_ProjectionSource2D_i::~StdMeshers_ProjectionSource2D_i() { - MESSAGE( "StdMeshers_ProjectionSource2D_i::~StdMeshers_ProjectionSource2D_i" ); } //============================================================================= @@ -298,12 +296,16 @@ void StdMeshers_ProjectionSource2D_i::LoadFrom( const char* theStream ) myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->SetSourceMesh ( meshImpl ); - GetImpl()->SetSourceFace ( shapes[ SRC_FACE ] ); - GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], - shapes[ SRC_VERTEX2 ], - shapes[ TGT_VERTEX1 ], - shapes[ TGT_VERTEX2 ]); + try { + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSourceFace ( shapes[ SRC_FACE ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], + shapes[ SRC_VERTEX2 ], + shapes[ TGT_VERTEX1 ], + shapes[ TGT_VERTEX2 ]); + } + catch( ... ) { + } myBaseImpl->LoadFrom( is ); std::istringstream str( theStream ); diff --git a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx index a97d95104..84ad6ca62 100644 --- a/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_ProjectionSource3D_i.cxx @@ -252,7 +252,7 @@ CORBA::Boolean StdMeshers_ProjectionSource3D_i::IsDimSupported( SMESH::Dimension //================================================================================ /*! * \brief Write parameters in a string - * \retval char* - resulting string + * \retval char* - resulting string */ //================================================================================ @@ -273,7 +273,7 @@ char* StdMeshers_ProjectionSource3D_i::SaveTo() //================================================================================ /*! * \brief Retrieve parameters from the string - * \param theStream - the input string + * \param theStream - the input string */ //================================================================================ @@ -299,13 +299,16 @@ void StdMeshers_ProjectionSource3D_i::LoadFrom( const char* theStream ) myCorbaMesh = SMESH::SMESH_Mesh::_duplicate( mesh ); - GetImpl()->SetSourceMesh ( meshImpl ); - GetImpl()->SetSource3DShape ( shapes[ SRC_SHAPE3D ] ); - GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], - shapes[ SRC_VERTEX2 ], - shapes[ TGT_VERTEX1 ], - shapes[ TGT_VERTEX2 ]); - + try { + GetImpl()->SetSourceMesh ( meshImpl ); + GetImpl()->SetSource3DShape ( shapes[ SRC_SHAPE3D ] ); + GetImpl()->SetVertexAssociation( shapes[ SRC_VERTEX1 ], + shapes[ SRC_VERTEX2 ], + shapes[ TGT_VERTEX1 ], + shapes[ TGT_VERTEX2 ]); + } + catch (...) { + } myBaseImpl->LoadFrom( is ); std::istringstream str( theStream ); diff --git a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx index a86b40f1f..515b7e85b 100644 --- a/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx +++ b/src/StdMeshers_I/StdMeshers_Projection_1D_2D_3D_i.cxx @@ -47,7 +47,6 @@ StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i( PortableServer::POA_ptr SMESH_Algo_i( thePOA ), SMESH_3D_Algo_i( thePOA ) { - MESSAGE( "StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i" ); myBaseImpl = new ::StdMeshers_Projection_3D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -56,13 +55,11 @@ StdMeshers_Projection_3D_i::StdMeshers_Projection_3D_i( PortableServer::POA_ptr StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i() { - MESSAGE( "StdMeshers_Projection_3D_i::~StdMeshers_Projection_3D_i" ); } //----------------------------------------------------------------------------- ::StdMeshers_Projection_3D* StdMeshers_Projection_3D_i::GetImpl() { - MESSAGE( "StdMeshers_Projection_3D_i::GetImpl" ); return ( ::StdMeshers_Projection_3D* )myBaseImpl; } @@ -92,7 +89,6 @@ StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i( PortableServer::POA_ptr SMESH_Algo_i( thePOA ), SMESH_2D_Algo_i( thePOA ) { - MESSAGE( "StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i" ); myBaseImpl = new ::StdMeshers_Projection_2D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -101,13 +97,11 @@ StdMeshers_Projection_2D_i::StdMeshers_Projection_2D_i( PortableServer::POA_ptr StdMeshers_Projection_2D_i::~StdMeshers_Projection_2D_i() { - MESSAGE( "StdMeshers_Projection_2D_i::~StdMeshers_Projection_2D_i" ); } //----------------------------------------------------------------------------- ::StdMeshers_Projection_2D* StdMeshers_Projection_2D_i::GetImpl() { - MESSAGE( "StdMeshers_Projection_2D_i::GetImpl" ); return ( ::StdMeshers_Projection_2D* )myBaseImpl; } @@ -126,7 +120,6 @@ StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i( PortableServer::POA_ SMESH_Algo_i( thePOA ), SMESH_2D_Algo_i( thePOA ) { - MESSAGE( "StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i" ); myBaseImpl = new ::StdMeshers_Projection_1D2D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -135,13 +128,11 @@ StdMeshers_Projection_1D2D_i::StdMeshers_Projection_1D2D_i( PortableServer::POA_ StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i() { - MESSAGE( "StdMeshers_Projection_1D2D_i::~StdMeshers_Projection_1D2D_i" ); } //----------------------------------------------------------------------------- ::StdMeshers_Projection_1D2D* StdMeshers_Projection_1D2D_i::GetImpl() { - MESSAGE( "StdMeshers_Projection_1D2D_i::GetImpl" ); return ( ::StdMeshers_Projection_1D2D* )myBaseImpl; } @@ -160,7 +151,6 @@ StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i( PortableServer::POA_ptr SMESH_Algo_i( thePOA ), SMESH_1D_Algo_i( thePOA ) { - MESSAGE( "StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i" ); myBaseImpl = new ::StdMeshers_Projection_1D( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -169,12 +159,10 @@ StdMeshers_Projection_1D_i::StdMeshers_Projection_1D_i( PortableServer::POA_ptr StdMeshers_Projection_1D_i::~StdMeshers_Projection_1D_i() { - MESSAGE( "StdMeshers_Projection_1D_i::~StdMeshers_Projection_1D_i" ); } //----------------------------------------------------------------------------- ::StdMeshers_Projection_1D* StdMeshers_Projection_1D_i::GetImpl() { - MESSAGE( "StdMeshers_Projection_1D_i::GetImpl" ); return ( ::StdMeshers_Projection_1D* )myBaseImpl; } diff --git a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx index ebff90789..7f17b00f6 100644 --- a/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx +++ b/src/StdMeshers_I/StdMeshers_QuadrangleParams_i.cxx @@ -379,7 +379,11 @@ void StdMeshers_QuadrangleParams_i::LoadFrom( const char* theStream ) for ( int i = 0; i < nb; ++i ) shapes.push_back( StdMeshers_ObjRefUlils::LoadFromStream( is, & myShapeEntries[i] )); - GetImpl()->SetEnforcedNodes( shapes, points ); + try { + GetImpl()->SetEnforcedNodes( shapes, points ); + } + catch (...) { + } } } diff --git a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx index 605395f2b..5801115bb 100644 --- a/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx +++ b/src/StdMeshers_I/StdMeshers_SegmentLengthAroundVertex_i.cxx @@ -50,7 +50,6 @@ StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ) { - MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i" ); myBaseImpl = new ::StdMeshers_SegmentLengthAroundVertex( theGenImpl->GetANewId(), theStudyId, theGenImpl ); @@ -66,7 +65,6 @@ StdMeshers_SegmentLengthAroundVertex_i::StdMeshers_SegmentLengthAroundVertex_i StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i() { - MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i" ); } //============================================================================= @@ -80,7 +78,6 @@ StdMeshers_SegmentLengthAroundVertex_i::~StdMeshers_SegmentLengthAroundVertex_i( void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength ) throw ( SALOME::SALOME_Exception ) { - MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::SetLength" ); ASSERT( myBaseImpl ); try { this->GetImpl()->SetLength( theLength ); @@ -103,7 +100,6 @@ void StdMeshers_SegmentLengthAroundVertex_i::SetLength( CORBA::Double theLength CORBA::Double StdMeshers_SegmentLengthAroundVertex_i::GetLength() { - MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetLength" ); ASSERT( myBaseImpl ); return this->GetImpl()->GetLength(); } @@ -118,7 +114,6 @@ CORBA::Double StdMeshers_SegmentLengthAroundVertex_i::GetLength() ::StdMeshers_SegmentLengthAroundVertex* StdMeshers_SegmentLengthAroundVertex_i::GetImpl() { - MESSAGE( "StdMeshers_SegmentLengthAroundVertex_i::GetImpl" ); return ( ::StdMeshers_SegmentLengthAroundVertex* )myBaseImpl; } diff --git a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py index 179309db9..0472b6e28 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py +++ b/src/Tools/MGCleanerPlug/MGCleanerMonPlugDialog.py @@ -205,7 +205,7 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): newLink=monStudyBuilder.NewObject(SOMesh) monStudyBuilder.Addreference(newLink, newStudyIter) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num+=1 return True @@ -263,7 +263,7 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): ACmt = myBuilder.FindOrCreateAttribute(myObject, "AttributeComment") ACmt.SetValue(datai) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num += 1 if verbose: print("save %s in Object Browser done: %s\n%s" % (name, myObject.GetID(), datai)) return True @@ -307,7 +307,7 @@ class MGCleanerMonPlugDialog(Ui_MGCleanerPlugDialog,QWidget): notebook.set("MGCleaner_%i" % self.num, data) """ - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num += 1 if verbose: print("save %s in Object Browser done:\n%s" % (name, data)) return True diff --git a/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py b/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py index 86972fa31..01c53069d 100644 --- a/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py +++ b/src/Tools/MGCleanerPlug/MGCleanerMonViewText.py @@ -57,6 +57,7 @@ class MGCleanerMonViewText(Ui_ViewExe, QDialog): self.monExe.readyReadStandardOutput.connect( self.readFromStdOut ) self.monExe.readyReadStandardError.connect( self.readFromStdErr ) + self.monExe.finished.connect( self.finished ) """ for test set environment env = QProcessEnvironment().systemEnvironment() @@ -69,7 +70,8 @@ class MGCleanerMonViewText(Ui_ViewExe, QDialog): cmds = '' ext = '' if sys.platform == "win32": - cmds += 'delete %s\n' % self.parent().fichierOut + if os.path.exists(self.parent().fichierOut): + cmds += 'del %s\n' % self.parent().fichierOut ext = '.bat' else: cmds += '#!/bin/bash\n' @@ -124,10 +126,10 @@ class MGCleanerMonViewText(Ui_ViewExe, QDialog): a=self.monExe.readAllStandardOutput() aa=unicode(a.data()) self.TB_Exe.append(aa) - if "END_OF_MGCleaner" in aa: - self.parent().enregistreResultat() - self.enregistreResultatsDone=True - #self.theClose() + + def finished(self): + self.parent().enregistreResultat() + self.enregistreResultatsDone=True def theClose(self): if not self.enregistreResultatsDone: diff --git a/src/Tools/YamsPlug/monViewText.py b/src/Tools/YamsPlug/monViewText.py index 45115e68d..c1e90255b 100644 --- a/src/Tools/YamsPlug/monViewText.py +++ b/src/Tools/YamsPlug/monViewText.py @@ -53,11 +53,14 @@ class MonViewText(Ui_ViewExe, QDialog): self.monExe.readyReadStandardOutput.connect( self.readFromStdOut ) self.monExe.readyReadStandardError.connect( self.readFromStdErr ) + self.monExe.finished.connect( self.finished ) cmds = '' ext = '' if sys.platform == "win32": - cmds += 'delete %s\n' % self.parent().fichierOut + if os.path.exists(self.parent().fichierOut): + cmds += 'del %s\n' % self.parent().fichierOut + ext = '.bat' else: cmds += '#!/bin/bash\n' cmds += 'pwd\n' @@ -109,11 +112,11 @@ class MonViewText(Ui_ViewExe, QDialog): def readFromStdOut(self) : a=self.monExe.readAllStandardOutput() aa=unicode(a.data()) - self.TB_Exe.append(aa) - if "END_OF_MGSurfOpt" in aa: - self.parent().enregistreResultat() - self.enregistreResultatsDone=True - #self.theClose() + self.TB_Exe.append(aa) + + def finished(self): + self.parent().enregistreResultat() + self.enregistreResultatsDone=True def theClose(self): if not self.enregistreResultatsDone: diff --git a/src/Tools/YamsPlug/monYamsPlugDialog.py b/src/Tools/YamsPlug/monYamsPlugDialog.py index 058fee9aa..7d778774e 100644 --- a/src/Tools/YamsPlug/monYamsPlugDialog.py +++ b/src/Tools/YamsPlug/monYamsPlugDialog.py @@ -178,7 +178,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): newLink=monStudyBuilder.NewObject(SOMesh) monStudyBuilder.Addreference(newLink, newStudyIter) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num+=1 return True @@ -236,7 +236,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): ACmt = myBuilder.FindOrCreateAttribute(myObject, "AttributeComment") ACmt.SetValue(datai) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num += 1 if verbose: print("save %s in Object Browser done: %s\n%s" % (name, myObject.GetID(), datai)) return True @@ -273,7 +273,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): data = self.getResumeData(separator=" ; ") self.editor.setAttributeValue(newStudyIter, "AttributeComment", data) - if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(0) + if salome.sg.hasDesktop(): salome.sg.updateObjBrowser(False) self.num += 1 if verbose: print("save %s in Object Browser done:\n%s" % (name, data)) return True @@ -479,7 +479,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): self.fichierIn="" def prepareFichier(self): - self.fichierIn=tempfile.mktemp(suffix=".meshb",prefix="ForSurfOpt_") + self.fichierIn=tempfile.mktemp(suffix=".mesh",prefix="ForSurfOpt_") if os.path.exists(self.fichierIn): os.remove(self.fichierIn) self.__selectedMesh.ExportGMF(self.__selectedMesh, self.fichierIn, True) @@ -522,7 +522,7 @@ class MonYamsPlugDialog(Ui_YamsPlugDialog,QWidget): self.commande+= " -O G" # This option has not been updated to the new option style yet deb=os.path.splitext(self.fichierIn) - self.fichierOut=deb[0] + "_output.meshb" + self.fichierOut=deb[0] + "_output.mesh" tolerance=self.SP_toStr(self.SP_Tolerance) if not self.RB_Absolute.isChecked(): diff --git a/src/Tools/ZCracksPlug/CMakeLists.txt b/src/Tools/ZCracksPlug/CMakeLists.txt index fabf877a5..288b9d783 100644 --- a/src/Tools/ZCracksPlug/CMakeLists.txt +++ b/src/Tools/ZCracksPlug/CMakeLists.txt @@ -17,19 +17,43 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -IF(SALOME_BUILD_DOC) - ADD_SUBDIRECTORY(doc) -ENDIF(SALOME_BUILD_DOC) +ADD_SUBDIRECTORY(casTests) + +INCLUDE(UsePyQt) # --- scripts --- # scripts / static SET(plugin_SCRIPTS - zcracks_plugin.py + __init__.py + ellipse.py + genereCrack.py + images_rc.py + main.py + output.py + rectangle.py + sphere.py + utilityFunctions.py + zcracks_plugin.py + Zset.py ) +SET(command_SCRIPTS + zcracksLaunch.py +) -# --- rules --- +# --- resources --- -SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_SMESH_INSTALL_PLUGINS}) +# uic files / to be processed by pyuic +SET(_pyuic_files + zcracks.ui +) + +# scripts / pyuic wrappings +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) + +# --- rules --- +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks) +SALOME_INSTALL_SCRIPTS("${command_SCRIPTS}" ${SALOME_INSTALL_BINS}) diff --git a/src/Tools/ZCracksPlug/Zset.py b/src/Tools/ZCracksPlug/Zset.py new file mode 100644 index 000000000..464619e2b --- /dev/null +++ b/src/Tools/ZCracksPlug/Zset.py @@ -0,0 +1,140 @@ + +import os, tempfile, shutil +import utilityFunctions as uF +from output import message + +def medToGeo(medFile, geoFile, tmpdir, opt=[], verbose=0): + medLoc=os.path.dirname(medFile) + medName=os.path.basename(medFile) + inpFile=os.path.join(tmpdir,'import.inp') + zfile = open(inpFile,'w') + zfile.write('****mesher\n') + zfile.write(' ***mesh %s\n' %(geoFile.replace('.geo','')+'.geo')) + zfile.write(' **import med %s\n' %medName) + for x in opt: + zfile.write(x+'\n') + zfile.write('****return\n') + zfile.close() + commande='cd %s; Zrun -m %s' %(medLoc,inpFile) + if verbose!=0: commande+=' >> %s' %os.path.join(tmpdir,'log.msg') + res=os.system(commande) + + return(res) + + #os.remove(inpFile) + + +def geoToMed(medFile, geoFile, tmpdir, opt=[], verbose=0): + medLoc=os.path.dirname(medFile) + medName=os.path.basename(medFile) + inpFile=os.path.join(tmpdir,'export.inp') + zfile = open(inpFile,'w') + zfile.write('****mesher\n') + zfile.write(' ***mesh\n') + zfile.write(' **open %s\n' %geoFile) + for x in opt: + zfile.write(x+'\n') + zfile.write(' **export med %s\n' %medName) + zfile.write('****return\n') + zfile.close() + commande='cd %s; Zrun -m %s' %(medLoc,inpFile) + if verbose!=0: commande+=' >> %s' %os.path.join(tmpdir,'log.msg') + res=os.system(commande) + #print ' -------- ' + #print res + #print ' -------- ' + return(res) + + +def launchZcrack(minS, maxS, + saneN, crackN, crackedN, + grad, quad, extrL, + nbLay, nbIter, + Gvol, Gfac, Gedg, Gnod, + surfOpt, tmpdir, cas2D, refine, verbose=0, ): + + zfile = open(os.path.join(tmpdir,'insert.z7p'),'w') + zfile.write(' #include \n') + zfile.write(' int main()\n{\n') + zfile.write(' init_var();\n') + + if cas2D==True: + zfile.write(' if_2D=1;\n') + zfile.write(' thickness.resize(1);\n') + zfile.write(' thickness[0]=-1.;\n') + + zfile.write(' format="geo";\n') + zfile.write(' gradation=%e;\n' %grad) + zfile.write(' min_size= %e;\n' %minS) + zfile.write(' max_size=%e;\n' %maxS) + zfile.write(' nb_velem=%d;\n' %(nbLay*2)) + zfile.write(' nb_iter=%d;\n' %nbIter) + zfile.write(' sane_name="%s";\n' %saneN.replace('.geo','')) + #zfile.write(' crack_name="%s";\n' %crackN.replace('.geo','')) + zfile.write(' convert_surface("%s");\n' %crackN.replace('.geo','')) + zfile.write(' cracked_name="%s";\n' %crackedN.replace('.geo','')) + + if Gfac!='': zfile.write(' faset_names="%s";\n' %(Gfac[0] if type(Gfac)==list else Gfac)) + if Gnod!='': zfile.write(' nset_names="%s";\n' %(Gnod[0] if type(Gnod)==list else Gnod)) + if Gvol!='': zfile.write(' elset_names="%s";\n' %(Gvol[0] if type(Gvol)==list else Gvol)) + if Gedg!='': zfile.write(' liset_names="%s";\n' %(Gedg[0] if type(Gedg)==list else Gedg)) + if surfOpt!='': + zfile.write(' yams_options="%s";\n' %surfOpt) + + if refine: zfile.write(' if_must_refine=1;\n') + + if extrL<=1.E-12: + zfile.write(' if_must_define_elset=0;\n') + else: + zfile.write(' if_must_define_elset=1;\n') + if extrL==[]: + zfile.write(' elset_radius=%e;\n' %maxS) + else: + zfile.write(' elset_radius=%e;\n' %extrL) + + zfile.write(' nice_cut(20.0);\n}\n\n') + zfile.close() + commande='Zrun -zp %s' %(os.path.join(tmpdir,'insert.z7p')) + if verbose!=0: commande+=' >> %s' %os.path.join(tmpdir,'log.msg') + res=os.system(commande) + #print ' -------- ' + #print res + #print ' -------- ' + return(res) + + + +def insertCrack(data, names, tmpdir='./zcracks_temp', verbose=0): + + saneN=names['saneGeoName'] + crackN=names['crackGeoName'] + crackedN=names['crackedGeoName'] + + minS=data['minSize'][0] + maxS=data['maxSize'][0] + extrL=data['extractLength'][0] + + grad = data['gradation'][0] if 'gradation' in data.keys() else 1.3 + quad = data['quad'] if 'quad' in data.keys() else False + cas2D = data['is2D'] if 'is2D' in data.keys() else False + refine = data['refine'] if 'refine' in data.keys() else False + nbLay = data['layers'][0] if 'layers' in data.keys() else 5 + nbIter = data['iterations'][0] if 'iterations' in data.keys() else 2 + + Gvol = data['grVol'] if 'grVol' in data.keys() else '' + Gfac = data['grFace'] if 'grFace' in data.keys() else '' + Gedg = data['grEdge'] if 'grEdge' in data.keys() else '' + Gnod = data['grNodes'] if 'grNodes' in data.keys() else '' + surfOpt = data['surfopt'] if 'surfopt' in data.keys() else '' + + + if not os.path.isdir(tmpdir): os.mkdir(tmpdir) + curDir=os.getcwd() + os.chdir(tmpdir) + res=launchZcrack(minS, maxS, saneN, crackN, crackedN,grad, quad, extrL, + nbLay, nbIter,Gvol, Gfac, Gedg, Gnod,surfOpt, tmpdir, cas2D, refine, verbose) + os.chdir(curDir) + return(res) + + +#def TUI(data, names, tmpdir='./zcracks_temp', verbose=0) diff --git a/src/Tools/ZCracksPlug/__init__.py b/src/Tools/ZCracksPlug/__init__.py new file mode 100644 index 000000000..61ea883f4 --- /dev/null +++ b/src/Tools/ZCracksPlug/__init__.py @@ -0,0 +1,76 @@ +import sys, os, shutil, pickle, tempfile +import main, genereCrack, Zset +import utilityFunctions as uF + +#commande="/bin/bash -c ""source $HOME/zebulon/Z8.6.6_NEW/do_config_bash""" +#os.system(commande) + +def IHM(): + + try: + from PyQt5.QtWidgets import QApplication + except: + from PyQt4.QtGui import QApplication + + app = QApplication(sys.argv) + myapp = main.ShipHolderApplication() + myapp.show() + sys.exit(app.exec_()) + + +def SCRIPT(dataFile=None, data=None, dim=3, names=None): + if dim!=3 and dim!=2: + print 'ERROR' + return(False) + + if dataFile==None and data==None: + print 'One of dataFile or data is mandatory' + return(False) + + if data==None: data=pickle.load(open(dataFile,'r')) + + print data + + tmpdir=tempfile.mkdtemp() + uF.removeFromSessionPath('LD_LIBRARY_PATH', 'Meshgems-2111') + + if names==None: names={'saneGeoName':'salome_sane', 'crackGeoName':'salome_crack', 'crackedGeoName':'salome_cracked'} + + crackedMed=data['crackedName'] + crackMed=os.path.join(tmpdir,'crackMed.med') + saneMed=data['saneName'] + + saneGeo=os.path.join(tmpdir,names['saneGeoName']+'.geo') + crackGeo=os.path.join(tmpdir,names['crackGeoName']+'.geo') + crackedGeo=os.path.join(tmpdir,names['crackedGeoName']+'.geo') + + for f in [crackMed, crackedMed, saneGeo, crackGeo, crackedGeo]: + if os.path.isfile(f): os.remove(f) + + print crackMed + genereCrack.main(data, crackMed) + goOn=os.path.isfile(crackMed) + + if goOn: Zset.medToGeo(crackMed, crackGeo, tmpdir) + goOn=os.path.isfile(crackGeo) + + if dim==3: + if goOn: Zset.medToGeo(saneMed,saneGeo, tmpdir) + elif dim==2: + if goOn: Zset.medToGeo(saneMed,saneGeo, tmpdir, opt=[' **to_3d']) + goOn=os.path.isfile(saneGeo) + + if goOn: Zset.insertCrack(data, names, tmpdir) + goOn=os.path.isfile(crackedGeo) + + if goOn: Zset.geoToMed(crackedMed, crackedGeo, tmpdir) + goOn=os.path.isfile(crackedMed) + + if goOn: maxAR=uF.extendElsets(crackedMed) + + shutil.rmtree(tmpdir) + + return([os.path.isfile(crackedMed), maxAR]) + + + diff --git a/src/Tools/ZCracksPlug/casTests/CMakeLists.txt b/src/Tools/ZCracksPlug/casTests/CMakeLists.txt new file mode 100644 index 000000000..f1fcad706 --- /dev/null +++ b/src/Tools/ZCracksPlug/casTests/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright (C) 2012-2016 EDF R&D +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- scripts --- + +# scripts / static +SET(plugin_SCRIPTS + __init__.py + genereCube.py + launchCas.py + launchManuel.py +) + +# --- rules --- + +SALOME_INSTALL_SCRIPTS("${plugin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/Zcracks/casTests) diff --git a/src/Tools/ZCracksPlug/casTests/__init__.py b/src/Tools/ZCracksPlug/casTests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/Tools/ZCracksPlug/casTests/genereCube.py b/src/Tools/ZCracksPlug/casTests/genereCube.py new file mode 100644 index 000000000..2ab20472e --- /dev/null +++ b/src/Tools/ZCracksPlug/casTests/genereCube.py @@ -0,0 +1,197 @@ +# -*- coding: utf-8 -*- + +### +### This file is generated automatically by SALOME v7.7.0 with dump python functionality +### + +import salome + +salome.salome_init() +theStudy = salome.myStudy + +import salome_notebook +notebook = salome_notebook.NoteBook(theStudy) + +### +### GEOM component +### + + +#L = 1. +#N = 20 #Nombre d elements sur un cote + +def cube3D(L, N, outFile): + + N=int(N) + from salome.geom import geomBuilder + + geompy = geomBuilder.New(theStudy) + + eps=L*1.e-6 + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + cube = geompy.MakeBoxDXDYDZ(L, L, L) + geompy.TranslateDXDYDZ(cube, -L/2., -L/2., -L/2.) + + epais=1./(2.*N) + larg=L*1.1 + + boxX = geompy.MakeBoxDXDYDZ(epais, larg, larg) + geompy.TranslateDXDYDZ(boxX, -epais/2., -larg/2., -larg/2.) + boxXM = geompy.TranslateDXDYDZ(boxX, -L/2., 0., 0., theCopy=True) + boxXP = geompy.TranslateDXDYDZ(boxX, L/2., 0., 0., theCopy=True) + + boxY = geompy.MakeBoxDXDYDZ(larg, epais, larg) + geompy.TranslateDXDYDZ(boxY, -larg/2., -epais/2., -larg/2.) + boxYM = geompy.TranslateDXDYDZ(boxY, 0., -L/2., 0., theCopy=True) + boxYP = geompy.TranslateDXDYDZ(boxY, 0., L/2., 0., theCopy=True) + + boxZ = geompy.MakeBoxDXDYDZ(larg, larg, epais) + geompy.TranslateDXDYDZ(boxZ, -larg/2., -larg/2., -epais/2.) + boxZM = geompy.TranslateDXDYDZ(boxZ, 0., 0., -L/2., theCopy=True) + boxZP = geompy.TranslateDXDYDZ(boxZ, 0., 0., L/2., theCopy=True) + + box = geompy.MakeBoxDXDYDZ(larg, larg, larg) + + boxXPLUS = geompy.TranslateDXDYDZ(box, 0., -larg/2., -larg/2., theCopy=True) + boxXMOIN = geompy.TranslateDXDYDZ(box, -larg, -larg/2., -larg/2., theCopy=True) + + boxYPLUS = geompy.TranslateDXDYDZ(box, -larg/2., 0., -larg/2., theCopy=True) + boxYMOIN = geompy.TranslateDXDYDZ(box, -larg/2., -larg, -larg/2., theCopy=True) + + boxZPLUS = geompy.TranslateDXDYDZ(box, -larg/2., -larg/2., 0., theCopy=True) + boxZMOIN = geompy.TranslateDXDYDZ(box, -larg/2., -larg/2., -larg, theCopy=True) + + + from salome.smesh import smeshBuilder + import SMESH + + smesh = smeshBuilder.New(theStudy) + Nb_Segments_1 = smesh.CreateHypothesis('NumberOfSegments') + Nb_Segments_1.SetNumberOfSegments( N ) + Length_From_Edges_1 = smesh.CreateHypothesis('LengthFromEdges') + Regular_1D = smesh.CreateHypothesis('Regular_1D') + NETGEN_2D_ONLY = smesh.CreateHypothesis('NETGEN_2D_ONLY', 'NETGENEngine') + Hexa_3D = smesh.CreateHypothesis('Hexa_3D') + Maillage_1 = smesh.Mesh(cube) + status = Maillage_1.AddHypothesis(Nb_Segments_1) + status = Maillage_1.AddHypothesis(Regular_1D) + Quadrangle_2D = Maillage_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + status = Maillage_1.AddHypothesis(Hexa_3D) + isDone = Maillage_1.Compute() + + geometries = [boxXPLUS, boxXMOIN, boxYPLUS, boxYMOIN, boxZPLUS, boxZMOIN] + + noms = ['VOLXP', 'VOLXM', 'VOLYP', 'VOLYM', 'VOLZP', 'VOLZM'] + + for cont, geo in enumerate(geometries): + aCriteria = smesh.GetCriterion(SMESH.VOLUME,SMESH.FT_BelongToGeom,SMESH.FT_Undefined, geo) + aFilter_1 = smesh.GetFilterFromCriteria([aCriteria]) + aFilter_1.SetMesh(Maillage_1.GetMesh()) + VOLUME_temp = Maillage_1.GroupOnFilter( SMESH.VOLUME, noms[cont], aFilter_1 ) + + nbAdded, Maillage_1, Group = Maillage_1.MakeBoundaryElements( SMESH.BND_2DFROM3D, '', '', 0, [ VOLUME_temp ]) + + geometries = [boxX, boxXM, boxXP, + boxY, boxYM, boxYP, + boxZ, boxZM, boxZP] + + noms = ['FACEX', 'FACEXM', 'FACEXP', + 'FACEY', 'FACEYM', 'FACEYP', + 'FACEZ', 'FACEZM', 'FACEZP'] + + for cont, geo in enumerate(geometries): + aCriteria = smesh.GetCriterion(SMESH.FACE,SMESH.FT_BelongToGeom,SMESH.FT_Undefined, geo) + aFilter_1 = smesh.GetFilterFromCriteria([aCriteria]) + aFilter_1.SetMesh(Maillage_1.GetMesh()) + FACE_temp = Maillage_1.GroupOnFilter( SMESH.FACE, noms[cont], aFilter_1 ) + + Maillage_1.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + + #if salome.sg.hasDesktop(): + #salome.sg.updateObjBrowser(1) + + + +def cube2D(L, N, outFile): + + N=int(N) + from salome.geom import geomBuilder + + geompy = geomBuilder.New(theStudy) + + eps=L*1.e-6 + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + face = geompy.MakeFaceHW(L, L, 1) + + epais=1./(2.*N) + larg=L*1.1 + + boxX = geompy.MakeBoxDXDYDZ(epais, larg, epais) + geompy.TranslateDXDYDZ(boxX, -epais/2., -larg/2., -epais/2.) + boxXM = geompy.TranslateDXDYDZ(boxX, -L/2., 0., 0., theCopy=True) + boxXP = geompy.TranslateDXDYDZ(boxX, L/2., 0., 0., theCopy=True) + + boxY = geompy.MakeBoxDXDYDZ(larg, epais, epais) + geompy.TranslateDXDYDZ(boxY, -larg/2., -epais/2., -epais/2.) + boxYM = geompy.TranslateDXDYDZ(boxY, 0., -L/2., 0., theCopy=True) + boxYP = geompy.TranslateDXDYDZ(boxY, 0., L/2., 0., theCopy=True) + + box = geompy.MakeBoxDXDYDZ(larg, larg, epais) + + boxXPLUS = geompy.TranslateDXDYDZ(box, 0., -larg/2., -epais/2., theCopy=True) + boxXMOIN = geompy.TranslateDXDYDZ(box, -larg, -larg/2., -epais/2., theCopy=True) + + boxYPLUS = geompy.TranslateDXDYDZ(box, -larg/2., 0., -epais/2., theCopy=True) + boxYMOIN = geompy.TranslateDXDYDZ(box, -larg/2., -larg, -epais/2., theCopy=True) + + + from salome.smesh import smeshBuilder + import SMESH + + smesh = smeshBuilder.New(theStudy) + Nb_Segments_1 = smesh.CreateHypothesis('NumberOfSegments') + Nb_Segments_1.SetNumberOfSegments( N ) + Length_From_Edges_1 = smesh.CreateHypothesis('LengthFromEdges') + Regular_1D = smesh.CreateHypothesis('Regular_1D') + NETGEN_2D_ONLY = smesh.CreateHypothesis('NETGEN_2D_ONLY', 'NETGENEngine') + Maillage_1 = smesh.Mesh(face) + + status = Maillage_1.AddHypothesis(Nb_Segments_1) + status = Maillage_1.AddHypothesis(Regular_1D) + Quadrangle_2D = Maillage_1.Quadrangle(algo=smeshBuilder.QUADRANGLE) + isDone = Maillage_1.Compute() + + geometries = [boxXPLUS, boxXMOIN, boxYPLUS, boxYMOIN] + + noms = ['FACEXP', 'FACEXM', 'FACEYP', 'FACEYM'] + + for cont, geo in enumerate(geometries): + aCriteria = smesh.GetCriterion(SMESH.FACE,SMESH.FT_BelongToGeom,SMESH.FT_Undefined, geo) + aFilter_1 = smesh.GetFilterFromCriteria([aCriteria]) + aFilter_1.SetMesh(Maillage_1.GetMesh()) + FACE_temp = Maillage_1.GroupOnFilter( SMESH.FACE, noms[cont], aFilter_1 ) + + nbAdded, Maillage_1, Group = Maillage_1.MakeBoundaryElements( SMESH.BND_1DFROM2D, '', '', 0, [ FACE_temp ]) + + geometries = [boxX, boxXM, boxXP, boxY, boxYM, boxYP] + + noms = ['EDGEX', 'EDGEXM', 'EDGEXP', 'EDGEY', 'EDGEYM', 'EDGEYP'] + + for cont, geo in enumerate(geometries): + aCriteria = smesh.GetCriterion(SMESH.EDGE,SMESH.FT_BelongToGeom,SMESH.FT_Undefined, geo) + aFilter_1 = smesh.GetFilterFromCriteria([aCriteria]) + aFilter_1.SetMesh(Maillage_1.GetMesh()) + EDGE_temp = Maillage_1.GroupOnFilter( SMESH.EDGE, noms[cont], aFilter_1 ) + + Maillage_1.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + + #if salome.sg.hasDesktop(): + #salome.sg.updateObjBrowser(1) \ No newline at end of file diff --git a/src/Tools/ZCracksPlug/casTests/launchCas.py b/src/Tools/ZCracksPlug/casTests/launchCas.py new file mode 100644 index 000000000..e4a4d163c --- /dev/null +++ b/src/Tools/ZCracksPlug/casTests/launchCas.py @@ -0,0 +1,277 @@ + +from Zcracks import genereCrack, Zset +from Zcracks import utilityFunctions as uF +import genereCube + +from math import sqrt + + +if False: + import Zcracks + from Zcracks import casTests + from Zcracks.casTests import launchCas + launchCas.LAUNCH(['10']) + +import os, shutil +import tempfile +import string + +#tmpdir = "/local00/home/B27118/projets/Zcracks/Zcracks/casTests/tmpdir" +#if not os.path.isdir(tmpdir): os.mkdir(tmpdir) +tmpdir=tempfile.mktemp(prefix='tmpZcracks') +print "tmpdir=", tmpdir + +meshgemsdir=os.environ('MESHGEMSHOME') +if len(meshgemsdir) > 0: + meshgems=string.split(meshgemsdir,os.sep)[-1] + uF.removeFromSessionPath('LD_LIBRARY_PATH', meshgems) + +def LAUNCH(listCas=[]): + if type(listCas)!=list: listCas=[listCas] + + N=20 + L=1. + te=L/N + offset=te/2. + genereCube.cube3D(L, N, os.path.join(tmpdir,'cube3D.med')) + genereCube.cube2D(L, N, os.path.join(tmpdir,'cube2D.med')) + crack={} + synthese={} + + # -------- # + # CAS 2D # + # -------- # + data={'minSize':[te/10.], 'maxSize':[te], 'extractLength':[2.*te], 'is2D':True, 'crack':crack, + 'grEdge':['EDGEXP EDGEXM EDGEYP EDGEYM']} + + cas='1' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L/2.], 'Centre':[L/2., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + cas='2' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L], 'Centre':[L/2., 0., 0.], 'Normale':[1., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + cas='3' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L*sqrt(2.)], 'Centre':[-L/2., L/2., 0.], 'Normale':[1., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + cas='4' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[0., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + data['grFace']=['FACEXM FACEXP'] + cas='5' + crack['actif']='Ellipse'; crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[0., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + cas='6' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L/8.], 'Centre':[-L/16., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + + data['grFace']=[''] + cas='7' + crack['actif']='Sphere' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[0., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + cas='8' + crack['actif']='Sphere' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[L/2., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + data['grFace']=['FACEXM FACEXP'] + cas='9' + crack['actif']='Sphere' + crack['Sphere']={'Rayon':[L/4.], 'Centre':[0., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute2D(data, cas) + + # -------- # + # CAS 3D # + # -------- # + data['grEdge']=[''] + data['grFace']=['FACEXP FACEXM FACEYP FACEYM FACEZP FACEZM'] + data['is2D']=False + + cas='10' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[L/2., offset, 0.], 'Normale':[0., 1., 0.], 'Direction':[1., 0., 0.], 'Longueur':[L/2.], 'Largeur':[L]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='11' + crack['actif']='Sphere' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[0., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='12' + crack['actif']='Ellipse' + crack[crack['actif']]={'Centre':[L/4., L/4., L/4.], 'Normale':[1., 1., 1.], 'Rayon':[L]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='13' + crack['actif']='Sphere' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[L/2., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='14' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[L/2., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='15' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[L/2., 0., 0.], 'Normale':[0., 1., 0.], 'Direction':[-1., 0., 0.], + 'Longueur':[L/2.], 'Largeur':[L], 'Rayon entaille':[te*1.5]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='16' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[L/2., offset, 0.], 'Normale':[0., 1., 0.], 'Direction':[1., 0., 0.], + 'Longueur':[L/2.], 'Largeur':[L/4.], 'Rayon':[2.*te]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='17' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[0., offset, 0.], 'Normale':[0., 1., 0.], 'Direction':[1., 0., 0.], + 'Longueur':[L/4.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + cas='18' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[0., 0., 0.], 'Normale':[1., 1., 0.], 'Direction':[1., -1., 0.], + 'Longueur':[L], 'Angle':[180.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + + data['grVol']=['VOLYP VOLYM'] + + cas='19' + crack['actif']='Rectangle' + crack[crack['actif']]={'Centre':[0., 0., 0.], 'Normale':[0., 1., 0.], 'Direction':[1., 0., 0.], + 'Longueur':[L], 'Angle':[180.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + data['grVol']=['VOLXP VOLXM'] + + cas='20' + crack['actif']='Sphere' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[0., 0., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + data['grVol']=['VOLYP VOLYM'] + + cas='21' + crack['actif']='Ellipse' + crack[crack['actif']]={'Rayon':[L/4.], 'Centre':[L/2., offset, 0.], 'Normale':[0., 1., 0.]} + if cas in listCas or listCas==[]: + synthese[cas]=execute3D(data, cas) + + OK=[] + NOOK=[] + for s in synthese.keys(): + if synthese[s]: + OK.append(s) + else: + NOOK.append(s) + + print 'OK:' + print OK + print ' ' + print 'NOOK:' + print NOOK + print ' ' + + return(synthese) + + + +def execute3D(data, cas): + names={'saneGeoName':'cube3D', 'crackGeoName':'crack'+cas, 'crackedGeoName':'cracked'+cas} + + crackMed=os.path.join(tmpdir,'crack'+cas+'.med') + crackedMed=os.path.join(tmpdir,'cracked'+cas+'.med') + + saneGeo=os.path.join(tmpdir,names['saneGeoName'],'.geo') + crackGeo=os.path.join(tmpdir,names['crackGeoName'],'.geo') + crackedGeo=os.path.join(tmpdir,names['crackedGeoName'],'.geo') + + for f in [crackMed, crackedMed, saneGeo, crackGeo, crackedGeo]: + if os.path.isfile(f): os.remove(f) + + genereCrack.main(data, crackMed) + + Zset.medToGeo(os.path.join(tmpdir,names['saneGeoName']),names['saneGeoName'], tmpdir) + Zset.medToGeo(crackMed, names['crackGeoName'], tmpdir) + Zset.insertCrack(data, names, tmpdir) + shutil.copy(os.path.join(tmpdir,'_mesh_out_to_ghs3d.mesh'),os.path.join(tmpdir,'mesh'+cas+'.mesh')) + shutil.copy(os.path.join(tmpdir,'insert.z7p'),os.path.join(tmpdir,'insert'+cas+'.z7p')) + + Zset.geoToMed(crackedMed, names['crackedGeoName'], tmpdir) + + if os.path.isfile(crackedMed): + uF.extendElsets(crackedMed) + maxAR=uF.getMaxAspectRatio(tmpdir) + return(maxAR<30. and maxAR>=1.) + else: + return(False) + + + +def execute2D(data, cas): + names={'saneGeoName':'cube2D', 'crackGeoName':'crack'+cas, 'crackedGeoName':'cracked'+cas} + + crackMed=os.path.join(tmpdir,'crack'+cas+'.med') + crackedMed=os.path.join(tmpdir,'cracked'+cas+'.med') + + saneGeo=os.path.join(tmpdir,names['saneGeoName'],'.geo') + crackGeo=os.path.join(tmpdir,names['crackGeoName'],'.geo') + crackedGeo=os.path.join(tmpdir,names['crackedGeoName'],'.geo') + + for f in [crackMed, crackedMed, saneGeo, crackGeo, crackedGeo]: + if os.path.isfile(f): os.remove(f) + + genereCrack.main(data, crackMed) + + Zset.medToGeo(os.path.join(tmpdir,names['saneGeoName']),names['saneGeoName'], tmpdir, opt=[' **to_3d']) + Zset.medToGeo(crackMed, names['crackGeoName'], tmpdir) + Zset.insertCrack(data, names, tmpdir) + shutil.copy(os.path.join(tmpdir,'_mesh_out_.mesh'),os.path.join(tmpdir,'mesh'+cas+'.mesh')) + shutil.copy(os.path.join(tmpdir,'insert.z7p'),os.path.join(tmpdir,'insert'+cas+'.z7p')) + Zset.geoToMed(crackedMed, names['crackedGeoName'], tmpdir) + + if os.path.isfile(crackedMed): + uF.extendElsets(crackedMed) + maxAR=uF.getMaxAspectRatio(tmpdir) + return(maxAR<30. and maxAR>=1.) + else: + return(False) + + + + diff --git a/src/Tools/ZCracksPlug/casTests/launchManuel.py b/src/Tools/ZCracksPlug/casTests/launchManuel.py new file mode 100644 index 000000000..1eadd07c6 --- /dev/null +++ b/src/Tools/ZCracksPlug/casTests/launchManuel.py @@ -0,0 +1,27 @@ + +import os, tempfile + +directory=tempfile.mktemp(prefix='tmpZcracks') +print "directory=", tmpdir + +# Tous les cas +listCas=['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21'] + +# Cas sans les aretes ou faces sur la fissure : +listCas=['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','20'] + +synthese={} + +for cas in listCas: + result=os.path.join(directory,'cracked'+cas+'.geo') + if os.path.isfile(result): os.remove(result) + try: + os.remove(os.path.join(directory,'cracked'+cas+'.geo')) + except: + pass + os.system('cd '+directory+';Zrun -zp insert'+cas+'.z7p') + + synthese[cas]= os.path.isfile(result) + +print synthese + diff --git a/src/Tools/ZCracksPlug/ellipse.py b/src/Tools/ZCracksPlug/ellipse.py new file mode 100644 index 000000000..9ffeb8b66 --- /dev/null +++ b/src/Tools/ZCracksPlug/ellipse.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- + +### +### This file is generated automatically by SALOME v7.7.1 with dump python functionality +### + + +import sys, numpy +import salome + +salome.salome_init() +theStudy = salome.myStudy + +import salome_notebook +notebook = salome_notebook.NoteBook(theStudy) + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS +import utilityFunctions as uF +from output import message + +#ellipse.generate(data_demi_grand_axe, data_centre, data_normale,data_direction, data_demi_petit_axe, data_angle, rayon_entaille,extension, outFile) +#if True: + #data_demi_grand_axe = 2. + #data_centre = [0., 0., 0.] + #data_normale = [1., 0., 0.] + #data_direction = [0., 1., 0.] + #data_demi_petit_axe = 1. + #data_angle=180. + #rayon_entaille=0.1 + #extension=0.1 + #outFile='/home/I60976/00_PROJETS/2015_INTEGRATION_ZCRACKS/zcracks_salome/test.med' + + +def generate(data_demi_grand_axe, data_centre, data_normale, + data_direction, data_demi_petit_axe, data_angle, + rayon_entaille, extension, outFile): + + Vnormale, Vdirection, Vortho = uF.calcCoordVectors(data_normale, data_direction) + Vcentre = numpy.array(data_centre) + + geompy = geomBuilder.New(theStudy) + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + CENTRE = geompy.MakeVertex(Vcentre[0], Vcentre[1], Vcentre[2]) + NORMALE = geompy.MakeVectorDXDYDZ(Vnormale[0], Vnormale[1], Vnormale[2]) + DIRECTION = geompy.MakeVectorDXDYDZ(Vdirection[0], Vdirection[1], Vdirection[2]) + DIRECTION_op = geompy.MakeVectorDXDYDZ(-Vdirection[0], -Vdirection[1], -Vdirection[2]) + V3 = geompy.MakeVectorDXDYDZ(Vortho[0], Vortho[1], Vortho[2]) + V3_op = geompy.MakeVectorDXDYDZ(-Vortho[0], -Vortho[1], -Vortho[2]) + if data_demi_grand_axe >= data_demi_petit_axe: + ELLIPSE = geompy.MakeEllipse(CENTRE, NORMALE, data_demi_grand_axe, data_demi_petit_axe, DIRECTION) + else: + ELLIPSE = geompy.MakeEllipse(CENTRE, NORMALE, data_demi_petit_axe, data_demi_grand_axe, V3) + + if rayon_entaille<1.e-12: + FELLIPSE = geompy.MakeFaceWires([ELLIPSE], 1) + dim=2 + else: + dim=3 + VP1=Vcentre+Vdirection*(data_demi_grand_axe-rayon_entaille)+Vnormale*rayon_entaille + VP2=Vcentre+Vdirection*(data_demi_grand_axe) + VP3=Vcentre+Vdirection*(data_demi_grand_axe-rayon_entaille)-Vnormale*rayon_entaille + PE1=geompy.MakeVertex(VP1[0], VP1[1], VP1[2]) + PE2=geompy.MakeVertex(VP2[0], VP2[1], VP2[2]) + PE3=geompy.MakeVertex(VP3[0], VP3[1], VP3[2]) + ARC = geompy.MakeArc(PE1, PE2, PE3) + TUYAU = geompy.MakePipe(ARC, ELLIPSE) + subShapesList=geompy.GetFreeBoundary(TUYAU)[1] + entailleFace1 = geompy.MakeFaceWires([subShapesList[0]], 1) + entailleFace2 = geompy.MakeFaceWires([subShapesList[1]], 1) + FELLIPSE = geompy.MakeShell([TUYAU, entailleFace1, entailleFace2]) + + edgesIDs = geompy.SubShapeAllIDs(FELLIPSE, geompy.ShapeType["EDGE"]) + edges = geompy.CreateGroup(FELLIPSE, geompy.ShapeType["EDGE"]) + geompy.UnionIDs(edges, edgesIDs) + geompy.addToStudy( FELLIPSE, 'FELLIPSE' ) + geompy.addToStudyInFather( FELLIPSE , edges, 'edges' ) + + hauteur=numpy.max([data_demi_grand_axe,data_demi_petit_axe])*1.1 + + eps=1.E-05 + bool_boite=True + extrusion=numpy.max([1.,rayon_entaille])*1.1 + if ( (data_angle>(eps)) and (data_angle<(180.-eps)) ): + rayon2=hauteur*numpy.tan(data_angle*numpy.pi/180./2.) + + B1=geompy.MakeTranslationVectorDistance(CENTRE,DIRECTION,hauteur) + B2=geompy.MakeTranslationVectorDistance(B1,V3,rayon2) + geompy.TranslateVectorDistance(B1,V3_op,rayon2, False) + LB01 = geompy.MakeLineTwoPnt(CENTRE, B1) + LB02 = geompy.MakeLineTwoPnt(CENTRE, B2) + LB12 = geompy.MakeLineTwoPnt(B1, B2) + plan_BOITE = geompy.MakeFaceWires([LB01, LB02, LB12], True) + + BOITE = geompy.MakePrismVecH2Ways(plan_BOITE, NORMALE, extrusion) + + FACE_FISSURE = geompy.MakeCommonList([FELLIPSE, BOITE]) + + elif ( (data_angle>=(180.-eps)) and (data_angle<=(180.+eps)) ): + VP1=Vcentre+Vortho*hauteur + VP2=Vcentre-Vortho*hauteur + VP3=Vcentre-Vortho*hauteur+Vdirection*hauteur + VP4=Vcentre+Vortho*hauteur+Vdirection*hauteur + + Sommet_1 = geompy.MakeVertex(VP1[0], VP1[1], VP1[2]) + Sommet_2 = geompy.MakeVertex(VP2[0], VP2[1], VP2[2]) + Sommet_3 = geompy.MakeVertex(VP3[0], VP3[1], VP3[2]) + Sommet_4 = geompy.MakeVertex(VP4[0], VP4[1], VP4[2]) + + Ligne_1 = geompy.MakeLineTwoPnt(Sommet_1, Sommet_2) + Ligne_2 = geompy.MakeLineTwoPnt(Sommet_2, Sommet_3) + Ligne_3 = geompy.MakeLineTwoPnt(Sommet_3, Sommet_4) + Ligne_4 = geompy.MakeLineTwoPnt(Sommet_4, Sommet_1) + + Contour_1 = geompy.MakeWire([Ligne_1, Ligne_2, Ligne_3, Ligne_4], 1e-07) + Face_1 = geompy.MakeFaceWires([Contour_1], 1) + BOITE = geompy.MakePrismVecH2Ways(Face_1, NORMALE, extrusion) + FACE_FISSURE = geompy.MakeCommonList([FELLIPSE, BOITE]) + + elif ( (data_angle>(180.+eps)) and (data_angle<(360.-eps)) ): + rayon2=hauteur*numpy.tan((360.-data_angle)*numpy.pi/180./2.) + + B1=geompy.MakeTranslationVectorDistance(CENTRE,DIRECTION_op,hauteur) + B2=geompy.MakeTranslationVectorDistance(B1,V3,rayon2) + geompy.TranslateVectorDistance(B1,V3_op,rayon2, False) + LB01 = geompy.MakeLineTwoPnt(CENTRE, B1) + LB02 = geompy.MakeLineTwoPnt(CENTRE, B2) + LB12 = geompy.MakeLineTwoPnt(B1, B2) + plan_BOITE = geompy.MakeFaceWires([LB01, LB02, LB12], True) + extrusion=numpy.max([1.,rayon_entaille])*1.1 + BOITE = geompy.MakePrismVecH2Ways(plan_BOITE, NORMALE, extrusion) + + FACE_FISSURE = geompy.MakeCutList(FELLIPSE, [BOITE]) + + elif ( (data_angle<=(eps)) or (data_angle>=(360.-eps)) ): + bool_boite=False + FACE_FISSURE = FELLIPSE + + else: + message('E','Angle non prevu') + + if bool_boite: + #geompy.addToStudy( BOITE, 'BOITE' ) + newEdgesIDs = geompy.SubShapeAllIDs(FACE_FISSURE, geompy.ShapeType["EDGE"]) + newEdges = geompy.CreateGroup(FACE_FISSURE, geompy.ShapeType["EDGE"]) + geompy.UnionIDs(newEdges, newEdgesIDs) + + [oldEdges] = geompy.RestoreGivenSubShapes(FACE_FISSURE, [FELLIPSE, edges], GEOM.FSM_GetInPlace, True, False) + + toExtrude = geompy.CutListOfGroups([newEdges], [oldEdges]) + + if extension>1.e-12: + extrusion = geompy.MakePrismVecH(toExtrude, DIRECTION_op, extension) + try: + FACE_FISSURE = geompy.MakeFuseList([FACE_FISSURE, extrusion], False, True) + except: + FACE_FISSURE = geompy.MakeFuseList([FACE_FISSURE, extrusion], False, False) + + #geompy.addToStudy( FACE_FISSURE, 'FACE_FISSURE' ) + + #geompy.addToStudy( FACE_FISSURE, 'FACE_FISSURE' ) + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New(theStudy) + + A=numpy.pi/(30.) + minAxes=numpy.min([data_demi_grand_axe,data_demi_petit_axe]) + maxAxes=numpy.max([data_demi_grand_axe,data_demi_petit_axe]) + R=minAxes**2/maxAxes + + if rayon_entaille>1.e-12: + R=numpy.min([R,rayon_entaille]) + A=numpy.pi/(15.) + + chordal, minSize = uF.calcElemSize(A, R) + maxSize=maxAxes/5. + + Maillage=uF.meshCrack(FACE_FISSURE, minSize, maxSize, chordal, dim) + + try: + Maillage.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + smesh.SetName(Maillage.GetMesh(), 'MAILLAGE_FISSURE') + except: + print 'ExportToMEDX() failed. Invalid file name?' + + + ## Set names of Mesh objects + + + if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) diff --git a/src/Tools/ZCracksPlug/genereCrack.py b/src/Tools/ZCracksPlug/genereCrack.py new file mode 100644 index 000000000..372772b43 --- /dev/null +++ b/src/Tools/ZCracksPlug/genereCrack.py @@ -0,0 +1,235 @@ +import os, shutil +import sphere, ellipse, rectangle +import utilityFunctions as uF +from output import message + +def main(data, outFile): + activeCrack=data['crack']['actif'] + crack=data['crack'][activeCrack] + + res=False + + if activeCrack == 'Ellipse': + res=generateEllipse(crack, outFile) + + elif activeCrack == 'Rectangle': + res=generateRectangle(crack, outFile) + + elif activeCrack == 'Sphere': + res=generateSphere(crack, outFile) + + elif activeCrack == 'Custom': + res=generateCustom(crack, outFile) + + return(res) + + +def generateEllipse(crack, outFile): + res=True + test=uF.testStrictRange(crack['Rayon']) + if not test: + message('E','Bad Rayon',goOn=True) + res=False + demiGrandAxe=crack['Rayon'][0] + + if 'Rayon 2' not in crack.keys(): crack['Rayon 2']=[] + if len(crack['Rayon 2'])==0: + demiPetitAxe=demiGrandAxe + else: + test=uF.testStrictRange(crack['Rayon 2']) + if not test: + message('E','Bad Rayon 2',goOn=True) + res=False + demiPetitAxe=crack['Rayon 2'][0] + + test=uF.test3dVector(crack['Centre']) + if not test: + message('E','Invalid Centre',goOn=True) + res=False + centre=crack['Centre'] + + test=uF.test3dVector(crack['Normale']) + if not test: + message('E','Invalid Normale',goOn=True) + res=False + normale=crack['Normale'] + + if 'Direction' not in crack.keys(): crack['Direction']=[] + if len(crack['Direction'])==0: + if normale==[1.,0.,0.]: + direction=[0.,1.,0.] + else: + direction=[1.,0.,0.] + else: + test=uF.test3dVector(crack['Direction']) + if not test: + message('E','Invalid Direction',goOn=True) + res=False + direction=crack['Direction'] + test=(direction!=normale) + if not test: + message('E','Normale and Direction are equals',goOn=True) + res=False + + if 'Angle' not in crack.keys(): crack['Angle']=[] + if len(crack['Angle'])==0: + angle=0.0 + else: + test=uF.testRange(crack['Angle'], inf=0.0, sup=360.) + if not test: + message('E','Angle not valid or out of range 0 to 360',goOn=True) + res=False + angle=crack['Angle'][0] + + if 'Rayon entaille' not in crack.keys(): crack['Rayon entaille']=[] + if len(crack['Rayon entaille'])==0: + rayon_entaille=0.0 + else: + test=uF.testStrictRange(crack['Rayon entaille'], inf=0.0) + if not test: + message('E','rayon entaille not valid or negative',goOn=True) + res=False + rayon_entaille=crack['Rayon entaille'][0] + + if 'Extension' not in crack.keys(): crack['Extension']=[] + if len(crack['Extension'])==0: + extension=0.0 + else: + test=uF.testStrictRange(crack['Extension'], inf=0.0) + if not test: + message('E','extension not valid or negative',goOn=True) + res=False + extension=crack['Extension'][0] + + if res: + ellipse.generate(demiGrandAxe, centre, normale, + direction, demiPetitAxe, angle, + rayon_entaille, extension, outFile) + return(True) + else: + return(False) + +def generateRectangle(crack, outFile): + res=True + test=uF.testStrictRange(crack['Longueur']) + if not test: + message('E','Bad Longueur',goOn=True) + res=False + longueur=crack['Longueur'][0] + + if 'Largeur' not in crack.keys(): crack['Largeur']=[] + if len(crack['Largeur'])==0: + largeur=longueur + else: + test=uF.testStrictRange(crack['Largeur']) + if not test: + message('E','Bad Largeur',goOn=True) + res=False + largeur=crack['Largeur'][0] + + test=uF.test3dVector(crack['Centre']) + if not test: + message('E','Invalid Centre',goOn=True) + res=False + centre=crack['Centre'] + + test=uF.test3dVector(crack['Normale']) + if not test: + message('E','Invalid Normale',goOn=True) + res=False + normale=crack['Normale'] + + test=uF.test3dVector(crack['Direction']) + if not test: + message('E','Invalid Direction',goOn=True) + res=False + direction=crack['Direction'] + + if 'Angle' not in crack.keys(): crack['Angle']=[] + if len(crack['Angle'])==0: + angle=0.0 + else: + test=uF.testRange(crack['Angle'], inf=0.0, sup=360.) + if not test: + message('E','Angle not valid or out of range 0 to 360',goOn=True) + res=False + angle=crack['Angle'][0] + + if 'Rayon' not in crack.keys(): crack['Rayon']=[] + if len(crack['Rayon'])==0: + rayon=0.0 + else: + test=uF.testRange(crack['Rayon'], inf=0.0) + if not test: + message('E','Rayon not valid',goOn=True) + res=False + rayon=crack['Rayon'][0] + + if 'Rayon entaille' not in crack.keys(): crack['Rayon entaille']=[] + if len(crack['Rayon entaille'])==0: + rayon_entaille=0.0 + else: + test=uF.testStrictRange(crack['Rayon entaille'], inf=0.0) + if not test: + message('E','rayon entaille not valid or negative',goOn=True) + res=False + rayon_entaille=crack['Rayon entaille'][0] + + if res: + rectangle.generate(longueur,largeur,centre, + normale,direction,angle, + rayon,rayon_entaille,outFile) + return(True) + else: + return(False) + +def generateSphere(crack, outFile): + res=True + test=uF.testStrictRange(crack['Rayon']) + if not test: + message('E','Bad Rayon',goOn=True) + res=False + rayon=crack['Rayon'][0] + + test=uF.test3dVector(crack['Centre']) + if not test: + message('E','Invalid Centre',goOn=True) + res=False + centre=crack['Centre'] + + if res: + sphere.generate(rayon,centre,outFile) + return(True) + else: + return(False) + +def generateCustom(crack, outFile): + res=True + test=os.path.isfile(crack['med file']) + if not test: + message('E','crack med file missing',goOn=True) + res=False + + import salome + salome.salome_init() + theStudy = salome.myStudy + import salome_notebook + notebook = salome_notebook.NoteBook(theStudy) + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + + smesh = smeshBuilder.New(theStudy) + ([Maillage_1], status) = smesh.CreateMeshesFromMED(crack['med file']) + isCrack=False + for group in Maillage_1.GetGroups(): + if [group.GetType(), group.GetName()]==[SMESH.NODE, 'crack']: isCrack=True + if isCrack: + shutil.copy(crack['med file'],outFile) + else: + Group_1 = Maillage_1.CreateEmptyGroup( SMESH.NODE, 'crack' ) + nbAdd = Group_1.AddFrom( Maillage_1.GetMesh() ) + Maillage_1.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + return(True) + + + diff --git a/src/Tools/ZCracksPlug/images.qrc b/src/Tools/ZCracksPlug/images.qrc new file mode 100644 index 000000000..c8177fcaf --- /dev/null +++ b/src/Tools/ZCracksPlug/images.qrc @@ -0,0 +1,7 @@ + + + images/schema_shpere.png + images/schema_ellipse.png + images/schema_rectangle.png + + diff --git a/src/Tools/ZCracksPlug/images/Rectangle.svg b/src/Tools/ZCracksPlug/images/Rectangle.svg new file mode 100644 index 000000000..ab1d9adba --- /dev/null +++ b/src/Tools/ZCracksPlug/images/Rectangle.svg @@ -0,0 +1,1082 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + Largeur Longueur + Direction + + Normale + Angle Centre + + + + Direction + Normale Centre + + + + + + + + + Rayon entaille + + + Rayon + Carré + + + Rectangle Rectangle tronqué + Rectangle bords arrondis + + + + + + + + + + Exemples : + Entaille droite + diff --git a/src/Tools/ZCracksPlug/images/Sphere.svg b/src/Tools/ZCracksPlug/images/Sphere.svg new file mode 100644 index 000000000..3147bb792 --- /dev/null +++ b/src/Tools/ZCracksPlug/images/Sphere.svg @@ -0,0 +1,614 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + Centre + + + Rayon + + + + diff --git a/src/Tools/ZCracksPlug/images/big_loader.gif b/src/Tools/ZCracksPlug/images/big_loader.gif new file mode 100644 index 000000000..9b53d5bf6 Binary files /dev/null and b/src/Tools/ZCracksPlug/images/big_loader.gif differ diff --git a/src/Tools/ZCracksPlug/images/schema_ellipse.png b/src/Tools/ZCracksPlug/images/schema_ellipse.png new file mode 100644 index 000000000..158bb71e0 Binary files /dev/null and b/src/Tools/ZCracksPlug/images/schema_ellipse.png differ diff --git a/src/Tools/ZCracksPlug/images/schema_rectangle.png b/src/Tools/ZCracksPlug/images/schema_rectangle.png new file mode 100644 index 000000000..622e3477a Binary files /dev/null and b/src/Tools/ZCracksPlug/images/schema_rectangle.png differ diff --git a/src/Tools/ZCracksPlug/images/schema_shpere.png b/src/Tools/ZCracksPlug/images/schema_shpere.png new file mode 100644 index 000000000..9754aed89 Binary files /dev/null and b/src/Tools/ZCracksPlug/images/schema_shpere.png differ diff --git a/src/Tools/ZCracksPlug/images_rc.py b/src/Tools/ZCracksPlug/images_rc.py new file mode 100644 index 000000000..c33e7342c --- /dev/null +++ b/src/Tools/ZCracksPlug/images_rc.py @@ -0,0 +1,7580 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created: mer. oct. 19 07:56:41 2016 +# by: The Resource Compiler for PyQt (Qt v4.8.4) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = "\ +\x00\x00\x5a\xbe\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\xed\x00\x00\x00\xed\x08\x06\x00\x00\x00\x53\x4d\xf2\x8f\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x12\x74\x00\x00\x12\x74\ +\x01\xde\x66\x1f\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x20\x00\x49\x44\ +\x41\x54\x78\x9c\xec\x9d\x77\x58\x54\x47\xdb\xc6\xef\x39\x65\x97\ +\xbe\x54\x0b\x45\x91\x22\x20\x88\x88\xbd\x60\x37\x1a\xbb\xc6\x68\ +\x8a\xbd\xa4\xf8\xea\x9b\xa8\xd1\xa8\x31\x9a\xbc\x26\x1a\x5b\x8c\ +\x26\x31\xa6\xa8\x31\xc6\x24\x16\xcc\x67\x43\x05\x3b\xb1\x00\x62\ +\x89\x05\x94\x62\xa1\x29\x82\xf4\xb6\xbb\xe7\x9c\xef\x8f\x75\x17\ +\x96\xa5\xb3\xb0\x45\x7e\xd7\xc5\x05\x7b\xce\xcc\x9c\x67\x97\xbd\ +\xcf\xcc\x99\x79\xe6\x79\x88\x20\x08\x68\xc2\x30\x21\x84\x88\x01\ +\x58\xbe\xf8\xb1\x28\xf3\xb7\x23\x00\x4f\x00\x71\x00\x52\x01\xe4\ +\xbd\xf8\xc9\x57\xfe\x2d\x08\x42\x89\x2e\x6c\x6e\xa2\xfe\x30\xba\ +\x36\xa0\x09\x4d\x08\x21\xa6\x50\x88\xce\x1b\x80\x17\x00\x2f\xb1\ +\x58\xec\x0d\xc0\x1a\x80\x05\xc7\x71\xe6\x1c\xc7\x99\x02\xa0\xab\ +\x68\x43\x10\x04\x81\x54\x76\x9e\xa2\x28\x8e\xa6\xe9\x22\x8a\xa2\ +\x0a\x08\x21\xf9\x00\xb2\x4b\x4a\x4a\x62\x01\xdc\x7b\xf1\x13\x0b\ +\x20\x4e\x10\x84\x22\xed\xbd\xb3\x26\xb4\x01\x69\xea\x69\x75\x07\ +\x21\xc4\x19\x2f\x44\x09\xc0\x8b\x61\x18\x3f\x8a\xa2\x7c\xa4\x52\ +\x69\x0b\x00\x84\xa2\x28\xc1\xd1\xd1\x51\xea\xe5\xe5\xc5\xb8\xba\ +\xba\xd2\xe6\xe6\xe6\xb0\xb4\xb4\x84\xb9\xb9\x39\x2c\x2c\x2c\x60\ +\x61\x61\x81\xe4\xe4\x64\x84\x85\x85\x21\x32\x32\x12\x1c\xc7\xa1\ +\x77\xef\xde\x18\x3f\x7e\x3c\x82\x82\x82\x10\x1e\x1e\x8e\xe0\xe0\ +\x60\x84\x87\x87\x83\xa6\x69\x74\xe9\xd2\x05\x03\x07\x0e\x84\x8b\ +\x8b\x0b\xf2\xf3\xf3\x91\x9f\x9f\x8f\x82\x82\x02\xe4\xe5\xe5\x21\ +\x27\x27\x07\x0f\x1e\x3c\xe0\xe2\xe2\xe2\xb8\xf4\xf4\x74\xf6\x85\ +\xe0\x05\x91\x48\xf4\x84\xe7\xf9\x18\xb9\x5c\x7e\x1b\xa5\x82\xbe\ +\x27\x08\x42\xb2\xee\x3e\xb9\x97\x9b\x26\xd1\x36\x22\x84\x10\x4f\ +\x00\xfd\x69\x9a\x1e\x44\x51\xd4\x20\x99\x4c\x66\x03\x00\x16\x16\ +\x16\x72\x77\x77\x77\xde\xcb\xcb\x4b\xe4\xe1\xe1\x01\x77\x77\x77\ +\xb8\xbb\xbb\xc3\xd5\xd5\x15\x0c\x53\x3a\x18\x2a\xfb\xbf\xba\x7d\ +\xfb\x36\xd6\xaf\x5f\x8f\x33\x67\xce\xa0\x53\xa7\x4e\x18\x33\x66\ +\x0c\x46\x8e\x1c\x09\x1b\x1b\x1b\x8d\xeb\x3e\x7f\xfe\x1c\x21\x21\ +\x21\x38\x78\xf0\x20\xa2\xa3\xa3\x11\x14\x14\x84\x45\x8b\x16\xa1\ +\x7d\xfb\xf6\x15\xb6\x5d\x52\x52\x82\x87\x0f\x1f\x22\x31\x31\x51\ +\xf5\x13\x17\x17\x27\x4b\x4c\x4c\x24\x85\x85\x85\x0c\x00\xb0\x2c\ +\x9b\xc5\xf3\xfc\x29\x8e\xe3\x4e\x01\x38\x2b\x08\x42\x9c\xd6\x3f\ +\xb0\x26\x2a\xa4\x49\xb4\x0d\x08\x21\xa4\x35\x80\x01\x14\x45\x0d\ +\x60\x18\xe6\x15\xa9\x54\xda\xcc\xcc\xcc\x4c\xde\xab\x57\x2f\x12\ +\x14\x14\x44\xb7\x6f\xdf\x1e\x1e\x1e\x1e\xb0\xb5\xb5\xd5\xa8\x5b\ +\xd1\xff\x45\x10\x04\xc4\xc7\xc7\x63\xe3\xc6\x8d\x38\x76\xec\x18\ +\x3a\x77\xee\x8c\x8f\x3f\xfe\x18\x5d\xbb\x76\xad\xb6\x9e\x92\x2b\ +\x57\xae\x60\xfd\xfa\xf5\x88\x8e\x8e\xc6\x90\x21\x43\xb0\x60\xc1\ +\x02\xb4\x6d\xdb\xb6\xda\x7a\x4a\x32\x32\x32\x90\x98\x98\x88\x3b\ +\x77\xee\xe0\xd2\xa5\x4b\xdc\x95\x2b\x57\x84\xc2\xc2\x42\x46\x24\ +\x12\xa5\xcb\x64\xb2\x50\x41\x10\xce\x00\x38\x23\x08\xc2\xa3\x1a\ +\x7e\x4c\x4d\xd4\x92\x26\xd1\x6a\x11\x42\x48\x0b\x00\x03\x01\xf4\ +\x17\x89\x44\x43\xa5\x52\xa9\x93\x48\x24\xe2\xba\x76\xed\x2a\xf4\ +\xe9\xd3\x87\xe9\xdd\xbb\x37\xda\xb7\x6f\x0f\x9a\x56\x7f\x14\xad\ +\x89\x60\x72\x72\x72\xf0\xf9\xe7\x9f\x23\x38\x38\x18\x3e\x3e\x3e\ +\x58\xbc\x78\x31\xfa\xf5\xeb\x57\x6d\xbd\xca\x8e\x9d\x3e\x7d\x1a\ +\x1b\x37\x6e\x44\x6c\x6c\x2c\xc6\x8e\x1d\x8b\xe5\xcb\x97\x43\x22\ +\x91\xd4\xba\x2d\x8e\xe3\x70\xfb\xf6\x6d\x5c\xbe\x7c\x19\x17\x2f\ +\x5e\x94\x5f\xbd\x7a\x95\xc8\x64\x32\x5a\x24\x12\xa5\xc8\x64\xb2\ +\x13\x82\x20\x9c\x05\x70\x5a\x10\x84\x27\x1a\x8d\x35\x51\x27\x9a\ +\x44\x5b\x4f\x08\x21\xe6\x00\xc6\x31\x0c\x33\x9d\xe3\xb8\x7e\x14\ +\x45\x09\x1d\x3a\x74\xe0\xfa\xf7\xef\xcf\xf6\xee\xdd\x1b\x9d\x3a\ +\x75\x02\xcb\xb2\xaa\xf2\x35\x15\x55\xd9\x63\xe1\xe1\xe1\x98\x3f\ +\x7f\x3e\x78\x9e\xc7\x67\x9f\x7d\x86\x11\x23\x46\x80\x10\x52\xa7\ +\xb6\xca\x1e\x13\x04\x01\xc7\x8e\x1d\xc3\xaa\x55\xab\x40\x51\x14\ +\xd6\xaf\x5f\x8f\x5e\xbd\x7a\xd5\xcb\x56\x99\x4c\x86\x6b\xd7\xae\ +\xe1\xca\x95\x2b\x08\x0f\x0f\x97\xdd\xbe\x7d\x9b\xe6\x79\x9e\x30\ +\x0c\x73\x5e\x26\x93\xed\x00\x70\x50\x10\x84\x02\x8d\x46\x9a\xa8\ +\x31\x4d\xa2\xad\x03\x84\x10\x0a\x40\x7f\x8a\xa2\xa6\x12\x42\x5e\ +\x07\x20\x1a\x38\x70\xa0\x30\x61\xc2\x04\x7a\xc0\x80\x01\x30\x33\ +\x33\x53\x95\x2d\xff\xf9\xd6\x46\x08\x25\x25\x25\x58\xb3\x66\x0d\ +\xb6\x6f\xdf\x8e\x21\x43\x86\x60\xdd\xba\x75\x6a\xcf\xac\xf5\x15\ +\xad\x92\xac\xac\x2c\x2c\x5b\xb6\x0c\x27\x4f\x9e\xc4\xf4\xe9\xd3\ +\xb1\x68\xd1\x22\x88\xc5\xe2\x3a\xb7\x5f\xf6\x75\x51\x51\x11\x2e\ +\x5c\xb8\x80\xbf\xff\xfe\x9b\x3f\x7f\xfe\x3c\x00\x48\x05\x41\x38\ +\xc0\xf3\xfc\x6f\x50\xf4\xc0\xbc\x46\x83\x4d\x54\x49\x93\x68\x6b\ +\x01\x21\xa4\x1d\x80\x29\x2c\xcb\x4e\x93\xc9\x64\xcd\xfd\xfd\xfd\ +\x65\x6f\xbd\xf5\x16\x3b\x66\xcc\x18\xd8\xd8\xd8\xd4\xfa\x0b\x5d\ +\xd5\xb1\x3b\x77\xee\x60\xee\xdc\xb9\x48\x49\x49\xc1\xe7\x9f\x7f\ +\x8e\x37\xde\x78\xa3\x5e\x37\x80\x9a\xd8\x15\x1c\x1c\x8c\xcf\x3f\ +\xff\x1c\x2d\x5b\xb6\xc4\x37\xdf\x7c\x03\x6f\x6f\xef\x3a\xb7\x55\ +\x51\x99\xec\xec\x6c\x84\x84\x84\x20\x38\x38\x58\x76\xfb\xf6\x6d\ +\x96\x65\xd9\x67\x32\x99\xec\x57\x00\xbf\x09\x82\x70\x5b\xa3\x52\ +\x13\x15\xd2\x24\xda\x6a\x20\x84\xd8\x03\x78\x5b\x24\x12\xcd\x90\ +\x4a\xa5\xfe\x8e\x8e\x8e\xd2\x37\xdf\x7c\x53\x34\x7e\xfc\x78\xb8\ +\xb9\xb9\xa9\x95\xd5\x96\x68\x4f\x9e\x3c\x89\x39\x73\xe6\xc0\xd7\ +\xd7\x17\x5b\xb6\x6c\x41\xeb\xd6\xad\xeb\xdc\x56\x6d\xed\x4a\x4e\ +\x4e\xc6\xc2\x85\x0b\x71\xeb\xd6\x2d\x6c\xde\xbc\x19\x83\x06\x0d\ +\xaa\x73\x5b\x55\x1d\x7b\xf4\xe8\x11\xfe\xef\xff\xfe\x0f\x07\x0f\ +\x1e\x94\x3e\x79\xf2\x44\xc4\xb2\xec\x1d\x99\x4c\xb6\x1d\xc0\x1e\ +\x41\x10\xd2\x35\x1a\x68\x42\x45\x93\x68\x2b\x81\x10\xe2\x4c\x08\ +\x59\x44\x51\xd4\x7b\x26\x26\x26\xd4\xd8\xb1\x63\xe9\x09\x13\x26\ +\x90\x6e\xdd\xba\xd5\xeb\x79\xb2\xba\x32\xbf\xfd\xf6\x1b\x96\x2f\ +\x5f\x8e\xb7\xde\x7a\x0b\x5f\x7c\xf1\x85\xda\xa4\x55\x63\x88\x16\ +\x00\x78\x9e\xc7\x17\x5f\x7c\x81\xdd\xbb\x77\x63\xe5\xca\x95\x78\ +\xfb\xed\xb7\xeb\xdc\x56\x75\xc7\x04\x41\x40\x74\x74\x34\x0e\x1d\ +\x3a\x24\x1c\x3b\x76\x8c\x2b\x2e\x2e\x16\x04\x41\xf8\x49\x10\x84\ +\x75\x82\x20\x3c\xd6\xa8\xd4\x44\x93\x68\xcb\x43\x08\x71\xa3\x28\ +\x6a\x29\x80\x69\xcd\x9a\x35\x13\x16\x2c\x58\xc0\xbe\xf5\xd6\x5b\ +\x10\x89\x44\x6a\xe5\x1a\x42\xb4\x6b\xd7\xae\xc5\x96\x2d\x5b\xb0\ +\x68\xd1\x22\x7c\xf0\xc1\x07\xf5\x6a\x4b\x1b\x76\xfd\xf0\xc3\x0f\ +\xd8\xb0\x61\x03\xe6\xcc\x99\x83\x05\x0b\x16\xd4\xab\xad\x9a\x1c\ +\x2b\x2e\x2e\xc6\xc1\x83\x07\xb1\x6d\xdb\x36\x59\x46\x46\x06\x05\ +\x60\x37\xcf\xf3\xab\x9b\xd6\x80\xd5\x69\x12\xed\x0b\x08\x21\xed\ +\x68\x9a\xfe\x84\xe7\xf9\x37\x5c\x5c\x5c\xb8\x8f\x3e\xfa\x88\x1d\ +\x3f\x7e\xbc\x6a\xe6\x57\x5b\x5f\xcc\x8a\xca\xc8\x64\x32\x2c\x5a\ +\xb4\x08\xc1\xc1\xc1\x58\xbb\x76\x2d\xde\x7c\xf3\xcd\x06\x15\x47\ +\x6d\xda\x0a\x0e\x0e\xc6\xd2\xa5\x4b\x31\x66\xcc\x18\xac\x59\xb3\ +\x06\x14\x45\x35\x98\x5d\xca\xd7\x72\xb9\x1c\x87\x0f\x1f\xc6\xd6\ +\xad\x5b\x65\xa9\xa9\xa9\x0c\x45\x51\xfb\x39\x8e\xfb\x42\x10\x84\ +\x5b\x1a\x8d\xbc\x84\xbc\xf4\xa2\x25\x84\x04\x32\x0c\xb3\x42\x2e\ +\x97\x8f\xf2\xf0\xf0\x90\x2f\x5e\xbc\x98\x1d\x35\x6a\x54\xb5\x6b\ +\xa9\xda\x12\x87\x4c\x26\xc3\x8c\x19\x33\x70\xe9\xd2\x25\xfc\xf8\ +\xe3\x8f\x18\x38\x70\x60\x9d\xdb\xd2\xa6\x5d\x65\x8f\x9d\x3b\x77\ +\x0e\x73\xe7\xce\x45\xf7\xee\xdd\xf1\xc3\x0f\x3f\xa8\x79\x69\x69\ +\xd3\xae\xf2\xaf\x39\x8e\xc3\xf1\xe3\xc7\xb1\x75\xeb\x56\xd9\x83\ +\x07\x0f\x18\x9a\xa6\x43\x38\x8e\xfb\x9f\x20\x08\x91\x1a\x8d\xbd\ +\x44\xbc\xb4\xa2\x25\x84\xf4\x64\x59\xf6\x33\x99\x4c\x36\xd8\xd7\ +\xd7\x57\xbe\x78\xf1\x62\x66\xd8\xb0\x61\x35\x7e\x5e\xd5\xc6\x17\ +\x53\x10\x04\xcc\x9d\x3b\x17\x27\x4f\x9e\xc4\x9f\x7f\xfe\x89\xce\ +\x9d\x3b\xd7\xb9\x2d\x6d\xda\x55\xd1\xb1\xeb\xd7\xaf\x63\xca\x94\ +\x29\x18\x34\x68\x10\x36\x6e\xdc\x08\x42\x48\xa5\x75\xb5\x6d\x83\ +\x20\x08\x38\x7d\xfa\x34\xbe\xff\xfe\x7b\xf9\xbd\x7b\xf7\x18\x86\ +\x61\xce\xca\xe5\xf2\x15\x82\x20\xfc\xa3\x51\xe1\x25\xe0\xa5\x13\ +\x2d\x21\xa4\x25\x4d\xd3\x9b\x38\x8e\x9b\x18\x18\x18\x28\x5f\xbc\ +\x78\x31\xd3\x50\x33\xa4\xd5\xd5\x5b\xb9\x72\x25\x7e\xfd\xf5\x57\ +\xfc\xfa\xeb\xaf\x1a\xde\x4d\xfa\x26\x5a\x00\xb8\x70\xe1\x02\x66\ +\xcf\x9e\x8d\xc9\x93\x27\xe3\x93\x4f\x3e\xd1\xba\x5d\x35\xb5\xe1\ +\xfb\xef\xbf\x97\xdf\xba\x75\x8b\xa1\x69\x7a\x2f\xc7\x71\xf3\x05\ +\x41\x48\xd3\xa8\x68\xc4\xbc\x34\xa2\x25\x84\xd0\x00\xfe\xc3\x30\ +\xcc\x1a\x07\x07\x07\x76\xfd\xfa\xf5\xec\xab\xaf\xbe\xda\xa0\x5f\ +\xb0\xaa\xea\x7d\xf7\xdd\x77\x58\xb3\x66\x0d\xbe\xff\xfe\x7b\x8c\ +\x1e\x3d\xba\x51\x6d\xa8\x4f\x5b\x87\x0f\x1f\xc6\x82\x05\x0b\xb0\ +\x70\xe1\x42\xbc\xf7\xde\x7b\x5a\xb5\xab\x36\xf5\xce\x9c\x39\x83\ +\x55\xab\x56\xc9\x32\x33\x33\x65\x1c\xc7\x7d\x02\xe0\x5b\x41\x10\ +\x38\x8d\xc2\x46\x88\xe6\xac\x82\x11\x42\x08\xe9\xce\xb2\xec\x4d\ +\x86\x61\x36\xcd\x9d\x3b\xd7\x2c\x2a\x2a\x8a\x7d\xf5\xd5\x57\x75\ +\x66\xcf\xde\xbd\x7b\xb1\x7a\xf5\x6a\xac\x5a\xb5\x0a\x63\xc6\x8c\ +\xd1\x99\x1d\x75\x61\xe4\xc8\x91\xf8\xf4\xd3\x4f\xb1\x61\xc3\x06\ +\x1c\x38\x70\x40\x67\x76\x0c\x18\x30\x00\xc7\x8f\x1f\x67\x67\xcc\ +\x98\x61\x46\xd3\xf4\x46\x96\x65\x6f\x11\x42\x7a\xea\xcc\xa0\x46\ +\xc4\xa8\x7b\x5a\x42\x88\x1d\x45\x51\x6b\x79\x9e\x9f\xd1\xab\x57\ +\x2f\xee\xeb\xaf\xbf\x66\x3c\x3c\x3c\xd4\xca\x34\x76\x4f\x7b\xea\ +\xd4\x29\x4c\x9b\x36\x0d\xf3\xe6\xcd\xc3\xe2\xc5\x8b\x75\x62\x83\ +\x36\xda\xda\xb4\x69\x13\xb6\x6d\xdb\x86\x1f\x7f\xfc\x11\x7d\xfb\ +\xf6\xd5\x89\x0d\x4a\x12\x13\x13\xf1\xbf\xff\xfd\x8f\x8b\x8a\x8a\ +\xa2\x28\x8a\xda\xc5\xf3\xfc\x62\x41\x10\x9e\x69\x54\x34\x12\x8c\ +\x52\xb4\x44\x31\x4b\x32\x93\x61\x98\x0d\x12\x89\xc4\xec\xab\xaf\ +\xbe\x62\x5f\x7b\xed\x35\x00\xba\x19\xca\x29\x49\x4a\x4a\xc2\xe0\ +\xc1\x83\x31\x74\xe8\x50\x6c\xda\xb4\x49\x27\x36\x68\xb3\xad\x8f\ +\x3f\xfe\x18\xa7\x4e\x9d\xc2\xa1\x43\x87\xe0\xe4\xe4\xa4\x13\x1b\ +\xca\xbe\x0e\x09\x09\xc1\x9a\x35\x6b\x64\xb9\xb9\xb9\xc5\x1c\xc7\ +\x2d\x02\xf0\xb3\x60\x84\xbe\xcd\x46\x27\x5a\x42\x88\x1f\xcb\xb2\ +\x3b\x38\x8e\xeb\x3c\x7b\xf6\x6c\x2c\x5b\xb6\x8c\x58\x5a\x5a\xaa\ +\xce\xeb\x4a\xb4\x32\x99\x0c\xa3\x47\x8f\x46\x51\x51\x11\x42\x42\ +\x42\x60\x62\x62\xd2\xe8\x36\x68\xbb\xad\xe2\xe2\x62\xbc\xf6\xda\ +\x6b\x10\x8b\xc5\xf8\xeb\xaf\xbf\x2a\x5d\xd3\x6e\x48\x1b\xca\xbf\ +\xce\xcf\xcf\xc7\x77\xdf\x7d\x87\x3f\xfe\xf8\x43\xa0\x28\xea\x86\ +\x5c\x2e\x9f\x26\x08\xc2\xbf\x1a\x8d\x18\x30\x46\xf5\x4c\x4b\x08\ +\x99\x45\xd3\x74\xb4\x9f\x9f\x5f\xc0\xf9\xf3\xe7\xc9\x9a\x35\x6b\ +\xd4\x04\xab\x4b\x56\xad\x5a\x85\x7b\xf7\xee\xe1\xc7\x1f\x7f\x54\ +\x13\xac\x21\x63\x62\x62\x82\x6f\xbf\xfd\x16\xf1\xf1\xf1\x58\xbb\ +\x76\xad\xae\xcd\x01\x00\x58\x58\x58\x60\xc9\x92\x25\xd8\xb7\x6f\ +\x1f\xf1\xf6\xf6\x6e\x4f\xd3\x74\x14\x21\x64\x96\xae\xed\xd2\x26\ +\x46\x21\x5a\x42\x88\x05\xc3\x30\x7f\x12\x42\x7e\x9a\x3f\x7f\xbe\ +\x28\x2c\x2c\x8c\xf5\xf3\xf3\xd3\xb5\x59\x2a\x42\x42\x42\xf0\xf3\ +\xcf\x3f\x63\xcd\x9a\x35\xf0\xf4\xf4\xd4\xb5\x39\x5a\xc5\xcd\xcd\ +\x0d\xab\x56\xad\xc2\xae\x5d\xbb\x10\x1a\x1a\xaa\x6b\x73\x54\x78\ +\x79\x79\x61\xcf\x9e\x3d\xcc\xac\x59\xb3\x44\x84\x90\x9f\x5e\x7c\ +\x3f\x2c\x74\x6d\x97\x36\x30\xf8\xe1\x31\x21\xa4\x03\xcb\xb2\x7f\ +\x5b\x58\x58\x38\x6f\xdf\xbe\x9d\xed\xdf\xbf\xbf\xea\x5c\x63\x0d\ +\xc9\xaa\x3a\xf6\xf0\xe1\x43\xbc\xf2\xca\x2b\x18\x3a\x74\x28\x36\ +\x6f\xde\xac\xf3\x21\x6d\x43\xb5\xb5\x7c\xf9\x72\x84\x84\x84\xe0\ +\xd0\xa1\x43\x70\x76\x76\x6e\x54\x1b\xaa\x2b\x73\xf9\xf2\x65\x2c\ +\x5a\xb4\x48\x5e\x58\x58\x98\x24\x93\xc9\xc6\x0a\x82\x70\x53\xa3\ +\x82\x01\x61\xd0\xa2\x25\x84\xbc\x4b\x51\xd4\xb7\xdd\xba\x75\x23\ +\x3b\x77\xee\x64\x9a\x37\x6f\xae\x76\x5e\xd7\xa2\xe5\x38\x0e\xc3\ +\x87\x0f\x47\x41\x41\x01\x4e\x9e\x3c\x09\x53\x53\x53\xbd\x12\x9a\ +\x36\xdb\x2a\x29\x29\xc1\xf8\xf1\xe3\x21\x12\x89\xb0\x77\xef\xde\ +\x3a\x85\xd4\x69\x48\xdb\x9f\x3d\x7b\x86\x8f\x3e\xfa\x48\x7e\xe3\ +\xc6\x0d\x81\xe7\xf9\x79\x82\x20\xfc\xa8\x51\xc9\x40\x30\xc8\xe1\ +\x31\x21\xc4\x92\x61\x98\xbd\x84\x90\x1f\x16\x2d\x5a\xc4\x1e\x3d\ +\x7a\x54\x43\xb0\xfa\xc0\x8e\x1d\x3b\x70\xe7\xce\x1d\x6c\xdb\xb6\ +\x0d\xa6\xa6\xa6\xba\x36\xa7\x41\x11\x8b\xc5\xd8\xbc\x79\x33\x62\ +\x63\x63\xf1\xfb\xef\xbf\xeb\xda\x1c\x0d\x1c\x1c\x1c\xb0\x63\xc7\ +\x0e\xe6\x9d\x77\xde\x61\x09\x21\x3f\xbc\xf8\xfe\xe8\xc7\x84\x47\ +\x2d\x31\xb8\x9e\x96\x10\xd2\x91\x65\xd9\xbf\x2d\x2d\x2d\x1d\x77\ +\xee\xdc\xc9\x2a\xd7\x08\x75\x39\x63\x59\xd1\xb1\xb4\xb4\x34\x04\ +\x05\x05\x61\xfa\xf4\xe9\x58\xb6\x6c\x59\xbd\xaf\xa7\x4d\xdb\x1b\ +\xb2\xad\x2d\x5b\xb6\x60\xc7\x8e\x1d\x38\x7e\xfc\x38\x5a\xb4\x68\ +\xd1\x28\x36\xd4\xb6\x5e\x44\x44\x04\x3e\xfa\xe8\x23\x59\x61\x61\ +\x61\xea\x8b\xe1\xf2\x75\x8d\xc2\x7a\x8c\x41\x89\x96\x10\x32\x8b\ +\xa2\xa8\xad\x3d\x7b\xf6\x24\xdb\xb7\x6f\x57\xeb\x5d\xf5\x4d\xb4\ +\xd3\xa7\x4f\x47\x4c\x4c\x0c\xce\x9e\x3d\xab\x95\xe5\x1d\x6d\xda\ +\xde\x90\x6d\x49\xa5\x52\x0c\x1f\x3e\x1c\x1e\x1e\x1e\xd8\xba\x75\ +\x6b\xa3\xd8\x50\x97\x7a\x19\x19\x19\x58\xbc\x78\xb1\xfc\xda\xb5\ +\x6b\x06\x37\x5c\x36\x98\xe1\x31\x21\x64\x25\x80\x9f\x17\x2e\x5c\ +\xc8\x1e\x39\x72\x44\x2f\x87\xc3\x4a\x4e\x9e\x3c\x89\xe3\xc7\x8f\ +\x63\xed\xda\xb5\x46\xb3\xbc\x53\x53\x44\x22\x11\xfe\xf7\xbf\xff\ +\xe1\xd4\xa9\x53\x38\x7d\xfa\xb4\xae\xcd\xa9\x14\x7b\x7b\x7b\xfc\ +\xfc\xf3\xcf\xcc\x3b\xef\xbc\xc3\x02\xd8\x46\x08\xf9\x52\xd7\x36\ +\xd5\x14\xbd\xef\x69\x09\x21\x14\x21\xe4\x3b\x42\xc8\x7b\xdf\x7c\ +\xf3\x0d\x99\x3a\x75\x2a\x00\xdd\xde\xa5\xab\x2a\x53\x50\x50\x80\ +\xa0\xa0\x20\xf4\xe8\xd1\x03\xdf\x7f\xff\xbd\x41\xf4\x8e\x0d\xd1\ +\xd6\xe2\xc5\x8b\x11\x11\x11\x81\xe3\xc7\x8f\xc3\xcc\xcc\x4c\xef\ +\x7a\xda\xb2\xaf\x8f\x1c\x39\x82\x15\x2b\x56\xf0\x82\x20\xec\x10\ +\x04\xe1\x3d\x41\xcf\x37\x1e\xe8\x75\x4f\x4b\x08\x11\xd1\x34\xbd\ +\x8f\x61\x98\x77\x76\xef\xde\xad\x12\xac\x3e\xb3\x6e\xdd\x3a\x14\ +\x16\x16\xe2\xf3\xcf\x3f\xd7\xb5\x29\x3a\x65\xc9\x92\x25\x28\x2c\ +\x2c\xc4\xe6\xcd\x9b\x75\x6d\x4a\xb5\x8c\x1c\x39\x12\x5b\xb6\x6c\ +\xa1\x18\x86\x99\x4e\xd3\x74\xf0\x8b\x6c\x84\x7a\x8b\xde\x8a\xf6\ +\xc5\x0c\x71\xa8\x89\x89\xc9\xe8\x43\x87\x0e\xd1\x23\x46\x8c\xd0\ +\xb5\x49\xd5\x12\x17\x17\x87\x5f\x7e\xf9\x05\x9f\x7e\xfa\x29\xec\ +\xed\xed\x75\x6d\x8e\x4e\xb1\xb5\xb5\xc5\xe2\xc5\x8b\xf1\xdb\x6f\ +\xbf\x21\x21\x21\x41\xd7\xe6\x54\x4b\x50\x50\x10\x7e\xf9\xe5\x17\ +\xda\xc4\xc4\x64\x38\xc3\x30\xa7\x08\x21\x56\xba\xb6\xa9\x32\xf4\ +\x72\x78\x4c\x08\x69\xc6\xb2\x6c\x98\x95\x95\x95\xcf\x91\x23\x47\ +\x58\x5f\x5f\x5f\x8d\x32\xfa\x32\xb4\x2a\xcb\xac\x59\xb3\x70\xff\ +\xfe\x7d\x9c\x3d\x7b\x56\x15\x4b\xc9\x90\x86\xb4\xda\x6e\x8b\xe7\ +\x79\x8c\x1c\x39\x12\x1e\x1e\x1e\xf8\xe6\x9b\x6f\x1a\xcc\x06\x6d\ +\xd6\x8b\x8b\x8b\xc3\x3b\xef\xbc\x23\xcb\xcd\xcd\xbd\x27\x97\xcb\ +\x07\x09\x82\xf0\x54\xa3\x90\x8e\xd1\xbb\x9e\x96\x10\xd2\x86\x65\ +\xd9\x48\x47\x47\x47\x9f\xf3\xe7\xcf\xeb\x95\x3b\x62\x55\xdc\xba\ +\x75\x0b\x47\x8f\x1e\xc5\xc7\x1f\x7f\x5c\x61\xf0\xb3\x97\x11\x8a\ +\xa2\xf0\xe1\x87\x1f\xe2\xc4\x89\x13\xb8\x7b\xf7\xae\xae\xcd\xa9\ +\x11\x1e\x1e\x1e\xd8\xb3\x67\x0f\xdb\xbc\x79\x73\x2f\x86\x61\x22\ +\x09\x21\x6e\xd5\xd7\x6a\x5c\xf4\xaa\xa7\x25\x84\x74\x60\x18\xe6\ +\x94\x8f\x8f\x8f\xe4\xd0\xa1\x43\xac\x72\x88\xa9\xcf\x93\x18\x4a\ +\x26\x4d\x9a\x84\x67\xcf\x9e\xe1\xc4\x89\x13\x0d\x72\x3d\x43\x6e\ +\xeb\xb5\xd7\x5e\x83\x9d\x9d\x1d\x7e\xfc\xf1\xc7\x2a\xcb\xe9\xfa\ +\x7f\x58\xf6\x58\x76\x76\x36\xde\x7d\xf7\x5d\x59\x42\x42\x42\xae\ +\x5c\x2e\x1f\x28\xe8\x91\xeb\xa3\xde\x74\x09\x84\x90\x00\x9a\xa6\ +\xff\xe9\xd9\xb3\xa7\x75\x68\x68\x28\x6b\x48\xcf\x84\x51\x51\x51\ +\x08\x0b\x0b\xc3\xd2\xa5\x4b\x75\x6d\x8a\x5e\xb2\x60\xc1\x02\x9c\ +\x3b\x77\x0e\xd7\xaf\x1b\x8e\x0f\x83\xb5\xb5\x35\x76\xee\xdc\xc9\ +\x06\x06\x06\x4a\x68\x9a\xbe\x48\x08\xe9\xa2\x6b\x9b\x94\xe8\x45\ +\x4f\x4b\x08\x69\xc3\x30\x4c\x64\xaf\x5e\xbd\xac\x83\x83\x83\x99\ +\xba\x04\x06\xd7\xe5\x5d\x7a\xdc\xb8\x71\x00\x80\xe0\xe0\xe0\x06\ +\xbb\x9e\xa1\xb7\x35\x79\xf2\x64\x00\x8a\x0c\x0a\xda\xb6\xa1\x21\ +\xeb\xc9\x64\x32\xfc\xe7\x3f\xff\x91\x5f\xbb\x76\x2d\x4f\x2e\x97\ +\x77\x17\x04\xe1\xbe\x46\xa5\x46\x46\xe7\x3d\xed\x8b\x49\xa7\xb3\ +\xbe\xbe\xbe\x92\xbd\x7b\xf7\x6a\x08\x56\xdf\x09\x0f\x0f\xc7\xc5\ +\x8b\x17\xd5\x5c\x15\x9b\xd0\x64\xfe\xfc\xf9\x88\x88\x88\xc0\xe5\ +\xcb\x97\x75\x6d\x4a\xad\x60\x59\x16\x9b\x36\x6d\x62\x3c\x3c\x3c\ +\x2c\x18\x86\x39\x43\x08\x69\xa9\x6b\x9b\x74\xda\xd3\x12\x42\x2c\ +\x58\x96\xfd\xc7\xc9\xc9\xa9\xdd\xd9\xb3\x67\x59\x7b\x7b\x7b\xbd\ +\xbc\xdb\x56\x55\x6f\xd8\xb0\x61\xb0\xb3\xb3\xc3\xee\xdd\xbb\xf5\ +\xa2\x47\xd3\xe7\xb6\xde\x7f\xff\x7d\x3c\x7f\xfe\x1c\x7b\xf7\xee\ +\xd5\xaa\x0d\x8d\x51\x2f\x2b\x2b\x0b\x93\x27\x4f\x96\x3d\x7d\xfa\ +\x34\x4e\x2e\x97\xf7\x14\x04\x21\x47\xa3\x60\x23\xa1\xb3\x9e\x96\ +\x10\x22\x62\x18\xe6\xb0\x44\x22\x69\x77\xec\xd8\x31\x83\x7a\x86\ +\x55\x72\xf5\xea\x55\x44\x47\x47\x63\xee\xdc\xb9\xba\x36\xc5\x20\ +\x98\x35\x6b\x16\x6e\xdc\xb8\x61\x50\xcf\xb6\x4a\x6c\x6c\x6c\xf0\ +\xd3\x4f\x3f\xb1\x56\x56\x56\x9e\x0c\xc3\x84\x10\x42\x74\xe6\x9f\ +\xaa\x13\xd1\x12\x42\x08\x4d\xd3\xbb\x4d\x4c\x4c\x82\x8e\x1e\x3d\ +\xca\xb6\x6a\xd5\x4a\x17\x66\xd4\x9b\x9f\x7e\xfa\x09\xfe\xfe\xfe\ +\xe8\xd6\xad\x9b\xae\x4d\x31\x08\x3a\x75\xea\x04\x5f\x5f\x5f\xb5\ +\xe7\x5a\x43\xc2\xd1\xd1\x11\xdb\xb6\x6d\x63\x45\x22\x51\x57\x9a\ +\xa6\xf7\xbe\x88\xa5\xdd\xe8\xe8\x4a\xb4\x9b\x29\x8a\x7a\x2d\x38\ +\x38\x98\xa9\xc8\x71\xc2\x10\x48\x4b\x4b\xc3\xb1\x63\xc7\x30\x7b\ +\xf6\x6c\x5d\x9b\x62\x50\x4c\x99\x32\x05\x27\x4f\x9e\xc4\xd3\xa7\ +\x7a\xe7\xb3\x50\x23\x3c\x3d\x3d\xf1\xed\xb7\xdf\x32\x84\x90\xe1\ +\x14\x45\xfd\xa0\x0b\x1b\x1a\x5d\xb4\x84\x90\xa5\x84\x90\xb9\xbb\ +\x77\xef\xa6\x7b\xf6\x34\xdc\xd8\xd2\x3b\x77\xee\x84\x8d\x8d\x0d\ +\xc6\x8e\x1d\xab\x6b\x53\x0c\x8a\xe1\xc3\x87\xc3\xc6\xc6\x06\x7f\ +\xfc\xf1\x87\xae\x4d\xa9\x33\x81\x81\x81\x58\xb7\x6e\x1d\x2d\x08\ +\xc2\x2c\x42\x48\xa3\x3b\x99\x37\xaa\x68\x09\x21\x53\x01\xac\xfe\ +\xf6\xdb\x6f\x89\x21\xf8\x12\x57\x46\x49\x49\x09\x76\xef\xde\x8d\ +\xa9\x53\xa7\xaa\xc2\x86\x36\x51\x33\x58\x96\xc5\x9b\x6f\xbe\x89\ +\xbd\x7b\xf7\xa2\xa4\xa4\x44\xd7\xe6\xd4\x99\x7e\xfd\xfa\xe1\xd3\ +\x4f\x3f\x25\x00\x56\x34\x76\xb4\xc7\x46\x13\x2d\x21\xa4\x03\x4d\ +\xd3\x3f\x7f\xfc\xf1\xc7\x30\x84\xdd\x3a\x55\x71\xe0\xc0\x01\xe4\ +\xe5\xe5\x61\xda\xb4\x69\xba\x36\xc5\x20\x79\xe3\x8d\x37\x90\x9f\ +\x9f\x8f\x23\x47\x8e\xe8\xda\x94\x7a\x31\x66\xcc\x18\xcc\x9a\x35\ +\x0b\x14\x45\x6d\x25\x84\x74\x68\xac\xeb\x36\x8a\x68\x09\x21\x16\ +\x22\x91\xe8\xef\x6e\xdd\xba\x51\xc6\xb0\x9e\xf9\xd3\x4f\x3f\x61\ +\xec\xd8\xb1\x70\x70\x70\xd0\xb5\x29\x06\x89\xbd\xbd\x3d\x86\x0f\ +\x1f\x6e\xb0\x13\x52\x65\x79\xef\xbd\xf7\x10\x10\x10\x40\x58\x96\ +\xfd\xbb\xb1\x42\xb4\x36\x8a\x68\x19\x86\xf9\xc5\xcc\xcc\xcc\x65\ +\xd7\xae\x5d\x74\xf9\x28\x7d\x86\x46\x64\x64\x24\x62\x62\x62\x9a\ +\x26\xa0\xea\xc9\xd4\xa9\x53\x71\xff\xfe\x7d\x44\x46\x1a\x76\x7e\ +\x68\x8a\xa2\xf0\xd5\x57\x5f\x31\xa6\xa6\xa6\x2e\x34\x4d\xff\xd2\ +\x28\xd7\x6c\xe8\x0b\x10\x42\x66\x73\x1c\x37\x71\xd7\xae\x5d\x4c\ +\xcb\x96\x3a\x77\x26\xa9\x37\xfb\xf7\xef\x47\xfb\xf6\xed\xe1\xef\ +\xef\xaf\x6b\x53\x0c\x9a\x76\xed\xda\x21\x20\x20\x00\x7f\xff\xfd\ +\xb7\xae\x4d\xa9\x37\xf6\xf6\xf6\xf8\xea\xab\xaf\x18\x9e\xe7\x27\ +\x10\x42\x1a\xfc\x6e\xde\xa0\xa2\x25\x84\xb4\xa7\x69\xfa\xbb\x05\ +\x0b\x16\xa0\x7c\xe2\x66\x43\x44\x2a\x95\xe2\xd0\xa1\x43\x50\x26\ +\xf3\x6a\xa2\x7e\x8c\x1c\x39\x12\x61\x61\x61\x06\x3d\x21\xa5\xa4\ +\x5b\xb7\x6e\x98\x39\x73\x26\xa1\x28\xea\x3b\x42\x48\xfb\x86\xbc\ +\x56\x83\x89\x96\x10\x62\xce\xb2\xec\xff\x75\xea\xd4\x89\x5a\xb1\ +\x62\x45\x43\x5d\xa6\x51\x39\x75\xea\x14\x72\x73\x73\x55\x1b\x04\ +\x9a\xa8\x1f\xc3\x86\x0d\x43\x71\x71\x31\xce\x9c\x39\xa3\x6b\x53\ +\xb4\xc2\xbb\xef\xbe\x0b\x7f\x7f\x7f\x8a\x65\xd9\xff\x6b\xc8\xe7\ +\xdb\x06\x13\x2d\x4d\xd3\x3f\x99\x99\x99\xb5\xda\xbd\x7b\x37\xc3\ +\x30\x4c\x43\x5d\xa6\x51\xd9\xbf\x7f\x3f\x7a\xf7\xee\xad\x16\xcf\ +\xb7\x89\xba\x63\x63\x63\x83\xde\xbd\x7b\x1b\xfc\x2c\xb2\x92\x32\ +\xcf\xb7\xad\x28\x8a\x6a\xb0\x90\xac\x0d\x22\x5a\x42\xc8\x0c\x9e\ +\xe7\xdf\xda\xbe\x7d\x3b\x53\x51\x5e\x17\x43\x24\x3b\x3b\x1b\x61\ +\x61\x61\x18\x3f\x7e\xbc\xae\x4d\x31\x2a\x46\x8e\x1c\x89\x0b\x17\ +\x2e\x20\x3b\x3b\x5b\xd7\xa6\x68\x05\x07\x07\x07\xac\x59\xb3\x86\ +\xe1\x79\xfe\x2d\x42\xc8\x8c\x86\xb8\x86\xd6\x45\x4b\x08\xf1\xa1\ +\x69\xfa\x87\x79\xf3\xe6\xe1\xd5\x57\x5f\xd5\x76\xf3\x3a\xe3\xf0\ +\xe1\xc3\xa0\x28\x0a\x86\xec\x14\xa2\x8f\x0c\x1c\x38\x10\x62\xb1\ +\x58\x23\xe2\x87\x21\xd3\xbd\x7b\x77\xcc\x98\x31\x03\x14\x45\xfd\ +\x40\x08\xf1\xd1\x76\xfb\x5a\x17\x2d\xcb\xb2\x3f\xb7\x6b\xd7\x8e\ +\xfa\xdf\xff\xfe\xa7\xed\xa6\x75\xca\xfe\xfd\xfb\x31\x74\xe8\x50\ +\x58\x58\x18\x45\xb6\x44\xbd\xc1\xc4\xc4\x04\x83\x07\x0f\xc6\xe1\ +\xc3\x87\x75\x6d\x8a\x56\x79\xff\xfd\xf7\xe1\xed\xed\x4d\x18\x86\ +\xf9\x59\xdb\x6d\x6b\x55\xb4\x84\x90\xc9\x72\xb9\xbc\xe7\xd6\xad\ +\x5b\x19\x63\x72\xef\x4b\x4a\x4a\x42\x64\x64\x64\xd3\xac\x71\x03\ +\x31\x6a\xd4\x28\x5c\xbf\x7e\x1d\xc9\xc9\xc9\xba\x36\x45\x6b\x50\ +\x14\x85\xe5\xcb\x97\xb3\x1c\xc7\xf5\x24\x84\x4c\xd6\x6a\xdb\xda\ +\x6a\x88\x10\x62\xcd\xb2\xec\x37\x33\x66\xcc\x40\xa7\x4e\x9d\xb4\ +\xd5\xac\x5e\x70\xfc\xf8\x71\x58\x59\x59\x61\xc0\x80\x01\xba\x36\ +\xc5\x28\xe9\xd6\xad\x1b\xac\xad\xad\x8d\x6a\x88\x0c\x00\x6d\xdb\ +\xb6\xc5\xc4\x89\x13\xc1\x30\xcc\x37\x84\x10\x6b\x6d\xb5\xab\x4d\ +\xd1\x7e\x61\x66\x66\x66\xb5\x6a\xd5\x2a\xa2\xad\x36\xf5\x85\xb0\ +\xb0\x30\xf4\xeb\xd7\xaf\x69\x73\x40\x03\x41\xd3\x34\x7a\xf7\xee\ +\x8d\xf3\xe7\xcf\xeb\xda\x14\xad\xf3\xde\x7b\xef\x11\x73\x73\x73\ +\x4b\x6d\xe6\x0a\xd2\x8a\x68\x09\x21\x9d\x00\xcc\x59\xbb\x76\x2d\ +\x63\x6d\xad\xb5\x1b\x8a\x5e\x50\x50\x50\x80\x4b\x97\x2e\xe1\x95\ +\x57\x5e\xd1\xb5\x29\x46\x4d\xbf\x7e\xfd\x70\xfd\xfa\x75\xe4\xe5\ +\xe5\xe9\xda\x14\xad\x62\x61\x61\x81\x85\x0b\x17\xb2\x00\xde\x7f\ +\xa1\x93\x7a\x53\x6f\xd1\x12\x42\x28\x96\x65\x7f\xee\xdc\xb9\x33\ +\xa7\x8c\xb8\x67\x4c\x9c\x3f\x7f\x1e\x72\xb9\xbc\x69\x68\xdc\xc0\ +\xf4\xee\xdd\x1b\x00\x70\xf1\xe2\x45\x1d\x5b\xa2\x7d\x86\x0d\x1b\ +\x86\xf6\xed\xdb\x73\x0c\xc3\xfc\x4c\x08\xa9\xb7\xe6\xb4\xd1\xd3\ +\xbe\xc3\x71\x5c\xc0\x77\xdf\x7d\xc7\x10\x62\x74\x23\x63\x84\x85\ +\x85\x21\x30\x30\x10\x76\x76\x76\xba\x36\xc5\xa8\x91\x48\x24\xe8\ +\xd0\xa1\x03\x2e\x5c\xb8\xa0\x6b\x53\x1a\x84\x65\xcb\x96\x31\x3c\ +\xcf\x77\x00\xf0\x4e\x7d\xdb\xaa\x97\x68\x09\x21\x0e\x0c\xc3\xac\ +\x7b\xff\xfd\xf7\x49\xfb\xf6\x0d\xea\x6e\xa9\x33\x4e\x9d\x3a\x85\ +\xc1\x83\x07\xeb\xda\x8c\x97\x82\x3e\x7d\xfa\x20\x3c\x3c\xbc\xc2\ +\x88\x88\x86\x8e\x87\x87\x07\xde\x78\xe3\x0d\x8a\xa6\xe9\x75\x84\ +\x90\x7a\xed\xe9\xac\xaf\x68\xd7\x4b\x24\x12\x93\x4f\x3f\xfd\xb4\ +\x3e\xcd\xe8\x2d\xb7\x6e\xdd\xc2\x93\x27\x4f\x9a\x44\xdb\x48\xf4\ +\xed\xdb\x17\x19\x19\x19\x06\x93\xf7\xa7\xb6\xbc\xf7\xde\x7b\xb0\ +\xb2\xb2\x32\xa1\x28\x6a\x43\x7d\xda\xa9\xb3\x68\x09\x21\x5d\x05\ +\x41\x98\xb2\x71\xe3\x46\xd6\xca\x4a\x6f\xb3\x02\xd6\x8b\x53\xa7\ +\x4e\xa1\x45\x8b\x16\x30\xd6\x51\x84\xbe\xe1\xed\xed\x8d\xe6\xcd\ +\x9b\x1b\xed\x10\xd9\xcc\xcc\x0c\x0b\x17\x2e\x64\x79\x9e\x9f\x4c\ +\x08\xe9\x5a\xd7\x76\xea\x2c\x5a\x9a\xa6\x57\xf8\xf9\xf9\xc9\x27\ +\x4e\x9c\x58\xd7\x26\xf4\x9e\xb0\xb0\x30\xa3\xd8\x52\x68\x48\xf4\ +\xe9\xd3\xc7\x28\x97\x7e\x94\x0c\x19\x32\x04\x9e\x9e\x9e\x1c\x4d\ +\xd3\x2b\xeb\xda\x46\x9d\x44\x4b\x08\xf1\xe7\x38\x6e\xd8\xf2\xe5\ +\xcb\x8d\x76\xe1\x32\x3f\x3f\x1f\xd1\xd1\xd1\x18\x38\x70\xa0\xae\ +\x4d\x51\xc1\xf3\x3c\x8a\x8b\x8b\x51\x58\x58\x88\xfc\xfc\x7c\x14\ +\x16\x16\xaa\x9d\x97\xcb\xe5\x48\x4f\x4f\xc7\x93\x27\x4f\x90\x96\ +\x96\x86\xcc\xcc\x4c\xb5\xf3\x1c\xc7\x21\x27\x27\x07\x79\x79\x79\ +\x28\x28\x28\x40\x71\x71\x71\x63\x9a\x5f\x23\x82\x82\x82\x70\xeb\ +\xd6\x2d\x14\x14\x14\xe8\xda\x94\x06\x63\xf6\xec\xd9\x0c\xc7\x71\ +\xaf\x12\x42\xea\x14\x49\xa1\x4e\x7b\xe6\x28\x8a\xfa\xc4\xcd\xcd\ +\x4d\x3e\x6a\xd4\x28\xa3\x15\xed\xd5\xab\x57\xc1\xf3\xbc\xd6\x03\ +\x91\x0b\x82\x80\x92\x92\x12\x14\x15\x15\x41\x10\x04\xd8\xda\xda\ +\xaa\xce\x15\x15\x15\xe1\xee\xdd\xbb\x90\xc9\x64\x90\x4a\xa5\x10\ +\x8b\xc5\xe8\xda\xb5\x74\x14\x95\x9b\x9b\x8b\xf0\xf0\x70\xd5\x6b\ +\x89\x44\x82\xa0\xa0\x20\xd5\xeb\x82\x82\x02\x44\x45\x45\xa9\x9d\ +\x57\x2e\xa5\x00\x8a\x1b\x51\xd9\x25\x15\x89\x44\x82\xb2\x61\x6c\ +\xf3\xf2\xf2\x10\x19\x19\x09\x96\x65\x21\x12\x89\x60\x69\x69\x89\ +\x76\xed\xda\xa9\xce\xcb\x64\x32\x3c\x7b\xf6\x0c\x0c\xc3\x40\x24\ +\x12\xc1\xd4\xd4\x14\xda\xce\xbd\x14\x18\x18\x08\x9e\xe7\x71\xe3\ +\xc6\x0d\xf4\xea\xd5\x4b\xab\x6d\xeb\x0b\xfd\xfa\xf5\x43\xab\x56\ +\xad\xb8\xe4\xe4\xe4\xe5\x00\x26\xd4\xb6\x7e\xad\x45\x4b\x08\x69\ +\x4b\x08\x79\x7d\xd9\xb2\x65\xc4\x18\x97\x78\x94\x44\x46\x46\xa2\ +\x4d\x9b\x36\xb5\x0e\xde\x26\x97\xcb\x51\x58\x58\x88\xa2\xa2\x22\ +\xc8\xe5\x72\x38\x3a\x3a\xaa\xce\xe5\xe7\xe7\xe3\xf4\xe9\xd3\xe0\ +\x79\x1e\x00\x60\x69\x69\xa9\xd1\x93\xcb\x64\x32\x88\x44\x22\x98\ +\x9b\x9b\xc3\xdc\xdc\x5c\xed\x9c\x85\x85\x05\x7a\xf5\xea\x05\x8a\ +\xa2\x40\x51\x14\xca\xc7\xdb\xb2\xb2\xb2\xc2\xd0\xa1\x43\x41\x51\ +\x14\x08\x21\x1a\xb3\xb0\x96\x96\x96\xe8\xd7\xaf\x1f\x78\x9e\x07\ +\xc7\x71\x1a\xc9\xaf\xc5\x62\x31\x3c\x3c\x3c\x20\x93\xc9\x20\x93\ +\xc9\x34\x3c\xc0\x8a\x8a\x8a\x70\xe7\xce\x1d\x95\xfd\x12\x89\x44\ +\xed\xa6\x56\x54\x54\x84\xd4\xd4\x54\x88\xc5\x62\x98\x98\x98\xc0\ +\xcc\xcc\x0c\xa6\xa6\xa6\xb5\xf9\xf8\x60\x67\x67\x87\x56\xad\x5a\ +\x21\x3a\x3a\xda\x68\x45\x4b\x08\xc1\xac\x59\xb3\x98\x95\x2b\x57\ +\x8e\x27\x84\xb4\xad\x6d\x26\xbe\xba\x88\x76\xa9\x93\x93\x93\x7c\ +\xc2\x84\x09\x46\xdb\xcb\x02\x0a\xd1\x56\xd5\xcb\x96\x94\x94\xa0\ +\xa0\xa0\x40\xad\xa7\x2c\x2e\x2e\x46\x48\x48\x88\xea\xb5\xa9\xa9\ +\xa9\x9a\x68\x4d\x4d\x4d\x11\x10\x10\x00\x53\x53\x53\x98\x99\x99\ +\xc1\xc4\x44\x3d\x1d\x8c\xa9\xa9\x29\xba\x77\xef\x0e\xa0\xe2\x44\ +\x50\x0c\xc3\xa8\x5d\xaf\x7c\x19\x42\x88\x9a\x90\xcb\xdf\x54\x29\ +\x8a\x82\x99\x99\x59\xa5\xed\x8b\x44\x22\xb4\x6e\xdd\xba\xd2\xf6\ +\xad\xac\xac\x30\x68\xd0\x20\x70\x1c\x87\x92\x92\x12\x95\x78\x95\ +\x94\x94\x94\xe0\xe9\xd3\xa7\x28\x2e\x2e\x06\xc7\x71\xb0\xb7\xb7\ +\x47\x40\x40\x80\xea\x7c\x51\x51\x11\x32\x33\x33\x61\x61\x61\x01\ +\x73\x73\x73\x54\x16\x1c\x21\x30\x30\xd0\x20\xf3\xfd\xd4\x86\x21\ +\x43\x86\x60\xeb\xd6\xad\xf2\xf4\xf4\xf4\x65\x00\xa6\xd5\xa6\x6e\ +\xad\x44\x4b\x08\x69\x45\x51\xd4\xe4\xa5\x4b\x97\x1a\x7c\x54\xc5\ +\xaa\xe0\x38\x0e\xd1\xd1\xd1\x58\xb5\x6a\x95\xda\x71\x9e\xe7\x71\ +\xe1\xc2\x05\xe4\xe5\xe5\xa1\xa4\xa4\x04\x34\x4d\x63\xf4\xe8\xd1\ +\x2a\x71\x88\xc5\x62\x74\xef\xde\x1d\x66\x66\x66\x30\x33\x33\x83\ +\x48\x24\x52\xfb\xe2\xd3\x34\x0d\x43\xcd\x5b\x54\x16\x9a\xa6\x55\ +\xe2\x2f\x8b\xb5\xb5\x35\x7a\xf6\xec\x09\x41\x10\x20\x97\xcb\xc1\ +\x71\x9c\xda\xf9\x82\x82\x02\x24\x24\x24\x40\x2e\x97\x03\x50\xe4\ +\xc6\xf1\xf6\xf6\x56\x9d\x97\xcb\xe5\x10\x04\x01\x9d\x3a\x75\xc2\ +\xea\xd5\xab\x2b\x1c\x0d\x18\x0b\x14\x45\x61\xe6\xcc\x99\xec\xea\ +\xd5\xab\x27\x11\x42\x56\x08\x82\xf0\xb8\xa6\x75\x6b\xdb\xd3\x2e\ +\x76\x70\x70\xe0\x27\x4d\x9a\x64\xb4\x8a\xcd\xce\xce\xc6\xbf\xff\ +\xfe\x8b\x71\xe3\xc6\x41\x22\x91\x40\x2e\x97\xab\x7a\x04\x8a\xa2\ +\x60\x6b\x6b\x0b\x67\x67\x67\x58\x59\x59\xc1\xd2\xd2\x52\xad\x37\ +\x23\x84\xa8\xf5\xac\x2f\x33\x0c\xc3\x68\xf4\xa4\xf6\xf6\xf6\xe8\ +\xdb\xb7\xaf\x6a\x94\x52\xfe\xc6\x9f\x9a\x9a\x8a\x84\x84\x04\x50\ +\x14\x85\xa2\xa2\x22\x5c\xb9\x72\x05\x86\x9c\x3a\xa6\x3a\x86\x0f\ +\x1f\x8e\x6d\xdb\xb6\xf1\xcf\x9f\x3f\x5f\x0c\xa0\xc6\xa9\x17\x6b\ +\x7c\x1b\x23\x84\x34\xa7\x28\x6a\xf6\xa2\x45\x8b\x58\x43\x4b\xfc\ +\x5c\x19\x45\x45\x45\x1a\xbd\xc1\xe5\xcb\x97\x91\x96\x96\x06\x7b\ +\x7b\x7b\xb8\xb9\xb9\x69\x0c\x01\xfd\xfd\xfd\xe1\xe1\xe1\x01\x07\ +\x07\x07\x8d\xe1\x6d\x13\x35\x43\x2c\x16\xc3\xd6\xd6\x16\xe5\xd7\ +\xf7\x5b\xb6\x6c\x09\x7f\x7f\x7f\x04\x04\x04\xc0\xc2\xc2\x42\x63\ +\x88\x9c\x9d\x9d\x8d\x8c\x8c\x0c\x48\xa5\xd2\xc6\x34\xb7\xc1\x60\ +\x59\x16\xd3\xa6\x4d\x63\x09\x21\xef\x10\x42\x9a\xd7\xb4\x5e\x6d\ +\xc6\x1e\x0b\x25\x12\x09\x99\x39\x73\x66\x1d\xcc\xd3\x1f\x9e\x3c\ +\x79\x82\xa8\xa8\x28\x1c\x39\x72\x04\x87\x0f\x1f\x46\x7a\x7a\xba\ +\xda\xf9\x7e\xfd\xfa\xe1\xcc\x99\x33\xb8\x73\xe7\x0e\x7c\x7d\x7d\ +\xb5\x3e\x3b\xda\x44\xe5\xb0\x2c\x0b\x3b\x3b\x3b\xb8\xb9\xb9\xa1\ +\x4b\x97\x2e\x88\x8b\x8b\x53\x3b\xff\xec\xd9\x33\xdc\xbe\x7d\x1b\ +\x97\x2f\x5f\x46\x44\x44\x84\x51\xc4\x95\x1a\x33\x66\x0c\x2c\x2c\ +\x2c\x08\x80\x85\x35\xad\x53\x23\xd1\x12\x42\x24\x34\x4d\xcf\x5d\ +\xb0\x60\x01\x5b\xdb\xd9\x40\x5d\x22\x08\x02\x64\x32\x99\xda\xb1\ +\xb4\xb4\x34\xe4\xe6\xe6\xc2\xcd\xcd\x0d\x7d\xfb\xf6\xd5\x98\x1d\ +\x36\x35\x35\x45\x44\x44\x84\xda\x52\x4b\x13\x8d\x4f\x60\x60\x20\ +\xae\x5d\xbb\xa6\x76\xcc\xd3\xd3\x13\xbd\x7b\xf7\x86\xbf\xbf\x3f\ +\x5a\xb4\x68\xa1\x31\x33\xfd\xf4\xe9\x53\xe4\xe6\xe6\x1a\x94\xef\ +\xb2\x58\x2c\xc6\xe4\xc9\x93\x19\x9a\xa6\xe7\x12\x42\x6c\x6a\x52\ +\x87\xd4\xe4\x0d\x12\x42\x66\x8a\x44\xa2\x1f\x93\x93\x93\x69\x2b\ +\x2b\x2b\x8d\x0f\xa5\xb2\x94\xf7\xd5\x1d\xab\x6b\xbd\xaa\xda\x2a\ +\x2e\x2e\x46\x4a\x4a\x0a\x9e\x3c\x79\x82\x27\x4f\x9e\xa0\x4d\x9b\ +\x36\xe8\xd8\xb1\x63\x8d\x6d\x48\x4d\x4d\x85\xbf\xbf\x3f\x8e\x1e\ +\x3d\xaa\x36\x7b\xac\xcf\xef\xd9\x58\xda\x2a\xfb\x3a\x3a\x3a\x1a\ +\x93\x26\x4d\xc2\xc9\x93\x27\xe1\xe2\xe2\x52\xa3\x7a\x57\xaf\x5e\ +\x45\x61\x61\x21\x18\x86\x81\x44\x22\x81\x97\x97\x97\xda\x73\xb3\ +\xbe\xbe\xe7\xc2\xc2\x42\x0c\x19\x32\x44\x5e\x52\x52\xf2\xa1\x20\ +\x08\xdf\x6b\x54\x2a\x47\x8d\x7a\x5a\x91\x48\x34\x73\xcc\x98\x31\ +\xc4\x10\x7c\x8c\x9f\x3d\x7b\x86\x6b\xd7\xae\x81\xe3\x38\xf8\xf9\ +\xf9\xc1\xd3\xd3\xb3\x56\xf5\xa3\xa2\xa2\x40\x08\x81\x9f\x9f\x5f\ +\x03\x59\x58\x73\xe4\xbc\x1c\x19\x85\x19\xe0\x05\xbe\xfa\xc2\x46\ +\x86\xaf\xaf\x2f\x28\x8a\xaa\xd5\xe6\x81\xce\x9d\x3b\xa3\x73\xe7\ +\xce\x68\xdd\xba\x75\x85\xeb\xd8\xe5\x47\x5d\xfa\x82\x99\x99\x19\ +\x06\x0f\x1e\x4c\xb3\x2c\x5b\xa3\x90\xab\xd5\xce\x1e\x13\x42\xda\ +\x00\xe8\x3e\x69\xd2\x24\xbd\xf2\xa4\x90\x4a\xa5\x78\xfc\xf8\x31\ +\xb2\xb2\xb2\xd0\xa5\x4b\x17\xd5\x71\x27\x27\x27\xbc\xf6\xda\x6b\ +\xa0\x28\xaa\x4e\xc3\xa4\xd8\xd8\x58\x38\x3b\x3b\x6b\x38\x36\x34\ +\x16\xd9\xc5\xd9\x58\x1f\xb1\x1e\xe1\x49\xe1\x78\x94\xf3\x08\x72\ +\x5e\x0e\x96\x62\xd1\xbe\x59\x7b\xbc\xee\xf5\x3a\x26\xf9\x4d\x6a\ +\xd0\xeb\xa7\xe4\xa7\xe0\xc0\xbd\x03\x00\x80\x80\x66\x01\xe8\xe3\ +\xdc\xa7\x41\xaf\x57\x19\x26\x26\x26\x68\xd5\xaa\x15\xe2\xe2\xe2\ +\x30\x64\xc8\x90\x1a\xd7\x53\x2e\xb7\x95\x9f\xc5\xcf\xce\xce\xc6\ +\xad\x5b\xb7\x60\x6d\x6d\x0d\x7b\x7b\x7b\xd8\xd9\xd9\x55\xba\x4e\ +\xac\x0b\x86\x0d\x1b\x46\x8e\x1e\x3d\x1a\x58\x13\x67\x8b\x9a\x58\ +\x3d\xd9\xce\xce\x4e\x3e\x70\xe0\x40\xbd\x70\xa6\x10\x04\x01\xe7\ +\xcf\x9f\x47\x5a\x5a\x9a\x6a\x89\x85\xe7\x79\xd5\xd2\x4b\x7d\xd7\ +\xf5\x62\x62\x62\xd4\x5c\xf7\x1a\x93\xf0\xa4\x70\xcc\x39\x39\x07\ +\xcf\x8b\x9e\xab\x1d\x97\xf1\x32\x5c\x7b\x72\x0d\x8f\x73\x1e\x37\ +\xb8\x68\x93\xf3\x92\xb1\x39\x7a\x33\x00\x60\x9a\xdf\x34\x9d\x89\ +\x16\x50\x3c\xc3\x96\x9f\x8c\xaa\x2b\x56\x56\x56\xf0\xf1\xf1\xc1\ +\xb3\x67\xcf\x90\x98\x98\x88\xdc\xdc\xdc\x5a\x8f\xc2\x1a\x92\xc0\ +\xc0\x40\xd8\xda\xda\xca\x9e\x3f\x7f\x3e\x19\x40\x95\x7b\x5d\xab\ +\x15\xad\x48\x24\x9a\x39\x69\xd2\x24\x56\x5f\x9c\x29\x08\x21\xb0\ +\xb1\xb1\x41\xeb\xd6\xad\xe1\xe4\xe4\xa4\x72\xb5\xd3\xd6\xe4\x43\ +\x4c\x4c\x0c\x46\x8e\x1c\xa9\x95\xb6\x6a\x43\x56\x71\x16\xe6\x85\ +\xce\x53\x09\x36\xc8\x25\x08\xf3\xbb\xcc\x87\xa7\xad\x27\x52\xf3\ +\x53\xf1\x4f\xd2\x3f\x08\xbe\x17\x5c\x61\xdd\xec\xe2\x6c\x3c\x29\ +\x78\x02\x17\x2b\x17\x98\x31\x9a\x4e\x0f\x15\xf1\x38\xf7\x31\x44\ +\xb4\x08\x2d\xcc\xeb\x9f\xe2\x24\x25\x3f\x05\x00\xe0\x64\xe1\xa4\ +\x76\x3c\xbd\x30\x1d\xb9\xd2\x5c\xb4\xb6\x6a\x0d\x86\xd4\xbe\x57\ +\xf3\xf4\xf4\x54\xf3\x30\xab\x0f\x14\x45\xc1\xce\xce\x0e\x76\x76\ +\x76\xe0\x38\x4e\x63\xa9\x2f\x27\x27\x07\x0c\xc3\x54\xe8\x34\xd2\ +\x18\xbc\x08\x84\xcf\xfe\xf9\xe7\x9f\x33\x5e\x38\x5b\x54\xfa\x85\ +\xae\x72\x22\x8a\x10\xd2\x13\xc0\xc5\xc8\xc8\x48\xb5\xd4\x8e\x8d\ +\x31\x29\xc3\xf3\x3c\x1e\x3d\x7a\x84\xfb\xf7\xef\xa3\x6d\xdb\xb6\ +\x70\x75\x75\xad\x73\x5b\x35\xad\x57\x52\x52\x02\x17\x17\x17\x6c\ +\xdb\xb6\x0d\x63\xc7\x8e\x6d\xf0\xeb\x95\x3d\xb6\xe2\xc2\x0a\x6c\ +\xbf\xb9\x1d\x00\xd0\xb9\x65\x67\xfc\x3d\xee\x6f\x0d\x37\x44\x29\ +\x27\x05\x4b\x95\x0e\x78\x0e\xde\x3b\x88\x75\x57\xd6\xa9\x44\x43\ +\x08\x41\x97\x16\x5d\xb0\xba\xef\x6a\x78\xda\x94\xf6\x22\xdd\x7e\ +\xeb\x86\x27\x05\x4f\xd0\xd2\xa2\x25\x36\x0d\xd8\x84\xf9\x67\xe6\ +\x23\x2d\x3f\x0d\x00\x10\xe4\x1c\x84\xad\xaf\x6c\x85\x39\x63\x8e\ +\xc5\xe7\x17\xab\x86\xc6\xe5\x59\xde\x63\x39\xa6\xfb\x4d\xc7\xe0\ +\xfd\x83\x91\x98\x9d\x08\x2b\x91\x15\x76\x0f\xdf\x8d\x39\x61\x73\ +\x90\x92\x9f\x82\x11\xee\x23\xb0\xa9\xdf\x26\x48\x39\x29\x7e\xfe\ +\xf7\x67\x6c\xbf\xbd\x1d\x79\x52\x45\x90\x36\x9a\xd0\x18\xee\x36\ +\x1c\xcb\xba\x2e\x83\x8d\x49\xe9\x04\x69\x75\x9f\xcd\xc9\x93\x27\ +\xb1\x60\xc1\x02\x44\x47\x47\x43\x2c\x16\xd7\xfa\x33\xad\xee\x58\ +\xd9\xd7\xb1\xb1\xb1\xc8\xcc\xcc\x84\xa5\xa5\x25\x5a\xb4\x68\x01\ +\x7b\x7b\x7b\xd5\xe7\xdf\x58\x93\x6f\x89\x89\x89\x78\xe3\x8d\x37\ +\x00\xa0\xaf\x20\x08\x95\x6e\x2a\xae\x72\x2c\x49\x08\x99\xe6\xed\ +\xed\x2d\x6b\xec\x5c\xac\x29\x29\x29\x38\x78\xf0\x20\x2e\x5f\xbe\ +\x0c\x33\x33\x33\x58\x5a\x5a\x36\xca\x75\xef\xdf\xbf\x0f\x9e\xe7\ +\xe1\xe3\xa3\xf5\x4c\x0e\xd5\x72\xfd\x69\xa9\x23\xc1\x9c\xc0\x39\ +\x1a\x82\x05\xa0\x26\xd8\x1d\xff\xee\xc0\x07\xa7\x3e\x40\x4a\x7e\ +\x0a\x2c\x58\x0b\xf4\x70\xea\x01\x9a\xd0\x88\x4c\x8b\xc4\xe8\xe0\ +\xd1\x48\xcd\x4f\xd5\xa8\x9f\x51\x98\x81\x49\x47\x27\x21\xa3\x30\ +\x43\x75\x2c\x3c\x39\x1c\x3f\xde\xa8\x7d\xae\xa8\x22\x79\x11\xa6\ +\x84\x4c\x51\xdd\x30\x94\x7c\x1c\xfe\x31\xbe\xb9\xf6\x0d\xf2\xa4\ +\x79\x68\x6e\xd6\x1c\x01\xcd\x02\xc0\x09\x1c\x0e\x27\x1c\xc6\xe4\ +\xe3\x93\x21\xe7\xe5\x35\xbe\x86\xa7\xa7\x27\x78\x9e\x47\x62\x62\ +\x62\xad\xed\xab\x2d\xde\xde\xde\x68\xdf\xbe\x3d\xc4\x62\x31\x12\ +\x13\x13\x55\xae\x96\x8d\x89\x9b\x9b\x1b\x3c\x3c\x3c\x64\x84\x90\ +\xa9\x55\x95\xab\x54\xb4\x84\x10\x31\x4d\xd3\x6f\x4e\x9d\x3a\xb5\ +\xd1\x9f\x65\x2d\x2d\x2d\xe1\xe5\xe5\x85\xb1\x63\xc7\x22\x28\x28\ +\xa8\xd1\x82\xaa\xc5\xc4\xc4\x40\x24\x12\xc1\xdd\xdd\xbd\x51\xae\ +\xa7\x44\x10\x04\xdc\xcb\xbc\xa7\x7a\xed\x61\xe3\x51\x65\xf9\x5c\ +\x69\x2e\xbe\xba\xfc\x15\x00\xa0\xb9\x79\x73\x5c\x9b\x7e\x0d\x7b\ +\x47\xef\xc5\xbe\x31\xfb\x00\x00\x05\xb2\x02\xac\x8f\x58\xaf\x51\ +\x4f\xc6\xcb\x30\xd6\x73\x2c\x22\xa7\x44\x22\x78\x4c\xe9\x50\xfb\ +\x62\x8a\x62\xbb\xde\xba\xbe\xeb\xf0\xe7\xc8\x3f\x55\xc7\xa7\xf9\ +\x4d\x43\xc2\xec\x04\x24\xcc\x4e\xc0\x74\xbf\xe9\x1a\x6d\xb5\x30\ +\x6f\x81\xef\x06\x7e\x87\x88\xb7\x23\xf0\x7e\x87\xf7\x11\xf5\x24\ +\x0a\x47\x13\x8e\x02\x00\xfa\x3a\xf7\xc5\x85\x89\x17\xb0\x6f\xc4\ +\x3e\x2c\xe9\xba\x04\x00\x10\x97\x1d\x87\xfd\xf7\xf7\xd7\xf8\x73\ +\x69\xdd\xba\x35\x44\x22\x91\xd6\x9e\x6b\xab\xc3\xca\xca\x0a\x6d\ +\xdb\xb6\x45\xe7\xce\x9d\xd5\x76\x38\x71\x1c\xd7\x68\xa1\x5d\x47\ +\x8c\x18\xc1\x52\x14\x35\x91\x10\x52\xa9\xbb\x5d\x55\x0f\x1a\xa3\ +\x78\x9e\x37\x7f\xd1\x5d\x37\x18\x19\x19\x19\x88\x8d\x8d\x45\x8f\ +\x1e\x3d\x54\x53\xf4\x56\x56\x56\x3a\x09\xf1\x12\x13\x13\x03\x4f\ +\x4f\xcf\x46\x0f\x4a\x4e\x08\x01\x43\x95\xfe\x2b\x64\x7c\xd5\x4b\ +\x13\xb1\x99\xb1\x28\x92\x17\x01\x00\xac\x44\x56\xf8\xfc\xe2\xe7\ +\xaa\x73\x0c\xc5\x40\xce\xcb\x71\x23\xfd\x46\x85\x75\xe7\x06\xce\ +\x85\x8d\x89\x0d\x02\x9b\x07\xc2\x9c\x35\x47\x81\xac\x00\xe9\x05\ +\xe9\x15\x96\xad\x8e\x85\x9d\x17\x62\x40\xab\x01\x8a\x7d\xc1\x26\ +\xb6\xf8\xd5\xde\xc6\x26\x00\x00\x20\x00\x49\x44\x41\x54\xf9\x56\ +\x69\xda\x9a\x12\xae\x04\x2b\x2f\x2b\x82\x33\xe4\x94\xe4\xa8\x8e\ +\xdf\x78\x76\x03\x6f\x7a\xbf\x59\xa3\xf6\x69\x9a\x86\x9b\x9b\x5b\ +\xa3\x89\xb6\xec\x75\xcb\x92\x99\x99\x89\x84\x84\x04\x58\x5b\x5b\ +\xc3\xd9\xd9\xb9\x41\x47\x7e\x43\x86\x0c\xc1\x96\x2d\x5b\xcc\x00\ +\x8c\x06\xb0\xb7\xa2\x32\x95\x8a\x96\x61\x98\xe9\x7d\xfa\xf4\xe1\ +\x5b\xb6\x6c\xd9\x20\x33\x50\x19\x19\x19\xb8\x71\xe3\x06\x52\x53\ +\x53\xd1\xac\x59\x33\x14\x17\x17\xeb\x6c\x99\x45\x49\x4c\x4c\x8c\ +\x4e\x86\xc6\x00\xe0\x63\xef\x83\x2b\x29\x57\x00\x00\x77\x33\xee\ +\xc2\xcb\xd6\xab\xd2\xb2\x4f\x0b\x9e\xaa\xfe\x8e\xcb\x8a\x43\x5c\ +\x96\xe6\x97\xfa\x71\xae\xe6\xa6\x11\x3b\x53\x3b\xb4\x96\x94\x6e\ +\xbd\x63\x69\x16\x90\x01\x9c\xc0\x69\x94\xad\x0e\x96\x62\xd1\xd3\ +\x51\xdd\x99\xbf\xac\xf8\xaf\xa4\x5d\xc1\x95\xb4\x2b\x1a\xf5\x92\ +\xf3\x6a\x97\xaf\x47\x9b\x33\xc8\x75\xa5\x59\xb3\x66\x10\x8b\xc5\ +\x48\x4e\x4e\xc6\xed\xdb\xb7\xe1\xe1\xe1\x01\x7b\x7b\xfb\x06\xb9\ +\x96\x9d\x9d\x1d\x3a\x77\xee\xcc\x5f\xbb\x76\x6d\x1a\x6a\x23\x5a\ +\x42\x88\x2d\x21\xe4\x95\x29\x53\xa6\x34\xd8\x94\xf1\xe3\xc7\x8f\ +\x21\x97\xcb\x31\x68\xd0\x20\xb4\x6c\xd9\xb2\xa1\x2e\x53\x2b\x62\ +\x63\x63\x31\x63\x46\x83\xa4\x14\xad\x96\x9e\x4e\x3d\x55\xa2\xdd\ +\x1c\xb5\x19\x43\xda\x0c\x81\x19\xab\x3e\x93\xf9\xac\xf0\x19\x1c\ +\xcc\x1c\xe0\x2a\x71\x55\x1d\xeb\xd7\xaa\x1f\x56\xf6\x2e\x0d\x37\ +\xa4\x9c\xd8\x20\xd0\x7c\x26\x16\xd1\xea\x7e\xd4\x15\x95\xa1\xca\ +\xc4\xd2\xae\xca\xa9\xc3\x94\x31\x85\x09\xa3\x3e\x82\x6b\x65\x55\ +\xba\xed\xf0\x1d\xff\x77\x30\xce\x73\x9c\x86\x5d\x26\x74\xed\x36\ +\x59\x78\x7a\x7a\xe2\xcf\x3f\xff\xac\xbe\x60\x03\x23\x91\x48\x20\ +\x91\x48\x90\x9b\x9b\xdb\xe0\x33\xcc\xc3\x87\x0f\xa7\xa3\xa2\xa2\ +\x06\x13\x42\x6c\x05\x41\x78\x5e\xfe\x7c\x65\xcf\xb4\x7d\x29\x8a\ +\xa2\xb4\x99\x8b\xb5\xfc\x6e\x99\x8e\x1d\x3b\x62\xc8\x90\x21\x7a\ +\x23\xd8\xc2\xc2\x42\x24\x27\x27\xab\xed\xef\x6c\x4c\xe6\x76\x9e\ +\x0b\x77\x1b\xc5\xb3\x74\x7c\x56\x3c\x86\xee\x1d\x8a\x3d\x77\xf6\ +\xe0\x62\xf2\x45\x1c\xbc\x77\x10\x8b\xce\x2c\xc2\x88\xfd\x8a\xff\ +\x47\x5b\xdb\xb6\x70\xb4\x50\x38\x0f\xfc\x93\xfc\x0f\x12\xb3\x13\ +\xe1\x62\xe9\x82\x36\x92\x36\xa0\x09\x8d\xa3\xf1\x47\x11\x92\x50\ +\xb7\xa5\x92\x66\x66\xcd\x54\x7f\x5f\x4c\xb9\x88\xb0\x47\x61\x88\ +\x48\x8b\x40\xa1\xbc\xb0\x8a\x5a\x0a\x7a\x3a\xf6\x54\x0d\xf3\x8f\ +\x25\x1e\x43\xbe\x34\x1f\x6d\xac\xda\xa0\x95\x65\x2b\x14\xc9\x8b\ +\xb0\xfb\xee\x6e\xdc\x7d\x5e\xbb\xf0\xa8\x1e\x1e\x1e\x48\x4b\x4b\ +\x43\x51\x51\x51\xed\xde\x48\x03\x61\x65\x65\xa5\xe6\x94\x21\x97\ +\xcb\x11\x17\x17\x87\x92\x92\x12\xad\x5d\xa3\x4f\x9f\x3e\x78\x91\ +\x89\xa0\x6f\x45\xe7\x2b\x1b\x1e\x0f\x08\x08\x08\x90\x5b\x5a\x5a\ +\xb2\xf5\x5d\xff\xe4\x79\x1e\xb7\x6f\xdf\xc6\xfd\xfb\xf7\x31\x72\ +\xe4\x48\xd5\xae\x99\x8a\xc2\xa1\xe8\x12\x65\x9a\x45\x5d\x6d\x52\ +\x17\xd3\x62\xfc\xf4\xea\x4f\xf8\xcf\xc9\xff\x20\x36\x33\x16\x89\ +\xd9\x89\xf8\xf8\xec\xc7\x6a\x65\xec\x4d\xed\x55\x65\x37\x0e\xdc\ +\x88\xa9\x47\xa7\x42\xca\x49\x31\x33\x64\x26\x4c\x19\x53\xf0\x02\ +\x8f\x12\x4e\xf1\xe5\x99\xe2\x37\xa5\x4e\x76\x38\x5b\x38\xc3\xcd\ +\xda\x0d\x89\xd9\x89\x48\xc8\x4e\xc0\x7b\xa1\xef\x01\x00\x8e\x8c\ +\x3b\x82\x76\x76\x55\x3b\x9d\xb8\x5b\xbb\x63\x61\xe7\x85\x58\x1b\ +\xb9\x16\x29\xf9\x29\x18\x7f\x64\x3c\x2c\x45\x96\x28\x94\x15\xaa\ +\x86\xe0\x01\xcd\x02\xaa\x6c\x43\xc3\x1e\x67\x67\x00\x0a\x9f\xf0\ +\xc6\x9e\x20\xac\x09\x32\x99\x0c\x85\x85\x85\xf8\xf7\xdf\x7f\xe1\ +\xe4\xe4\x84\x96\x2d\x5b\x56\x38\xf3\x5f\x1b\xcc\xcc\xcc\xe0\xe5\ +\xe5\x25\x8f\x89\x89\x19\x08\xe0\xef\xf2\xe7\x2b\x14\xad\x58\x2c\ +\x1e\xa6\x0d\x0f\xa8\x27\x4f\x9e\xe0\xca\x95\x2b\x28\x28\x28\x80\ +\xbf\xbf\xbf\x5e\xb9\x8d\x95\x27\x29\x29\x09\x00\x34\x9c\xd3\x1b\ +\x13\x6f\x3b\x6f\x9c\x7c\xe3\x24\x76\xdf\xde\x8d\xf0\xa4\x70\x24\ +\x64\x25\xe0\x59\xe1\x33\xb4\x30\x6f\x81\x80\xe6\x01\x98\xe0\x53\ +\x1a\x03\xac\xb7\x73\x6f\x9c\x79\xf3\x0c\xbe\x89\xfa\x06\x77\x32\ +\xee\x20\x25\x2f\x05\x16\x22\x0b\x34\x37\x6f\x8e\x1e\x4e\x3d\x30\ +\xda\x63\xb4\xaa\x6c\x60\xf3\x40\x64\x16\x65\xc2\xde\x4c\xfd\x39\ +\xac\x53\xf3\x4e\xc8\x93\xe6\xc1\xce\xb4\x74\x76\x9e\xa6\x68\xfc\ +\x36\xec\x37\xfc\x7a\xfb\x57\xc4\x67\xc5\xab\x26\xbc\xcc\x59\xc5\ +\x7c\x83\xbf\xbd\x3f\xec\x4d\xec\x61\x21\xaa\x38\xb9\xf6\xac\xf6\ +\xb3\xd0\xb1\x59\x47\xfc\xfc\xef\xcf\x48\xc8\x4e\x40\x66\x71\x26\ +\x1c\x2d\x1c\xe1\x6c\xe1\x8c\x5e\x4e\xbd\x34\x9e\x83\xab\x43\xe9\ +\x8e\x98\x92\x92\xa2\x97\xa2\x35\x35\x35\x85\xbf\xbf\x3f\x52\x53\ +\x53\x91\x92\x92\x02\x86\x61\xd0\xac\x59\xb3\xea\x2b\x56\x43\xd7\ +\xae\x5d\xd9\x84\x84\x84\x57\x2b\x3a\xa7\xe1\x5c\x41\x08\x69\x01\ +\x20\x2d\x24\x24\x04\x03\x07\x0e\xac\xd7\xc2\xf2\xed\xdb\xb7\xf1\ +\xec\xd9\x33\x74\xed\xda\x15\xe6\xe6\xe6\x7a\xbb\xcb\x02\x00\x76\ +\xed\xda\x85\x2f\xbe\xf8\x02\x71\x71\x71\x8d\xb6\x98\xde\xd4\x56\ +\xcd\xea\xf5\xe8\xd1\x03\x1f\x7c\xf0\x81\xd2\xf1\x40\x6f\xff\x17\ +\x52\xa9\x14\x2c\xcb\x6a\xc5\x29\x23\x32\x32\x12\xf3\xe6\xcd\x03\ +\x80\x96\x82\x20\x3c\x29\x7b\xbe\xa2\xae\x6f\x00\xc3\x30\x7c\x8f\ +\x1e\x3d\xea\x1d\x9c\x47\x1f\x76\xca\xd4\x94\xa4\xa4\x24\xd5\x50\ +\xac\x09\xfd\xc2\xd1\xd1\x11\x29\x29\x29\xd5\x17\xd4\x31\xe5\x03\ +\x26\x48\xa5\x52\xe4\xe6\xe6\xd6\x69\xa6\xd9\xdf\xdf\x1f\x34\x4d\ +\xf3\x1c\xc7\x0d\x00\xf0\x47\xd9\x73\x1a\xc2\x24\x84\x0c\xe8\xdc\ +\xb9\x33\x57\xdb\x19\x32\xb9\x5c\xae\x1a\x0a\x1b\x22\x49\x49\x49\ +\x3a\x1d\x1a\x37\x26\x37\xd3\x6f\x62\xc1\x99\x05\x90\x72\x86\x11\ +\xb6\xc5\x50\x44\x5b\x9e\x9c\x9c\x1c\x24\x26\x26\x22\x31\x31\x51\ +\x63\x22\xb6\x3a\x4c\x4c\x4c\xd0\xae\x5d\x3b\x0e\x80\x46\x8e\x55\ +\x0d\xd1\x8a\x44\xa2\xa1\x83\x06\x0d\xaa\xd5\xf3\x6c\x76\x76\x36\ +\x8e\x1e\x3d\x8a\x07\x0f\x1e\x20\x3f\x3f\xbf\x56\xc6\xe9\x0b\xc9\ +\xc9\xc9\x2f\x8d\x68\x4f\x3d\x3a\x85\x6b\xe9\xd7\x34\x96\x80\xf4\ +\x15\x47\x47\x47\xa4\xa6\x6a\xba\x65\xea\x3b\x0e\x0e\x0e\xf0\xf2\ +\xf2\x42\x76\x76\x36\x6e\xdf\xbe\x5d\xeb\xfd\xbc\xdd\xba\x75\x63\ +\x59\x96\x1d\x5a\xfe\xb8\x9a\x68\x09\x21\xae\x25\x25\x25\x4e\x7d\ +\xfb\x56\x38\xd3\x5c\x21\x4a\xc1\x8a\x44\x22\x8c\x1a\x35\x0a\xcd\ +\x9b\xd7\x38\x3e\x95\x5e\xf1\x32\x0d\x8f\xc3\x93\xc2\xd1\xdb\xa9\ +\x77\xf5\x05\xf5\x04\x43\xed\x69\x01\xc5\xfa\xae\x9f\x9f\x1f\x6c\ +\x6d\x6d\x6b\xed\x69\xd7\xa9\x53\x27\xc8\x64\x32\x27\x42\x88\x6b\ +\xd9\xe3\xe5\x7b\xda\x01\x22\x91\x88\xab\x4d\x2a\x0c\x6b\x6b\x6b\ +\x74\xeb\xd6\x0d\x43\x87\x0e\xd5\xb9\x47\x53\x5d\x91\xcb\xe5\x78\ +\xf2\xe4\xc9\x4b\xd1\xd3\xe6\x94\xe4\xe0\x56\xc6\x2d\x04\x39\x07\ +\x55\x5f\x58\x4f\x70\x74\x74\x44\x66\x66\xa6\x56\xd7\x42\x1b\x13\ +\x91\x48\x54\xa7\x0e\xc1\xcf\xcf\x0f\x2c\xcb\x6a\x0c\x91\xd5\x44\ +\x4b\x51\xd4\xa0\x1e\x3d\x7a\x08\x65\xb7\x41\xd5\x04\x4f\x4f\x4f\ +\x83\x0e\x2a\x9d\x9a\x9a\x0a\x9e\xe7\x5f\x0a\xd1\x5e\x4a\xb9\x04\ +\x40\xe1\x81\x65\x28\x28\x97\x7d\x0c\x71\x88\x5c\x11\x82\x20\x20\ +\x39\x39\x59\x63\x4f\x6f\x79\x44\x22\x11\xda\xb7\x6f\x2f\x10\x42\ +\xd4\x52\x37\xaa\x29\x8d\x61\x98\xc1\x03\x07\x0e\xac\x72\x31\xb5\ +\xa4\xa4\x04\x11\x11\x11\xd5\x5e\xd0\x90\x50\x3a\x56\xbc\x0c\xc3\ +\xe3\xf0\xe4\x70\x74\x70\xe8\x00\x4b\x51\xe3\x6c\x77\xd4\x06\x65\ +\xd7\x6a\x8d\x01\xa9\x54\xaa\xda\x28\x53\xdd\x16\xc0\x6e\xdd\xba\ +\x31\x34\x4d\xab\x65\x35\x57\x89\x96\x10\xd2\x4c\x2a\x95\xda\x97\ +\x8d\xb7\x54\x9e\xa2\xa2\x22\x84\x84\x84\xe0\xd1\xa3\x47\x1a\x69\ +\x16\x0d\x99\x47\x8f\x1e\x41\x2c\x16\x37\xda\x16\x40\x5d\x12\x9e\ +\x14\x8e\x20\x17\xc3\x19\x1a\x03\x80\x8d\x8d\x0d\xc4\x62\x31\x9e\ +\x3e\x7d\x5a\x7d\x61\x03\x40\x2c\x16\xc3\xc7\xc7\x07\x72\xb9\x1c\ +\xb1\xb1\xb1\x55\x4e\x50\xf9\xf9\xf9\x41\x2e\x97\xdb\x13\x42\x54\ +\x1e\x1b\x65\x7b\x5a\x2f\x00\x68\xdb\xb6\x6d\x85\x95\x0b\x0a\x0a\ +\x70\xec\xd8\x31\xc8\xe5\x72\x0c\x1b\x36\xac\xd1\x36\xa6\x37\x06\ +\xcf\x9f\x3f\x87\x8d\x4d\x8d\x42\xce\x1a\x34\x0f\x73\x1e\x22\x29\ +\x2f\xc9\xa0\x9e\x67\x95\x48\x24\x12\xe4\xe4\xe4\x54\x5f\xd0\x40\ +\x50\x0a\xd7\xc4\xc4\xa4\x4a\xb7\xc7\x32\x09\xd1\x54\xdb\xbe\xd4\ +\x44\x6b\x62\x62\xc2\x39\x39\xa9\xc7\xf9\x51\xc2\x30\x0c\xec\xec\ +\xec\x30\x7c\xf8\x70\x58\x58\x54\xec\xc2\x66\xa8\x64\x65\x65\xa9\ +\x65\xa3\x33\x56\xfe\x49\xfe\x07\x16\xac\x45\xad\xfd\x7f\xf5\x01\ +\x6b\x6b\x6b\xa3\x12\x2d\xa0\x78\x66\xf5\xf0\xf0\xa8\xd2\xbd\xd7\ +\xc1\xc1\x01\x62\xb1\x98\x43\x65\xa2\x75\x77\x77\xe7\x2a\x53\xbd\ +\x58\x2c\x46\xff\xfe\xfd\x75\x16\xf8\xaa\x21\xc9\xce\xce\x86\xb5\ +\xb5\xb5\xae\xcd\x68\x70\x2e\x24\x5d\x40\x0f\xa7\x1e\x6a\x1b\xee\ +\x0d\x05\x63\xeb\x69\x6b\x83\x8b\x8b\x4b\xc5\xa2\xa5\x69\xda\xc7\ +\xd7\xd7\x57\x2f\xc2\xa4\x36\x36\xd9\xd9\xd9\x46\x3f\x3c\x96\xf3\ +\x72\x5c\x4e\xbd\x8c\x3e\x2e\xba\x0b\x89\x5a\x1f\x24\x12\x89\x51\ +\xe4\xee\xa9\x8a\xf4\xf4\x74\x3c\x78\xf0\x40\xe3\xb8\xbb\xbb\x3b\ +\x4b\xd3\xb4\x2a\x3a\x83\xea\x96\xcb\x30\x8c\x9f\x97\x97\x97\x5a\ +\x37\x1b\x13\x13\x83\xe2\xe2\x62\xb5\xc4\xc0\xc6\x48\x76\x76\xb6\ +\xd1\x2f\xf7\xdc\x4c\xbf\x89\x3c\x69\x9e\x41\x39\x55\x94\xc5\xda\ +\xda\x5a\xb5\x13\x0b\x00\xee\xdf\x17\xe3\xca\x15\x75\xbf\x00\x13\ +\x13\x1e\xcd\x9b\xcb\xe1\xe3\x53\x04\x7b\x7b\xfd\xcc\x26\x50\x15\ +\x62\xb1\x18\x8f\x1f\x3f\x86\xa9\xa9\xa9\x9a\x93\x52\xeb\xd6\xad\ +\x09\x4d\xd3\x2a\x47\x7e\x06\x00\x08\x21\x2c\x21\xc4\xd9\xcb\xab\ +\x34\xc4\x49\x5a\x5a\x1a\xae\x5c\xb9\x82\x4e\x9d\x3a\x35\xa6\xdd\ +\x3a\x21\x2b\x2b\x4b\x27\x31\xa9\x1a\x93\xf0\xe4\x70\x38\x5b\x3a\ +\xa3\x8d\x75\x1b\x5d\x9b\x52\x27\x24\x12\x09\x6e\xdd\xba\xa5\x7a\ +\x7d\xfd\xba\x19\xd6\xae\xad\x38\x66\x33\x4d\x0b\x18\x3b\x36\x0b\ +\x2b\x56\xa4\xa2\x9e\x5b\x5b\x1b\x15\x89\x44\x02\x67\x67\x67\xa4\ +\xa4\xa4\xa8\x45\x21\x6d\xdd\xba\x35\x64\x32\x99\x33\x21\x84\x15\ +\x04\x41\xa6\x1c\x1e\xbb\x09\x82\x40\x2b\x67\x8e\x8b\x8b\x8b\x71\ +\xe6\xcc\x19\xb8\xba\xba\x1a\xfd\x97\x19\x78\x39\x86\xc7\xe1\xc9\ +\xe1\x06\x39\x6b\xac\xa4\xaa\x67\xda\x66\xcd\xe4\xe8\xdc\xb9\x00\ +\x76\x76\x8a\x35\x4f\x8e\x23\x38\x70\xc0\x16\xc7\x8e\x19\xde\x3c\ +\x85\x32\xe6\x72\xd9\x2d\x7b\xad\x5b\xb7\x86\x20\x08\x34\x00\x37\ +\xa0\x74\x78\xec\x45\x08\x51\xa5\x49\xc8\xcb\xcb\x83\x44\x22\x41\ +\x50\x90\xe1\xfe\x93\x6b\x83\xb1\x8b\x36\x4f\x9a\x87\x9b\xe9\x37\ +\x31\xd3\xdf\x70\x73\x0b\x57\x35\x7b\xdc\xaf\x5f\x2e\x56\xac\x50\ +\x04\x5f\x5f\xb4\xc8\x19\xc7\x8f\x4b\x00\x00\x77\xef\x9a\x62\xc4\ +\x08\xc5\x73\x70\x71\x31\x85\x63\xc7\x24\x48\x48\x10\x23\x23\x83\ +\x41\x51\x11\x05\x7b\x7b\x19\x3c\x3c\x4a\x30\x6a\xd4\x73\x98\x9b\ +\xf3\xe0\x79\x60\xfb\xf6\x66\x90\xcb\x29\xd8\xda\xca\x30\x61\x42\ +\xa6\xea\x1a\x3c\x4f\xf0\xcb\x2f\xcd\xc1\xf3\x80\xa3\xa3\x14\x23\ +\x47\x96\x9e\xbb\x78\xd1\x0a\x57\xaf\x5a\x20\x29\x49\x0c\x5b\x5b\ +\x19\xda\xb6\x2d\xc2\xc8\x91\xcf\xa1\xf0\x40\x54\x70\xf5\xaa\x25\ +\xae\x5d\xb3\x84\x20\x08\x18\x3e\x3c\x13\xcf\x9f\x33\x38\x7d\xda\ +\x16\x4f\x9f\xb2\x68\xdf\x3e\x1f\x13\x27\xa6\x83\xa2\x14\x42\x2d\ +\x1f\x3d\xa5\xcc\x6b\x2f\x00\xf7\x94\xa2\xf5\x6e\xd1\xa2\x45\x89\ +\x99\x99\x99\x18\x50\x4c\x33\x2b\xe3\x43\xe9\x53\x48\x98\x86\x80\ +\xe7\x79\xe4\xe6\xe6\x1a\xb5\x68\x2f\xa7\x5e\x06\x2f\xf0\xb5\x8e\ +\x1a\xa1\x4f\x48\x24\x12\x14\x15\x15\xa9\x36\x9a\x57\x86\x87\x47\ +\xa9\x7f\x72\xab\x56\xa5\x7f\x3f\x7b\xc6\xe0\xb3\xcf\x2a\x5e\xce\ +\xdc\xb6\xad\x19\xfe\xfc\x33\x1e\x8e\x8e\x52\xc4\xc7\x9b\xe2\xc4\ +\x09\x6b\x10\x02\xf4\xea\x95\x07\x27\x27\xc5\xf6\xc5\xab\x57\x2d\ +\xf0\xc3\x0f\x8a\xe1\xf8\x7f\xff\xab\xb8\x41\x48\xa5\x14\x16\x2e\ +\x6c\x83\x8b\x17\x35\xb3\x49\xfe\xfa\x6b\x0b\x6c\xd8\x10\x8f\xb6\ +\x6d\x8b\x5e\xd4\xb7\xc4\x2f\xbf\x28\xe2\xa1\x3d\x7a\x64\x82\xd3\ +\xa7\x6d\xc0\x71\x8a\xb1\xfb\xa9\x53\xb6\x88\x8f\x37\xc3\xa7\x9f\ +\x6a\x4e\x42\x01\x8a\x67\x5d\x7b\x7b\xfb\x92\x8c\x8c\x0c\x6f\x00\ +\x87\x95\xc3\x63\x2f\x1f\x1f\x1f\xfd\x48\xd6\xd3\xc8\xe4\xe4\xe4\ +\x40\x10\x04\xa3\x16\xed\x85\xa4\x0b\x68\xef\xd0\x1e\xd6\x26\x86\ +\x37\x5c\x54\x22\x91\x28\x7a\xcf\x8a\x7a\xdb\x67\xcf\x58\x44\x45\ +\x99\x63\xef\x5e\x5b\x04\x07\x2b\xfe\x8f\x16\x16\x3c\xfa\xf7\x2f\ +\x0d\x30\xce\x30\x02\x46\x8d\xca\xc2\x96\x2d\x8f\xf0\xd7\x5f\xf1\ +\xf8\xe5\x97\x44\x4c\x9a\xa4\xc8\xb4\x90\x9d\xcd\x60\xd3\x26\x85\ +\x20\xdf\x7a\x4b\x71\x4c\x10\x80\xbf\xff\x2e\x5d\xbb\x3f\x79\x52\ +\xf1\xd9\x51\x94\x80\x11\x23\x14\x01\x12\xb7\x6d\x6b\xa1\x12\x6c\ +\x9b\x36\xc5\x58\xb2\x24\x09\x7d\xfb\x2a\xec\x4b\x4d\x15\xe1\xb3\ +\xcf\x5c\x55\xc2\x2c\x4b\x68\xa8\x2d\xba\x75\xcb\xc5\xac\x59\x69\ +\x10\x89\x14\xfb\x6c\x8f\x1d\xb3\x47\x56\x96\xe6\xcd\xa8\xb8\xb8\ +\xf8\x45\xfb\x6d\x68\xbc\x58\xf6\xa1\x00\x40\x2c\x16\xfb\xf8\xf8\ +\xf8\x30\xba\x48\x85\xa0\x6b\xb2\xb2\xb2\x00\xc0\xa8\x45\xfb\x4f\ +\xf2\x3f\x06\xfd\x3c\x0b\x40\xb5\x8e\x5e\x91\x68\xcf\x9e\xb5\xc4\ +\xf4\xe9\xae\x58\xb5\xaa\x25\x52\x53\x59\xf8\xf9\x15\xe1\xef\xbf\ +\xe3\xd0\xbc\x79\xe9\x0c\x72\xcb\x96\x32\x7c\xf1\x45\x32\xdc\xdc\ +\x8a\x91\x97\x47\x23\x3b\x9b\x81\xaf\x6f\x21\xcc\xcc\x14\xa2\x89\ +\x8d\x55\x64\x95\xf7\xf7\x2f\x40\xbb\x76\x0a\x17\xdd\x43\x87\x6c\ +\xc1\xf3\x04\x1c\x47\x70\xfa\xb4\xe2\xa6\xd1\xb3\x67\x1e\x1c\x1c\ +\x14\xed\x1e\x3c\x58\x1a\x91\xe2\xfb\xef\xe3\xf0\xfa\xeb\xcf\xf0\ +\xf5\xd7\x09\xf0\xf2\x52\xd4\xbf\x7f\xdf\x0c\xb1\xb1\x9a\x7e\x0d\ +\x83\x07\x3f\xc7\xe6\xcd\x71\x78\xf7\xdd\x14\xbc\xf2\x8a\xe2\x06\ +\xc0\xf3\x40\x4a\x8a\xfa\x46\x9d\xe2\xe2\x62\xdc\xb9\x73\x07\x39\ +\x39\x39\x70\x75\x75\x65\x58\x96\xf5\x01\x4a\x67\x8f\xed\x6d\x6d\ +\x6d\x71\xe8\xd0\x21\xf8\xf8\xf8\xe8\x2c\xd5\xa3\x2e\x50\xa6\x7b\ +\x30\x35\x35\xd5\xb1\x25\x0d\x43\x52\x5e\x12\x1e\xe6\x3c\x34\xd8\ +\xf5\x59\x25\x26\x26\x8a\x78\xc9\xca\x9e\xa7\x2c\x96\x96\x1c\xcc\ +\xcd\x79\x3c\x79\xa2\xe8\xa9\x62\x62\x4c\x70\xe2\x84\x04\xd3\xa6\ +\x95\xe6\x2c\xca\xca\x62\xb0\x60\x81\x0b\xae\x5e\xad\x78\xfb\x68\ +\x46\x46\x69\x2f\xf7\xd6\x5b\x19\x58\xbe\xbc\x15\x9e\x3d\x63\x71\ +\xe1\x82\x25\x44\x22\x1e\x39\x39\x8a\x27\xc9\x31\x63\x14\x22\xcb\ +\xcc\x64\x90\x9b\xab\x18\x9c\xb6\x6a\x55\xa2\x76\x83\x08\x0c\xcc\ +\xc7\xbd\x7b\x0a\xb1\x3e\x78\x60\x02\x5f\x5f\xf5\x68\x2e\xdd\xba\ +\xe5\xaa\xfe\xb6\xb2\x2a\xed\x28\x0b\x0a\xd4\x77\xca\x99\x98\x98\ +\xc0\xc6\xc6\x06\xc9\xc9\xc9\x90\x48\x24\x20\x84\xd8\x03\x2f\x7a\ +\x5a\x41\x10\x2c\xad\xad\xad\x91\x9d\x9d\x8d\x16\x2d\xea\x9f\xfa\ +\xd0\x90\x90\x4a\x15\xcf\x2c\xe5\xe3\xfb\x18\x0b\xe1\x49\xe1\x30\ +\x67\xcd\x11\xd8\x3c\x50\xd7\xa6\xd4\x0b\xe5\xff\xa7\x22\xe7\xfa\ +\x57\x5f\xcd\xc1\xa9\x53\xf7\xb1\x6f\x5f\x22\x4c\x4c\x78\x70\x1c\ +\xc1\xa6\x4d\xcd\x11\x13\x53\x7a\x23\xfe\xea\xab\x96\x2a\xc1\x0e\ +\x1d\x9a\x8d\xd5\xab\x93\xb0\x69\xd3\x43\x48\x24\x8a\xc9\xa2\xb2\ +\x53\x37\x43\x86\x64\xc3\xd6\x56\x21\xa6\x83\x07\xed\x10\x1a\xaa\ +\xe8\xe5\x25\x12\x39\xfa\xf4\x51\xf4\xf4\x26\x26\xa5\x15\x0a\x0a\ +\xd4\x9f\x2c\xcb\xbe\x16\x8b\x35\xc3\xcc\xb4\x68\x51\x1a\xe6\xa7\ +\xba\x0c\xb2\x2d\x5b\xb6\x44\x71\x71\x31\x1c\x1c\x1c\x00\xc0\x12\ +\x78\x21\x5a\x9e\xe7\xcd\x4d\x4d\x4d\x61\x6d\x6d\xfd\x52\xf8\xe0\ +\x96\x45\xf9\x48\x60\xac\xa2\xbd\x90\x74\x01\xdd\x1d\xbb\x1b\xa4\ +\xeb\x62\x59\x94\x93\x4f\x55\xed\x88\x69\xd7\xae\x08\xff\xfd\xaf\ +\x22\x35\x09\xcf\x13\xac\x5f\x5f\xda\x01\xc5\xc6\x2a\x7a\x6a\x8a\ +\x12\xf0\xd9\x67\x29\x18\x31\x22\x1b\xce\xce\x52\xe4\xe4\x68\xaa\ +\x86\x65\x05\xbc\xfe\xba\x62\x76\xf8\x9f\x7f\x2c\x11\x16\xa6\x10\ +\xed\xf0\xe1\x59\x60\x59\x85\x58\xcd\xcd\x39\x34\x6f\xae\x10\x5f\ +\x66\x26\x83\x98\x18\xb3\x17\xf6\x11\x44\x47\x97\x6e\xa6\x71\x77\ +\xaf\x5f\x90\x75\x53\x53\x53\x38\x38\x38\x40\x24\x12\x81\xe7\x79\ +\x73\xe0\x85\x68\x39\x8e\x33\x63\x18\x06\x6d\xda\x18\xe6\xc2\x7b\ +\x7d\x50\x7e\x09\x1a\x3b\xe9\x56\x63\xc0\x0b\x3c\x2e\xa5\x5c\x42\ +\x6f\x67\xc3\xf4\x82\x2a\x4b\x4d\x44\x0b\x00\x13\x27\x66\xa9\xd6\ +\x6b\xa3\xa2\xcc\x55\xbd\xab\x72\x16\x98\xe7\x09\x56\xac\x70\xc6\ +\x0f\x3f\x34\xc3\x7f\xff\x5b\xf9\xf7\xfd\xf5\xd7\x33\xc1\x30\x02\ +\x78\x9e\xa8\x7a\xce\xd1\xa3\xd5\x33\x74\xbc\xff\x7e\x69\x64\xd3\ +\x19\x33\xbc\xb0\x74\x69\x1b\x8c\x1c\xe9\x87\x94\x14\x45\x07\x30\ +\x60\x40\x36\xdc\xdc\x34\x87\xf3\xb5\xa5\x55\xab\x56\x60\x18\x06\ +\x1c\xc7\x99\x01\x00\x45\x08\x31\xe1\x79\x9e\x6e\xd6\xac\x19\x3a\ +\x76\xec\x58\xef\x0b\x18\x1a\xc6\x3c\x3c\xbe\x99\x7e\x13\x39\x25\ +\x39\x06\xff\x3c\x0b\xd4\x5c\xb4\x62\x31\x8f\x69\xd3\x4a\xd7\x50\ +\xb7\x6e\x55\x6c\x43\x9d\x37\xef\x29\x2c\x2d\x15\x43\xe1\xd0\x50\ +\x09\x7e\xf8\xa1\x39\x5e\x7d\x35\x1b\x2e\x2e\x15\x47\xa4\xb4\xb7\ +\x97\x61\xf0\xe0\xd2\x49\x2f\x1f\x9f\x22\xd5\xf2\x8d\x92\x51\xa3\ +\x32\xf1\xdf\xff\xa6\xc2\xd4\x94\x87\x54\x4a\x10\x1a\x6a\x83\x67\ +\xcf\x14\x76\xbe\xf2\x4a\x16\x3e\xf9\xe4\x51\x2d\xdf\x65\xe5\x98\ +\x99\x99\x41\x10\x04\x9a\x10\x62\xc2\xe0\xc5\x38\xd9\xc2\xc2\xa2\ +\xde\xe9\x0c\x0c\x11\xe5\xf0\xd8\x18\x7b\xda\x7f\x92\xff\x81\xa3\ +\x85\x23\xdc\xad\xf5\x2f\x32\x7f\x6d\x29\x2f\xda\xfe\xfd\xf3\xe0\ +\xe6\xa6\x10\x9c\x83\x83\xba\xf0\xde\x7c\xf3\x39\x7c\x7d\x15\x33\ +\xb8\x84\x28\x7a\x57\x1f\x9f\x62\x1c\x39\x72\x1f\x17\x2f\x5a\x42\ +\x2a\x25\xf0\xf5\x2d\x82\x97\x57\x21\x06\x0e\xcc\x41\x71\x31\xa5\ +\x72\x6c\x28\xcb\xf0\xe1\xcf\x71\xfc\xb8\x62\x68\x3c\x6a\x54\xa6\ +\xc6\x79\x00\x98\x36\xed\x29\x46\x8f\xce\xc4\x9d\x3b\xa6\x48\x4a\ +\x12\xc3\xce\x4e\x0e\x4f\xcf\x22\xb8\xba\x16\xab\xf9\x38\x8c\x1a\ +\x95\x81\x2e\x5d\xf2\x20\x08\x02\x3c\x3d\x4b\x03\x48\x8c\x1b\x97\ +\x8e\x9e\x3d\x15\x0e\x20\xe5\x6f\x0a\x65\x29\xb3\xbb\xce\x92\x01\ +\x60\x05\xc0\xa8\x36\xb5\xd7\x06\x65\x4f\x6b\x2c\xa2\xbd\x9b\x79\ +\x17\x91\xa9\x91\x48\xcc\x7e\x80\x73\x8f\xcf\xc2\xcf\xc1\x70\x02\ +\xc6\x57\x85\x72\xcf\xa9\x52\xb4\xcd\x9a\xc9\xd1\xac\x99\xe2\x86\ +\x5b\xde\x01\xc8\xc4\x84\x47\x97\x2e\x9a\xf1\xb7\x6d\x6d\xe5\x18\ +\x39\x32\x4b\xf5\x5a\x10\x00\x3f\x3f\xcd\x08\x2c\x59\x59\x0c\x9e\ +\x3e\x65\xf1\xd7\x5f\x0e\x00\x14\x13\x47\xa3\x46\x69\x24\xaf\x53\ +\x61\x63\x23\x47\xaf\x5e\xb9\x95\x9e\x07\x14\x5e\x54\x8e\x8e\x52\ +\x0d\x5b\x9d\x9c\x4a\xe0\xe4\x54\x82\x1b\x37\x14\x37\x93\xca\x10\ +\x8b\xc5\x98\x30\x61\x02\xf6\xed\xdb\x67\xc5\x00\xb0\x54\xee\xa0\ +\x7f\x19\x91\xcb\xe5\x46\x31\x34\x2e\x96\x17\x63\xf5\xe5\x35\xd8\ +\x75\x7b\x57\x99\x2f\x86\x80\xc7\xb9\x8f\xb1\x3c\xfc\x53\x2c\xeb\ +\xbe\x54\x23\x75\xa6\xa1\xc1\xb2\x6c\xad\x63\x07\xd7\x85\x2f\xbe\ +\x70\x56\xad\xcb\x02\xc0\xf2\xe5\xc9\xaa\xf5\xdc\x86\x22\x2a\xca\ +\x0a\x1f\x7e\xe8\x89\x19\x33\xd2\xf0\xc6\x1b\x69\xaa\x09\x2f\x25\ +\x0c\xc3\xa0\x7b\xf7\xee\xd8\xb7\x6f\x9f\x25\x63\x6b\x6b\x6b\x37\ +\x6f\xde\x3c\x55\x8f\xf3\xb2\x21\x93\xc9\x8c\xa2\x97\x5d\x72\x6e\ +\x29\x0e\xde\x3f\xa8\x71\x5c\x00\xf0\xfb\x9d\xdf\x91\x53\x92\x83\ +\x6f\x07\x6d\x69\x7c\xc3\xb4\x48\x63\x89\xd6\xdb\xbb\x08\xc5\xc5\ +\x14\xdc\xdd\x8b\xd1\xbf\x7f\x0e\x02\x02\x1a\x27\x00\x7f\x61\x21\ +\x8d\xef\xbe\x73\xc6\xff\xfd\x9f\x3d\x3e\xfc\x30\x09\x41\x41\xa5\ +\xa3\x02\x33\x33\x33\x98\x98\x98\xc0\xc5\xc5\xa5\x05\xe3\xe1\xe1\ +\xd1\x06\xc0\x4b\x11\xd4\xac\x22\xa4\x52\xa9\xc1\xf7\xb4\x67\x1f\ +\x9d\xad\x40\xb0\xea\x77\xea\x23\xf1\x47\x30\xae\xed\x58\xf4\x6f\ +\xd5\xbf\xf1\x0c\xd3\x32\x8d\x25\xda\xd9\xb3\xd5\x03\xc8\x35\xb6\ +\xfb\x7d\x72\xb2\x09\x3e\xfa\xc8\x13\xdd\xba\xe5\x60\xfe\xfc\xc7\ +\x68\xd3\xa6\x48\x15\x53\xdc\xd5\xd5\xd5\x95\xb2\xb7\xb7\x6f\x05\ +\xbc\xbc\xa2\x95\xcb\xe5\x06\xdf\xd3\x9e\x7d\x7c\xae\x46\xe5\x4e\ +\x3f\x3a\xd3\xb0\x86\x34\x30\x8d\x25\x5a\x7d\x21\x22\x42\x82\xb7\ +\xdf\xf6\xc3\xd7\x5f\xb7\x06\x21\xb6\xd8\xbe\x7d\xbb\x10\x17\x17\ +\x27\x65\xb2\xb2\xb2\x6c\x62\x62\x62\x04\x53\x53\x53\x8d\xb4\x97\ +\x2f\x03\x62\xb1\x18\xbe\xbe\xbe\xba\x36\xa3\x5e\xc4\x64\xc6\x68\ +\x1e\xbc\xb4\x1c\xb8\xb8\x5c\xed\xd0\x1e\x42\xb0\x8f\x32\xdc\x1b\ +\x94\x4c\xd6\x11\xeb\xd7\xb7\xc2\xd7\x5f\xfb\x54\x5f\xd8\xc0\xa8\ +\x68\x63\x81\xf2\xf8\xde\xbd\xcd\x71\xf2\xa4\x1d\xf2\xf3\x5b\x0a\ +\x72\x79\xb4\x0d\x73\xf9\xf2\x65\xd9\xe5\xcb\x97\xc9\xea\xd5\xab\ +\x0d\x7e\x98\x58\x17\x8a\x8a\x8a\x10\x1b\x1b\xab\x6b\x33\xea\x45\ +\x33\xb3\x0a\x92\x18\xbb\x1f\x03\x2c\xd5\x83\x7b\xfb\xd9\xb7\xc7\ +\xd4\xf6\x8a\x0c\xf1\x35\xc9\x93\x5a\x11\x35\x29\x57\xd3\x1c\xaf\ +\xb5\xad\xb7\x76\xed\x2d\xf4\xea\xd5\x03\xbd\x7b\xa7\xd5\xba\xed\ +\x8a\xca\xd5\xe7\x3d\xd7\xf5\xfd\x54\x56\xe6\xfc\x79\x1b\x9c\x3f\ +\x5f\xf1\x2e\x2c\x4b\x4b\x39\xa6\x4e\x7d\x88\xcd\x9b\x4f\x50\x00\ +\x5a\x31\x00\x92\x00\xe0\xe1\xc3\x87\x95\xc6\x3c\x36\x66\x58\x96\ +\x35\xf8\x49\xb8\x0e\xcd\xfc\x71\x24\xfe\x88\xfa\xc1\xe6\x37\x14\ +\x3f\x65\x18\xd9\x63\x29\xc6\x77\x50\x4c\xaa\x18\x52\x52\x69\x25\ +\x1b\x37\x4a\x11\x18\xc8\x61\xcc\x98\xec\x4a\xcb\x34\x86\x9d\xda\ +\x6c\x4b\xf9\x3a\x2d\x4d\xac\x21\x5a\x8a\x12\x30\x6e\xdc\x33\xbc\ +\xf3\x4e\x32\x32\x33\xef\x63\xf3\x66\x39\x00\x24\x51\x00\x1e\x01\ +\x40\x5c\x5c\x9c\xc6\x05\x5e\x06\x18\x86\x31\x78\xd1\xbe\xed\xfb\ +\x36\x9c\x2d\xab\x4e\x69\xd2\xd2\xbc\x25\xde\x6e\xf7\x76\x23\x59\ +\xd4\x30\x54\xb7\x01\xde\x98\xe8\xd4\x29\x17\xbf\xff\x7e\x07\x8b\ +\x16\x3d\x84\x44\x22\x57\xa5\xae\x01\xf0\x88\x02\x90\x0c\xa0\xc2\ +\xd0\x8d\x2f\x03\x22\x91\xc8\xe0\x45\x6b\xce\x9a\xe3\xdb\xc1\x5b\ +\x60\x67\x5a\xf1\x64\xa2\x8d\x89\x0d\xbe\x19\xb4\x09\xe6\xac\x61\ +\x66\x35\x54\x62\x2c\xcb\x73\x55\xe1\xe8\x58\x82\xaf\xbe\x8a\xc3\ +\xd6\xad\xb1\x70\x77\x2f\x75\xfc\x28\x93\x7c\xec\x11\x03\x20\x17\ +\x50\xe4\xb3\x79\x19\x61\x18\xc6\x28\x66\x24\x3b\xb5\xe8\x84\x53\ +\x6f\x84\x61\x43\xe4\x46\x5c\x4e\xb9\x8c\x87\x39\x0f\xe1\x2a\x71\ +\x45\x0f\xa7\x1e\x58\xd0\x79\x7e\xa5\x82\x36\x24\x8c\x59\xb4\xa6\ +\xa6\x1c\xde\x7f\x3f\x05\x6f\xbf\xfd\x44\x2d\xb6\x94\x92\x32\xa2\ +\xcd\x65\x00\xe4\x01\xc0\xbf\xff\xfe\xdb\x78\x16\xea\x11\x2c\xcb\ +\x82\xe7\x79\x70\x1c\x07\xba\xba\xcd\x8d\x7a\x8e\x9d\xa9\x1d\x56\ +\xf7\xf9\x12\x80\x22\x38\xb9\x72\x3b\x9e\x31\xac\x0a\x70\x1c\x07\ +\x9e\xe7\x8d\x56\xb4\x93\x26\x95\xee\x18\xaa\xe8\xdf\x15\x1f\x1f\ +\xaf\xfc\x33\x8f\xc2\x0b\xd1\x5e\xba\x74\x09\xf9\xf9\x8d\xe3\xf9\ +\xa1\x4f\x54\xb5\xb9\xda\x90\x31\xf4\xfd\xb3\xe5\x31\xe6\x2d\x94\ +\xd5\x51\x54\x54\x54\xb6\x53\xcd\xa5\x00\xe4\x03\x10\x78\x9e\xc7\ +\xb1\x63\xc7\x74\x67\x99\x8e\x50\x3a\xa2\x1b\xfa\x73\xad\xb1\xf3\ +\x32\x8b\x36\x3c\x3c\x1c\x3c\xcf\x03\x0a\x37\xb7\x02\x4a\x10\x04\ +\x9e\xa6\xe9\x62\x5f\x5f\x5f\xec\xdf\xbf\x5f\xc7\xe6\x35\x3e\xc6\ +\xda\xd3\x1a\x1b\x2f\xb3\x68\x4f\x9d\x3a\x05\x57\x57\x57\xd0\x34\ +\x5d\x2c\x08\x02\x4f\x01\x00\xc3\x30\x05\x7e\x7e\x7e\x08\x0d\x0d\ +\x45\x6e\x6e\xd5\x5b\x8c\x8c\x8d\xa6\x9e\xd6\x30\x78\x59\x45\x5b\ +\x50\x50\x80\xcb\x97\x2f\xc3\xdd\xdd\x1d\x14\x45\x15\x00\x2f\xc2\ +\xcd\x10\x42\xf2\x5d\x5d\x5d\x01\x00\xbb\x77\xef\xd6\x9d\x85\x3a\ +\x40\xf9\x25\x68\x12\xad\x7e\xa3\x14\xed\xcb\xe6\xb5\x77\xf4\xe8\ +\x51\x08\x82\x00\x27\x27\x27\x10\x42\xf2\x81\xd2\x54\x97\x79\x32\ +\x99\x0c\x73\xe6\xcc\xc1\x97\x5f\x7e\x69\xf4\x29\x05\xcb\xa2\xdc\ +\x47\xdc\x24\x5a\xfd\xc6\xd8\x82\x15\xd4\x84\xbc\xbc\x3c\x6c\xdf\ +\xbe\x1d\x13\x26\x4c\x00\xc7\x71\xc0\x8b\x49\x63\x0a\x00\xa4\x52\ +\x69\x42\x62\x62\xa2\xb0\x74\xe9\x52\x50\x14\x85\x2f\xbf\xfc\x52\ +\x97\xb6\x36\x2a\xca\xdd\x4d\x2f\x6b\xc2\x62\x43\x41\x19\x9f\xda\ +\xc2\xc2\x42\xc7\x96\x34\x1e\xdb\xb7\x6f\x07\x45\x51\x98\x31\x63\ +\x06\x52\x53\x53\x05\xb9\x5c\x9e\x00\x94\x86\x50\xbd\x7b\xe7\xce\ +\x1d\xa9\x44\x22\xc1\xca\x95\x2b\xf1\xc3\x0f\x3f\x94\x5d\x17\x32\ +\x6a\x94\x91\xeb\x5f\xa6\xd1\x85\x21\xa2\xbc\xa9\x2a\xff\x5f\xc6\ +\x4e\x52\x52\x12\xf6\xef\xdf\x8f\x77\xdf\x7d\x17\x16\x16\x16\x48\ +\x48\x48\x90\xf2\x3c\x7f\x17\x28\x1d\x1e\xdf\x4b\x4c\x4c\x64\x04\ +\x41\xc0\x8c\x19\x33\xe0\xe5\xe5\x85\x25\x4b\x96\xe8\xd0\xe4\xc6\ +\x43\x2c\x16\xc3\xc4\xc4\x44\x95\x1e\xa4\x09\xfd\x24\x27\x27\x07\ +\x34\x4d\xbf\x34\x3d\xed\x96\x2d\x5b\xd0\xba\x75\x6b\x8c\x1e\x3d\ +\x1a\x82\x20\x20\x25\x25\x85\x01\x70\x0f\x28\x23\xda\x92\x92\x12\ +\x3a\x39\x39\x19\x34\x4d\x63\xc3\x86\x0d\x38\x72\xe4\x08\x82\x83\ +\x83\x75\x67\x75\x23\x62\x6d\x6d\x8d\xe7\xcf\x2b\x0f\xdc\xd5\x84\ +\xee\xc9\xce\xce\x56\x25\xe1\x32\x76\x4e\x9f\x3e\x8d\x0b\x17\x2e\ +\x60\xfe\xfc\xf9\xa0\x28\x0a\xe9\xe9\xe9\x90\x4a\xa5\x34\xca\x8b\ +\x16\x00\xee\xdd\xbb\x07\x00\xe8\xdf\xbf\x3f\xfe\xf3\x9f\xff\x60\ +\xf6\xec\xd9\xb8\x73\xe7\x8e\x4e\x0c\x6f\x4c\x6c\x6c\x6c\x9a\x86\ +\xc7\x7a\x4e\x4e\x4e\xce\x4b\x21\xda\x84\x84\x04\xac\x5a\xb5\x0a\ +\x13\x27\x4e\x44\x97\x2e\x5d\x00\xa8\xed\x0b\x28\x15\xad\x20\x08\ +\xd9\x22\x91\x28\xeb\xfe\xfd\xfb\xaa\xca\xeb\xd6\xad\x43\xa7\x4e\ +\x9d\xf0\xfa\xeb\xaf\x1b\xfd\xd0\x51\x22\x91\x18\xfd\x7b\x34\x74\ +\x5e\x06\xd1\xe6\xe5\xe5\x61\xd1\xa2\x45\xf0\xf1\xf1\xc1\x07\x1f\ +\x7c\xa0\x3a\xfe\xe8\xd1\x23\x30\x0c\x93\x25\x08\x42\x36\x50\xda\ +\xd3\x82\x10\x72\x4f\xd9\xd3\x02\x0a\xa7\x83\x3f\xfe\xf8\x03\x32\ +\x99\x0c\x53\xa6\x4c\x51\xba\x51\x19\x25\x36\x36\x36\x4d\xc3\x63\ +\x3d\x27\x3b\x3b\xdb\xa8\x27\xa1\x78\x9e\xc7\x27\x9f\x7c\x02\xb9\ +\x5c\x8e\xd5\xab\x57\xab\x6d\x5e\x79\xf4\xe8\x11\x08\x21\x2a\x71\ +\xaa\x44\x5b\x52\x52\x72\xfb\xee\xdd\xbb\x6a\x09\x6a\x1d\x1c\x1c\ +\xb0\x6f\xdf\x3e\xfc\xf3\xcf\x3f\xf8\xf4\xd3\x4f\x1b\xc5\x78\x5d\ +\xa0\xcc\x18\xd8\x84\xfe\x62\xec\x3d\xed\xf7\xdf\x7f\x8f\xeb\xd7\ +\xaf\x63\xdd\xba\x75\x1a\xb9\x92\x13\x13\x13\xe5\x32\x99\xec\xb6\ +\xf2\x75\xd9\x84\x98\xf7\x62\x62\x62\x34\xba\xd3\x8e\x1d\x3b\x62\ +\xeb\xd6\xad\xf8\xfa\xeb\xaf\xb1\x71\xe3\xc6\x86\xb3\x5a\x87\xd8\ +\xd8\xd8\x34\x0d\x8f\xf5\x1c\x63\x9e\x88\xda\xbd\x7b\x37\x7e\xff\ +\xfd\x77\x7c\xf2\xc9\x27\xf0\xf6\xf6\xd6\x38\xff\xe0\xc1\x03\x1e\ +\x2f\x9e\x67\x81\x17\x49\xa5\x5f\x70\xef\xd9\xb3\x67\xa2\xfc\xfc\ +\x7c\x8d\x69\xf5\x37\xdf\x7c\x13\xb9\xb9\xb9\xf8\xf0\xc3\x0f\x91\ +\x9f\x9f\x8f\x15\x2b\x56\x34\x94\xfd\x3a\xa1\x69\xf6\x58\xff\x31\ +\xd6\x9e\x76\xdb\xb6\x6d\xd8\xb9\x73\x27\x16\x2d\x5a\x84\xa1\x43\ +\x87\x6a\x9c\x2f\x2a\x2a\xc2\xf3\xe7\xcf\x45\xa8\x44\xb4\xb1\x00\ +\x70\xff\xfe\x7d\x04\x06\x6a\x26\x20\x56\x2e\xf2\xbe\xf3\xce\x3b\ +\xc8\xcd\xcd\xc5\xfa\xf5\xeb\x8d\x26\x61\x57\xd3\xf0\x58\xff\x31\ +\xb6\x67\x5a\x41\x10\xf0\xf5\xd7\x5f\x63\xdf\xbe\x7d\x58\xb9\x72\ +\x25\x86\x0d\x1b\x56\x61\xb9\xc7\x8f\x1f\x2b\xff\x54\x85\x0c\x2d\ +\x2b\xda\x07\x14\x45\xc9\xee\xdc\xb9\xc3\x56\x24\x5a\x00\x78\xfb\ +\xed\xb7\x61\x66\x66\x86\xa9\x53\xa7\x22\x3f\x3f\x1f\x5b\xb7\x6e\ +\x05\x45\x51\x15\x96\x35\x24\x9c\x9c\x9c\x90\x9b\x9b\x8b\x92\x92\ +\x12\x88\xc5\x62\x5d\x9b\xd3\x44\x39\x4a\x4a\x4a\x90\x9f\x9f\x6f\ +\x34\x01\xf5\x79\x9e\xc7\x97\x5f\x7e\x89\xe3\xc7\x8f\x63\xf5\xea\ +\xd5\x18\x30\x60\x40\xa5\x65\xe3\xe3\xe3\x41\x51\x94\x8c\xe7\x79\ +\x55\x10\x37\x95\xe2\x04\x41\x90\xd3\x34\x1d\x79\xfe\xfc\xf9\x2a\ +\x63\x93\x8c\x1d\x3b\x16\xfb\xf6\xed\xc3\xbe\x7d\xfb\x30\x65\xca\ +\x14\x14\x17\xd7\x3f\x69\xae\xae\x71\x71\x71\x81\x20\x08\x65\x23\ +\xde\x35\xa1\x47\xa4\xa5\xa5\x41\x10\x04\x38\x3a\x3a\xea\xda\x94\ +\x7a\x23\x95\x4a\xf1\xc9\x27\x9f\xe0\xe4\xc9\x93\xd8\xb0\x61\x43\ +\x95\x82\x05\x80\xe8\xe8\x68\x81\xa2\xa8\x48\x41\x10\x54\x93\xc4\ +\x6a\xdd\xa4\x4c\x26\x0b\x0d\x0b\x0b\xab\x76\x37\xf8\x90\x21\x43\ +\x70\xe8\xd0\x21\x9c\x3d\x7b\x16\x7d\xfb\xf6\x35\xf8\xf0\xab\x2e\ +\x2e\x2e\x00\x14\xfe\x9e\x4d\xe8\x1f\xca\xa0\x66\x86\x2e\xda\xc7\ +\x8f\x1f\x63\xfa\xf4\xe9\x88\x88\x88\xc0\x96\x2d\x5b\xd0\xb3\x67\ +\xcf\x6a\xeb\x5c\xb9\x72\x45\x26\x97\xcb\x43\xcb\x1e\x2b\x3f\xb6\ +\x3d\xf3\xe4\xc9\x13\x51\x4d\xc2\xa9\x06\x05\x05\x21\x22\x22\x02\ +\x66\x66\x66\xe8\xd5\xab\x17\xf6\xee\xdd\x5b\xab\x37\xa0\x4f\x58\ +\x5a\x5a\xc2\xca\xca\xaa\x49\xb4\x7a\x4a\x6a\x6a\x2a\x4c\x4c\x4c\ +\x60\x6b\x6b\xab\x6b\x53\xea\x4c\x68\x68\x28\x26\x4d\x9a\x04\x86\ +\x61\xb0\x67\xcf\x9e\x0a\xe7\x8d\xca\x93\x92\x92\x82\xcc\xcc\x4c\ +\x11\x00\xb5\x24\x4c\xe5\x45\x1b\x41\xd3\x74\xf1\xd9\xb3\x67\x6b\ +\x64\x88\xb3\xb3\x33\xc2\xc2\xc2\x30\x7b\xf6\x6c\xcc\x98\x31\x03\ +\x73\xe6\xcc\x41\x51\x51\xe5\xd9\xac\xf5\x19\x17\x17\x97\xa6\xe1\ +\xb1\x9e\x92\x9a\x9a\x6a\xb0\xbd\xac\x54\x2a\xc5\xea\xd5\xab\xb1\ +\x6c\xd9\x32\x8c\x1e\x3d\x1a\xbf\xfc\xf2\x0b\x5a\xb6\x6c\x59\xa3\ +\xba\x57\xaf\x5e\x05\x4d\xd3\xc5\x00\x22\xca\x1e\x57\x13\xad\x20\ +\x08\x32\x8a\xa2\x2e\x9e\x3b\x77\xae\xc6\x31\x37\x19\x86\xc1\x97\ +\x5f\x7e\x89\xe0\xe0\x60\x1c\x3e\x7c\x18\x41\x41\x41\x06\x99\x1b\ +\xc7\xd9\xd9\xb9\xa9\xa7\xd5\x53\x52\x53\x53\xe1\xe4\xe4\xa4\x6b\ +\x33\x6a\xcd\xe3\xc7\x8f\x31\x6d\xda\x34\x84\x85\x85\x61\xc3\x86\ +\x0d\x58\xb8\x70\x61\xad\x36\xf1\x5f\xbd\x7a\x55\x20\x84\x5c\x14\ +\x04\x41\xed\x91\x55\x63\xea\x57\x26\x93\x85\x9e\x3a\x75\x4a\x5e\ +\xfe\x78\x75\x0c\x1d\x3a\x14\x57\xae\x5c\x81\x95\x95\x15\x7a\xf7\ +\xee\x8d\xf5\xeb\xd7\x1b\x54\x34\x08\x17\x17\x97\x26\xd1\xea\x29\ +\x86\x26\x5a\x99\x4c\x86\x1d\x3b\x76\xe0\xad\xb7\xde\x52\x0d\x87\ +\xfb\xf5\xeb\x57\xeb\x76\x22\x23\x23\xe5\xe5\x9f\x67\x81\x0a\x44\ +\x0b\xe0\x4c\x66\x66\x26\x5b\xd6\x0f\xb9\xa6\x38\x3b\x3b\x23\x34\ +\x34\x14\x4b\x96\x2c\xc1\xba\x75\xeb\xd0\xb5\x6b\x57\xd4\x74\xa8\ +\xad\x6b\x9a\x86\xc7\xfa\x8b\x21\x0d\x8f\x23\x22\x22\x30\x71\xe2\ +\x44\x6c\xdf\xbe\x1d\xb3\x67\xcf\xc6\x8e\x1d\x3b\xea\x64\xfb\xc3\ +\x87\x0f\x91\x9d\x9d\xcd\xa2\xdc\xf3\x2c\x50\xb1\x68\xaf\x31\x0c\ +\x93\x7f\xee\xdc\xb9\xda\x5b\x0c\xc5\x70\xf9\xa3\x8f\x3e\x42\x74\ +\x74\x34\xbc\xbc\xbc\x30\x62\xc4\x08\x4c\x9d\x3a\x15\x69\x69\x69\ +\xd5\x57\xd6\x21\xce\xce\xce\x48\x4b\x4b\x53\xc6\xe2\x69\x42\x4f\ +\xe0\x38\x0e\x4f\x9f\x3e\xd5\xfb\x9e\xf6\xd9\xb3\x67\x58\xba\x74\ +\x29\xe6\xcc\x99\x83\x36\x6d\xda\xe0\xc0\x81\x03\x98\x3a\x75\xaa\ +\x2a\xda\x67\x6d\x89\x8e\x8e\x06\xc3\x30\xf9\x00\xae\x95\x3f\xa7\ +\x21\x5a\x41\x10\x78\x00\xe7\xce\x9e\x3d\x5b\xaf\x6d\x3d\xad\x5a\ +\xb5\xc2\xde\xbd\x7b\xb1\x7f\xff\x7e\x44\x45\x45\x21\x20\x20\x00\ +\xdf\x7e\xfb\x2d\xe4\xf2\x5a\x8f\xbc\x1b\x05\x67\x67\x67\xc8\xe5\ +\x72\xbd\xbf\xb9\xbc\x6c\xa4\xa7\xa7\x83\xe3\x38\xbd\xed\x69\x39\ +\x8e\xc3\xef\xbf\xff\x8e\x71\xe3\xc6\xe1\xf6\xed\xdb\xd8\xb4\x69\ +\x13\x36\x6e\xdc\x58\xe3\xc9\xa6\xca\x88\x8a\x8a\xe2\x05\x41\x38\ +\xf7\x42\x8f\x6a\x54\xe8\xce\x24\x97\xcb\xc3\xce\x9c\x39\xc3\x69\ +\x23\x07\xcc\xb0\x61\xc3\x70\xf5\xea\x55\xbc\xf7\xde\x7b\x58\xb9\ +\x72\x25\xba\x75\xeb\x86\x03\x07\x0e\xe8\xdd\x56\x3f\xe5\x5a\x6d\ +\xd3\x10\x59\xbf\x50\xae\xd1\xea\x5b\x4f\xcb\xf3\x3c\x42\x43\x43\ +\x31\x61\xc2\x04\x7c\xfb\xed\xb7\x98\x38\x71\x22\xf6\xef\xdf\x8f\ +\x3e\x7d\xfa\xd4\xbb\x6d\x41\x10\x10\x15\x15\xc5\x71\x1c\x17\x56\ +\xd1\xf9\xca\x7c\x10\xcf\xe6\xe4\xe4\xb0\xd7\xae\x69\xf4\xcc\x75\ +\xc2\xcc\xcc\x0c\x9f\x7f\xfe\x39\xa2\xa2\xa2\xd0\xb9\x73\x67\xcc\ +\x9c\x39\x13\x5d\xbb\x76\xd5\x2b\xf1\x3a\x38\x38\xc0\xdc\xdc\xdc\ +\xe0\x1d\x45\x8c\x8d\x87\x0f\x1f\xc2\xcc\xcc\x4c\x6f\x5c\x18\x05\ +\x41\x40\x68\x68\x28\x26\x4e\x9c\x88\x65\xcb\x96\xc1\xcf\xcf\x0f\ +\xfb\xf7\xef\xc7\xdc\xb9\x73\x55\xe1\x78\xeb\x4b\x6c\x6c\x2c\xf2\ +\xf3\xf3\x59\x00\x15\x4e\x08\x55\x28\x5a\x41\x10\x6e\x89\x44\xa2\ +\xc7\x7f\xfc\xf1\x87\x56\x8c\x50\xe2\xee\xee\x8e\x1f\x7f\xfc\x11\ +\xd7\xae\x5d\x43\xc7\x8e\x1d\x31\x6b\xd6\x2c\xbd\xe9\x79\x09\x21\ +\xf0\xf6\xf6\x46\x4c\x4c\x8c\x4e\xed\x68\x42\x9d\xfb\xf7\xef\xc3\ +\xc3\xc3\x43\xe7\x9b\x53\x04\x41\x40\x58\x58\x18\x26\x4c\x98\x80\ +\xa5\x4b\x97\xc2\xdb\xdb\x1b\x07\x0f\x1e\xc4\xe7\x9f\x7f\x8e\x56\ +\xad\x5a\x69\xf5\x5a\xc7\x8f\x1f\x07\xcb\xb2\x8f\x05\x41\xb8\x55\ +\xd1\xf9\x4a\xbd\xfd\xa5\x52\xe9\xf6\x3d\x7b\xf6\xc8\x1a\xe2\x19\ +\xd4\xdd\xdd\x1d\x3f\xff\xfc\x33\xa2\xa2\xa2\xe0\xef\xef\x8f\x99\ +\x33\x67\xa2\x5b\xb7\x6e\x08\x0e\x0e\xd6\xa9\x78\x7d\x7c\x7c\x70\ +\xf7\xee\x5d\x9d\x5d\xbf\x09\x4d\xe2\xe2\xe2\xe0\xe9\xe9\xa9\xb3\ +\xeb\xf3\x3c\x8f\x53\xa7\x4e\x61\xc2\x84\x09\x58\xb2\x64\x09\x3c\ +\x3d\x3d\x11\x1c\x1c\x8c\x55\xab\x56\x69\x5d\xac\x80\xe2\x19\xf9\ +\xc4\x89\x13\x32\x99\x4c\xb6\xb3\xb2\x32\x55\x6d\xd1\xd9\x9d\x95\ +\x95\xc5\x84\x86\x6a\x2c\x13\x69\x0d\x4f\x4f\x4f\x6c\xdf\xbe\x1d\ +\x51\x51\x51\xf0\xf3\xf3\xc3\x8c\x19\x33\xd0\xa1\x43\x07\x6c\xda\ +\xb4\x09\x19\x19\x19\x0d\x76\xdd\xca\x68\xea\x69\xf5\x0f\x5d\x89\ +\x36\x2b\x2b\x0b\x3b\x77\xee\xc4\xc8\x91\x23\xf1\xf1\xc7\x1f\xc3\ +\xdd\xdd\x1d\xc1\xc1\xc1\x58\xbd\x7a\x35\x94\x29\x74\x1a\x82\x2b\ +\x57\xae\x20\x27\x27\x87\x05\x50\x69\x7e\x9e\x4a\x45\x2b\x08\xc2\ +\x03\x96\x65\xaf\xec\xde\xbd\xbb\xc1\xbb\xbe\xb6\x6d\xdb\x62\xe7\ +\xce\x9d\xb8\x79\xf3\x26\x46\x8f\x1e\x8d\xcd\x9b\x37\xc3\xc7\xc7\ +\x07\xb3\x66\xcd\x42\x44\x44\x44\xf5\x0d\x68\x09\x1f\x1f\x1f\x64\ +\x66\x66\x22\x3d\x3d\xbd\xd1\xae\xd9\x44\xe5\x3c\x7f\xfe\x1c\x99\ +\x99\x99\x8d\x2a\xda\x9b\x37\x6f\x62\xd9\xb2\x65\x18\x32\x64\x08\ +\x7e\xfd\xf5\x57\x0c\x1a\x34\x08\x87\x0e\x1d\xc2\x57\x5f\x7d\xd5\ +\xa0\x62\x55\x12\x12\x12\xc2\xb3\x2c\x1b\x25\x08\x42\x42\x65\x65\ +\xaa\xdc\x0c\x2b\x93\xc9\x76\x1c\x3d\x7a\x54\x68\xac\x0d\xe2\xae\ +\xae\xae\xf8\xe2\x8b\x2f\x10\x1b\x1b\x8b\xcd\x9b\x37\x23\x3e\x3e\ +\x1e\x83\x07\x0f\x46\xaf\x5e\xbd\xb0\x73\xe7\x4e\x14\x16\x16\x36\ +\xe8\xf5\x7d\x7c\x7c\x00\xa0\x69\x88\xac\x27\x28\x27\x05\x1b\x5a\ +\xb4\x45\x45\x45\x38\x70\xe0\x00\x26\x4c\x98\x80\xa9\x53\xa7\xe2\ +\xd1\xa3\x47\xf8\xf4\xd3\x4f\x11\x1a\x1a\x8a\xf9\xf3\xe7\xc3\xd9\ +\xd9\xb9\x41\xaf\xaf\xa4\xb0\xb0\x10\xe7\xce\x9d\x13\x64\x32\xd9\ +\xf6\xaa\xca\x55\xb7\x83\x7d\x1f\xcf\xf3\xdc\xc1\x83\x07\xb5\x68\ +\x5a\xf5\x98\x98\x98\xe0\xad\xb7\xde\xc2\xb9\x73\xe7\x70\xfe\xfc\ +\x79\x74\xe8\xd0\x01\x4b\x96\x2c\x41\xdb\xb6\x6d\x31\x6f\xde\x3c\ +\x9c\x3d\x7b\xb6\x41\x9c\x20\x9a\x35\x6b\x06\x5b\x5b\xdb\xa6\x21\ +\xb2\x9e\x10\x17\x17\x07\x6b\x6b\x6b\xd8\xdb\xdb\x6b\xbd\x6d\x9e\ +\xe7\x71\xe5\xca\x15\x7c\xf6\xd9\x67\x18\x38\x70\x20\xd6\xad\x5b\ +\x07\x6f\x6f\x6f\xfc\xf1\xc7\x1f\xd8\xb3\x67\x0f\x46\x8e\x1c\xd9\ +\xe8\x01\x11\x4e\x9f\x3e\x0d\x8e\xe3\x78\x00\xfb\xaa\x2a\x57\xa5\ +\xbb\x86\x20\x08\xb9\x0c\xc3\xfc\xdf\xae\x5d\xbb\xc6\xcd\x98\x31\ +\xa3\x6e\xae\x1d\xf5\x44\x19\x58\xee\xcb\x2f\xbf\xc4\x9e\x3d\x7b\ +\x70\xe0\xc0\x01\xfc\xf6\xdb\x6f\xb0\xb7\xb7\xc7\xa8\x51\xa3\x30\ +\x6e\xdc\x38\xf4\xec\xd9\x53\x6b\xb3\x8b\xde\xde\xde\x4d\x3d\xad\ +\x9e\x70\xff\xfe\x7d\xad\xf6\xb2\x82\x20\xe0\xfa\xf5\xeb\x38\x7e\ +\xfc\x38\xc2\xc2\xc2\xf0\xfc\xf9\x73\xf8\xfa\xfa\xe2\xfd\xf7\xdf\ +\xc7\xa8\x51\xa3\x20\x91\x48\xa0\x0d\xdf\x84\xba\x72\xf4\xe8\x51\ +\x39\x21\xe4\xa8\x20\x08\x55\x46\x19\xac\x56\x88\x1c\xc7\xfd\x1a\ +\x11\x11\x31\xe1\xc1\x83\x07\x68\xd3\xa6\x8d\xf6\x2c\xac\x25\x36\ +\x36\x36\x98\x3b\x77\x2e\xe6\xce\x9d\x8b\x07\x0f\x1e\xe0\xe0\xc1\ +\x83\x38\x78\xf0\x20\x76\xec\xd8\x81\x16\x2d\x5a\xa8\x04\xdc\xb5\ +\x6b\xd7\x7a\x09\xd8\xc7\xc7\x07\x57\xaf\x5e\xd5\xa2\xe5\x4d\xd4\ +\x95\xb8\xb8\x38\xb4\x6b\xd7\xae\xde\xed\xdc\xba\x75\x0b\x27\x4e\ +\x9c\xc0\x89\x13\x27\x90\x9e\x9e\x0e\x2f\x2f\x2f\x4c\x9a\x34\x09\ +\xaf\xbc\xf2\x8a\xca\xa9\x46\xd7\x3c\x7d\xfa\x14\xd7\xaf\x5f\x67\ +\x00\xec\xaa\xae\x6c\x4d\x7a\xcf\x50\x96\x65\x33\xf7\xec\xd9\x63\ +\xb7\x7c\xf9\xf2\xfa\x5b\xa7\x05\xda\xb4\x69\x83\x05\x0b\x16\x60\ +\xc1\x82\x05\x88\x8b\x8b\xc3\xdf\x7f\xff\x8d\x83\x07\x0f\xe2\xa7\ +\x9f\x7e\x82\x93\x93\x13\xc6\x8d\x1b\x87\x01\x03\x06\xa0\x7b\xf7\ +\xee\xb5\x1e\xe2\xb4\x6b\xd7\x0e\x7b\xf6\xec\x01\xcf\xf3\x46\x11\ +\xff\xca\x90\x89\x8f\x8f\xc7\x98\x31\x63\x6a\x5d\xaf\xa4\xa4\x04\ +\x91\x91\x91\xb8\x74\xe9\x12\xce\x9c\x39\x83\x94\x94\x14\x78\x78\ +\x78\xe0\xf5\xd7\x5f\xc7\x90\x21\x43\x54\x13\x4a\xba\xec\x55\xcb\ +\x73\xe2\xc4\x09\x30\x0c\x93\x23\x97\xcb\x43\xaa\x2b\x4b\x6a\x62\ +\x38\x21\x64\x83\x8b\x8b\xcb\x7f\xe3\xe2\xe2\x58\x40\xf3\xcd\x56\ +\xd4\x46\x4d\x8e\xd5\xb5\x5e\x65\x6d\xc5\xc6\xc6\x22\x38\x38\x18\ +\x21\x21\x21\xb8\x7b\xf7\x2e\x4c\x4c\x4c\xd0\xab\x57\x2f\x0c\x18\ +\x30\x00\xfd\xfb\xf7\x87\xb7\xb7\x77\xb5\x36\x5c\xbf\x7e\x1d\x83\ +\x07\x0f\x46\x64\x64\xa4\xda\xc8\x42\x5f\xdf\xb3\x31\xb5\x55\xf6\ +\xf5\xe3\xc7\x8f\x31\x64\xc8\x10\xec\xd9\xb3\x07\x1d\x3b\x12\xa7\ +\x2e\x40\x00\x00\x1a\x23\x49\x44\x41\x54\x76\xac\xb6\x5e\x5c\x5c\ +\x1c\x2e\x5e\xbc\x88\x8b\x17\x2f\x22\x3a\x3a\x1a\x52\xa9\x14\x9e\ +\x9e\x9e\x18\x30\x60\x00\x86\x0e\x1d\x0a\x0f\x0f\x0f\xbd\x7e\xcf\ +\xe3\xc7\x8f\x97\x25\x25\x25\xfd\xc4\xf3\xfc\x5c\x8d\x4a\xe5\xa8\ +\xa9\x68\x3b\x00\xb8\x71\xf4\xe8\x51\x0c\x1a\x34\xc8\x20\xbe\xc0\ +\x4f\x9f\x3e\xc5\xe9\xd3\xa7\x71\xf6\xec\x59\x9c\x3b\x77\x0e\x19\ +\x19\x19\x68\xd1\xa2\x05\xfa\xf7\xef\x8f\xfe\xfd\xfb\xa3\x6f\xdf\ +\xbe\xb0\xb7\xb7\xd7\xa8\x27\x97\xcb\xe1\xe6\xe6\x86\x75\xeb\xd6\ +\x61\xe2\xc4\x89\x5a\xb7\x5d\x1f\xbe\x28\xfa\xda\x56\xd9\xd7\x87\ +\x0e\x1d\xc2\x8a\x15\x2b\x10\x19\x19\x09\x91\x48\xa4\x51\x2e\x3b\ +\x3b\x1b\x97\x2e\x5d\xc2\xc5\x8b\x17\x71\xe9\xd2\x25\xa4\xa7\xa7\ +\xc3\xc6\xc6\x06\x3d\x7b\xf6\x44\xcf\x9e\x3d\xd1\xa3\x47\x0f\x38\ +\x38\x38\x34\x88\x9d\xda\x6c\x4b\x10\x04\x44\x44\x44\x60\xde\xbc\ +\x79\x00\xd0\x45\x10\x84\x6a\x9f\xcd\x6a\x24\x5a\x00\x60\x59\xf6\ +\x42\x97\x2e\x5d\x7a\x9c\x3d\x7b\x96\x31\xb4\x2f\xb0\x20\x08\xf8\ +\xf7\xdf\x7f\x71\xe6\xcc\x19\x9c\x39\x73\x06\x51\x51\x51\x90\x4a\ +\xa5\x70\x77\x77\x47\x97\x2e\x5d\xd0\xa5\x4b\x17\x74\xee\xdc\x19\ +\xde\xde\xde\xa0\x69\x1a\x63\xc6\x8c\x81\x9b\x9b\x9b\x5a\x46\x05\ +\x43\x7b\xcf\x86\xd8\x56\xd9\xd7\x2b\x57\xae\x44\x7c\x7c\x3c\x7e\ +\xff\xfd\x77\xf0\x3c\x8f\xf8\xf8\x78\xdc\xb8\x71\x03\x37\x6f\xde\ +\xc4\x8d\x1b\x37\xf0\xf0\xe1\x43\x30\x0c\x83\x80\x80\x00\xf4\xec\ +\xd9\x13\xbd\x7a\xf5\x82\x8f\x8f\x8f\x6a\x3e\xc3\x90\xde\xf3\xec\ +\xd9\xb3\xb9\xbb\x77\xef\x5e\x91\x4a\xa5\xbd\x35\x2a\x54\x40\x8d\ +\x45\x4b\x08\x19\x04\x20\xec\xcc\x99\x33\xe8\xd1\xa3\x87\xd6\x0c\ +\xae\x4b\xbd\xfa\xb6\x55\x50\x50\x80\xf0\xf0\x70\x44\x44\x44\x20\ +\x32\x32\x12\x37\x6f\xde\x44\x51\x51\x11\xcc\xcd\xcd\x11\x18\x18\ +\x08\xa9\x54\x8a\x94\x94\x14\x9c\x3e\x7d\x5a\x15\x4c\xac\x49\xb4\ +\x0d\xdf\x96\xf2\x75\x76\x76\x36\x5e\x7b\xed\x35\x34\x6b\xd6\x0c\ +\x26\x26\x26\xb8\x75\xeb\x16\x0a\x0a\x0a\x60\x62\x62\x02\x5f\x5f\ +\x5f\x04\x04\x04\x20\x30\x30\x10\x5d\xbb\x76\x85\x99\x99\x99\x41\ +\xbf\xe7\x1b\x37\x6e\x60\xf6\xec\xd9\x00\x30\x58\x10\x84\x53\x1a\ +\x15\x2a\xa0\xc6\xa2\x05\x00\x91\x48\x74\xb5\x6f\xdf\xbe\x01\x47\ +\x8e\x1c\xa1\xcb\x1e\x37\xe4\x0f\x4d\x10\x04\xc8\xe5\x72\xdc\xbd\ +\x7b\x17\x57\xaf\x5e\xc5\xd5\xab\x57\x71\xe1\xc2\x05\x3c\x79\xf2\ +\x04\x00\xe0\xe6\xe6\x06\x3f\x3f\x3f\x78\x79\x79\xa9\x7e\xdc\xdc\ +\xdc\x2a\xdc\xdc\x6c\x28\xef\x59\x5f\xda\x92\xc9\x64\x78\xf8\xf0\ +\x21\xe2\xe3\xe3\x55\x3f\x31\x31\x31\xaa\x7c\xac\x0e\x0e\x0e\xe8\ +\xd1\xa3\x07\x3a\x74\xe8\x80\x0e\x1d\x3a\xc0\xcb\xcb\x0b\x34\x4d\ +\x1b\xd5\x0d\x74\xde\xbc\x79\x5c\x74\x74\xf4\x4d\xa9\x54\xda\x49\ +\xa3\x70\x25\xd4\x4a\xb4\x84\x90\x91\x00\x0e\x5f\xbe\x7c\x19\x01\ +\x01\x01\xf5\x36\x58\x1f\x3e\xb4\x8a\xca\xe4\xe4\xe4\xc0\xd3\xd3\ +\x13\x0b\x17\x2e\x04\xcf\xf3\x88\x89\x89\x41\x6c\x6c\x2c\x1e\x3d\ +\x7a\x04\x8e\xe3\xc0\xb2\x2c\x5c\x5d\x5d\xe1\xed\xed\x0d\x2f\x2f\ +\x2f\xb4\x6d\xdb\x16\xde\xde\xde\x68\xd3\xa6\x8d\x46\xe0\x2e\x7d\ +\x7c\xcf\x8d\xdd\x96\x5c\x2e\x47\x62\x62\xa2\x4a\x98\x71\x71\x71\ +\x88\x8f\x8f\xc7\xa3\x47\x8f\x20\x97\xcb\x41\xd3\x34\x9c\x9d\x9d\ +\xe1\xe1\xe1\x81\xb6\x6d\xdb\x82\xa2\x28\x6c\xdd\xba\x15\x97\x2f\ +\x5f\x86\x95\x95\x55\x83\xd9\xae\xeb\xcf\x2f\x36\x36\x16\x93\x27\ +\x4f\x06\x80\x51\x82\x20\x1c\xd1\x28\x5c\x09\xb5\x75\x98\x38\xca\ +\xb2\xec\xdd\xaf\xbe\xfa\xca\xeb\xaf\xbf\xfe\xa2\xab\x2f\x6e\x98\ +\x58\x59\x59\xc1\xcb\xcb\x0b\x52\xa9\x14\xca\x65\x2e\x41\x10\x20\ +\x95\x4a\x11\x1f\x1f\x8f\x7b\xf7\xee\x21\x36\x36\x16\xf7\xef\xdf\ +\xc7\xa1\x43\x87\xf0\xe0\xc1\x03\xd5\x97\xaf\x45\x8b\x16\x70\x76\ +\x76\x86\x93\x93\x53\x85\x3f\x96\x96\x96\x3a\x7e\x77\xda\x27\x3f\ +\x3f\x1f\xa9\xa9\xa9\x48\x4d\x4d\x45\x5a\x5a\x1a\x52\x52\x52\xd4\ +\x5e\x3f\x7d\xfa\x14\x1c\xc7\x81\xa6\x69\xb4\x6e\xdd\x1a\x1e\x1e\ +\x1e\x18\x32\x64\x08\xdc\xdd\xdd\xe1\xe1\xe1\x81\x36\x6d\xda\x40\ +\x24\x12\xa9\xbe\xd0\x5f\x7f\xfd\x35\xdc\xdc\xdc\x74\xee\xec\xd0\ +\xd0\xec\xd8\xb1\x83\x67\x59\xf6\x9e\x4c\x26\x3b\x5a\x9b\x7a\xb5\ +\x12\xad\x20\x08\x02\x21\xe4\x7f\x87\x0f\x1f\xfe\x2b\x36\x36\xb6\ +\xc2\xb4\x7c\xc6\x42\xd7\xae\x5d\x35\x36\x2b\x88\x44\x22\xb4\x6b\ +\xd7\x0e\xed\xda\xb5\x53\xfb\x32\xc9\x64\x32\x24\x24\x24\x20\x2e\ +\x2e\x0e\x8f\x1f\x3f\x46\x6a\x6a\x2a\x52\x52\x52\x70\xee\xdc\x39\ +\xa4\xa4\xa4\xa8\x65\xe4\xb3\xb4\xb4\x54\x09\xd8\xde\xde\x1e\x36\ +\x36\x36\x90\x48\x24\xb0\xb1\xb1\x81\xb5\xb5\xb5\xea\x47\x22\x91\ +\xc0\xda\xda\x5a\x27\x22\xcf\xcf\xcf\x47\x76\x76\xb6\xda\x4f\x4e\ +\x4e\x8e\xea\x77\x4e\x4e\x0e\x32\x32\x32\x54\xc2\xcc\xcb\xcb\x53\ +\xd5\xb5\xb1\xb1\x81\xa3\xa3\x23\x5a\xb6\x6c\x89\x76\xed\xda\x61\ +\xd0\xa0\x41\x70\x72\x72\x82\x9b\x9b\x1b\x5c\x5d\x5d\xd5\x46\x22\ +\x95\x09\xf2\xda\xb5\x6b\x35\x0a\xe6\x6d\xc8\x3c\x78\xf0\x00\x67\ +\xcf\x9e\xa5\x00\x7c\x2e\xd4\xf2\xce\x54\x17\xd7\xc4\xfd\x0c\xc3\ +\xac\x5e\xb7\x6e\x9d\xeb\x8e\x1d\x3b\x8c\xd6\xfb\xa0\x6b\xd7\xae\ +\xf8\xeb\xaf\xbf\x20\x95\x4a\x35\x96\x1c\xca\xc3\xb2\xac\x6a\xa8\ +\x5c\x1e\x41\x10\x50\x5c\x5c\x8c\x94\x94\x14\x24\x27\x27\xab\x04\ +\xad\xfc\x3b\x26\x26\x46\x25\x88\xbc\xbc\x3c\x8d\xfd\xc4\x0c\xc3\ +\x40\x22\x91\x40\x22\x91\x40\x24\x12\x81\x65\x59\xd5\x6f\xe5\x4f\ +\x45\xaf\x19\x86\x01\xc7\x71\x90\x4a\xa5\x90\xc9\x64\x90\x4a\xa5\ +\xaa\xbf\x95\xaf\xcb\xfe\x2d\x95\x4a\x55\x82\x2c\xef\xd7\x4d\x08\ +\x81\xa5\xa5\xa5\xca\x0e\x89\x44\x82\xe6\xcd\x9b\xc3\xcf\xcf\x4f\ +\x25\x50\x47\x47\x47\xb4\x68\xd1\x02\xa6\xa6\xa6\x35\x1e\x2a\x56\ +\x84\x4c\x26\xc3\xed\xdb\xb7\xf1\xfa\xeb\xaf\xd7\xa8\xbc\xa1\xb2\ +\x73\xe7\x4e\x81\x65\xd9\x87\x32\x99\x6c\x7f\x6d\xeb\xd6\xea\x99\ +\x56\x55\x89\x90\x69\x14\x45\x6d\xbf\x73\xe7\x0e\xe5\xea\xea\x6a\ +\xb0\xcf\x14\x55\x95\x79\xf4\xe8\x11\x3a\x77\xee\x8c\x90\x90\x10\ +\x74\xe9\xd2\xa5\x51\x9e\xa3\x78\x9e\x47\x5e\x5e\x5e\x85\xbd\x9b\ +\x32\xab\x5f\x45\xc2\xab\xe8\x98\x5c\x2e\x07\xc3\x30\x55\x8a\xbb\ +\xec\x31\x91\x48\xa4\x26\x4c\x6b\x6b\x6b\x58\x59\x59\xc1\xca\xca\ +\x0a\x96\x96\x96\x2a\xef\xb0\x86\xfe\x5f\xdc\xb8\x71\x03\x6f\xbe\ +\xf9\x26\x42\x43\x43\x55\x89\xd1\x1a\xf2\x7a\x75\xa9\x57\xdf\xb6\ +\x52\x53\x53\x31\x76\xec\x58\x81\xe7\xf9\x19\x82\x20\xfc\xaa\x51\ +\xa8\x1a\xea\xba\x09\xe0\x77\x9a\xa6\xbf\xd8\xb0\x61\x83\xe3\x77\ +\xdf\x7d\x67\x1c\x49\x6a\xcb\xd1\xba\x75\x6b\xb4\x6c\xd9\x12\x17\ +\x2f\x5e\x44\x97\x2e\x5d\x1a\xe5\x9a\x14\x45\xa9\x44\x53\x51\x54\ +\x04\x7d\xf8\xd2\x35\x34\x11\x11\x11\x68\xde\xbc\xb9\xde\xf8\x04\ +\x37\x04\xbb\x76\xed\x02\x4d\xd3\x69\x3c\xcf\xff\x5e\x97\xfa\x75\ +\x1a\xde\x0a\x82\x20\x97\xc9\x64\x5f\xee\xda\xb5\x4b\x50\x4e\xcf\ +\x1b\x23\x83\x06\x0d\x42\x43\x46\xee\x68\x42\x93\x0b\x17\x2e\x20\ +\x28\x28\x48\xd7\x66\x34\x18\x69\x69\x69\x38\x7c\xf8\x30\x2f\x93\ +\xc9\xbe\x10\xca\xa4\xaf\xac\x0d\xf5\x79\x26\xdd\x4e\x08\x79\xf0\ +\xe1\x87\x1f\x1a\x6d\x74\xef\xc1\x83\x07\x23\x3a\x3a\x5a\x6d\x22\ +\xa9\x89\x86\x23\x27\x27\x07\x37\x6f\xde\x44\xdf\xbe\x7d\x75\x6d\ +\x4a\x83\xb1\x7e\xfd\x7a\x9e\x10\xf2\x10\x40\x95\x1b\xdd\xab\xa2\ +\xce\xa2\x15\x04\x41\x2a\x93\xc9\xde\x3b\x71\xe2\x04\x1d\x12\x52\ +\xed\xc6\x04\x83\xa4\x6f\xdf\xbe\x60\x18\x06\xa7\x4f\x9f\xd6\xb5\ +\x29\x2f\x05\xe1\xe1\xe1\x20\x84\x68\x78\xdc\x19\x0b\xe1\xe1\xe1\ +\x08\x0f\x0f\xa7\x64\x32\xd9\xbb\x82\x20\xd4\x39\xd1\x55\xbd\x66\ +\x7f\x05\x41\x38\x45\x51\xd4\xfe\x0f\x3e\xf8\x40\x66\xa8\x29\x2e\ +\xab\x42\x99\x7b\x37\x2c\xac\xc2\x98\xd1\x4d\x68\x99\xf3\xe7\xcf\ +\xa3\x73\xe7\xff\x6f\xef\xdc\xa3\xa2\xba\xee\x3d\xfe\xdd\xf3\x52\ +\x44\x31\x6a\x6d\x6c\x29\x57\xed\x84\x68\xcc\x4d\x72\x9b\xc6\x36\ +\x82\xae\x26\xb6\x68\x8c\x17\x88\x81\x88\x80\x2f\x42\x89\x59\xf5\ +\x8d\x18\x89\x89\xf5\x81\x31\x4e\x30\x5c\x31\x16\x1a\x7c\xa0\x22\ +\x6a\x40\x20\x81\xfa\x26\xbe\x6d\xa0\xda\xd8\xa5\xd1\x00\x01\x41\ +\x03\x6a\x08\xc8\x4b\x06\x98\x7d\xf6\xf9\xdd\x3f\x82\x2e\x15\x63\ +\x78\xcc\xcc\x99\x19\xe7\xb3\x16\x0b\x38\xec\xf3\x3b\x5f\xe0\x7c\ +\xd7\xd9\x7b\x9f\xdf\xde\xbf\xe7\xe0\xea\xea\xaa\xb4\x14\xb3\x63\ +\x32\x99\xb0\x7a\xf5\x6a\xae\x56\xab\xd3\xa9\x9d\xe9\x8a\x3f\x46\ +\x97\x5f\xd9\xc8\xb2\x3c\xef\xfa\xf5\xeb\xdc\x60\x30\x74\x35\x94\ +\x4d\xe2\xe3\xe3\x83\xc3\x87\x0f\xdb\x6c\x39\x13\x47\x41\x08\x81\ +\x93\x27\x4f\x9a\x65\x87\x7e\x5b\x24\x39\x39\x19\x55\x55\x55\x92\ +\x10\x62\x5e\x57\x63\x75\xd9\xb4\x44\x74\x55\x08\xb1\x24\x2e\x2e\ +\x4e\x2e\x2a\x2a\xea\x6a\x38\x9b\xc3\xc7\xc7\x07\x75\x75\x75\x38\ +\x7d\xfa\xb4\xd2\x52\x1c\x9a\x73\xe7\xce\xa1\xb6\xb6\xd6\x21\x4d\ +\xfb\xed\xb7\xdf\x22\x39\x39\x59\x16\x42\xbc\x4b\x44\x57\xbb\x1a\ +\xcf\x5c\xc9\x11\xeb\x18\x63\x45\x73\xe7\xce\x75\xb8\x49\xa9\x41\ +\x83\x06\x41\xaf\xd7\x3b\x67\x91\x2d\xcc\xd1\xa3\x47\xe1\xee\xee\ +\x0e\xbd\x5e\xaf\xb4\x14\xb3\x63\x30\x18\x04\x63\xac\x08\xc0\x3a\ +\x73\xc4\x33\x8b\x69\x5b\x5f\x01\x45\x1c\x3b\x76\x4c\xb5\x7b\xf7\ +\x6e\x73\x84\xb4\x29\x7c\x7c\x7c\x90\x9b\xdb\xa5\x61\x88\x93\x9f\ +\xe0\xd8\xb1\x63\x0e\xf9\x94\x3d\x72\xe4\x08\xf2\xf2\xf2\x54\x9c\ +\xf3\x88\xce\xbe\xe2\xb9\x17\xb3\xa5\x21\x12\xd1\x49\x95\x4a\x95\ +\xb2\x60\xc1\x02\xe9\xce\x5c\x54\x47\xc0\xc7\xc7\x07\x85\x85\x85\ +\xce\xe2\x5c\x16\xa2\xbc\xbc\x1c\x05\x05\x05\x18\x3d\x7a\xb4\xd2\ +\x52\xcc\x4a\x73\x73\x33\x0c\x06\x03\x57\xa9\x54\xdb\x89\xe8\xa4\ +\xb9\xe2\x9a\x35\x77\x58\x96\xe5\x85\x35\x35\x35\xcd\x31\x31\x31\ +\xe6\x0c\xab\x38\xde\xde\xde\xf8\xf9\xcf\x7f\x8e\x8c\x8c\x0c\xa5\ +\xa5\x38\x24\x39\x39\x39\xe8\xd7\xaf\x9f\xc3\xbd\xea\xd9\xb8\x71\ +\x23\x6a\x6a\x6a\x5a\x64\x59\x8e\x32\x67\x5c\xb3\x9a\x96\x88\x2a\ +\x25\x49\x7a\x2b\x21\x21\x81\x4e\x9d\x3a\x65\xce\xd0\x8a\xa2\x56\ +\xab\x31\x61\xc2\x04\xa7\x69\x2d\x44\x76\x76\x36\xc6\x8f\x1f\x0f\ +\xb5\xda\x71\x56\x7b\x7e\xf5\xd5\x57\xd8\xb6\x6d\x9b\x2c\x84\x78\ +\x8b\x88\xcc\x5a\x67\xc6\x12\xab\x74\xfe\xae\x52\xa9\x0e\x4e\x9e\ +\x3c\x59\xaa\xae\xae\xb6\x40\x78\x65\x78\xed\xb5\xd7\x70\xf9\xf2\ +\x65\xe7\x9e\xc8\x66\xe6\xfc\xf9\xf3\x28\x2d\x2d\x85\xaf\xaf\xaf\ +\xd2\x52\xcc\x46\x7d\x7d\x3d\xa2\xa2\xa2\x38\x63\xec\x10\x80\xbf\ +\x9b\x3b\xbe\xd9\x4d\x4b\x44\x24\x49\x52\x68\x4d\x4d\x4d\x75\x78\ +\x78\xb8\x59\xaa\xc9\xdb\x02\x4f\x3f\xfd\x34\x86\x0c\x19\x82\xf4\ +\xf4\x0e\xaf\xa4\x72\xf2\x00\xb2\xb3\xb3\x31\x68\xd0\x20\x3c\xf5\ +\xd4\x53\x4a\x4b\x31\x1b\x4b\x97\x2e\x15\x35\x35\x35\x37\x84\x10\ +\xa1\x1d\x5d\x2b\xdb\x1e\x2c\xb2\x1e\x96\x88\xaa\x39\xe7\x01\xb9\ +\xb9\xb9\x2c\x3e\x3e\xde\x12\x97\x50\x84\xc0\xc0\x40\x7c\xf6\xd9\ +\x67\xce\x44\x0b\x33\x21\x84\xc0\xde\xbd\x7b\x1d\xea\x29\xbb\x63\ +\xc7\x0e\x9c\x38\x71\x82\x49\x92\x14\x40\x44\x16\xe9\x6a\x5a\x6c\ +\x11\x3b\x11\x9d\x22\xa2\x77\x96\x2c\x59\x42\xff\xfa\xd7\xbf\x2c\ +\x75\x19\xab\x12\x10\x10\x80\x9a\x9a\x1a\x1c\x39\x72\x44\x69\x29\ +\x0e\xc1\xa9\x53\xa7\x50\x5d\x5d\xed\x30\xa6\xbd\x70\xe1\x02\xd6\ +\xae\x5d\x2b\x13\xd1\x3b\x44\x64\xb1\x49\x1d\x4b\xef\x3c\x61\x50\ +\xa9\x54\xb9\x21\x21\x21\xdc\x5a\xe5\x32\x2d\xc9\xaf\x7e\xf5\x2b\ +\x8c\x18\x31\x02\x8e\xf8\x2e\x5a\x09\xb2\xb3\xb3\xf1\xcc\x33\xcf\ +\x58\xa4\xa2\xba\xb5\x69\x68\x68\x40\x54\x54\x14\x07\xf0\x39\x00\ +\x8b\xe6\xf4\x5a\xd4\xb4\xad\xe3\xdb\x90\xaa\xaa\xaa\x9a\x88\x88\ +\x08\x87\xc8\x96\x0a\x0c\x0c\xc4\xfe\xfd\xfb\x51\x57\x57\xa7\xb4\ +\x14\xbb\xa6\xb1\xb1\x11\xb9\xb9\xb9\xf0\xf3\xf3\x53\x5a\x8a\x59\ +\x58\xb6\x6c\x99\xb8\x71\xe3\x46\x8d\x10\x22\xc4\x12\xe3\xd8\x3b\ +\xb1\xf8\x1e\x4f\x44\x54\xc5\x39\x7f\x6d\xdf\xbe\x7d\x2c\x21\x21\ +\xc1\xd2\x97\xb3\x38\x7e\x7e\x7e\x50\xa9\x54\x48\x4d\x4d\x55\x5a\ +\x8a\x5d\x93\x99\x99\x09\x95\x4a\xe5\x10\xa6\xdd\xb9\x73\x27\x8e\ +\x1d\x3b\xc6\x24\x49\x7a\x8d\x88\xaa\x2c\x7d\x3d\xab\x6c\xcc\x46\ +\x44\xc7\x89\xe8\xaf\x8b\x17\x2f\x96\xbf\xfc\xf2\x4b\x6b\x5c\xd2\ +\x62\xb8\xb9\xb9\x21\x28\x28\x08\x9b\x36\x6d\xb2\x48\x61\xeb\x87\ +\x01\x59\x96\x91\x92\x92\x82\x09\x13\x26\xd8\xfd\x96\xb2\x17\x2f\ +\x5e\x44\x5c\x5c\x9c\x4c\x44\x7f\x25\xa2\xe3\xd6\xb8\xa6\x35\x77\ +\x53\x5c\x05\xe0\x70\x40\x40\x00\xbf\x72\xe5\x8a\x15\x2f\x6b\x7e\ +\x22\x22\x22\x50\x51\x51\x81\x7d\xfb\xf6\x29\x2d\xc5\x2e\x39\x7a\ +\xf4\x28\xae\x5c\xb9\x72\x6b\xa3\x6e\xbb\xe5\xda\xb5\x6b\x98\x33\ +\x67\x0e\x67\x8c\x1d\xc1\x0f\xf7\xb7\x55\xb0\x9a\x69\x5b\xc7\xb7\ +\x01\xb5\xb5\xb5\x45\xe3\xc7\x8f\xe7\xf6\x9c\x78\xa1\xd7\xeb\x31\ +\x7a\xf4\x68\x6c\xd8\xb0\x41\x69\x29\x76\xc9\x96\x2d\x5b\x30\x6a\ +\xd4\xa8\xdb\x75\x62\xed\x91\xda\xda\x5a\xcc\x98\x31\x83\xd7\xd7\ +\xd7\x5f\x6a\xed\x16\x5b\x2d\x21\xc1\xaa\xfb\x16\x13\x51\x3d\xe7\ +\xfc\x4f\xe5\xe5\xe5\xd7\xfd\xfd\xfd\x25\xa3\xd1\x68\xcd\xcb\x9b\ +\x95\x88\x88\x08\xe4\xe5\xe5\xe1\xfc\xf9\xf3\x4a\x4b\xb1\x2b\x0a\ +\x0b\x0b\x91\x9f\x9f\x8f\x69\xd3\xa6\x29\x2d\xa5\xd3\x34\x35\x35\ +\x61\xe6\xcc\x99\xd2\xf5\xeb\xd7\xbf\x97\x24\xe9\x8f\x44\x54\x63\ +\xcd\xeb\x5b\x7d\xb3\x71\x22\xba\xce\x39\x7f\xf1\xc2\x85\x0b\xf5\ +\x93\x26\x4d\x12\x9c\x73\x6b\x4b\x30\x0b\x2f\xbc\xf0\x02\x3c\x3d\ +\x3d\x9d\x4f\xdb\x0e\xb2\x75\xeb\x56\xfc\xfa\xd7\xbf\x86\xb7\xb7\ +\xb7\xd2\x52\x3a\x85\x24\x49\x88\x8c\x8c\x14\x45\x45\x45\x8d\xad\ +\x86\xad\xb0\xb6\x06\x45\x2a\x04\x10\x51\x09\xe7\xfc\x4f\xc7\x8f\ +\x1f\x6f\x79\xe3\x8d\x37\x64\x7b\x4c\x75\x64\x8c\xe1\xcf\x7f\xfe\ +\x33\xb2\xb2\xb2\x50\x55\x65\xf1\x09\x43\x87\xa0\xba\xba\x1a\x39\ +\x39\x39\x98\x3a\x75\xea\xed\x3a\xb2\xf6\x04\x11\x61\xc9\x92\x25\ +\xf2\xe9\xd3\xa7\xb9\x10\x62\x2c\x11\x15\x28\xa1\x43\xb1\xb2\x1e\ +\x44\x74\x56\x08\xf1\xbf\x99\x99\x99\x22\x3a\x3a\xda\xfe\x5c\x0b\ +\x60\xe2\xc4\x89\x70\x71\x71\x41\x72\x72\xb2\xd2\x52\xec\x82\x1d\ +\x3b\x76\xa0\x7b\xf7\xee\x78\xe5\x95\x57\x94\x96\xd2\x29\x3e\xfc\ +\xf0\x43\x1c\x38\x70\x80\x84\x10\x13\x88\x28\xff\xa7\xcf\xb0\x0c\ +\x8a\xd6\xe2\x21\xa2\x23\xb2\x2c\x87\x24\x26\x26\x22\x2e\x2e\x4e\ +\x49\x29\x9d\xa2\x47\x8f\x1e\x78\xf3\xcd\x37\x91\x94\x94\x04\x47\ +\xc8\xf8\xb2\x24\xf5\xf5\xf5\xd8\xba\x75\x2b\xc2\xc2\xc2\xe0\xe2\ +\xe2\xa2\xb4\x9c\x0e\x93\x9c\x9c\x8c\xd4\xd4\x54\x22\xa2\x69\x44\ +\xb4\x5f\x49\x2d\x8a\x17\xd0\x22\xa2\xdd\x44\x34\x73\xe9\xd2\xa5\ +\x48\x49\x49\x51\x5a\x4e\x87\x99\x31\x63\x06\x34\x1a\x0d\xfe\xf6\ +\xb7\xbf\x29\x2d\xc5\xa6\xd9\xb0\x61\x03\x34\x1a\x0d\xa6\x4f\x9f\ +\xae\xb4\x94\x0e\xf3\xe9\xa7\x9f\x62\xdd\xba\x75\x00\xb0\x80\x88\ +\x14\xcf\xaa\x51\xdc\xb4\x00\x40\x44\x89\x00\x96\xcf\x9a\x35\x8b\ +\xd2\xd2\xd2\x94\x96\xd3\x21\x5c\x5d\x5d\x31\x77\xee\x5c\x6c\xd8\ +\xb0\x01\xdf\x7f\xff\xbd\xd2\x72\x6c\x92\xaa\xaa\x2a\xa4\xa4\xa4\ +\x60\xc6\x8c\x19\xe8\xd1\xa3\x87\xd2\x72\x3a\xc4\xde\xbd\x7b\x11\ +\x13\x13\x43\x8c\x31\x03\x11\xfd\x9f\xd2\x7a\x00\x1b\x31\x2d\x00\ +\x10\xd1\x32\x22\x5a\x1b\x11\x11\x81\xc4\xc4\x44\xa5\xe5\x74\x88\ +\xb0\xb0\x30\x3c\xf2\xc8\x23\x58\xbb\x76\xad\xd2\x52\x6c\x92\xc4\ +\xc4\x44\xb8\xb9\xb9\x21\x24\x24\x44\x69\x29\x1d\x62\xc7\x8e\x1d\ +\x58\xbc\x78\x31\x88\x68\x9d\x2c\xcb\xd1\x4a\xeb\xb9\x85\xcd\x98\ +\x16\x00\x64\x59\x8e\x24\xa2\xe8\x45\x8b\x16\x61\xf9\xf2\xe5\x4a\ +\xcb\x69\x37\xdd\xba\x75\x43\x64\x64\x24\xb6\x6d\xdb\x86\x8a\x0a\ +\xab\xbf\x01\xb0\x69\xae\x5e\xbd\x8a\x5d\xbb\x76\xe1\x2f\x7f\xf9\ +\x0b\xba\x75\xeb\xa6\xb4\x9c\x76\xb3\x7e\xfd\x7a\x7c\xf0\xc1\x07\ +\x00\xf0\xb6\x2c\xcb\x5d\xde\x60\xdc\x9c\xd8\x94\x69\x01\x80\x88\ +\x0c\x00\xc2\xe2\xe2\xe2\xe4\x59\xb3\x66\x91\xbd\xe4\xf7\x06\x07\ +\x07\xc3\xdd\xdd\x1d\x6b\xd6\xac\x51\x5a\x8a\x4d\xb1\x7e\xfd\x7a\ +\xfc\xe2\x17\xbf\x40\x60\x60\xa0\xd2\x52\xda\x85\x2c\xcb\x88\x89\ +\x89\xa1\x4d\x9b\x36\xc9\x00\xc2\x89\x68\xb5\xd2\x9a\xee\xc5\xe6\ +\x4c\x0b\x00\x44\xb4\x85\x88\xfc\x53\x53\x53\x4d\xa1\xa1\xa1\xa2\ +\xb9\xb9\x59\x69\x49\x3f\x89\x56\xab\x45\x54\x54\x14\xd2\xd2\xd2\ +\x9c\x5b\xad\xb6\x52\x52\x52\x82\xac\xac\x2c\xcc\x9e\x3d\x1b\x1a\ +\x4d\x67\x4b\x21\x5b\x0f\x93\xc9\x84\x85\x0b\x17\x8a\xac\xac\x2c\ +\x4e\x44\x13\x88\x68\xb3\xd2\x9a\xee\x47\xa7\x2a\xc1\x5b\x0b\xc6\ +\xd8\x08\x8d\x46\xb3\x7f\xf8\xf0\xe1\x3d\xd2\xd2\xd2\x34\x6e\x6e\ +\x6e\xb7\x7f\xa6\x74\x35\xf0\xfb\xb5\x11\x42\x60\xcc\x98\x31\xe8\ +\xd5\xab\x17\x32\x33\x33\xc1\x18\xb3\x89\x42\xd0\x4a\xc5\x9a\x3c\ +\x79\x32\x1a\x1a\x1a\x90\x95\x95\x75\xdf\x64\x0a\x5b\xfa\x1f\x36\ +\x36\x36\x62\xce\x9c\x39\xd2\xd9\xb3\x67\x9b\x85\x10\xe3\xcc\xb9\ +\x4f\xb1\xb9\xb1\xc9\x27\xed\x2d\x88\xe8\x0b\x49\x92\x46\x9c\x39\ +\x73\xa6\x6a\xec\xd8\xb1\xfc\xbb\xef\xbe\x53\x5a\xd2\x03\x51\xa9\ +\x54\x88\x8d\x8d\x45\x7e\x7e\x3e\x76\xed\xda\xa5\xb4\x1c\x45\xc9\ +\xca\xca\xc2\x99\x33\x67\x10\x13\x13\x03\x95\xca\xa6\x6f\x33\xd4\ +\xd4\xd4\x20\x2c\x2c\x8c\xff\xe7\x3f\xff\xa9\x11\x42\x78\xd9\xb2\ +\x61\x01\x1b\x37\x2d\x00\x10\xd1\x45\xce\xf9\xf0\xe2\xe2\xe2\xb2\ +\xd1\xa3\x47\xf3\xd2\xd2\x52\xa5\x25\x3d\x90\xdf\xfc\xe6\x37\x98\ +\x36\x6d\x1a\x56\xac\x58\x01\x7b\x5e\xc9\xd4\x15\x6a\x6b\x6b\xb1\ +\x7a\xf5\x6a\x04\x07\x07\xe3\xe9\xa7\x9f\x56\x5a\xce\x03\xa9\xa8\ +\xa8\x40\x68\x68\x28\xbf\x74\xe9\x52\xb9\x24\x49\xc3\x89\xc8\xe6\ +\x57\x80\xd8\xbc\x69\x01\x80\x88\xca\x4d\x26\xd3\xf3\x95\x95\x95\ +\xe7\x46\x8e\x1c\x29\xe5\xe4\xe4\x28\x2d\xe9\x81\x2c\x5e\xbc\x18\ +\x3a\x9d\x0e\xcb\x96\x2d\x53\x5a\x8a\x22\x7c\xf0\xc1\x07\xd0\x68\ +\x34\x58\xb0\x60\x81\xd2\x52\x1e\xc8\xe1\xc3\x87\x11\x18\x18\x28\ +\x55\x56\x56\x5e\xe0\x9c\xff\x8e\x88\x2e\x2b\xad\xa9\x3d\xd8\x85\ +\x69\x01\x80\x88\x6e\x98\x4c\xa6\x91\x46\xa3\x31\x79\xf2\xe4\xc9\ +\x88\x8e\x8e\x26\x93\xa9\xd3\xc5\xb4\x2d\x4a\xaf\x5e\xbd\xb0\x72\ +\xe5\x4a\xa4\xa7\xa7\xe3\xe4\x49\x9b\xee\x69\x99\x9d\x33\x67\xce\ +\x20\x23\x23\x03\xef\xbe\xfb\x2e\x7a\xf6\xec\xa9\xb4\x9c\xfb\xc2\ +\x39\x87\xc1\x60\xa0\xf9\xf3\xe7\xa3\xb9\xb9\x39\x99\x73\x3e\xc2\ +\x1a\xdb\xc4\x98\x0b\x9b\x9e\x88\xfa\x31\x18\x63\x93\xd4\x6a\xf5\ +\xa6\x61\xc3\x86\x69\xb7\x6f\xdf\xae\x1d\x38\x70\xa0\x4d\x4c\x44\ +\xdd\x7b\x2c\x34\x34\x14\xa5\xa5\xa5\x38\x72\xe4\x08\x74\x3a\x5d\ +\x97\xae\x67\x4e\xed\x96\x8a\x25\x49\x12\x7c\x7d\x7d\xe1\xee\xee\ +\xde\x66\xc9\xa2\xd2\xff\x8b\x5b\xc7\x2a\x2a\x2a\x30\x7f\xfe\x7c\ +\xe9\x9b\x6f\xbe\xe1\x42\x88\xd7\x89\xc8\xee\x26\x1f\xec\xe6\x49\ +\x7b\x27\x44\xb4\x4b\x08\xf1\x3f\x05\x05\x05\x45\x5e\x5e\x5e\x36\ +\xdb\x5d\x5e\xbd\x7a\x35\xae\x5d\xbb\x86\xf7\xde\x7b\x4f\x69\x29\ +\x56\x21\x3e\x3e\x1e\x15\x15\x15\x36\x3b\x2c\xc8\xcd\xcd\xc5\xab\ +\xaf\xbe\x2a\x95\x94\x94\x14\x0a\x21\x9e\xb1\x47\xc3\x02\x76\x6a\ +\x5a\x00\x20\xa2\x6f\x38\xe7\xbf\x35\x1a\x8d\x1b\xa7\x4c\x99\x82\ +\x45\x8b\x16\xd9\x5c\x77\xd9\xc3\xc3\x03\xab\x56\xad\x42\x52\x52\ +\x12\x0e\x1c\x38\xa0\xb4\x1c\x8b\x72\xec\xd8\x31\x7c\xfc\xf1\xc7\ +\x58\xba\x74\x29\xdc\xdd\xdd\x95\x96\x73\x17\x9c\x73\xbc\xff\xfe\ +\xfb\x14\x19\x19\x89\x96\x96\x96\x8d\x9c\xf3\xdf\x12\x91\xdd\xbe\ +\x4c\xb7\xcb\xee\xf1\xbd\x30\xc6\x26\x6a\x34\x9a\xe4\xa1\x43\x87\ +\x6a\x53\x52\x52\xb4\xb7\xf6\x1e\xb2\x95\x2e\xd9\xdc\xb9\x73\x71\ +\xe0\xc0\x01\xe4\xe6\xe6\xde\xf7\x86\xb6\xf7\xee\xf1\xb5\x6b\xd7\ +\xe0\xeb\xeb\x8b\xd1\xa3\x47\xc3\x60\x30\xd8\xd4\x50\xa5\xbc\xbc\ +\x1c\xf3\xe6\xcd\x93\x8a\x8b\x8b\x4d\x42\x88\x30\x22\xb2\xaf\x15\ +\x29\xf7\xc1\x21\x4c\x0b\x00\x8c\x31\xbd\x56\xab\xcd\xd2\x6a\xb5\ +\x4f\xc4\xc7\xc7\x6b\x02\x03\x03\x6d\xc6\xb4\x4d\x4d\x4d\x18\x37\ +\x6e\x1c\x5c\x5d\x5d\x91\x95\x95\x05\xad\x56\x6b\x75\x0d\x96\x8a\ +\x25\x84\x40\x70\x70\x30\x1a\x1a\x1a\x90\x91\x91\x01\x17\x17\x17\ +\x9b\x31\xed\xde\xbd\x7b\xb1\x6c\xd9\x32\x49\x92\xa4\xaf\x39\xe7\ +\x13\x88\xa8\xa4\x4d\x43\x3b\xc4\x6e\xbb\xc7\xf7\x42\x3f\x6c\x61\ +\x33\xbc\xa9\xa9\x29\xe1\x8d\x37\xde\x20\x3f\x3f\x3f\xa9\xb8\xb8\ +\x58\x69\x59\x00\x00\x17\x17\x17\x6c\xd8\xb0\x01\x05\x05\x05\x0e\ +\x37\xbe\x8d\x8d\x8d\xc5\xd7\x5f\x7f\x8d\x8f\x3e\xfa\xc8\x66\x16\ +\xb7\x97\x95\x95\x21\x3c\x3c\x5c\x8a\x8e\x8e\xa6\x96\x96\x96\xbf\ +\x73\xce\x87\x3b\x8a\x61\x01\x07\x32\x2d\x00\x10\x51\x8b\x2c\xcb\ +\x73\x89\x68\x78\x5e\x5e\xde\x79\x2f\x2f\x2f\xf9\xbd\xf7\xde\x83\ +\x2d\xe4\x2e\x7b\x7a\x7a\xc2\x60\x30\x20\x29\x29\x09\x07\x0f\x1e\ +\x54\x5a\x8e\x59\xf8\xfc\xf3\xcf\xb1\x71\xe3\x46\xac\x58\xb1\x02\ +\x7a\xbd\x5e\x69\x39\x68\x69\x69\xc1\xba\x75\xeb\xe0\xef\xef\x2f\ +\x9f\x3d\x7b\xf6\x6b\x22\x7a\x5e\x08\x31\x9b\x88\x5a\x94\xd6\x66\ +\x4e\x1c\xa6\x7b\x7c\x2f\x8c\x31\x15\x80\x08\x8d\x46\x13\xdb\xbf\ +\x7f\xff\xee\x1f\x7e\xf8\xa1\xf6\xa5\x97\x5e\x52\x3c\xdf\x35\x32\ +\x32\x12\x7b\xf6\xec\x41\x56\x56\x16\x9e\x78\xe2\x09\x45\x34\x98\ +\x23\x56\x61\x61\x21\x82\x83\x83\x31\x76\xec\x58\xac\x5a\xb5\xaa\ +\xdd\xe7\x99\x53\xc3\x9d\xdf\x1f\x3d\x7a\x14\x31\x31\x31\xbc\xba\ +\xba\xba\x45\x92\xa4\x68\x00\x89\x44\x24\xb7\x39\xd9\x01\x70\x58\ +\xd3\xde\x82\x31\xd6\x5f\xad\x56\xaf\x11\x42\x4c\x19\x33\x66\x8c\ +\x6c\x30\x18\xd4\x77\x56\x69\xb3\xf6\x0d\xd6\xd2\xd2\x82\x90\x90\ +\x10\x94\x94\x94\x20\x3b\x3b\x1b\x1e\x1e\x1e\x76\x67\xda\xf2\xf2\ +\x72\x4c\x9c\x38\x11\x83\x07\x0f\x46\x72\x72\xb2\xa2\x63\xf4\x8a\ +\x8a\x0a\xac\x5c\xb9\x52\x1c\x3f\x7e\x5c\xad\x52\xa9\xb6\xcb\xb2\ +\xbc\x80\x88\x2a\xdb\x9c\xe4\x40\x38\xbc\x69\x6f\xc1\x18\x1b\xa9\ +\xd3\xe9\x36\x00\xf0\x7c\xeb\xad\xb7\xd4\x33\x67\xce\x84\x4e\xa7\ +\x53\xe4\xa9\xd0\xd0\xd0\x80\x57\x5f\x7d\x15\x46\xa3\x11\x9f\x7d\ +\xf6\x19\xfa\xf5\xeb\x67\x55\x0d\x5d\x89\x55\x55\x55\x85\xa0\xa0\ +\x20\xb8\xb8\xb8\x60\xe7\xce\x9d\xe8\xd9\xb3\xa7\x22\xbd\x17\xce\ +\x39\x92\x93\x93\x91\x90\x90\x20\x00\x14\x73\xce\x23\x88\xe8\x44\ +\x9b\xc6\x0e\xc8\x43\x63\x5a\x00\x60\x8c\x69\x00\xcc\x51\xab\xd5\ +\x2b\x3d\x3c\x3c\x34\x4b\x96\x2c\xd1\xfa\xfa\xfa\xb6\x59\x85\x62\ +\x8d\x99\xce\xca\xca\x4a\xf8\xfb\xfb\xa3\x77\xef\xde\x48\x4f\x4f\ +\x6f\x93\xf2\x67\x8b\xa6\x6d\x6c\x6c\x44\x48\x48\x08\xea\xea\xea\ +\x90\x96\x96\x86\xfe\xfd\xfb\x9b\x55\x57\x7b\xda\xc8\xb2\x8c\x03\ +\x07\x0e\x60\xed\xda\xb5\xfc\xea\xd5\xab\x92\x10\x62\x09\x80\x78\ +\x22\x92\xda\x9c\xec\xa0\x3c\x54\xa6\xbd\x05\x63\xcc\x5d\xad\x56\ +\x1b\x64\x59\x0e\x1e\x38\x70\xa0\x14\x15\x15\xa5\x0b\x0c\x0c\xbc\ +\xbd\x50\xdb\x5a\xaf\x27\xca\xca\xca\xe0\xe7\xe7\x87\x21\x43\x86\ +\x20\x35\x35\xf5\xae\x6e\xa6\xad\x99\x96\x73\x8e\xb0\xb0\x30\x14\ +\x15\x15\x21\x3d\x3d\x1d\x0f\x1a\x62\x58\x42\x83\x10\x02\x39\x39\ +\x39\x48\x4c\x4c\x34\x95\x97\x97\x6b\x19\x63\xbb\x64\x59\x5e\x48\ +\x0a\xec\xf0\xaf\x34\x0f\xa5\x69\x6f\xc1\x18\xd3\xab\x54\xaa\xb7\ +\x01\x4c\x7f\xf4\xd1\x47\xe5\xc8\xc8\x48\x6d\x68\x68\x68\x9b\x31\ +\x1a\x60\xb9\x1b\xf3\xfc\xf9\xf3\x08\x08\x08\xc0\x73\xcf\x3d\x87\ +\xa4\xa4\x24\xb8\xba\xba\x76\x3a\x96\x39\x75\xdd\x79\xcc\x68\x34\ +\x62\xe6\xcc\x99\xf8\xf7\xbf\xff\x8d\x1d\x3b\x76\xe0\xc9\x27\x9f\ +\xb4\x88\xae\xfb\xb5\x69\x69\x69\x41\x66\x66\x26\x3e\xfe\xf8\x63\ +\x5e\x59\x59\xa9\x62\x8c\x6d\x97\x65\x79\x15\x11\x15\xb5\x69\xfc\ +\x90\xf0\x50\x9b\xf6\x16\x8c\x31\x0f\xc6\xd8\x5b\x8c\xb1\x19\x7d\ +\xfa\xf4\xc1\xdc\xb9\x73\xb5\xd3\xa6\x4d\xbb\x6b\xbb\x4f\x4b\xde\ +\x98\xe7\xce\x9d\xc3\x94\x29\x53\x30\x60\xc0\x00\xa4\xa4\xa4\xa0\ +\x7f\xff\xfe\x36\x63\xda\xea\xea\x6a\x84\x87\x87\xe3\xda\xb5\x6b\ +\xd8\xbc\x79\x33\x86\x0d\x1b\x66\x31\x5d\x77\x7e\xdf\xd4\xd4\x84\ +\x4f\x3e\xf9\x04\x49\x49\x49\xbc\xae\xae\x0e\x44\xb4\x89\x88\x0c\ +\x44\x54\xd6\x26\xd0\x43\x86\xd3\xb4\x77\xc0\x18\x1b\x00\x60\x81\ +\x5a\xad\x9e\xe5\xea\xea\xaa\x99\x39\x73\xa6\x26\x3c\x3c\x1c\xbd\ +\x7b\xf7\xb6\x78\x17\xf0\xf2\xe5\xcb\x08\x0d\x0d\x85\x10\x02\xa9\ +\xa9\xa9\x18\x3c\x78\x70\xa7\x63\x99\x4b\x57\x59\x59\x19\xa6\x4f\ +\x9f\x0e\x95\x4a\x85\x2d\x5b\xb6\xb4\x7b\xa6\xbb\xab\x93\x74\xdb\ +\xb7\x6f\xc7\xe6\xcd\x9b\x25\xa3\xd1\x28\x64\x59\x4e\x04\x10\x4b\ +\x44\x57\xdb\x04\x78\x48\x71\x9a\xf6\x3e\x30\xc6\xfa\x01\x98\xaf\ +\xd1\x68\xe6\xe9\x74\xba\x6e\x93\x27\x4f\xd6\x04\x05\x05\xe1\xa9\ +\xa7\x9e\xba\xdd\xc6\x12\xdd\xd0\xea\xea\x6a\x4c\x9d\x3a\x15\x97\ +\x2f\x5f\xc6\xd6\xad\x5b\xf1\xec\xb3\xcf\x76\x3a\x56\x57\x75\x9d\ +\x3f\x7f\x1e\xaf\xbf\xfe\x3a\xdc\xdd\xdd\xb1\x69\xd3\x26\xf4\xed\ +\xdb\xb7\xd3\xb1\xda\x73\xec\xe2\xc5\x8b\xf8\xf4\xd3\x4f\x91\x9e\ +\x9e\x2e\x99\x4c\x26\x93\x10\xe2\x23\x00\x71\xe4\xe0\xaf\x6f\x3a\ +\x83\xd3\xb4\x0f\x80\x31\xd6\x1b\xc0\x9b\x3a\x9d\x2e\xc2\x64\x32\ +\xe9\xf5\x7a\xbd\x29\x34\x34\x54\x17\x10\x10\x80\x01\x03\x06\xb4\ +\x69\x6f\x8e\x1b\xda\x68\x34\x62\xc6\x8c\x19\xf8\xe7\x3f\xff\x89\ +\xd8\xd8\x58\x4c\x98\x30\xa1\xd3\xb1\x3a\xab\x6b\xcf\x9e\x3d\x58\ +\xb4\x68\x11\x86\x0f\x1f\x8e\xf5\xeb\xd7\x3f\x70\x98\xd0\x15\x5d\ +\xd7\xaf\x5f\x47\x4e\x4e\x0e\x76\xef\xde\x6d\x2a\x2b\x2b\xd3\x69\ +\xb5\xda\x52\xce\xf9\x46\xfc\x90\x18\x61\xd5\x9a\xaf\xf6\x84\xd3\ +\xb4\xed\x84\x31\xf6\x3b\xc6\xd8\x54\xb5\x5a\x3d\x45\x08\xd1\xcb\ +\xdb\xdb\x5b\x04\x07\x07\x6b\x5e\x7e\xf9\xe5\xdb\x37\xb5\xb9\x6e\ +\x68\x49\x92\xb0\x62\xc5\x0a\x6c\xde\xbc\x19\xbe\xbe\xbe\x78\xff\ +\xfd\xf7\xcd\xda\x45\xff\x31\x5d\xf5\xf5\xf5\x58\xba\x74\x29\xb2\ +\xb3\xb3\x31\x7d\xfa\x74\xbc\xfd\xf6\xdb\x50\xab\xd5\x9d\x8a\xf5\ +\x63\x6d\x9a\x9a\x9a\x70\xe8\xd0\x21\x64\x64\x64\x48\xf9\xf9\xf9\ +\x6a\xb5\x5a\x7d\x53\x08\xb1\x9d\x88\xb6\x11\x51\x5e\x9b\x13\x9d\ +\xb4\xc1\x69\xda\x0e\xc2\x18\xd3\x01\x18\xaf\xd1\x68\x5e\x97\x65\ +\x79\x9c\x4e\xa7\x83\xaf\xaf\xaf\x2a\x28\x28\x88\x79\x79\x79\xfd\ +\xe4\x3b\xdf\x8e\x98\xea\xf8\xf1\xe3\x98\x3f\x7f\x3e\x18\x63\x88\ +\x8b\x8b\xc3\xa8\x51\xa3\x3a\x1d\xeb\xa7\x8e\x9d\x3c\x79\x12\x0b\ +\x17\x2e\x04\x11\x21\x36\x36\x16\x23\x47\x8e\x34\x5b\x57\x5b\x96\ +\x65\xe4\xe5\xe5\x21\x2b\x2b\x8b\xf6\xef\xdf\x2f\x73\xce\xc1\x18\ +\xdb\x2f\x84\x48\x06\x90\x43\x44\xb6\xb5\x10\xda\xc6\x71\x9a\xb6\ +\x0b\x30\xc6\x7e\x06\x20\x58\xab\xd5\x86\x73\xce\x9f\xe9\xdf\xbf\ +\x3f\x1f\x3f\x7e\xbc\xd6\xdb\xdb\x1b\x5e\x5e\x5e\xe8\xd7\xaf\x5f\ +\x97\x9f\x8e\xb5\xb5\xb5\x88\x8e\x8e\xc6\x9e\x3d\x7b\x30\x7d\xfa\ +\x74\x2c\x5e\xbc\x18\xdd\xbb\x77\xef\x54\xac\xfb\x1d\x6b\x6e\x6e\ +\x86\xc1\x60\xc0\xd6\xad\x5b\x31\x6e\xdc\x38\xac\x5c\xb9\x12\x8f\ +\x3c\xf2\x48\x97\xe2\x13\x11\x6e\xdc\xb8\x81\xfc\xfc\x7c\xe4\xe7\ +\xe7\xe3\xe0\xc1\x83\xbc\xaa\xaa\x4a\xab\xd5\x6a\xcf\x71\xce\x37\ +\x01\xd8\x49\x44\xce\x6a\x65\x9d\xc4\x69\x5a\x33\xc1\x18\x1b\x06\ +\x20\x48\xa7\xd3\x8d\x93\x24\xe9\x59\x22\x52\xeb\xf5\x7a\xd3\x8b\ +\x2f\xbe\xa8\xf3\xf6\xf6\xc6\x88\x11\x23\xe0\xe6\xe6\xd6\x69\x23\ +\x64\x64\x64\xe0\x9d\x77\xde\x81\xab\xab\x2b\xe6\xcd\x9b\x87\x49\ +\x93\x26\xb5\xe9\xba\xb6\x37\x16\xf0\x43\x17\x3c\x2d\x2d\x0d\xeb\ +\xd6\xad\xc3\xcd\x9b\x37\xb1\x7c\xf9\xf2\xbb\xc6\xcf\x1d\x89\x75\ +\xab\x6b\x7d\xfa\xf4\x69\x7c\xf1\xc5\x17\x38\x71\xe2\x84\xa9\xb4\ +\xb4\x54\xc7\x18\x13\x1a\x8d\xe6\x4b\x93\xc9\xb4\x0f\xc0\x27\x44\ +\x74\xb1\xcd\xc9\x4e\x3a\x8c\xd3\xb4\x16\x80\x31\xe6\x0a\x60\x14\ +\x80\xd1\x3a\x9d\xee\x25\xce\xf9\x7f\x03\xc0\xb0\x61\xc3\xf8\x1f\ +\xfe\xf0\x07\x9d\xb7\xb7\x37\x7e\xff\xfb\xdf\x77\x68\x2c\x0c\x00\ +\xdf\x7d\xf7\x1d\xe2\xe3\xe3\xb1\x73\xe7\x4e\xfc\xf2\x97\xbf\x44\ +\x64\x64\x24\xfc\xfd\xfd\xef\xea\x92\xff\x54\x2c\x22\xc2\x3f\xfe\ +\xf1\x0f\xac\x59\xb3\xe6\x76\xe2\xff\x9c\x39\x73\xf0\xe8\xa3\x8f\ +\xb6\x4b\xc3\x9d\x63\xd3\x5b\x26\x3d\x79\xf2\xa4\xa9\xa0\xa0\x40\ +\x0b\x00\x5a\xad\xf6\x2b\x93\xc9\xb4\x1f\xc0\x61\x00\x27\x88\xa8\ +\xf1\x01\x7f\x2a\x27\x9d\xc0\x69\x5a\x2b\xc0\x18\xeb\x03\xe0\x05\ +\xb4\x9a\xd8\x64\x32\x3d\xa6\x56\xab\xe5\x41\x83\x06\xf1\xa1\x43\ +\x87\x6a\xf5\x7a\xbd\x4a\xaf\xd7\xe3\xb1\xc7\x1e\x83\x5e\xaf\x47\ +\xaf\x5e\xbd\x1e\x68\x98\xf2\xf2\x72\xc4\xc5\xc5\x21\x33\x33\x13\ +\x9e\x9e\x9e\x98\x3d\x7b\x36\xc6\x8c\x19\x83\x6e\xdd\xba\xfd\xe8\ +\x79\x2d\x2d\x2d\x38\x74\xe8\x10\x12\x12\x12\x50\x50\x50\x00\x3f\ +\x3f\x3f\xcc\x9b\x37\x0f\x03\x07\x0e\xbc\x2b\xf6\xbd\xe7\xdd\xbc\ +\x79\x13\x97\x2e\x5d\xba\xfd\x51\x52\x52\x22\x17\x16\x16\xf2\x2b\ +\x57\xae\x68\x85\x10\x2a\x9d\x4e\x57\x7c\x87\x49\x8f\x3a\x67\x7d\ +\x2d\x8f\xd3\xb4\x0a\xd0\x9a\xc4\xf1\x22\x80\x67\x55\x2a\xd5\x50\ +\x8d\x46\xf3\x24\xe7\xfc\xbf\x88\x48\x0d\x00\x7d\xfa\xf4\x31\x79\ +\x7a\x7a\xb2\xc7\x1f\x7f\x5c\x7b\xcb\xcc\x83\x06\x0d\x82\x9b\x9b\ +\x1b\x7a\xf6\xec\x79\x7b\x3b\xd6\xe2\xe2\x62\xac\x59\xb3\x06\xfb\ +\xf7\xef\x47\x8f\x1e\x3d\xf0\xf2\xcb\x2f\xe3\x95\x57\x5e\xc1\xf3\ +\xcf\x3f\x0f\x95\x4a\x75\xe7\x04\x10\xf6\xed\xdb\x07\xa3\xd1\x08\ +\x1f\x1f\x1f\x44\x46\x46\xc2\xd3\xd3\x13\xc0\x0f\x45\xa7\x1a\x1b\ +\x1b\x51\x57\x57\x87\xb2\xb2\x32\x94\x94\x94\xa0\xb4\xb4\x14\x45\ +\x45\x45\xbc\xb8\xb8\x98\x6a\x6a\x6a\x74\xad\x9a\x85\x56\xab\xbd\ +\xc2\x39\xbf\x40\x44\x05\x00\xbe\x04\x70\x84\x88\xae\x2b\xf1\x37\ +\x7c\x98\x71\x9a\xd6\x46\x68\x5d\x81\x34\x18\xc0\x10\x00\x8f\x03\ +\x18\xa2\xd5\x6a\x87\x01\x18\xca\x39\xff\xd9\x9d\x6d\x55\x2a\x15\ +\xb9\xb8\xb8\x08\x57\x57\x57\xd9\xd5\xd5\x95\x5c\x5c\x5c\x54\x4d\ +\x4d\x4d\xea\x1b\x37\x6e\xa8\xea\xea\xea\xd0\xa3\x47\x0f\x78\x78\ +\x78\xe0\xdb\x6f\xbf\x85\xd1\x68\x44\xef\xde\xbd\xd1\xb7\x6f\x5f\ +\xb9\x7b\xf7\xee\xa2\xb9\xb9\x59\xbe\x79\xf3\x26\x33\x1a\x8d\xaa\ +\xa6\xa6\x26\xb5\x2c\xcb\x77\x55\xc6\xd2\x6a\xb5\xd5\x00\x0a\x38\ +\xe7\x17\x00\x14\x02\x28\x6a\xfd\x5c\x4a\x0f\xd1\x4a\x1a\x5b\xc6\ +\x69\x5a\x3b\x80\x31\xd6\x0b\x3f\x18\xb9\x2f\x80\x9e\x00\x7a\xb5\ +\x7e\xb4\xf9\x5a\xad\x56\xbb\x03\x18\x08\x40\x07\xc0\x04\xe0\xb2\ +\x10\xa2\x02\x40\x03\x80\x9b\xad\x9f\xef\xf7\xf5\x0d\x00\x45\x44\ +\xd4\x60\xbd\xdf\xcc\x49\x67\xf8\x7f\x32\x53\x4c\xb2\xc7\x0e\x3f\ +\x78\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\xab\xdc\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x02\x81\x00\x00\x01\x55\x08\x06\x00\x00\x00\x90\x14\x35\x1c\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x12\x74\x00\x00\x12\x74\ +\x01\xde\x66\x1f\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x20\x00\x49\x44\ +\x41\x54\x78\x9c\xec\xdd\x77\x78\x94\x65\xf6\xf0\xf1\xef\x99\x92\ +\x02\x84\x40\xe8\xa1\xf7\x26\x10\x42\xc0\x55\x41\x05\x14\x14\x75\ +\x57\x59\xb7\xd8\xbb\x38\xba\x56\x74\x49\x10\x45\x44\x12\xb0\xed\ +\x2a\xea\x58\x5e\x1b\xbb\xab\x2e\xea\xee\xa2\x62\x07\x6c\x3f\xc5\ +\xba\x2a\x2b\x28\x82\x8a\x14\xe9\x25\x94\xb4\xc9\x9c\xf7\x8f\x67\ +\x12\xd2\x08\x81\x64\x32\x99\xc9\xf9\x5c\x57\x2e\xe7\xe9\x67\x02\ +\x32\x67\xee\x72\x6e\x51\x55\x8c\x31\xc6\x34\x2c\x7e\xbf\xbf\x3d\ +\x30\x14\xe8\x00\xa4\x02\xab\x7d\x3e\xdf\xb3\x65\x8e\x9f\x0f\x3c\ +\x5d\xe6\x92\x5d\x3e\x9f\xaf\x45\x99\xe3\x2d\x80\x1d\x0d\xf8\x78\ +\x7b\xe0\x97\x32\xc7\x37\xf9\x7c\xbe\xf6\x31\x74\xbc\x1b\xf0\x63\ +\x99\xe3\x6b\x7c\x3e\x5f\xb7\x03\x1d\xdf\xbe\x7d\x3b\xd3\xa6\x4d\ +\x2b\x3d\xb9\x55\xab\x56\xcc\x9c\x39\x93\xfa\x38\xae\xaa\x6c\xdc\ +\xb8\x31\x38\x67\xce\x9c\x1f\x82\xc1\xe0\xfa\x40\x20\xb0\x36\x39\ +\x39\x79\xdb\x19\x67\x9c\xd1\xb5\xb0\xb0\x70\x6d\x41\x41\xc1\xca\ +\xcd\x9b\x37\x3f\xf7\xde\x7b\xef\x6d\xc5\xc4\x14\x4f\xa4\x03\x30\ +\xc6\x18\x53\xa5\xa3\x80\x7f\x01\x05\x38\xc9\xc6\x7c\xe0\xd9\x32\ +\xc7\x17\x01\x67\x94\xd9\x2e\xaa\x70\xfd\xde\x06\x7e\x7c\x47\x85\ +\xe3\xf9\x31\x76\x7c\x73\x85\xe3\xfb\x2a\x1e\x9f\x3f\x7f\xfe\xa2\ +\x26\x4d\x9a\x8c\x1e\x3b\x76\xac\x2b\x31\x31\x91\x39\x73\xe6\x94\ +\x1e\x14\x11\xf2\xf2\xf2\x4a\xb7\xc3\x7d\x3c\x2e\x2e\xce\x75\xc1\ +\x05\x17\xf4\xda\xb6\x6d\x5b\xaf\xcd\x9b\x37\x17\x17\x15\x15\x15\ +\x0f\x1c\x38\xd0\xdb\xa4\x49\x13\x11\x11\x36\x6c\xd8\x70\xbf\xc7\ +\xe3\x79\xab\xb8\xb8\xf8\x45\xe0\x25\x55\xdd\x88\x89\x7a\x62\x2d\ +\x81\xc6\x18\x13\x19\x7e\xbf\xdf\x03\x1c\x07\x9c\x0e\x74\xf2\xf9\ +\x7c\x67\x94\x39\xe6\x05\x92\x7c\x3e\xdf\xf6\x48\xc5\x67\xc2\x2b\ +\x3e\x3e\xfe\xa7\xf3\xcf\x3f\xbf\xeb\xa5\x97\x5e\x1a\xe9\x50\x0e\ +\x28\x18\x0c\xb2\x79\xf3\x66\x96\x2d\x5b\xc6\xdb\x6f\xbf\x5d\xfc\ +\xd1\x47\x1f\x51\x58\x58\xe8\xea\xdb\xb7\xef\xb7\x23\x46\x8c\x58\ +\xb5\x69\xd3\xa6\x7b\xdf\x78\xe3\x8d\x77\x22\x1d\xa7\x39\x3c\x96\ +\x04\x1a\x63\x4c\x04\xf8\xfd\xfe\x56\xc0\x77\x40\x2b\xe0\x6b\x60\ +\x01\x30\xdd\xe7\xf3\xd9\x3f\xca\x8d\x80\x88\xb4\x05\x36\xcd\x9d\ +\x3b\x97\xe1\xc3\x87\x47\x3a\x9c\x1a\x2b\x2c\x2c\xe4\x93\x4f\x3e\ +\x61\xf5\xea\xd5\xda\xbb\x77\x6f\x49\x48\x48\x60\xdd\xba\x75\x79\ +\x9f\x7e\xfa\xe9\x8c\x37\xdf\x7c\x73\xce\xc1\xef\x60\x1a\x12\x4b\ +\x02\x8d\x31\x26\x42\xfc\x7e\xff\x6f\x80\x2f\x7d\x3e\xdf\x9a\x48\ +\xc7\x62\xea\x97\x88\x4c\x74\xb9\x5c\x2f\x2c\x5a\xb4\x48\x12\x13\ +\x13\x23\x1d\xce\x61\x29\x2e\x2e\xe6\x9b\x6f\xbe\x61\xed\xda\xb5\ +\xfa\xcf\x7f\xfe\x53\x7e\xf8\xe1\x87\xcf\x02\x81\xc0\x0d\xaa\xfa\ +\x7e\xa4\x63\x33\x35\x63\x49\xa0\x31\xc6\x84\x99\xdf\xef\x17\xe0\ +\xf7\x40\x91\xcf\xe7\xfb\x57\xa4\xe3\x31\x91\x27\x22\xf7\xf6\xe9\ +\xd3\xe7\xaa\x79\xf3\xe6\xc5\x45\x3a\x96\xba\xf0\xed\xb7\xdf\x72\ +\xff\xfd\xf7\x07\xbe\xf8\xe2\x0b\x8f\xdb\xed\x7e\xf5\xd8\x63\x8f\ +\xbd\x77\xf1\xe2\xc5\x8b\x22\x1d\x97\xa9\x9e\x2b\xd2\x01\x18\x63\ +\x4c\x2c\xf3\xfb\xfd\x63\x80\x4f\x81\x7f\x00\xe9\x11\x0e\xc7\x34\ +\x10\x71\x71\x71\x27\x0c\x1b\x36\x2c\x26\x12\x40\x80\x7e\xfd\xfa\ +\xf1\xd0\x43\x0f\x79\xee\xbf\xff\x7e\x46\x8f\x1e\x3d\x6e\xe2\xc4\ +\x89\x6f\x5f\x71\xc5\x15\xcb\xc7\x8c\x19\x73\x44\xa4\x63\x33\x07\ +\x66\x49\xa0\x31\xc6\x84\x89\xdf\xef\xef\x00\xbc\x0c\xfc\x0c\x1c\ +\xe1\xf3\xf9\xa6\x1d\xe4\x12\xd3\x08\x88\x48\xd3\xa2\xa2\xa2\x01\ +\x43\x86\x0c\x89\x74\x28\x75\x6e\xc4\x88\x11\xdc\x7e\xfb\xed\x9e\ +\xbc\xbc\x7c\xf6\xed\x3b\xa9\x5f\x7a\xfa\xef\xbf\x1a\x3f\x7e\x7c\ +\xc3\x9d\xf9\xd2\xc8\x59\x77\xb0\x31\xc6\x84\x91\xdf\xef\xef\xec\ +\xf3\xf9\xd6\x46\x3a\x0e\xd3\x70\x88\xc8\x09\xc0\x5b\xaf\xbf\xfe\ +\x3a\x2d\x5a\xb4\x38\xe8\xf9\xd1\x24\x18\x84\xc5\x8b\x5b\xf1\xf8\ +\xe3\x9d\xf8\xf1\xc7\x04\x2e\xbb\xec\x7e\x7d\xf5\xd5\x3b\x75\xfd\ +\xfa\xf5\x7f\x52\x55\x7f\xa4\xe3\x33\xe5\x59\x4b\xa0\x31\xc6\xd4\ +\x21\xbf\xdf\x5f\xae\x8b\xcf\x12\x40\x53\x85\x91\xa9\xa9\xa9\x85\ +\xb1\x94\x00\x06\x83\xc2\x6b\xaf\xb5\xe6\xac\xb3\x86\x30\x6d\x5a\ +\x2f\x7e\xfc\x31\x01\x80\xdf\xfc\x66\x94\x9c\x7a\xea\xa9\x2e\xe0\ +\x21\xb7\xdb\xed\x17\x11\xab\x4f\xdc\x80\x58\x12\x68\x8c\x31\x75\ +\xc4\xef\xf7\x9f\x00\xac\xf2\xfb\xfd\xfd\x23\x1d\x8b\x69\xb8\xbc\ +\x5e\xef\x98\x8c\x8c\x8c\x98\x19\x0f\xf8\xce\x3b\x29\xfc\xee\x77\ +\x83\x99\x31\xa3\x27\x6b\xd6\x24\x94\x3b\xd6\xbc\x79\x80\x8b\x2e\ +\xba\x88\x39\x73\xe6\xe0\xf5\x7a\x2f\x1b\x32\x64\xc8\xe7\xc7\x1c\ +\x73\x4c\xa7\x08\x85\x6a\x2a\xb0\x24\xd0\x18\x63\xea\x80\xdf\xef\ +\xbf\x12\x78\x0d\x78\x8f\xf2\xcb\x85\x19\x53\x4a\x44\x3c\xc5\xc5\ +\xc5\x23\x62\x69\x3c\xe0\xe0\xc1\xbb\xe9\xdd\x3b\xaf\xd2\xfe\xb8\ +\xb8\x20\x71\x71\x41\x00\x8e\x3b\xee\x38\x9e\x78\xe2\x09\xf7\x1f\ +\xff\xf8\xc7\x41\x27\x9c\x70\xc2\xea\x13\x4f\x3c\x71\x4c\x7d\xc7\ +\x69\x2a\xb3\x31\x81\xc6\x18\x53\x4b\x7e\xbf\xff\x28\xe0\x43\x20\ +\xcb\xe7\xf3\xcd\x8e\x74\x3c\xa6\xe1\x12\x91\x11\xc0\xc7\x2f\xbe\ +\xf8\x22\x1d\x3b\x76\x8c\x74\x38\x75\xea\xa9\xa7\x52\x79\xf8\xe1\ +\xce\xa5\xdb\xad\x5b\x17\xf1\xca\x2b\x5f\x94\x3b\x67\xeb\xd6\xad\ +\x7c\xf9\xe5\x97\x1a\x08\x04\x8a\x5f\x7f\xfd\xf5\x81\x1f\x7d\xf4\ +\xd1\xca\xfa\x8e\xd3\xec\x67\x2d\x81\xc6\x18\x53\x4b\x3e\x9f\xef\ +\x23\xe0\x28\x4b\x00\x4d\x0d\x8c\x6c\xd1\xa2\x45\x51\xac\x25\x80\ +\x45\x45\x2e\xde\x7c\xb3\x35\x43\x86\xec\x66\xe4\xc8\x1d\x00\x24\ +\x25\x05\x2a\x9d\xd7\xba\x75\x6b\x86\x0f\x1f\x2e\xf1\xf1\xf1\x6e\ +\xe0\x55\x11\x49\xa8\x74\x92\xa9\x37\x36\x40\xd3\x18\x63\xea\x80\ +\xcf\xe7\x5b\x1a\xe9\x18\x4c\xc3\xe7\xf1\x78\x8e\x1f\x36\x6c\x98\ +\x3b\xd2\x71\xd4\xb5\x47\x1e\xe9\xc4\xa6\x4d\x71\xdc\x7b\xef\xb7\ +\xb4\x6f\x5f\xc8\xab\xaf\xb6\x66\xf1\xe2\x56\x55\x9e\x9b\x9c\x9c\ +\x4c\xaf\x5e\xbd\x64\xd9\xb2\x65\x5d\xdd\x6e\xf7\xe3\xc0\x39\xf5\ +\x1b\xad\x29\x61\x2d\x81\xc6\x18\x73\x18\xfc\x7e\x7f\x13\xbf\xdf\ +\xdf\x3c\xd2\x71\x98\xa8\x73\x6c\x5a\x5a\x5a\x4c\x7d\xf6\x7e\xfd\ +\x75\x12\xcf\x3c\xd3\x81\xeb\xae\x5b\x43\xfb\xf6\x85\x00\x4c\x98\ +\xb0\x95\x9c\x9c\xef\x0f\x78\x4d\xe7\xce\x9d\x99\x3d\x7b\xb6\x47\ +\x55\xff\x28\x22\x53\xea\x2b\x56\x53\x5e\x4c\xfd\x45\x34\xc6\x98\ +\xfa\x10\x5a\x06\xee\x29\x60\x61\x84\x43\x31\x51\x44\x44\xfa\x05\ +\x02\x81\xe4\x58\x9a\x14\x92\x97\xe7\xe2\xf6\xdb\x7b\x70\xf4\xd1\ +\x3b\x39\xed\xb4\x2d\xe5\x8e\x79\xbd\xc1\x6a\xaf\x1d\x3e\x7c\x38\ +\x37\xdc\x70\x83\x2b\x25\x25\x25\x67\xfc\xf8\xf1\xd7\x87\x33\x4e\ +\x53\x35\xeb\x0e\x36\xc6\x98\x43\x37\x0d\x38\x1d\x38\x29\xd2\x81\ +\x98\xa8\x32\x2a\x21\x21\x21\xd0\xab\x57\xaf\x98\xf9\xec\x7d\xe0\ +\x81\x2e\xec\xde\xed\x21\x2b\xeb\x87\xc3\xba\xfe\xcc\x33\xcf\x24\ +\x3e\x3e\x5e\x9a\x37\x6f\x7e\xcf\x98\x31\x63\xbe\xb6\xf5\x86\xeb\ +\x97\xb5\x04\x1a\x63\xcc\x21\xf0\xfb\xfd\xbd\x80\x5b\x81\x1b\x7c\ +\x3e\xdf\xe2\x48\xc7\x63\xa2\x87\x88\x8c\x1a\x32\x64\x88\xb8\x5c\ +\xb1\xf1\xd1\xfb\xe9\xa7\xc9\xfc\xeb\x5f\xed\xb8\xe9\xa6\x9f\x68\ +\xd5\xaa\xe8\xb0\xef\x33\x7e\xfc\x78\x02\x81\x00\x83\x07\x0f\x7e\ +\xa1\x0e\xc3\x33\x35\x10\x1b\x7f\x13\x8d\x31\xa6\xfe\x6c\x06\xa6\ +\x00\x0f\x45\x3a\x10\x13\x5d\xbc\x5e\xef\xd8\xa1\x43\x87\xc6\xc4\ +\xa4\x90\x3d\x7b\xdc\xdc\x71\x47\x0f\xc6\x8e\xdd\xc6\x09\x27\x6c\ +\xab\xd5\xbd\xe2\xe2\xe2\x68\xd7\xae\x9d\xf4\xed\xdb\xb7\xc5\xe8\ +\xd1\xa3\x27\xd7\x51\x88\xa6\x06\xac\x4e\xa0\x31\xc6\x18\x13\x66\ +\x22\x92\x0a\xac\xf7\xfb\xfd\x0c\x1d\x3a\x34\xd2\xe1\xd4\xda\xcc\ +\x99\x3d\x59\xba\x34\x99\x67\x9e\xf9\x9a\xe4\xe4\xca\xa5\x60\x0e\ +\xc7\xdc\xb9\x73\x75\xfe\xfc\xf9\x3f\x16\x15\x15\xf5\x51\xd5\xe2\ +\x3a\xb9\xa9\xa9\x96\xb5\x04\x1a\x63\x8c\x31\xe1\x37\xca\xed\x76\ +\x07\x07\x0e\x1c\x18\xe9\x38\x6a\xed\xfd\xf7\x5b\xb2\x70\x61\x6b\ +\xb2\xb2\x7e\xa8\xb3\x04\x10\x60\xe2\xc4\x89\x12\x0c\x06\xbb\x01\ +\x17\xd7\xd9\x4d\x4d\xb5\x2c\x09\x34\xc6\x98\x1a\xf0\xfb\xfd\x83\ +\xfc\x7e\x7f\xd5\x85\xcf\x8c\x39\xb8\x91\x7d\xfb\xf6\x2d\x8e\x8b\ +\x8b\xee\x25\x83\x77\xee\xf4\x90\x93\xd3\x9d\xd3\x4e\xdb\xc2\xc8\ +\x91\x3b\xeb\xf4\xde\x1d\x3b\x76\x64\xe2\xc4\x89\x2e\x8f\xc7\x33\ +\x4b\x44\x12\xeb\xf4\xe6\xa6\x4a\x96\x04\x1a\x63\xcc\x41\xf8\xfd\ +\x7e\x17\xf0\x0c\xf0\x97\x48\xc7\x62\xa2\x53\x5c\x5c\xdc\x09\xc3\ +\x86\x0d\xf3\x46\x3a\x8e\xda\xba\xf3\xce\xee\xc4\xc5\x29\xd7\x5d\ +\xb7\x26\x2c\xf7\xbf\xe4\x92\x4b\xe8\xd6\xad\x5b\xca\x98\x31\x63\ +\x1e\x08\xcb\x03\x4c\x39\x31\x33\x4d\xdd\x18\x63\xc2\xe8\x7c\xa0\ +\x3f\x70\x66\xa4\x03\x31\xd1\x47\x44\x92\x45\xa4\x6f\xb4\xd7\x07\ +\x7c\xf3\xcd\x56\x2c\x59\x92\xc2\xdc\xb9\x2b\x68\xda\x34\x3c\x43\ +\xf6\x5a\xb4\x68\xc1\xf9\xe7\x9f\xef\xf6\x78\x3c\x17\xf5\xef\xdf\ +\x7f\xea\x8a\x15\x2b\x36\x85\xe5\x41\x06\xb0\x96\x40\x63\x8c\xa9\ +\x89\x4b\x80\xe7\x7d\x3e\xdf\x77\x91\x0e\xc4\x44\xa5\xa3\x55\x55\ +\xa2\x39\x09\xdc\xba\xd5\xcb\xdd\x77\x77\xe3\xcc\x33\x37\x92\x91\ +\x91\x1b\xd6\x67\xfd\xea\x57\xbf\x22\x39\x39\x59\x7a\xf7\xee\x9d\ +\x15\xd6\x07\x19\x4b\x02\x8d\x31\xa6\x06\xe6\x03\x8f\x44\x3a\x08\ +\x13\xb5\x46\x76\xe9\xd2\xa5\x30\x29\x29\x29\xd2\x71\x1c\xb6\xec\ +\xec\x1e\x24\x27\x07\xb8\xea\xaa\xb5\x61\x7f\x56\xf3\xe6\xcd\xd9\ +\xbe\x7d\x3b\xa9\xa9\xa9\x67\x84\xfd\x61\x8d\x9c\x75\x07\x1b\x63\ +\xcc\x41\xf8\x7c\xbe\xb9\x91\x8e\xc1\x44\xaf\xb8\xb8\xb8\xb1\x19\ +\x19\x19\x51\x3b\x23\xe4\xa5\x97\xda\xb2\x74\x69\x32\x8f\x3c\xb2\ +\x9c\x84\x84\xea\x97\x82\xab\x4b\xef\xbf\xff\x7e\xaa\x88\x34\x51\ +\xd5\x7d\xf5\xf6\xd0\x46\xc6\x5a\x02\x8d\x31\xc6\x98\x30\x11\x91\ +\xf8\x40\x20\x90\x1e\xad\x5d\xc1\xbf\xfc\x12\xcf\x5f\xff\xda\x85\ +\x73\xce\xf9\x85\x41\x83\xf6\xd4\xdb\x73\x87\x0f\x1f\xce\x8a\x15\ +\x2b\xdc\xc0\xb8\x7a\x7b\x68\x23\x64\x49\xa0\x31\xc6\x18\x13\x3e\ +\x19\xc1\x60\xd0\x9b\x96\x96\x16\xe9\x38\x0e\x99\x2a\xcc\x9c\xd9\ +\x83\x0e\x1d\x0a\xb8\xfc\xf2\x75\xf5\xfa\xec\x16\x2d\x5a\x30\x68\ +\xd0\xa0\x62\x11\x39\xbd\x5e\x1f\xdc\xc8\x58\x77\xb0\x31\xc6\x1c\ +\x80\xdf\xef\x1f\x8f\x33\x29\xe4\x2c\x9f\xcf\x67\x2b\x18\x98\xc3\ +\x31\xaa\x55\xab\x56\x85\xed\xda\xb5\x8b\xba\xee\xe0\xf9\xf3\xdb\ +\xf3\xf5\xd7\x49\x3c\xf1\xc4\xff\xf0\x7a\xeb\x7f\x75\xb1\x31\x63\ +\xc6\x78\x96\x2f\x5f\x7e\xba\x88\xb8\x6d\x05\x91\xf0\xb0\x24\xd0\ +\x18\x63\x0e\xec\xf7\x40\x67\x4b\x00\xcd\xe1\xf2\x78\x3c\xc7\x67\ +\x64\x64\x44\x5d\x7d\xc0\x35\x6b\x12\x78\xe8\xa1\xce\x5c\x7c\xf1\ +\x7a\xfa\xf4\x89\xcc\x90\xbc\x91\x23\x47\xd2\xac\x59\xb3\xe4\xf7\ +\xde\x7b\xef\xf7\xc0\xb3\x11\x09\x22\xc6\x59\x77\xb0\x31\xc6\x1c\ +\xd8\x38\xe0\xe5\x48\x07\x61\xa2\x93\x88\x08\x70\xcc\x90\x21\x43\ +\x24\xd2\xb1\x1c\x8a\x60\x50\xb8\xfd\xf6\x9e\xf4\xec\x99\xc7\x05\ +\x17\x6c\x88\x58\x1c\x9d\x3a\x75\xa2\x65\xcb\x96\x9a\x9a\x9a\x7a\ +\x7e\xc4\x82\x88\x71\xd6\x12\x68\x8c\x31\x55\xf0\xfb\xfd\x6e\x20\ +\x15\xb0\xda\x80\xe6\x70\x1d\x11\x08\x04\x9a\x45\xdb\x78\xc0\x79\ +\xf3\x3a\xf0\xfd\xf7\x4d\x98\x37\xef\x7f\xb8\xdd\xf5\xdf\x0d\x5c\ +\xd6\xbe\x7d\xfb\x24\x31\x31\xb1\x73\x44\x83\x88\x61\x96\x04\x1a\ +\x63\x4c\xd5\x82\x40\x1a\x10\xfe\xc2\x68\x26\x56\x8d\x6a\xda\xb4\ +\x69\x51\xf7\xee\xdd\xa3\xa6\x3b\x78\xd5\xaa\x26\x3c\xfe\x78\x27\ +\xae\xbc\x72\x2d\xdd\xba\xe5\x45\x3a\x1c\x82\xc1\x20\x89\x89\x89\ +\xad\x23\x1d\x47\xac\xb2\x24\xb0\x91\x91\x2c\x39\x4b\x73\xd4\xc6\ +\x56\x18\x73\x10\x3e\x9f\x4f\x81\x65\x91\x8e\xc3\x44\x2f\x97\xcb\ +\x75\x6c\x5a\x5a\x9a\xcb\xe9\x15\x6e\xf8\x8a\x8a\x84\x19\x33\x7a\ +\x72\xc4\x11\x7b\xf8\xc3\x1f\x7e\x89\x74\x38\x00\x6c\xde\xbc\x99\ +\xe7\x9e\x7b\x2e\xef\xc1\x07\x1f\x8c\x74\x28\x31\xc9\xc6\x04\x36\ +\x22\x32\x55\x06\x00\xf3\x24\x4b\x7e\x17\xe9\x58\x8c\x31\x26\xd6\ +\xb9\xdd\xee\xd1\x43\x87\x0e\x75\x47\x3a\x8e\x9a\x7a\xfc\xf1\x4e\ +\xac\x5b\x17\xcf\x2d\xb7\xac\xc6\xd5\x40\xb2\x83\xe4\xe4\x64\x72\ +\x73\x73\xad\x25\x30\x4c\x1a\xc8\x1f\xb3\xa9\x27\x7f\xc5\x69\xfd\ +\xbd\x53\x66\x48\x42\xa4\x83\x31\xc6\x98\x58\x25\x22\x5d\x8b\x8a\ +\x8a\xda\x46\x4b\x91\xe8\x6f\xbe\x69\xc6\xbc\x79\x1d\xb8\xe6\x9a\ +\x9f\x49\x4d\x2d\x88\x74\x38\xa5\xda\xb4\x69\x43\x20\x10\x68\x26\ +\x22\x89\x91\x8e\x25\x16\x59\x12\xd8\x48\xc8\x54\xf9\x35\xca\x89\ +\xa1\xcd\x6e\xe4\x71\x63\x44\x03\x32\xa6\x81\xf3\xfb\xfd\x37\xfa\ +\xfd\xfe\xe7\x23\x1d\x87\x89\x5a\xa3\xbc\x5e\x6f\x71\xbf\x7e\xfd\ +\x22\x1d\xc7\x41\x15\x14\xb8\xb8\xfd\xf6\x9e\x8c\x18\x91\xcb\x19\ +\x67\x6c\x8e\x74\x38\xe5\xb4\x6e\x5d\xda\x08\x98\x1a\xc9\x38\x62\ +\x95\x25\x81\x8d\x80\xcc\x90\x38\xe0\xde\xf2\x3b\xc9\x94\x69\xd2\ +\x31\x32\x11\x19\x13\x15\xfa\x01\xad\x22\x1d\x84\x89\x4e\x22\x32\ +\x72\xc0\x80\x01\x41\xaf\xb7\xe1\xcf\x09\x79\xe8\xa1\xce\x6c\xdf\ +\xee\xe5\xe6\x9b\x7f\x88\x74\x28\x95\xb4\x68\xd1\x82\x3b\xee\xb8\ +\x83\x63\x8e\x39\x26\x23\xd2\xb1\xc4\x22\x4b\x02\x1b\x83\x7c\xae\ +\x47\xe9\x59\x61\x6f\x53\x8a\x99\x1d\x91\x78\x4c\x83\x26\xc2\x65\ +\x22\x0c\x29\xb3\xfd\x2b\x11\xce\x2b\xb3\xdd\x54\x84\x2b\x44\xe8\ +\x11\x99\x08\xeb\x4d\x7b\xa0\x61\x8c\x8e\x37\x51\xc7\xeb\xf5\x9e\ +\x90\x9e\x9e\x7e\xd8\x19\x60\x6e\xae\x87\x35\x6b\x12\x4b\x7f\xb6\ +\x6e\x8d\x43\xc3\x54\xad\xc5\xe3\x51\x6e\xbc\xf1\x27\xda\xb4\x29\ +\x0c\xcf\x03\x6a\x21\x39\x39\x99\x94\x94\x14\x92\x92\x92\x7a\x47\ +\x3a\x96\x58\x64\xb3\x83\x63\x9c\xdc\x2c\x1d\x80\x69\x07\x38\x7c\ +\x8e\x4c\x95\x07\x34\x5b\x3f\xae\xcf\x98\x0e\x95\x08\x6d\x28\x3f\ +\x4b\xb3\x08\x58\x07\xbc\x07\xdc\xa3\x4a\xc3\xea\xbf\x88\x20\x11\ +\x9a\x01\x7f\x02\x5e\x56\xe5\x9b\xc3\xbc\xcd\x83\xc0\xcd\xc0\x57\ +\xa1\xed\x89\xc0\x39\xc0\xdf\x42\xdb\x2d\x00\x3f\xf0\x3b\xa0\xe1\ +\x35\x1d\xd4\x1d\x0f\xce\xdf\x35\x63\x0e\x89\x88\xb4\x02\x7a\xd4\ +\x66\x3c\xe0\x82\x05\x6d\x79\xf0\xc1\xf2\xe5\xf1\xbc\xde\x20\x27\ +\x9f\xbc\x8d\xab\xaf\xfe\x99\xa4\xa4\x40\x2d\xa3\xdc\xef\xea\xab\ +\x7f\xae\xb3\x7b\xd5\xb5\x92\x99\xd5\x2e\x97\xab\xe1\x37\xa9\x46\ +\x21\x4b\x02\x63\x5d\x90\x1c\xa0\xd9\x01\x8e\x0a\xca\x7d\x22\x72\ +\x94\x6a\xb8\xbe\x63\xd6\x09\x17\xd0\x0e\x58\x08\xbc\x02\x34\x01\ +\xc6\x00\xd7\x01\xa7\x88\x90\xa1\x4a\x7e\x04\xe3\x6b\x48\x9a\x03\ +\x39\xc0\x7a\x38\xec\x24\x70\x32\xf0\x61\x9d\x45\x14\xbd\x2e\x05\ +\x6c\xb9\x38\x73\x38\x8e\x71\xb9\x5c\x0c\x1e\x3c\xb8\xd6\x37\x9a\ +\x3b\x77\x05\x6d\xdb\x16\xb1\x71\x63\x1c\x4b\x96\xa4\xf0\x9f\xff\ +\xb4\xa5\xa0\x40\x98\x31\x63\x75\x1d\x84\x69\x1a\x3b\x4b\x02\x63\ +\x98\x4c\x91\x11\xb8\x38\xd8\x72\x3b\x47\x92\xc5\xb9\xec\x6f\xe5\ +\x69\xc8\x3e\x53\xe5\xe1\xd0\xeb\x7b\x45\x78\x10\xb8\x12\x38\x0e\ +\x78\xa3\xec\x89\x22\x34\x07\x3a\x00\xdb\x55\xd9\x52\xdb\x07\x87\ +\xee\xd7\x06\xf8\x49\xb5\xfa\xc4\x40\x84\x76\x00\xaa\x6c\x3a\xc4\ +\x67\x78\x80\x6e\xc0\x7a\x55\xaa\xad\xd2\x2a\x42\x2b\x20\x5e\x95\ +\x43\x5a\xd3\x49\x04\x17\x4e\x37\x67\x33\xe0\xe7\xaa\x92\x67\x55\ +\xe6\x1e\xca\x3d\xab\x78\x46\x07\x40\x55\xd9\x58\x9b\xfb\x44\x9a\ +\xcf\xe7\x5b\x17\xe9\x18\x4c\xd4\x1a\xd5\xad\x5b\xb7\xa2\x26\x4d\ +\x9a\xc4\xd5\xf6\x46\x9d\x3a\x15\xd0\xa1\x43\x01\x5d\xbb\xe6\x71\ +\xe4\x91\xbb\xf8\xec\xb3\xe6\x7c\xf0\x41\xcb\x4a\xe7\xad\x5e\x9d\ +\xc8\xea\xd5\x4d\xd8\xb7\xcf\x4d\xfb\xf6\x85\x0c\x1d\x9a\x4b\x7c\ +\x7c\xb0\xf4\xf8\xb2\x65\x49\x34\x6f\x5e\x44\xd7\xae\xe5\xff\x97\ +\x57\x85\x2f\xbf\x6c\x4e\xfb\xf6\xce\x73\x4a\xac\x5a\xd5\x84\xef\ +\xbf\x6f\x82\xd7\xab\xf4\xef\xbf\x97\x8e\x1d\xcb\x5f\xb7\x72\x65\ +\x13\xdc\x6e\xe8\xde\x7d\x1f\x2b\x57\x36\x65\xe5\xca\x26\xb4\x6b\ +\x57\xc8\xf0\xe1\xbb\xea\xb4\xbc\x8c\xc7\xe3\xe1\xb6\xdb\x6e\x0b\ +\xe6\xe5\xe5\x7d\x5f\x77\x77\x35\x25\x2c\x09\x8c\x6d\xc9\x08\x37\ +\x94\xd9\x4e\x44\xc9\xc6\x49\x9e\x56\x95\xee\x55\x1a\xde\x40\x90\ +\x9a\x79\x0b\x27\x09\x2c\x9d\x35\x26\xc2\x20\xe0\xef\xc0\xe0\x32\ +\xfb\x56\x02\x17\xa8\xb2\x34\xb4\x7d\x09\xf0\x18\xd0\x5b\x95\x72\ +\x5f\xa7\x45\xf8\x14\xd8\xa5\xca\x09\xa1\xed\xbe\xc0\x53\xc0\xaf\ +\x42\xa7\x14\x88\xf0\x17\xe0\x56\x55\xa7\xab\x50\x84\x0b\x81\x27\ +\x81\x91\xc0\xa3\xc0\x80\xd0\xfe\xf7\x80\x89\xaa\x6c\xab\xee\x4d\ +\x88\xd0\x12\xb8\x1f\xf8\x3d\x10\x07\x04\x45\xf8\x0f\x30\x49\x95\ +\xad\xa1\x73\x4e\x06\x5e\x05\x4e\x02\x66\x02\xc3\x43\xfb\xff\x0b\ +\xfc\x46\x95\xb5\xa1\x31\x7a\x25\xef\x67\x9e\x08\xf3\x42\xaf\x7f\ +\xad\xca\xcb\x22\xdc\x0c\x5c\xcf\xfe\xc9\x0e\x2a\xc2\x53\xc0\xd5\ +\xaa\xec\x2d\x13\x4f\x21\x70\xb3\x2a\x77\x55\x17\x77\x15\xef\xe3\ +\x02\x60\x0e\x4e\xab\x2d\x22\xac\x01\x2e\x53\xe5\xad\x43\xb9\x8f\ +\x31\xd1\x2e\x2e\x2e\x6e\x4c\x46\x46\x46\xad\x13\xc0\xaa\x74\xea\ +\x94\xcf\xd6\xad\x71\x14\x17\x4b\xe9\x92\x6e\xd9\xd9\x3d\x78\xed\ +\xb5\x56\x74\xec\x58\x40\x71\xb1\xb0\x76\x6d\x02\x9d\x3a\xe5\xf3\ +\x97\xbf\x7c\x47\xe7\xce\x4e\xf2\xf6\xdc\x73\xed\xf8\xee\xbb\xa6\ +\x3c\xff\xfc\x57\x94\xad\x5d\xfd\xd9\x67\xc9\x5c\x7d\x75\x3f\xe6\ +\xce\x5d\x41\x87\x0e\x05\x14\x15\x09\xb3\x67\xf7\x60\xe1\xc2\xd6\ +\x74\xea\x94\x4f\x51\x91\x8b\x2d\x5b\xbc\x5c\x74\xd1\x06\x2e\xbb\ +\x6c\xff\xf7\xa2\xbf\xfc\xa5\x2b\x5e\xaf\xd2\xb2\x65\x80\x45\x8b\ +\x52\x68\xde\x3c\xc0\xf6\xed\x5e\x8e\x3e\x7a\x27\xf7\xdc\xf3\x5d\ +\xb9\x67\xd4\x86\x88\xb0\x7d\xfb\x76\x02\x81\x80\x0d\xcd\x08\x03\ +\x4b\x02\xa3\x84\x4c\x95\x36\x94\x7c\x78\xc7\xf3\xb3\x4e\xd7\x7d\ +\x07\xbb\x46\xe7\xe8\x5b\xb0\xff\x03\x58\xb2\xa4\x05\x90\x8d\xf2\ +\x82\xe6\xe8\x3b\x61\x0a\xb5\x3e\x9d\x16\xfa\x6f\xd9\xae\x4b\x17\ +\xf0\x08\x4e\xcb\xe0\x26\xe0\x58\x9c\xf1\x6d\x2f\x8a\xd0\x57\x95\ +\x3d\xc0\xb3\xc0\x3d\xc0\x65\x40\x66\xc9\x85\x22\xa4\x03\x19\x38\ +\xc9\x18\x22\x24\x00\x6f\x03\xb9\x38\x49\xe0\x4a\xe0\x5c\xe0\x2f\ +\x80\x02\x53\x2b\xc4\xf3\x64\xe8\x67\x3e\x30\x01\xb8\x1b\xb8\x0d\ +\xb8\xfa\x40\x6f\x40\x04\x01\x5e\xc7\xf9\xb3\xfd\x13\x4e\x77\xf7\ +\x78\x60\x06\x30\x2f\x74\x9f\xb2\x1e\x05\x9e\xc6\x19\xa3\x77\x6c\ +\xe8\x7d\xdc\x13\x8a\xf9\x67\xe0\x48\xe0\x63\x9c\x2e\xdd\x7f\x85\ +\xae\x29\x69\x91\xdc\x06\x9c\x05\x7c\x09\x24\x00\xbf\xc6\x99\x35\ +\xbe\x09\xc8\x3a\x50\x8c\x35\x21\xc2\x65\xa1\xd8\xee\xc6\x49\xc2\ +\xbd\x38\xbf\x9f\x57\x44\x18\x50\x31\xd9\x36\x26\x56\x89\x48\xa2\ +\x88\x0c\x09\x47\x7d\xc0\x95\x2b\x9b\xf0\xc9\x27\xc9\x1c\x79\xe4\ +\xae\x72\x6b\xfa\x9e\x76\xda\x66\xae\xb9\x66\x0d\xcd\x9a\x39\x9d\ +\x14\x6b\xd6\x24\x72\xd5\x55\xfd\xf8\xeb\x5f\xbb\x72\xcf\x3d\xce\ +\xd2\xd7\xbf\xfd\xed\x66\xae\xbc\xb2\x3f\x9f\x7f\xde\x9c\x8c\x8c\ +\xdc\xd2\x6b\xff\xfd\xef\xb6\x74\xee\x9c\x5f\xba\xef\xdf\xff\x6e\ +\xc7\xab\xaf\xb6\x66\xd6\xac\x55\x8c\x1d\xeb\x7c\x7f\x7d\xfc\xf1\ +\x8e\x3c\xf6\x58\x27\x06\x0e\xdc\xc3\xd1\x47\xef\x2c\xbd\xf6\xd3\ +\x4f\x93\x39\xe3\x8c\xcd\x2c\x58\xf0\x5f\x5a\xb4\x08\xf0\x8f\x7f\ +\x74\xe0\xa1\x87\x3a\xf3\xfe\xfb\x2d\x39\xf6\xd8\x1d\x75\xfe\xfe\ +\x4d\xdd\x8b\xda\x24\x50\xb2\xa4\x07\x90\x5d\xba\x23\xc8\xdd\x3a\ +\x47\x3f\x2b\x73\xfc\x72\x9c\x71\x63\x10\x64\xba\xce\xd1\xe8\x5e\ +\x04\x5e\xb9\x9e\x92\x0f\xea\x42\xc6\x00\x4b\x22\x1a\x4f\x64\x8c\ +\x14\x21\x13\x68\x0a\x8c\x03\x86\x01\xf7\xab\x52\xfa\x67\xab\xca\ +\x57\xec\x9f\xd0\x00\xf0\xaa\x08\xdb\x81\x8f\x80\xb1\xc0\x02\x55\ +\xf6\x85\x5a\xc9\x2e\x14\xe1\x96\x92\x16\x3d\x60\x12\x4e\x42\xf4\ +\x9f\xd0\xf6\xf9\x40\x27\x60\x98\x2a\x5f\x84\xf6\xcd\x0d\xcd\x9c\ +\xbd\x4e\x84\x1c\x55\x76\x97\x79\xd6\x3f\x55\xc9\x29\x73\xde\xc4\ +\x50\x9c\xd5\xf9\x03\x30\x02\xf8\xbd\x2a\x25\x35\xe9\x9e\x0a\x25\ +\xa0\x7e\x11\x06\x56\x98\xe0\xf1\x86\x2a\xb7\x86\x5e\x7f\x2f\xc2\ +\x89\xc0\xc9\xa1\xf7\x1e\x10\xa1\xe4\xab\xfa\x16\x55\x7e\x2a\xfb\ +\xa0\x32\x5d\xe9\x25\x1e\x14\xe1\x57\xc0\x79\xd4\x22\x09\x14\xc1\ +\x8b\x33\x0e\x71\x91\x2a\x37\x95\xd9\x7f\x3e\xce\xef\xf3\x1a\xe0\ +\xda\xc3\xbd\x7f\xa4\xf8\xfd\xfe\xc7\x80\xad\x3e\x9f\xaf\x56\x09\ +\xb2\x69\x74\x8e\x54\x55\x77\x5a\x5a\x5a\x9d\xdc\xec\xf6\xdb\x7b\ +\x12\x1f\x1f\xe4\x97\x5f\xe2\x59\xb3\x26\x81\xe1\xc3\x73\x99\x32\ +\xe5\xa7\x72\xe7\x0c\x1a\xb4\xa7\xf4\x75\x30\x28\x74\xe8\x50\xc0\ +\x69\xa7\x6d\xe1\x99\x67\x3a\xa0\x0a\x22\x90\x9e\x9e\x4b\xb7\x6e\ +\x79\x2c\x58\xd0\xb6\x34\xe1\xdb\xbe\xdd\xcb\x7b\xef\xb5\xe4\x8a\ +\x2b\xd6\x96\xb6\xdc\xbd\xf8\x62\x3b\x8e\x3c\x72\x67\x69\x02\x08\ +\x70\xd1\x45\xeb\x59\xb8\xb0\x0d\xcf\x3f\xdf\xae\x5c\x12\xe8\x72\ +\x29\x93\x26\xad\x25\x39\xd9\x99\xa4\x72\xc6\x19\x9b\x78\xf8\xe1\ +\x4e\x7c\xf7\x5d\x53\x4b\x02\xa3\x44\xd4\x26\x81\x04\x49\xc1\xc5\ +\x1f\x4a\xb7\x5d\xb4\x07\x8e\x2f\xdd\x56\x46\x20\xa1\xe3\x6e\xe6\ +\x02\xd1\x9d\x04\x1a\x80\x23\x80\xd6\x38\x63\xf3\x52\x71\x5a\xbc\ +\x6e\xad\x78\x92\x08\x47\xe3\x24\x70\xdd\x71\x26\x4a\x08\x4e\xcb\ +\x5d\xd7\x32\xa7\xf9\x71\x5a\xe8\x7e\x8d\xd3\x4a\xd8\x0c\x38\x1b\ +\x78\xa0\x4c\x52\x38\x14\xd8\x54\x26\x01\x2c\xf1\x2a\x70\x09\xd0\ +\x1b\xca\x1d\xfb\x77\x85\xf3\xde\xc7\xe9\x7e\xad\xce\x70\x9c\x19\ +\xa8\xed\x44\xb8\xa2\xcc\xfe\x92\x41\x3f\x83\x28\x3f\xc1\xa3\xaa\ +\x67\xfc\x41\x84\x26\xaa\x54\xdb\x3a\x2c\x42\x13\xe0\x02\x9c\x31\ +\x94\xa9\x38\x5d\xcf\x6d\x81\x54\x11\xe2\xf4\xf0\x87\x05\xf4\xc0\ +\x69\xc9\xdc\x58\xe1\x3d\x00\xfc\x18\x7a\x0f\xd1\xa8\x33\x4e\x8b\ +\xa6\x31\x87\x62\x54\xbb\x76\xed\x0a\x5b\xb5\x6a\x55\x27\xdd\xc1\ +\x1d\x3b\xe6\xd3\xb4\x69\x31\x45\x45\xc2\x86\x0d\xf1\xa4\xa4\x14\ +\x91\x92\x52\xbe\x67\x74\xfd\xfa\x04\x1e\x7d\xb4\x13\x9f\x7d\xd6\ +\x9c\xed\xdb\xbd\xe5\x4a\xc9\xec\xda\xe5\xa1\x45\x0b\x27\x49\x9b\ +\x38\x71\x33\x73\xe7\x76\x61\xe7\x4e\x67\xdf\xcb\x2f\xb7\x41\x04\ +\x4e\x3d\x75\x2b\x00\xc5\xc5\xc2\xba\x75\xf1\xe5\x12\x40\x00\x97\ +\x0b\xfa\xf7\xdf\xcb\xca\x95\x4d\xca\xed\x1f\x38\x70\x4f\x69\x02\ +\x08\x90\x94\x54\x4c\x6a\x6a\x01\x3b\x76\xd4\x5d\x6a\x11\x08\x04\ +\x98\x35\x6b\x96\xeb\xed\xb7\xdf\xee\x53\x67\x37\x35\xa5\xa2\x37\ +\x09\xac\xec\x38\xc9\x92\x93\x34\x47\x5f\x8f\x74\x20\x26\x6c\x1e\ +\x56\xe5\x36\x00\x11\x8e\xc4\xe9\xaa\x7d\x01\x4a\x57\x42\x41\x9c\ +\xc4\xff\x39\xe0\x4d\x9c\x04\xed\x5b\xa0\x00\xa7\x8b\xb2\xf4\x5f\ +\x30\x55\x56\x88\xf0\x2e\x70\x39\xf0\x22\x4e\xf7\x6a\x53\x9c\xb1\ +\x82\x25\xda\x01\x55\x7d\x9d\xdd\x1e\xfa\x6f\xc5\xf5\x2c\xd7\x57\ +\xd8\xde\xc7\xc1\xff\x1f\x4b\x05\x0a\x81\x53\xab\x38\xf6\x06\x54\ +\x9a\x20\x52\xd5\x33\x38\xd8\x73\x42\x13\x42\x16\xe2\x24\x64\xaf\ +\x00\x2f\x03\x6b\x71\x5a\xcb\x2f\x03\xe2\x43\x71\x1c\x8e\x92\x31\ +\x99\xbd\xa9\xfc\x3b\x59\x07\xe5\x5b\x24\x8d\x89\x65\x5e\xaf\xf7\ +\xf8\x8c\x8c\x8c\x3a\xfb\xf2\x70\xc9\x25\xeb\x4b\x27\x6c\x7c\xf0\ +\x41\x0b\x6e\xbc\xb1\x2f\x1d\x3a\x14\x70\xc5\x15\x6b\x01\x08\x04\ +\x84\xeb\xae\xeb\x8b\xcb\x05\x57\x5c\xb1\x96\x1e\x3d\xf2\x68\xd7\ +\xae\x80\x25\x4b\x5a\x71\xcf\x3d\x5d\x29\x2e\xde\x3f\x38\xef\xe4\ +\x93\xb7\xf0\xd0\x43\x9d\x79\xf5\xd5\x36\x9c\x75\xd6\x2f\x2c\x58\ +\xd0\x96\xe3\x8f\xdf\x4e\x8b\x16\x4e\x52\x59\x54\x24\x14\x17\x0b\ +\x71\x71\x95\x8b\x45\x78\xbd\x41\x0a\x0b\xcb\xcf\xf8\x68\xd2\xa4\ +\xf2\x1c\x39\xb7\x1b\x9c\xef\xdd\x75\x43\x55\x49\x4a\x4a\xc2\xeb\ +\xf5\xc6\x52\xbe\xd2\x60\xc4\xd6\x2f\x55\xc9\x11\x91\x37\x0e\x56\ +\xee\x44\x32\xe5\x68\x84\x1b\x81\xbe\x40\x32\x4e\x6b\xc5\xdb\x14\ +\x70\xa7\xde\xab\xa5\x1f\xba\x92\x25\x0b\x42\xc7\xd7\x11\xe4\xcf\ +\xb8\xb9\x8b\x20\x47\xe1\xe2\x59\xe2\x99\x45\x3e\xaf\x86\x4e\xfd\ +\x0a\x67\xfc\xd6\x0c\x94\x01\xb8\xf8\x08\xe5\x66\x12\x58\x47\x3e\ +\xb7\xe3\x7c\xc0\xc7\x01\xaf\x90\xc0\x34\x9d\xae\xf9\xa1\xfb\x77\ +\x03\xee\xc0\xf9\x60\x6e\x85\xd3\xea\xb0\x11\xf8\x9a\x20\xd9\x3a\ +\x47\x57\xd4\xe4\x6d\xcb\x14\x39\x11\x17\xd7\x02\xbd\x80\x26\x28\ +\x2b\x81\x27\x74\xb6\x3e\x53\x93\xeb\xa3\x91\x2a\x1f\x8b\x70\x35\ +\xf0\xa4\x08\xe7\xa8\xf2\x8f\xd0\xa1\xab\x81\xff\x01\x27\xa9\xa2\ +\x50\x3a\x5b\xb7\xaa\x45\xdc\xfd\xc0\xb3\x22\x74\xc7\x49\x06\xdf\ +\x52\x2d\x57\xf7\xee\x27\x60\x8c\x08\x52\x72\xaf\x90\x92\xa4\xa7\ +\x2e\x66\x8f\xae\xc6\xf9\x17\xf3\x94\x83\xcd\x3a\xae\xa1\x92\x38\ +\x2b\xfe\x2b\x3c\x08\xa7\xa5\xfc\x4a\x55\xfc\x25\x3b\x45\xe8\x5f\ +\x07\xcf\x2c\x19\xef\xf7\x90\x2a\x4f\xd7\xc1\xfd\x8c\x89\x4a\x22\ +\xe2\x76\xbb\xdd\x47\x0d\x19\x32\xa4\xee\xb2\xa0\x32\x46\x8e\xdc\ +\xc9\xc4\x89\x9b\xf8\xfb\xdf\x3b\x70\xea\xa9\x5b\xe8\xd4\x29\x9f\ +\x1f\x7e\x48\x64\xed\xda\x04\x66\xce\x5c\xc5\x89\x27\xee\x6f\xc1\ +\xdb\xb6\xad\xf2\xc7\x7b\x52\x52\x31\x27\x9e\xb8\x8d\x05\x0b\xda\ +\xd2\xa3\xc7\x3e\x36\x6c\x88\x67\xda\xb4\xfd\xff\xe4\x25\x24\x04\ +\x69\xdd\xba\x90\xb5\x6b\x2b\x2f\x2d\xff\xf3\xcf\x09\xe5\x66\x0f\ +\x9b\xd8\x10\x2b\x2b\x86\x7c\x00\x14\x20\xa4\x31\xa5\x4c\x17\x71\ +\x15\x24\x53\xae\x45\xf8\x00\x38\x03\x67\x16\x67\x47\x9c\x59\x9d\ +\xb7\x11\xcf\x7f\x65\x86\xec\xaf\xa9\x27\x8c\xc4\xe9\x3a\x3b\x11\ +\x17\xef\xa0\x9c\x8d\x93\x30\x24\xb1\x0f\x77\xe8\xd8\x71\x38\x45\ +\x73\x97\x00\xa7\x20\x74\x47\x39\x1b\x78\x85\x3c\x9e\xc7\x19\x6b\ +\x35\x08\x27\xe1\x9c\x4c\xbe\xd3\x92\x05\x80\xd2\x05\xa7\x05\x6a\ +\x30\x4e\xb2\xd9\x2a\xf4\xfa\x5c\x5c\x7c\x21\x53\xa4\xef\xc1\xde\ +\xb8\x64\xc9\xed\xb8\x78\x13\x38\x25\xf4\x8c\xf6\x08\x63\x11\xfe\ +\x21\x59\x52\xab\x52\x1f\x0d\x9d\x2a\x4f\x01\xff\x05\x66\x84\xca\ +\xab\x80\xf3\xc5\xe6\x87\x0a\x49\xdb\x79\x15\xaf\x0d\xf9\x17\xb0\ +\x19\x78\x08\x48\xc7\x99\x50\x52\xd6\xfb\x38\x7f\x2e\x15\x5b\xe9\ +\xce\xc7\x49\xd6\xeb\x62\xb2\xc3\x9b\x38\x2d\x94\x17\x55\x75\x30\ +\x34\x71\xe4\x50\x6c\x03\x82\x38\xa5\x66\xca\x2a\x49\x82\x4b\x63\ +\x0e\xfd\xce\xce\x3a\xc4\xfb\x57\xa2\xca\xcf\xc0\x0a\xe0\x8a\x50\ +\x8b\x63\x39\x87\xf1\x1e\x1a\x8a\x4b\xa9\xe5\x84\x19\xd3\xe8\x0c\ +\x29\x2e\x2e\x4e\xac\xab\xf1\x80\x55\xb9\xe4\x92\xf5\xb8\xdd\xca\ +\x93\x4f\x3a\xab\x7e\xb6\x6e\x5d\x84\xc7\xa3\xe4\xe6\xee\x4f\xfa\ +\x76\xec\xf0\xb2\x60\x41\xdb\x2a\xaf\x9f\x38\x71\x13\x6b\xd6\x24\ +\x70\xf7\xdd\xdd\xe8\xda\x35\x9f\xf4\xf4\xdc\x72\xc7\x47\x8f\xde\ +\xc1\xa2\x45\x29\xfc\xf2\x4b\x7c\xe9\xbe\x4f\x3f\x6d\xce\xf2\xe5\ +\xcd\x38\xfe\xf8\xed\x15\x6f\x67\xa2\x5c\xac\xb4\x04\xfe\x04\x7c\ +\x0e\x5c\x8b\x30\x53\x26\xc9\x8b\x54\x2e\xa3\x84\xfc\x59\x7a\xe2\ +\x66\x36\x4e\x2b\xc9\x0e\x84\x9b\x10\x3e\x27\x48\x36\xce\xe0\xfa\ +\xbe\xe4\x33\x8b\xca\x83\xd8\xdb\xa2\xc4\x21\xdc\x87\xf2\x09\xe5\ +\x27\x03\x00\x74\x40\xf9\x17\xc2\x23\x28\x39\x38\xb3\x4c\x07\x22\ +\xf4\x40\x98\x42\x90\x75\x08\x7f\xc3\x49\xba\xcf\xa3\x64\x46\xaa\ +\xb0\x01\x38\x9b\x04\x5e\xd3\xe9\xba\x53\x6e\x90\x44\xe2\xb8\x10\ +\xe1\x21\x20\x01\x17\x59\xc0\x85\x07\x7a\xd3\xa1\x3a\x80\x37\x87\ +\xee\xf5\x09\x01\xce\x26\xc8\x2e\xbc\x3c\x89\x93\xb8\xfc\x49\xa6\ +\xca\x7c\xcd\xd6\xf7\x6b\xfe\xab\x8c\x3a\x33\x70\x26\x72\x9c\x8b\ +\x53\xca\xe5\x49\x9c\x09\x0f\xb7\xe3\xcc\x1a\x1e\x09\x9c\x0e\x54\ +\x2a\xaf\xaf\x4a\x91\x08\x4f\xe0\x7c\xd0\x6f\x04\x5e\xaa\x70\xca\ +\x7f\x70\xbe\x60\xfc\x4d\x84\xe9\x38\x7f\xcf\x7e\x8f\x33\x7b\xf7\ +\x02\x55\x6a\xfd\xb5\x58\x95\xf7\x44\x78\x2c\x14\xf3\x00\x9c\x55\ +\x50\x04\xe8\x13\x7a\x4f\x63\xa1\xe6\x2b\xa2\xa8\x52\x28\xc2\x47\ +\xc0\x65\x22\x24\xe2\x4c\xcc\x78\x49\x95\x2f\x44\x58\x06\xdc\x15\ +\xaa\xe3\xb7\x1b\xe7\xef\x79\x5d\x95\x5d\xb8\x1c\xa7\x7b\xfe\x5d\ +\x11\xfe\x5f\xe8\xb9\x1d\x71\x7e\x57\x9f\xe3\x94\x8e\x89\x2a\x56\ +\x27\xd0\x1c\x86\x51\x49\x49\x49\x45\x5d\xba\x74\x09\xdb\x58\xd2\ +\x56\xad\x8a\x38\xe3\x8c\xcd\xcc\x9f\xdf\x8e\x8b\x2e\x5a\x4f\xa7\ +\x4e\xf9\x8c\x1c\xb9\x93\x07\x1f\xec\xcc\xb2\x65\xcd\x48\x4e\x0e\ +\xf0\xce\x3b\x29\x0c\x1d\xba\x9b\xc5\x8b\x53\x2a\x5d\xdf\xbf\xff\ +\x5e\xfa\xf7\xdf\xcb\x8a\x15\x4d\xb9\xf6\xda\xca\x2b\x85\x5c\x72\ +\xc9\x7a\x3e\xf9\x24\x99\x8b\x2e\x1a\xc8\x98\x31\x3b\x28\x2c\x14\ +\xde\x7a\xab\x15\x43\x87\xe6\x72\xe6\x99\x87\x54\xfa\xb4\x4e\x78\ +\xbd\x5e\x6e\xbe\xf9\xe6\x60\x41\x41\x81\x8d\xeb\x0f\x83\x58\x49\ +\x02\x41\x98\x85\x72\x31\xd0\x8b\x14\x2e\xa1\xaa\x0e\x61\x0f\x63\ +\x50\x9c\x76\x6e\xe5\x3f\x9a\xa3\x8f\x03\x48\xa6\xdc\x84\x53\x87\ +\x0d\x9c\x92\x1c\x95\x67\x32\xba\x38\x4f\xb3\xf5\x95\xd2\xc7\x4d\ +\x91\xa4\x32\x47\x8b\x49\xe4\x02\x9d\xae\x7b\x64\xaa\x1c\x87\x92\ +\x1e\xda\xff\xb6\x66\xeb\x9d\x00\x92\x25\xd3\x71\x3e\xd8\x3b\xc8\ +\x24\xf1\xea\x23\x5a\xa4\x39\xba\x4a\xa6\xca\x0e\x0a\xf8\xad\x64\ +\x49\x57\x12\x68\x0d\xb8\x50\x82\x38\x09\x63\xf5\x2d\x81\x2e\x4e\ +\xa6\xa4\x35\x57\xf9\x3f\x3c\xa1\x01\xf8\xca\x32\x4a\x5a\xaf\x94\ +\x93\x71\x5a\xb4\xa2\x59\x21\xf0\x2e\x55\x8c\x2d\x53\x65\x81\x08\ +\xcf\xe2\x24\x7b\x4f\xe1\x14\xbd\x1e\x8c\xd3\xb2\x76\x0e\xb0\x14\ +\x27\x91\x9a\x87\x53\x42\xa5\xa2\x7f\xe0\x24\x81\x4f\xa8\x96\x4f\ +\x14\x55\x51\x11\xc6\x01\xb3\x70\x92\x9c\xb6\x38\x13\x8c\x4e\x53\ +\xe5\x95\x32\xa7\x6e\x0c\xc5\x57\x71\x4c\xdd\xcf\x38\x49\x5d\xb5\ +\x54\xb9\x5c\x84\xa5\xc0\xc5\x38\x89\x5f\x30\xf4\x5e\x5f\x00\x76\ +\x85\x4e\xdb\x1e\x7a\xc6\x9e\x0a\x97\x97\x3c\xbb\x6c\xec\x7f\x04\ +\x6e\x04\x86\xe0\xb4\x32\x7e\x82\xb3\xbc\xdb\x65\x38\x25\x5c\xee\ +\x01\xbe\xc7\x19\x3b\xb9\x12\x98\x42\xf9\x95\x31\xde\xa3\xfc\xef\ +\xea\x07\xca\x97\xe1\x29\x08\x3d\xb3\xb4\x08\xb7\x2a\x1f\x84\x66\ +\x4d\xcf\xc2\x59\xa6\xb0\x35\x4e\xf2\xfa\x21\x15\x0a\x79\x1b\x13\ +\xab\xdc\x6e\xf7\xb1\xe9\xe9\xe9\x55\x0d\x3d\x39\x64\x43\x86\xec\ +\xe6\xd2\x4b\xd7\xd3\xac\x59\xe5\xe5\xe1\xce\x3f\x7f\x03\xcd\x9a\ +\x15\xb3\x79\x73\x1c\x9d\x3a\xe5\x33\x6d\xda\x6a\x9e\x7b\xae\x3d\ +\xab\x57\x37\x21\x2e\x4e\x99\x39\x73\x15\xcd\x9a\x05\xe8\xd1\x23\ +\x8f\x26\x4d\x82\x95\xae\x4f\x4f\xcf\x65\xd5\xaa\x44\x26\x4c\xa8\ +\x5c\x47\xbf\x45\x8b\x22\x9e\x7a\x6a\x19\x2f\xbc\xd0\x8e\x55\xab\ +\x9a\xe2\xf1\x04\xb9\xf6\xda\x35\x9c\x7e\xfa\x16\x5c\xae\xfd\x1f\ +\xac\xa7\x9e\xba\x15\x8f\xa7\xf2\x07\xed\x99\x67\x6e\x24\x35\xb5\ +\x6e\xbb\x8d\x73\x73\x73\x29\x2e\x2e\xae\xbb\x75\xf2\x4c\xa9\x98\ +\x49\x02\x35\x5b\xb7\x48\x96\xdc\x0b\x4c\x07\x6e\x45\x78\xa7\xd2\ +\x49\x41\x7a\x95\x76\x4c\x49\x99\x0f\xb5\x39\x2c\x27\x93\xbd\x38\ +\x13\x03\x7a\xc8\xef\xc5\xad\xf3\xb5\xec\x87\xe2\x3e\xf2\x59\x54\ +\xcd\xe3\xff\xa7\xd3\xd5\xf9\x70\x56\xd6\x96\xd9\xff\x51\x99\xd7\ +\x5b\x71\x92\x40\x21\x15\x2f\x50\x24\x59\x72\x12\x4e\x6b\x53\x7c\ +\xe8\xda\x8a\x2a\x7f\x8d\x2b\xaf\x57\x99\xd7\xd7\x87\xca\xc8\x54\ +\x77\x4e\x54\x52\x65\x07\x65\x67\x7e\x57\x3e\x7e\x76\x99\xd7\xfb\ +\x80\xab\x42\x3f\x65\x8d\x3f\xc0\xe5\x27\xe1\xb4\x86\x3d\x7a\x80\ +\x7b\xe7\x41\xb9\x82\xdb\x55\x9d\xf3\x3a\x4e\xad\xbf\x8a\xfb\x9f\ +\x01\x6a\x34\x2e\x53\x95\x27\x80\x27\xaa\x39\xfe\x31\x55\xfc\x0e\ +\x54\x79\x0d\x78\xad\xc2\xbe\x75\x38\x4b\xea\x55\x75\x8f\x51\x55\ +\xdc\xbe\xe2\xf5\x27\x54\xd8\x7e\x18\xf6\x97\x97\x09\x15\xb0\xae\ +\x2a\x96\xef\x80\x33\x0f\xf4\x1e\x8c\x89\x75\x2e\x97\xeb\xf8\xa1\ +\x43\x87\xd6\xc9\x30\xab\xc1\x83\x77\x33\x78\x70\xc5\x4e\x27\x47\ +\x4a\x4a\x11\x97\x5e\xba\xbf\xa1\xba\x59\xb3\x62\x2e\xbd\xb4\xe2\ +\x9c\x31\xe8\xd1\xa3\x72\x63\x76\x5e\x9e\x8b\xd7\x5e\x6b\xcd\x29\ +\xa7\x6c\x2d\x37\xb3\xb7\xac\xc4\xc4\x20\xe7\x9d\xf7\x4b\xb5\xf1\ +\x9d\x72\x4a\xd5\x0b\x31\xfd\xee\x77\xf5\xdf\x5a\x68\x0e\x5f\xcc\ +\x24\x81\x00\x04\xb9\x07\x17\x57\xe2\x2c\x17\x76\x46\xa5\xe3\x2e\ +\x7e\x29\x4d\xb4\xb4\xcc\x80\xf8\x9b\x49\xa5\x98\xa6\xa1\xad\xcd\ +\x15\x12\x40\x80\xf5\x65\x27\x8c\x54\x61\xff\xa0\x0a\xa1\xb8\x4c\ +\x32\xb7\xab\xaa\x93\xcb\xb8\x9b\x92\x04\x10\x2e\xc2\xc5\x1b\x04\ +\x70\xe3\xe2\x27\xaa\x9e\xc8\x50\xd1\xfe\xff\x4b\x05\x3f\xca\xd7\ +\x55\x9c\xf3\x53\x0d\xee\xd3\xe8\x88\x90\x8a\x33\x26\x34\x0b\xb8\ +\x4f\x95\x35\x11\x0e\xa9\x12\x11\x46\x00\x2b\xb4\xf2\xf0\x03\x53\ +\x0f\xac\x4e\xa0\x39\x14\x22\xd2\x0b\x48\x09\x47\x91\xe8\xba\xb0\ +\x7b\xb7\x87\x25\x4b\x52\x58\xb2\xa4\x25\x85\x85\x2e\x26\x4d\xb2\ +\xd1\x0e\x26\x76\x26\x86\x00\xa0\x73\x74\x37\x52\x5a\x40\xba\xf2\ +\xf4\xa6\x20\x9f\x94\xbe\x16\x4e\x93\x2c\xe9\x21\x93\xc4\x4b\x31\ +\x93\xca\x9c\xf5\x49\xa5\xeb\xc2\xa7\x73\xe8\xbf\x3b\xd8\xce\x3f\ +\x74\x96\xfe\x82\x70\x1a\x35\x4b\x00\x9d\x71\x80\x25\x94\x2e\xac\ +\xe6\x31\xcd\xd1\x87\x35\x47\x1f\x66\x3b\x8f\xa3\xe4\xa2\x95\x4a\ +\x8a\x18\xc7\xab\x38\xa5\x52\x3e\x06\x6e\x8f\x70\x2c\x95\x84\x26\ +\x53\x3c\x05\xac\x16\xe1\x6a\x11\xc2\xb2\x04\x95\xa9\x56\x67\x9c\ +\x2f\x94\xc6\xd4\xc4\xa8\xf8\xf8\xf8\xe2\x3e\x7d\x1a\x66\x39\xbb\ +\x1d\x3b\x3c\xbc\xf0\x42\x3b\x9a\x35\x2b\x66\xf6\xec\x95\xb4\x6c\ +\x19\x1d\xab\xb0\x05\x02\x01\xb2\xb3\xb3\x5d\xe3\xc6\x8d\x6b\x98\ +\xbf\xd8\x28\x17\x5b\x2d\x81\x00\x7b\xf0\xd3\x94\xeb\x81\x2e\x15\ +\x0f\xe9\x6c\xfd\x50\xb2\xe4\xef\x38\xe3\xae\x7a\x03\x2b\x49\x61\ +\x1b\xce\x58\x2f\x70\x6a\xae\x4d\xae\xb7\x58\x9d\xf1\x6a\xe3\x80\ +\x96\xa4\xf0\x95\x64\xc9\x4e\x84\xa1\x50\x3a\x26\xb0\x5a\x9a\xad\ +\x2f\xc8\x54\x79\x0b\xe5\x44\xe0\x14\x7a\xb1\x59\x32\xe5\x3d\x84\ +\x96\xa4\x70\x04\xd0\x0a\x65\x02\xb0\x2c\xac\xef\x22\x0a\xa9\x12\ +\xbe\xe9\x7b\x75\x20\x34\x1e\xf1\x68\x9c\xf1\x7a\x73\x70\x56\x28\ +\xb9\x05\x78\xb6\xc2\xcc\x67\x63\x4c\x03\x20\x22\xc7\x1e\x71\xc4\ +\x11\xea\x76\xd7\xc9\x90\xc0\x3a\xd7\xa5\x4b\x3e\xf3\xe6\x45\xdf\ +\x47\x81\xd5\x09\x0c\xaf\x98\x6a\x09\x04\xd0\xfb\xb5\x00\x67\x5c\ +\x60\xd5\xf6\x72\x29\xce\x2a\x13\x7b\x71\x5a\xdc\x4a\x12\xc0\x0f\ +\x71\x71\x94\xe6\xe8\xaa\xb0\x07\x59\xa2\x98\x2b\xa1\xb4\x0b\xb7\ +\x3f\xd0\x1d\x67\x22\x42\xcd\x47\xd5\x16\xf3\x5b\x9c\x25\xbb\xf6\ +\xa1\xa4\x20\x9c\x8e\x53\xb6\x26\x1e\x78\x89\x20\xf5\xf7\x7e\x4c\ +\x9d\x52\x65\xa7\x2a\x59\x38\xe3\x3a\x17\xe1\x4c\x6e\xf9\x42\xe4\ +\x80\xe3\x1b\x8d\x31\x11\xe2\xf5\x7a\xc7\xa4\xa7\xa7\x5b\xa2\x62\ +\xa2\x8a\x1c\xa4\xae\x72\xcc\x12\x11\xe1\x66\x3a\xa1\x24\x53\xc8\ +\x8f\x7a\x97\xee\x8d\x48\x1c\x33\xc4\x45\x3e\xdd\xf0\xa0\x3a\x53\ +\x7f\x3c\xec\xfb\x38\xef\x27\x15\xa5\x0d\xc2\x16\xbc\x6c\xd2\xe9\ +\x5a\x6e\xd4\xaf\x64\x49\x0b\x9c\x15\x30\x46\x6b\x8e\xbe\x53\xcb\ +\xd0\x4d\x3d\x13\xa1\x1f\xce\x7a\xd9\x67\x00\x8b\x81\x29\xaa\x7c\ +\x56\xfd\x55\xe6\x70\xf9\xfd\xfe\x4e\x40\xb1\xcf\xe7\xab\x7e\x84\ +\xbc\x69\xf4\x44\xa4\x1d\xb0\xf1\x81\x07\x1e\x20\x23\x23\x23\xd2\ +\xe1\xc4\x94\xa2\xa2\x22\x96\x2d\x5b\xc6\xc2\x85\x0b\x67\xbc\xf2\ +\xca\x2b\xb7\x45\x3a\x9e\x58\xd3\x68\x93\xc0\xc6\xc8\x92\xc0\xd8\ +\x20\xc2\xaf\x80\x3b\x71\xca\xe2\xbc\x00\xdc\xac\xca\xf7\x91\x8d\ +\xca\x98\xc6\x4b\x44\x7e\xeb\x72\xb9\x9e\x5f\xbc\x78\xb1\x24\x24\ +\x54\x1e\x8e\x6e\x6a\xe7\xe4\x93\x4f\x0e\x16\x14\x14\x9c\xb7\x77\ +\xef\xde\x98\x5d\x05\x2b\x52\x62\xae\x3b\xd8\x98\x58\xa7\xca\x52\ +\x55\x8e\x05\x7e\x8d\x33\x8c\x60\xb9\x08\x7e\x11\xda\x47\x38\x34\ +\x63\x1a\xab\x51\xbd\x7b\xf7\x2e\xb2\x04\x30\x3c\x72\x73\x73\xd9\ +\xb7\x6f\x9f\xd5\x09\x0c\x03\x4b\x02\x8d\x89\x52\xa1\x82\xd5\x43\ +\x70\x96\x37\x9b\x00\xac\x12\xe1\x0e\x11\x9a\x47\x36\x32\x63\x1a\ +\x97\xb8\xb8\xb8\x31\xc3\x86\x0d\xb3\x19\xfc\x26\xea\xd8\x20\xd6\ +\xc6\xe8\x43\x46\x8a\x48\x8b\x48\x87\x61\xea\xcc\x2e\x68\x73\x23\ +\xfc\x7d\x02\x1c\x7f\x2d\xe8\xd5\x22\x8b\x5f\x80\x0b\x5e\x87\x2d\ +\xb5\xa9\x03\xa1\xc0\x4e\x9c\x7a\x94\x6b\x55\xab\xad\x95\x19\x73\ +\xac\x4e\xa0\xa9\x09\x11\x69\x26\x22\x03\x1b\x6a\x7d\xc0\x18\x62\ +\x63\xd7\xc2\xc0\x92\xc0\xc6\xe8\x27\x66\x46\x3a\x04\x53\xd7\xb6\ +\xe0\x2c\x8a\x92\x8c\x53\x55\xe6\xba\x8b\xe1\xd3\x8b\xe1\x16\x9c\ +\x95\xf1\x2a\x2f\x1d\x75\x88\x8a\x44\xe4\x5d\x60\x01\xf0\x9c\xaa\ +\x6e\xad\xed\x0d\xa3\x40\x67\x20\x6c\x6b\xc0\x9a\x98\x71\x94\xaa\ +\xba\x2c\x09\x0c\x8f\x92\x3a\x81\x8b\x16\x2d\xaa\x7e\x19\x55\x73\ +\x58\xac\x3b\xd8\x98\x98\xb2\x0b\x98\x8a\x53\x55\xe6\x4d\xe0\x49\ +\xe0\xbf\x38\xbd\xc5\xb5\xe2\x05\x4e\x00\xe6\x02\xdf\x8a\xc8\x1f\ +\x6a\x7b\x43\x63\x62\xc4\xa8\x8e\x1d\x3b\x16\xb4\x68\x61\x9d\x2b\ +\xe1\x60\x75\x02\xc3\xcb\x7e\xa9\x8d\x51\x67\x66\xf2\x33\xcb\x23\ +\x1d\x86\x09\xa7\x0d\xc0\xe5\xc0\x92\x54\x98\xf9\x47\x58\x38\x1c\ +\x36\xac\x80\x7b\x9f\x85\x7b\x6a\x3a\x93\x58\x80\xd6\x40\x27\x20\ +\x1d\x67\xbd\x60\x0f\xd0\x0a\x78\x4e\x44\x7e\x0b\x5c\xd9\x48\x5a\ +\x05\x8d\xa9\x92\xd7\xeb\x1d\x9d\x91\x91\x11\x7f\xf0\x33\x8d\x69\ +\x78\x2c\x09\x6c\x8c\x46\xb1\x58\x3f\xb0\x12\x31\x8d\xc8\xbd\x4e\ +\x59\x99\xd4\x39\x70\xf7\xed\x70\xf7\xbf\x70\xca\xca\x7c\x7b\x28\ +\x37\x11\x91\xd6\x38\x7d\xcd\x37\x40\x92\x0b\x86\xfc\x0e\x3e\x38\ +\x56\x44\xce\x51\xd5\x45\x61\x89\x3c\xb2\x2e\x05\x2a\xae\x23\x6e\ +\x4c\x29\x11\xf1\xba\x5c\xae\xe1\x69\x69\x0d\x7a\x01\x22\x63\x0e\ +\xc8\x92\x40\x63\x1a\x01\x55\x96\x02\xc7\x89\x70\x0a\xce\x0a\x33\ +\xff\x13\xd2\xb1\x50\x48\x00\x00\x20\x00\x49\x44\x41\x54\xe1\x09\ +\xe0\x36\x55\x36\xd4\xec\x1e\xba\x55\x84\xbb\xe0\x7f\x6d\xa1\xcb\ +\xb9\xf0\xa4\x0b\x3e\x68\x07\x3c\x2f\x22\x83\x54\x35\xa6\xd6\xa9\ +\xf6\xf9\x7c\xeb\x22\x1d\x83\x69\xf0\xd2\x83\xc1\x60\xbc\x8d\x07\ +\x0c\x1f\xaf\xd7\xcb\xd4\xa9\x53\xb5\xb0\xb0\xf0\xbb\x48\xc7\x12\ +\x8b\x6c\x4c\xa0\x31\x8d\x88\x2a\x0b\x81\x34\xe0\x12\x9c\x99\x24\ +\xab\x44\xc8\x11\xa1\xda\x01\x4d\x22\xb8\x45\xb8\x0f\x58\x03\x47\ +\x9c\x0f\xcd\x5d\x90\x58\xb2\x5a\x49\x4b\xe0\xf1\xb0\x06\x6e\x4c\ +\xc3\x34\xaa\x65\xcb\x96\x85\xa9\xa9\xa9\x91\x8e\x23\xa6\x59\x9d\ +\xc0\xf0\xb1\x24\xd0\x98\x46\x46\x95\xa0\x2a\x4f\x03\x7d\x80\x69\ +\x38\x83\x07\x57\x8b\x70\xa3\x08\x55\x56\xbb\x55\xa5\x18\x67\xed\ +\xe2\x2d\xfb\xf7\x5e\xf8\x28\xf0\x79\x68\x63\xbc\x88\x4c\x0a\x67\ +\xdc\xc6\x34\x34\x6e\xb7\xfb\x38\x5b\x2f\xd8\x44\x33\x4b\x02\x8d\ +\x69\xa4\x54\x29\x50\xe5\x5e\xa0\x07\xf0\x08\x30\x03\x58\x29\xc2\ +\x45\x22\x55\xfe\xdb\xf0\x03\xce\xbf\x19\x2b\x9d\xcd\xb8\x5f\x80\ +\x0b\x81\xc2\xd0\xf1\xbb\x45\xa4\x47\x98\xc3\xae\x37\x7e\xbf\xff\ +\x69\xbf\xdf\x7f\x77\xa4\xe3\x30\x0d\x93\x38\x8e\x1d\x3a\x74\xa8\ +\x7d\x8e\x9a\xa8\x65\x7f\x79\x8d\x69\xe4\x54\xd9\xa5\xca\x54\xa0\ +\x37\xf0\x3a\xf0\x18\xf0\xb5\x08\xbf\xae\x70\xea\x23\x40\x11\x30\ +\x1c\x38\x0d\x58\xad\xaa\xff\x03\x6e\x0b\x1d\x6f\x06\x5c\x5f\xd5\ +\x33\x24\x4b\x6e\x91\x4c\x39\x5f\x44\x24\x0c\x6f\x21\x5c\xda\xe1\ +\xcc\x8e\x36\xa6\x2a\xfd\x03\x81\x40\x73\x1b\x0f\x18\x5e\x81\x40\ +\x80\x9c\x9c\x1c\x19\x37\x6e\x9c\xd5\x09\x0c\x03\x4b\x02\x1b\x09\ +\x99\x21\x4d\x80\x89\xce\x06\x27\xcb\x4d\xd2\x36\xb2\x11\x99\x86\ +\x46\x95\x0d\xaa\x5c\x0e\x0c\x04\xbe\x03\x16\x88\xf0\x81\x08\xc7\ +\x88\x70\x01\xf0\x5b\xe0\x7c\x55\x72\x55\x79\x45\x95\x15\xa1\x4b\ +\xef\x04\x4a\x26\x51\x54\x4c\x1c\x1d\x42\x47\x84\xa7\xc9\x62\xa9\ +\x4c\x91\x5f\x85\xf9\xad\x18\x53\x1f\x46\x26\x26\x26\x06\x7a\xf6\ +\xec\x19\xe9\x38\x62\x9a\xd5\x09\x0c\x2f\x4b\x02\x1b\x01\xc9\x94\ +\x41\x14\xf0\x35\x25\x83\xf7\x95\x3f\xe3\x61\xb9\x64\xc9\xb8\xc8\ +\x46\x66\x1a\x22\x55\xbe\x53\xe5\xb7\xc0\x51\x38\x25\x52\xde\x04\ +\x1e\x00\xee\x52\xe5\xfd\xca\xe7\x6b\x31\xf0\xef\xd0\x66\x17\x11\ +\x39\x70\xd3\x88\x32\x02\x17\x1f\x4a\x96\xfc\x5d\xa6\x49\xc7\xba\ +\x8f\xde\x98\xfa\x21\x22\xc7\x0e\x1e\x3c\x18\x97\xcb\x3e\x46\xeb\ +\x83\x88\xd8\xb2\x71\x61\x60\x7f\x7b\x63\x9c\x4c\x12\x2f\xc2\x3f\ +\x50\x2a\x7e\x5d\x6d\x85\xf0\xac\xfc\x59\xda\x47\x24\x30\xd3\xe0\ +\x85\xca\xca\x8c\xc1\x19\x03\xb8\x0a\xb8\xb5\x9a\xd3\xff\xaf\xcc\ +\xeb\xfe\x07\xb9\xb5\x00\xe7\x50\xcc\x77\x92\x25\xb7\xc8\x0c\xa9\ +\x72\x32\x4a\x03\x70\x01\x70\x63\xa4\x83\x30\x0d\x93\xc7\xe3\x19\ +\x6d\x93\x42\x4c\xb4\x13\x55\x4b\xae\x63\x99\x4c\x91\x5f\xe1\xe2\ +\xa3\x6a\x4e\xf9\x0b\xf0\x52\x7d\xc5\x63\xa2\xcc\x53\x9f\x5d\xc0\ +\xa6\xa1\x67\x33\x66\xf2\xe5\x0c\xff\xeb\x9a\x03\x9e\xb7\x84\x23\ +\xf8\x98\xb9\x00\x74\xe2\x21\xce\xe5\xf9\x72\xc7\x85\x1b\x50\x4e\ +\x3b\xc0\xd5\x6b\x80\x9b\x34\x47\x9f\x3f\xc0\x71\x63\x1a\x14\x11\ +\xe9\x04\xac\x7d\xf8\xe1\x87\xb1\x42\xd1\xe1\x77\xd2\x49\x27\x69\ +\x61\x61\xe1\xd9\x7b\xf7\xee\x7d\x2e\xd2\xb1\xc4\x1a\xfb\x16\x13\ +\xeb\x84\x83\xcd\xd6\xbc\x9e\x03\x0c\xe6\x37\x86\x93\x2f\x85\x6d\ +\x03\x60\xc0\x33\x4f\x55\x7b\xde\x10\xe0\xe3\xd0\xeb\xce\x5c\x09\ +\x5c\x59\xee\x78\xf5\xdf\x35\xbb\x02\x73\x65\xaa\xac\xd3\x6c\xad\ +\xee\x0b\x8b\x31\x0d\xc5\x48\x8f\xc7\x13\x1c\x38\x70\xa0\xf5\xa6\ +\xd5\x83\xdc\xdc\x5c\x82\xc1\xa0\xd5\x09\x0c\x03\x4b\x02\x63\xdf\ +\x37\x07\x39\x7e\x2d\xc5\xcc\xaf\x97\x48\xea\x83\x9b\xe9\x28\x67\ +\x03\x47\x13\x64\x5b\xa4\xc3\x89\x7a\xad\xbf\x74\x7e\x0e\xb6\x78\ +\xda\x42\x46\x00\x0b\x00\x58\xc6\x74\x46\xf2\x68\xb9\xe3\x1e\xee\ +\x44\x39\xaf\x8a\x2b\x0b\x51\xee\x27\x91\x99\x3a\x5d\x73\xeb\x24\ +\x66\x63\xc2\x6f\x54\xdf\xbe\x7d\x03\x5e\xaf\x37\x2e\xd2\x81\x18\ +\x53\x1b\x96\x04\xc6\x3a\xa1\x1b\x10\xa0\xaa\x3f\x6b\xe5\x47\x12\ +\x79\x42\xa7\xeb\x9e\xfa\x0e\x2b\x5c\x64\x8a\xfc\x19\x17\xbf\x46\ +\x99\xac\x77\xea\xc5\x91\x8e\xa7\xb1\x90\xbb\xa4\x59\xe9\xc6\x1e\ +\x56\xea\x9d\xba\xb1\xdc\xf1\xa9\xb2\xaf\x8a\xcb\x16\x52\xcc\xf5\ +\x7a\xa7\x7e\x1f\xee\xf8\x0e\x87\xdf\xef\x7f\x1a\xd8\xe2\xf3\xf9\ +\x6c\x5c\xa0\x29\x27\x2e\x2e\x6e\xcc\xb0\x61\xc3\x2c\x01\x34\x51\ +\xcf\x9a\xb2\x63\x94\xfc\x5e\xdc\x92\x29\x73\x80\x7f\xa3\x3c\x0f\ +\xbc\x53\xe1\x94\xe5\xc0\x6f\x62\x29\x01\x04\xd0\x39\xba\x1b\xb8\ +\x11\xe1\x42\x99\x2a\x47\x45\x3a\x9e\x46\xe4\xb8\x32\xaf\x57\x1c\ +\xf0\x2c\xc7\xb7\xc0\xc9\x9a\xa3\xa7\x36\xd4\x04\x30\xc4\xea\x04\ +\x9a\x4a\x44\xa4\x45\x51\x51\x51\x5f\x1b\x0b\x58\x3f\x4a\xea\x04\ +\x8e\x1f\x3f\xde\xea\x04\x86\x81\x25\x81\x31\x48\x6e\x96\x0e\xf4\ +\x64\x31\xc2\xd5\xc0\xc5\x3a\x5b\xcf\x66\x36\x63\x50\xd2\x50\xce\ +\x41\x38\x9a\x04\x86\xea\x6c\x5d\x16\xe9\x58\xc3\x41\x73\xf4\x59\ +\xe0\x5d\x94\x07\xe5\xf7\xe2\x8e\x74\x3c\xb1\x4e\x44\x3c\x50\x3a\ +\xe9\xe3\x67\x55\xfd\xea\x00\xa7\xee\x02\x6e\x60\x3b\x83\x35\x47\ +\x5f\xaf\x9f\xe8\x8c\xa9\x73\x47\x03\x0c\x1a\x34\x28\xd2\x71\x34\ +\x0a\x56\x27\x30\xbc\xec\x97\x1a\x63\x24\x4b\x8e\x07\x9e\x03\x76\ +\xa1\x1c\x59\x92\xe8\xa9\x33\x0d\xfc\xab\xd0\x4f\xec\x13\xae\x42\ +\xf9\x8a\x1e\x5c\x01\x3c\x18\xe9\x70\x62\x5c\x16\xd0\x21\xf4\xba\ +\xea\x99\xe6\x41\x16\xe0\xe2\x16\xcd\xd6\x2d\x55\x1e\x37\x26\x7a\ +\x8c\xea\xda\xb5\x6b\x61\x52\x52\x52\x7c\xa4\x03\x31\xa6\xb6\xac\ +\x25\x30\x46\x88\x88\x48\x96\x64\x01\x6f\x03\xef\x11\x24\x23\x56\ +\x5b\xfa\x6a\x42\xb3\x75\x39\x70\x1f\x70\x87\x4c\x95\x36\x91\x8e\ +\x27\x56\x85\x0a\x43\xdf\x12\xda\xdc\x0d\x54\xb9\xd6\xae\xce\xd6\ +\xd7\xa2\x30\x01\xb4\x3a\x81\xa6\x12\xaf\xd7\x3b\x7a\xd8\xb0\x61\ +\x96\x00\x9a\x98\x60\x2d\x81\x31\x40\xb2\xa4\x25\x99\xfc\x0d\x18\ +\x87\x70\x83\x66\xeb\xfd\x91\x8e\xa9\x41\x08\x32\x03\x17\x67\x11\ +\x64\x0e\x60\x93\x44\xea\x98\x88\x78\x81\xa7\x00\x6f\x68\xd7\x0d\ +\xaa\x7a\xe0\x5a\x82\x51\xc6\xe7\xf3\x6d\x8a\x74\x0c\xa6\x61\x11\ +\x91\x78\x97\xcb\x95\x6e\xe3\x01\xeb\x8f\xd7\xeb\x25\x2b\x2b\x4b\ +\x8b\x8a\x8a\xbe\x8b\x74\x2c\xb1\xc8\x5a\x02\xa3\x9c\x4c\x91\x0c\ +\xe0\x0b\x60\x30\x41\x8e\xb5\x04\x70\x3f\x9b\x24\x12\x3e\x22\x92\ +\x08\xf8\x81\x92\x4f\xc3\xd7\x54\xf5\xff\x45\x30\x24\x63\xea\xc3\ +\x88\x60\x30\xe8\x1d\x32\xe4\xc0\x2b\x23\x9a\xba\x97\x9b\x9b\xcb\ +\xbe\x7d\xfb\x8a\x22\x1d\x47\x2c\xb2\x24\x30\x8a\x49\xa6\xf8\x70\ +\xf1\x01\xf0\x2d\xc2\x50\x9d\xa3\x4b\x23\x1d\x53\x43\xa3\x39\xfa\ +\x2c\xca\x3b\x04\x79\xc8\x26\x89\xd4\x0d\x11\x19\x89\x33\xb6\xf4\ +\x92\xd0\xae\x1d\xc0\xa5\x91\x8b\xc8\x98\x7a\x33\xb2\x4d\x9b\x36\ +\x85\x6d\xdb\xb6\x8d\x74\x1c\xc6\xd4\x09\xeb\x0e\x8e\x42\x72\x93\ +\x34\xc5\xcb\xa3\x08\x7f\x04\x6e\x63\x36\x77\xa8\xad\xff\x77\x60\ +\x2e\xfe\x64\x93\x44\x6a\x4f\x44\xda\x00\xd3\x80\xab\x71\xd6\xff\ +\x05\x58\x0f\x9c\xab\xaa\x1b\x22\x16\x58\x98\x58\x9d\x40\x53\x91\ +\xc7\xe3\x39\x7e\xd8\xb0\x61\xde\x83\x9f\x69\x4c\x74\xb0\x24\x30\ +\xca\xc8\x14\xe9\x8f\x87\x17\x50\x5a\xe3\x62\x9c\xce\xd2\x45\xe4\ +\x1c\xc2\xf5\x22\x7d\x81\xc6\xd7\x35\x7a\x2e\x6f\xd3\x81\x3b\xa5\ +\xbd\xb8\xd9\x84\xad\x4c\x51\x33\x82\x53\x27\xaf\x13\x4e\xb7\xef\ +\x31\x40\xd9\xd6\xd4\xbf\x01\xd7\xa8\xea\xce\x08\xc4\x56\x1f\xda\ +\x71\xb0\x05\xef\x4c\xa3\x21\x22\x2e\xb7\xdb\x7d\x4c\x5a\x5a\x9a\ +\x1c\xfc\x6c\x53\x57\x02\x81\x00\xb3\x67\xcf\x96\xc5\x8b\x17\x5b\ +\x9d\xc0\x30\xb0\x24\x30\x8a\x48\x96\x9c\x85\x8b\xc7\x80\xff\x12\ +\xe4\x44\xcd\x39\xac\xd6\x97\xd1\x38\x63\xb9\x1a\x97\xf9\xc0\xe5\ +\x40\x06\xf7\xb1\x30\xd2\xc1\x44\xbd\x4d\xc0\x24\x55\x5d\x10\xe9\ +\x40\x8c\xa9\x47\x83\x8a\x8b\x8b\x9b\xda\x78\xc0\xfa\x65\x75\x02\ +\xc3\xcb\xc6\x04\x46\x01\x99\x21\x71\x92\x25\x0f\x02\xff\x40\xf1\ +\x93\xc0\x68\x9d\x13\x7b\xdd\x6f\x61\x55\x08\x2c\x02\x06\x01\x1d\ +\x23\x1c\x4b\x74\x2a\x02\xde\x00\x26\x01\xfd\x2c\x01\x34\x8d\xd0\ +\xc8\xa6\x4d\x9b\x16\x75\xeb\xd6\x2d\xd2\x71\x18\x53\x67\x2c\xb3\ +\x6e\xe0\x64\x9a\x74\xa5\x98\xe7\x81\x3e\x08\x13\x35\x47\xff\x53\ +\xcb\x5b\xbe\x0e\x9c\x51\x07\xa1\x45\x9f\x15\xc0\x58\x6e\xe7\x4c\ +\x9a\xf1\x00\x37\x52\x4c\x30\xd2\x21\x35\x70\x41\x9c\x56\xbf\x5f\ +\x80\x8d\xaa\x5a\x18\xe1\x78\xea\xdb\x05\x40\x71\xa4\x83\x30\x0d\ +\x83\xcb\xe5\x3a\x2e\x2d\x2d\xcd\x25\x62\xbd\xc1\x26\x76\x58\x12\ +\xd8\x80\x49\xa6\x9c\x82\x8b\x79\xc0\x1a\x20\x5d\xb3\xf5\x87\xda\ +\xde\x53\x55\x7f\x02\x7e\xaa\xed\x7d\xa2\x95\x4c\x95\x95\x28\x5f\ +\x72\x13\xa9\x9a\xa3\x0f\x44\x3a\x1e\xd3\x70\x59\x9d\x40\x53\x96\ +\xdb\xed\x3e\x3e\x3d\x3d\xdd\x2a\x0c\xd4\xb3\x50\x9d\x40\xac\x4e\ +\x60\x78\x58\x77\x70\x03\x24\xbf\x17\xb7\x4c\x95\x59\x08\x2f\x13\ +\xe4\x45\x12\x38\x5a\x73\x6a\x9f\x00\x9a\xd0\x4a\x22\xca\x7d\x28\ +\x33\xe5\x26\xb1\x3a\x0f\xc6\x98\x83\x12\x91\xee\x45\x45\x45\x6d\ +\x6c\x3c\x60\x64\x84\xea\x04\x06\x22\x1d\x47\x2c\x6a\x34\x49\xa0\ +\x4c\x95\x36\x72\x8d\x44\xc7\x52\x3f\x3d\x49\x47\xf9\x13\xc2\x05\ +\x3a\x5b\x2f\xd7\xe9\x9a\x1f\xe9\x90\x62\x4a\x22\x33\x10\xf6\xe1\ +\x61\x4e\xa4\x43\x31\xc6\x44\x85\x91\x5e\xaf\xb7\xb8\x5f\xbf\x7e\ +\x91\x8e\xc3\x98\x3a\x15\xb3\xdd\xc1\x22\x22\x64\x71\x29\x70\x39\ +\x4a\x5f\x20\x89\xa6\xa8\x64\xc9\xcf\x08\xcf\xa2\xdc\xa9\x39\xba\ +\x23\xac\x31\x64\xca\x55\x40\x12\xb0\x57\x67\xeb\xdc\x9a\x5e\xa7\ +\x39\xfa\xa9\xcc\x90\xae\x3a\x3d\x66\x4b\x6f\x44\x94\x4e\xd7\x3d\ +\x92\x29\x93\x11\x9e\x91\x4c\x79\x4c\x67\xeb\x87\x91\x8e\xc9\x34\ +\x3c\x56\x27\xd0\x94\x31\x6a\xe0\xc0\x81\x41\x8f\xc7\x63\xdd\xc1\ +\x26\xa6\xc4\x64\x4b\x60\x68\x2d\xdd\xf7\x51\x1e\x45\xc9\xc0\x49\ +\xc4\xc0\xa9\x7b\xd6\x15\x25\x13\x61\x40\xf8\x03\x61\x2a\x42\x0e\ +\xc2\x2d\x87\x7a\xa9\x25\x80\xe1\xa5\xb3\xf5\x39\x94\x77\x80\x07\ +\x6d\x25\x11\x73\x00\xed\x70\xea\x24\x9a\x46\x2e\x2e\x2e\x6e\x4c\ +\x7a\x7a\xba\x15\x89\x8e\x80\x50\x9d\x40\x4e\x3a\xe9\xa4\x3e\x91\ +\x8e\x25\x16\xc5\x6a\x4b\xe0\xfd\x38\x85\x6d\x01\x36\xa0\x4c\x46\ +\x58\x8a\xd0\x84\x20\xe9\xb8\xb8\xb6\xaa\x8b\x64\x92\x78\x49\xa1\ +\x2b\x45\xec\xd4\xbb\x75\x6b\x4d\x1e\x24\x53\x24\x09\x17\xad\x98\ +\xcd\x9a\xda\xae\xda\x21\x33\xa4\x09\x05\x74\xd3\x6c\x5d\x5e\xc5\ +\xfe\x4e\x14\xf3\x4b\x68\x3d\x5c\x53\x17\x9c\x95\x44\xbe\xa4\x27\ +\x3e\xc0\x26\x89\x18\x63\x2a\x11\x91\xd6\x40\xcf\xb4\xb4\xb4\x83\ +\x9e\x6b\xea\x9e\xd5\x09\x0c\xaf\x98\xfb\xa5\xca\x54\x39\x06\x38\ +\x37\xb4\x59\x80\x87\x91\x3a\x53\x7f\x2c\x73\xca\x72\xe0\xef\x32\ +\x49\xbc\x65\xae\xe9\x87\x32\x97\x14\x46\x03\x6e\xbc\x20\x59\xb2\ +\x11\xe1\xcf\x9a\xad\x7f\x2b\x3d\x2f\x53\xee\x41\xb8\xc1\xd9\xe0\ +\x37\x28\x57\xe1\xe2\x04\xc0\x45\x26\x6b\x65\xaa\xfc\x4e\xb3\xf5\ +\x63\x99\x22\x27\xe2\xe2\xcd\x32\xcf\x6c\x23\x59\x52\x92\x20\x7e\ +\xaa\x39\x3a\x42\x32\xe5\x56\x84\x19\xa1\x7d\x67\x02\xe7\x01\xa7\ +\x00\x1e\x11\x71\xa9\xaa\xca\xcd\x32\x9a\x20\x7f\xc5\xa9\x6e\x27\ +\xb8\x40\xb2\x64\x39\x8a\x4f\x67\xeb\x7b\x75\xf6\x4b\x6b\xa4\x34\ +\x5b\x97\x4b\xa6\xdc\x07\xcc\x94\x9b\x64\xbe\xde\xa5\x9b\x23\x1d\ +\x93\x31\xa6\xc1\x39\x46\x44\x74\xd0\xa0\x41\x56\x1b\xc6\xc4\x9c\ +\x98\x4b\x02\x29\xbf\x24\xda\xfc\x0a\x09\x60\x29\x7d\x44\x8b\x00\ +\xe4\x16\xe9\x8e\xf2\x29\xd0\x0c\x67\x89\xa8\x8f\x80\xde\x40\x7b\ +\x94\x79\x92\x29\x4d\x74\xb6\x3e\x52\xf9\x06\xfc\x23\x74\x4d\x21\ +\x10\x07\x74\x46\x79\x52\x66\xc8\x11\x87\x11\xf3\x03\x40\xfb\xb2\ +\x3b\x24\x53\xc6\x23\xbc\x1e\xda\x2c\x0c\xc5\x35\x02\x18\x80\xb0\ +\x44\xa6\xc8\x31\x3a\x47\x97\x1e\xc6\xb3\x4c\x59\x89\xcc\x20\x9f\ +\xb3\x43\x93\x44\x2e\xaa\x8b\x5b\xca\x0c\x69\x4e\x01\xa9\x00\xc4\ +\xb3\xb1\xa1\x76\xed\xcb\x54\xe9\x03\xb8\x50\xf2\x35\x47\x7f\x8a\ +\x74\x3c\x0d\x90\xd5\x09\x34\x00\xa3\x7a\xf6\xec\x59\x98\x98\x98\ +\x18\x1d\x13\x0b\x8d\x39\x04\xb1\x97\x04\x2a\x47\x94\x79\xfd\xed\ +\x41\xcf\x2f\xe2\x5e\x84\x66\x00\x08\xa7\x6a\xb6\xbe\x2a\x33\x24\ +\x81\x7c\x56\x02\x9d\x11\xe6\xc8\x0c\xf9\x9b\x4e\xd7\x7d\x15\xae\ +\xdc\x00\x9c\x4b\x02\x2b\xc8\xe7\x13\xa0\x3f\xd0\x9f\x22\x3a\xea\ +\x1c\x7d\x0b\x10\xc9\x92\xf5\x40\x2a\xb0\x45\x73\xb4\xba\x72\x24\ +\xcd\x51\xa6\xe3\xe5\x6f\x14\xd2\x46\x55\x55\xb2\xe4\xd1\xd0\xb1\ +\x42\xdc\xf4\xd1\x3b\x74\x4d\xa8\x70\xf4\x6a\xc0\x8d\x8b\xfb\x71\ +\x92\x42\x53\x0b\x07\x9b\x24\x22\x59\xf2\x07\x4a\x8a\x6b\x0b\x8a\ +\x92\x8f\xb0\x97\x20\xeb\x10\x3e\xd3\x1c\x7d\xbb\xd2\x4d\xf3\x38\ +\x1d\xe1\xe9\xd0\xeb\x2b\x89\xd0\x32\x7d\x72\xa3\xb4\xc6\x4d\x2f\ +\x00\x94\x9f\xf4\x4e\xdd\x58\xee\x04\xe5\x2b\x20\x01\xf8\x0a\x67\ +\x6d\x60\x53\x86\xd5\x09\x34\x00\x5e\xaf\x77\xec\xb0\x61\xc3\x2c\ +\x01\x8c\x10\xaf\xd7\x4b\x66\x66\x26\x81\x40\xc0\xea\x04\x86\x41\ +\xec\x25\x81\xce\xf2\x56\x0e\xe1\xe0\x03\x79\xa5\xb4\xe5\x30\x1f\ +\x65\x9c\x64\xc9\xb8\xd0\xf6\x9e\xd0\x7f\x93\x29\xa4\x1f\xf0\x45\ +\x85\x2b\xe7\x69\x8e\x7e\x0a\x20\x59\xf2\x7f\x38\x49\x20\x04\x49\ +\x05\xd6\x1e\x62\xcc\x2f\xeb\x6c\xbd\x3d\xf4\xfa\x47\xb9\x59\x3a\ +\x00\x5d\x42\xdb\x9b\x28\xe6\x7a\xc9\x2a\xed\x89\xd8\x09\xb4\x02\ +\x86\xca\x24\xf1\x96\xb4\x68\x9a\xc3\xa7\xb3\xf5\x39\xc9\x94\xcb\ +\x71\x26\x89\x64\xe8\x7c\xdd\xdf\xfa\x23\x0c\x46\xf9\x83\x73\x62\ +\xc9\x05\x38\x53\x8c\x00\xc9\x92\xf7\x81\x6b\x35\x47\xff\x5b\x9f\ +\x31\xd7\x48\x1c\xa7\xa0\x3c\x05\x80\x70\x3d\xf0\xd7\x88\xc6\x63\ +\x4c\x94\x11\x91\x26\x22\x32\xc8\xc6\x03\x46\x56\x6e\x6e\x2e\x80\ +\xd5\x09\x0c\x83\xd8\x4b\x02\x85\x65\x65\x3e\xac\x07\x57\x7b\xea\ +\x0c\xf1\x00\x6d\x42\x9b\x09\x50\xf5\x84\x11\x94\x2e\x54\x4c\x02\ +\x5d\xec\x6f\x31\x12\x8a\x4a\x9f\x19\xe4\xd0\x67\x9a\x0a\x0b\xcb\ +\x6d\x07\x43\x5d\x89\x8e\xce\x07\x88\xcb\x43\x1b\x52\x71\x56\x13\ +\x31\xb5\x55\x93\x49\x22\xca\x17\x08\xcb\x71\xfe\x4c\xd2\x71\x66\ +\x9d\x8f\x02\x96\xca\xcd\x32\x4c\x67\xe9\xff\x00\x28\xe6\x45\x3c\ +\xbc\x17\xba\x66\x5b\x3d\x44\x7f\x78\x94\xbe\x08\x2e\x82\x34\xb6\ +\xe5\xe0\x8c\xa9\xa9\x5f\xa9\xaa\xdb\x8a\x44\x9b\x58\x15\x7b\x49\ +\x60\x90\x77\x11\x82\x80\x0b\xe1\x74\xc9\x92\x61\x9a\xa3\x9f\x97\ +\x3d\x45\x6e\x90\x44\xe2\x88\xd3\xd9\xba\x4b\x32\x65\x0d\x42\x77\ +\x60\x2f\x70\x1c\xc2\xde\x4a\xf7\x8c\x67\x5d\xa5\x7d\xc5\x14\x94\ +\xbe\x56\x0e\x34\x2b\xb8\x64\x7f\xf5\xa5\x78\x82\x94\x9f\x89\x9c\ +\xc0\x6a\xf6\x97\x87\x5e\x81\x30\xb1\xca\xeb\xb6\xb0\xa1\xda\xfb\ +\x9a\x1a\x2b\x9d\x24\x22\x4c\x93\x6b\xe4\x31\xbd\x5f\x0b\xaa\x38\ +\xed\x45\xcd\xd1\x6c\x70\x8a\x8f\xa3\x3c\x89\x33\x99\x27\x2e\x34\ +\x1e\xf4\x48\x9d\xae\x41\x3c\x1c\x03\x4c\x05\x40\xf8\x0b\xb0\x00\ +\x40\xb2\xe4\x19\x20\x15\x65\x07\x01\x2e\xc3\xcb\xdd\x38\xb3\xd8\ +\x5f\xd7\x1c\xbd\x1a\x40\x32\x65\x24\xc2\x8d\x40\x1f\x20\x09\xe5\ +\x7b\x84\x67\x34\x47\xff\x5f\xc5\x60\x24\x4b\x4e\x02\xae\x04\x7a\ +\x01\x29\x38\x33\xe1\x97\xe8\x6c\x9d\x2c\x99\xf2\x17\x84\x93\xca\ +\x9c\xfe\x27\xc9\x92\xd3\x9d\x37\xcb\x34\x9d\xad\x1f\x20\x3c\x06\ +\xc4\x23\xac\x02\x2e\x2d\xbd\xef\x14\x49\xc2\x4d\x26\xca\xf1\x40\ +\x37\x60\x3b\xca\xb7\xb8\xc9\xd1\x59\x5a\xfa\x65\x48\x32\xe5\x6c\ +\x84\xcb\x43\xef\xf3\x66\x82\xa4\x23\x9c\x05\x74\x42\xf9\x14\x0f\ +\xd7\xe9\x1d\x7a\xa8\xad\xe2\x0d\x86\xd5\x09\x34\xc0\xc8\xf6\xed\ +\xdb\x17\xa4\xa4\xa4\x58\x77\xb0\x89\x49\x31\x57\x27\x50\x67\xeb\ +\x57\x68\x69\xb7\x97\x0b\x78\x57\xb2\x64\xba\x64\xc9\x18\x99\x2a\ +\x13\x24\x53\xa6\x11\xcf\x0f\xb8\x42\x63\x07\x85\xd7\x42\xe7\x36\ +\x05\xce\xa3\x88\xed\x9a\xad\xdf\x12\xcf\x06\x94\x41\x28\xd9\x3a\ +\x5d\xf7\x54\xf1\xa8\x83\x13\x7e\x09\xbd\x6a\x25\x59\x72\xa5\x64\ +\xc9\xf1\x92\x25\x3d\x0e\xfa\x1e\x9c\x89\x04\x25\x93\x3e\xfa\xa3\ +\x1c\x4f\x3c\xeb\x34\x5b\xbf\x05\xb6\xa1\x8c\x41\xf1\x59\x57\x70\ +\x1d\x4b\x64\x06\xc5\x1c\x73\x80\x04\xb0\x1c\xcd\xd6\x2d\x14\x70\ +\x3e\x90\xeb\xec\x20\x83\x7d\xf4\x0e\xbd\x6e\x0f\x1c\x17\xfa\xd9\ +\xdf\xaa\xab\xfc\x0a\xe7\x8b\xc6\x18\xbc\x2c\xc6\x99\x78\xd0\x0b\ +\x68\x0e\x20\x53\xe5\x46\x84\xf7\x80\xdf\xe0\x0c\x2f\x68\x87\x30\ +\x1a\x78\x4c\xb2\xa4\x74\x96\x7a\xe8\xdc\xfb\x81\xd7\x80\xd3\x4a\ +\xcf\x85\xa1\x08\x97\x38\x27\x90\x06\xec\x5f\xde\x40\xe9\x59\x1a\ +\x93\xab\xb4\xf6\xdd\xb1\xa1\x78\x32\x4a\xef\x7b\x93\xb4\xc5\xc5\ +\x72\x94\xa9\xc0\xd1\xa1\xf8\x8f\x40\x38\x93\x20\x9f\xca\x54\x39\ +\xaf\x4c\x18\x5d\x4a\xef\xa9\x3c\x82\x70\x3f\xce\xc4\xac\xce\x08\ +\x13\x29\xe6\xdf\x07\xfb\x3d\x36\x70\x56\x27\xb0\x91\xf3\x78\x3c\ +\xa3\x33\x32\x32\xe2\x22\x1d\x47\x63\x16\x08\x04\xb8\xe7\x9e\x7b\ +\x38\xf9\xe4\x93\xfb\x47\x3a\x96\x58\x14\x73\x49\x20\x00\x85\x4c\ +\x03\xfe\x1e\xda\x6a\x0a\xdc\x06\x2c\x42\x59\x88\x30\x93\xb2\x33\ +\x71\x83\x64\x02\x2b\x43\x5b\xd7\xe2\x61\xa3\x64\xc9\x56\xf2\xd9\ +\x05\xcc\xc7\xe9\xee\x3b\x5c\xaf\x96\x79\xfd\x20\xb0\x04\xb8\xa2\ +\x46\x57\x0a\x17\x01\xbb\x42\x5b\x7e\xf2\xd9\x26\x59\xb2\x0b\x65\ +\x73\xe8\x5e\xb6\x7e\x51\x1d\xd3\xe9\xba\x47\xef\xd4\xd5\x35\x3e\ +\xff\x5e\xdd\x0e\x7c\x59\xba\xc3\xcd\xa0\x1a\x5e\xda\x1c\xe8\x8e\ +\xe0\x07\xce\x06\x5e\x92\x29\xd2\x1f\x25\x1b\x67\xb4\xe1\x37\x08\ +\xfd\x49\xa0\x2d\xc2\x73\xa1\x6b\xce\x95\xa9\x72\x2a\x80\x64\xc9\ +\x09\x28\x57\x87\xf6\x6f\x41\x98\x4c\x90\xce\xb8\x18\x82\xe2\xcc\ +\x64\x57\xae\x43\x98\x5d\xfa\x44\xe1\x41\x60\x34\x30\x9a\x42\x3e\ +\x38\x60\x64\x1e\xfe\x0a\x74\x0a\x5d\x33\x1f\xe5\x08\x94\x6b\x80\ +\x3c\x9c\x99\xc4\x73\x65\xaa\xb4\xa9\xe2\xca\xee\x38\xff\x9f\x8d\ +\x06\x7e\x0a\xed\x1b\x26\x53\x25\xfc\x45\xd9\x8d\x09\x03\x11\x71\ +\xab\xea\x91\x69\x69\x69\x56\x1a\x26\x82\x54\x95\xc4\xc4\x44\x3c\ +\x1e\x4f\x6c\xe6\x2b\x11\x16\x7b\xdd\xc1\x80\xde\xab\x79\xc0\x79\ +\x92\x25\x8f\x03\x97\x00\x7d\x11\x7a\x12\x64\x17\x2e\x56\xa2\xbc\ +\x40\xbe\x33\xc6\x4f\xe7\xe8\x6e\xb9\x41\xd2\x88\xe7\x06\x9c\xae\ +\xbd\x1e\x38\xc9\xf1\x32\xe0\x73\x84\x97\x4b\x6f\x2c\xac\x06\xde\ +\x0d\x6d\xed\x2a\xb3\xff\x7b\xb4\x8a\xfd\xf1\xcc\xa2\x80\x5d\x04\ +\x39\x06\x21\xc5\x09\x8e\x92\x24\xe3\xa7\xd2\x7b\xb9\xd8\x5e\xe9\ +\x3d\x64\xeb\xb7\x32\x55\x7a\xa3\x4c\x03\x8e\x41\xe8\x8e\x52\x00\ +\x7c\x0f\xfc\x1f\xc2\xfc\xc3\xff\x0d\x99\x3a\x54\xb6\x95\x38\xe9\ +\x80\x67\x55\xa4\x4c\xd2\x1c\x7d\xa6\x64\x53\x32\xe5\x5a\x28\x9d\ +\xc8\xf4\x7f\x40\x3f\x0a\xe8\x87\xf2\xbf\x32\x57\x4d\x00\x5e\xc1\ +\x69\x29\x0c\x5d\xc8\x23\x9a\xad\xf7\x86\xb6\xd6\x01\x5f\x83\xd3\ +\x22\x2e\x53\xa5\xec\x68\xf6\x55\x9a\xa3\xef\xd4\x20\xb2\x09\xa5\ +\x11\x16\x72\x55\xa8\x68\xfa\x37\x92\x25\x27\x03\x27\x03\xc9\x38\ +\x5d\xd8\xff\xa9\x70\xdd\x0b\x9a\xa3\x33\x00\x24\x4b\x5e\x04\x26\ +\x87\xee\xd2\x05\xa7\x36\xa7\x31\xd1\x66\x68\x71\x71\x71\xa2\x8d\ +\x07\x34\xb1\x2c\x26\x93\xc0\x12\xa1\x0f\xbd\x77\x0e\x7a\x9e\x93\ +\x34\xce\x0a\xfd\x54\x77\xbf\x87\x80\x87\x2a\xed\xcf\xd6\xbf\x52\ +\xc5\xcc\x4b\x9d\xae\x85\xc0\xbd\xa1\x9f\xf2\xc7\x66\xeb\x3c\x60\ +\x5e\xb5\xcf\xcb\xd6\x2d\x1c\x68\xb2\x8a\x89\x38\x11\x11\x32\xcb\ +\xb5\xfe\xd5\x34\xd9\x09\x94\x19\x86\x10\xba\x59\xa8\x94\x8b\xe3\ +\x72\x34\x34\xd6\xae\xbc\x92\x73\xf6\xb7\x02\x17\x57\x98\x54\x54\ +\x0b\x72\xa3\xb4\xc6\x4b\x72\x68\xf3\xfb\x0a\xab\xe6\x7c\x82\x93\ +\x04\x96\x8d\xa3\xcc\xc5\x2c\x2e\xb3\xb5\xbf\x9c\x92\x12\xcd\x63\ +\xa9\xac\x4e\x60\xe3\x36\xb2\x79\xf3\xe6\x85\x9d\x3b\x77\xb6\xee\ +\x60\x13\xb3\x62\x3a\x09\x34\x26\xac\xa6\x70\x0d\xce\x4c\x61\x80\ +\x5c\x8a\xca\xb5\xda\x55\x67\xbb\xe6\xe8\x8e\x72\x7b\x94\x5f\xd8\ +\xdf\xe9\xf4\x34\xfb\xc7\x84\x96\x55\x32\x11\x68\xff\x44\x25\x17\ +\x19\x07\x38\xf7\xd0\xfd\xcc\x0e\x7a\x52\x00\xc4\x03\x5d\xe5\x06\ +\x49\x0c\x7d\x41\x02\x67\xa2\xca\xfe\x58\x2b\x0a\xb2\xb3\xdc\x56\ +\x0c\xb0\x3a\x81\x8d\x9b\xcb\xe5\x3a\x2e\x3d\x3d\xdd\xd6\x15\x8f\ +\x30\xaf\xd7\xcb\xe4\xc9\x93\x09\x06\x83\x2b\x22\x1d\x4b\x2c\xb2\ +\x3e\x76\x63\x6a\x4a\xe8\x2d\x99\x72\x8a\x64\xc9\x15\x92\x29\xff\ +\x46\xca\xb4\xfe\x0a\x37\xe8\x5d\x5a\x79\x66\x79\xcd\xef\xfd\x49\ +\x99\xad\x1e\x6c\xe7\x71\xcd\xd1\x87\x35\x47\x1f\x66\x35\x8f\x01\ +\x5b\x28\x66\x63\xe8\xdc\xb2\x05\xad\x2f\x93\x4c\x29\x6d\x8d\x94\ +\x29\x72\x62\xe9\x91\x60\x99\x61\x06\xca\x30\xb9\x49\x9a\x56\x17\ +\x42\xa8\x3e\x62\xc9\xec\xdf\x78\xe2\xb8\x5c\x66\x88\x2b\x34\xae\ +\x6f\x4c\xe9\x5d\x85\xcf\xab\xbe\x83\x31\xb1\xc3\xe5\x72\x1d\x37\ +\x74\xe8\x50\x4b\x02\x1b\x80\xbc\xbc\x3c\x0a\x0a\x0a\xac\x55\x3e\ +\x0c\x2c\x09\x34\xa6\xe6\x2e\x44\x78\x05\xf0\x23\x9c\x1e\xda\x97\ +\x0f\xcc\xd4\x6c\x7d\xbc\x36\x37\xd6\x1c\x7d\x1b\xe5\x85\xd0\xe6\ +\x28\x52\xd8\x22\x59\xb2\x40\x32\x65\x31\x3d\xd9\x00\xbc\x80\x8b\ +\x9e\x00\xac\xe2\x09\xe0\xe3\xd0\xb9\x83\x11\xbe\x96\x2c\xf9\x5e\ +\xb2\x64\x0b\x2e\x9e\xdf\x7f\x53\xfe\xcb\xfe\xe2\xe9\xe7\xe2\x61\ +\x8f\x64\x89\xca\x0c\x69\x71\xc0\x40\x5c\xfc\x89\x92\xa2\xac\xc2\ +\x5f\xc9\x67\x7d\x68\x5c\x62\xbb\xd0\x19\xf7\x85\x66\xa9\x1b\x13\ +\xb3\x44\xa4\x4f\x20\x10\x68\x69\x45\xa2\x4d\xac\xb3\x24\xd0\x98\ +\x9a\x53\x60\x0b\xb0\x0c\xe1\xad\xd0\xec\xde\xfe\x9a\xa3\xb7\xd6\ +\xc9\xdd\x0b\x39\x1f\xb8\x15\xa7\xec\x4c\x32\xf0\xeb\x50\x89\x98\ +\x24\xe0\x35\x5c\x7c\x03\xa5\x2d\x76\x27\x03\xf7\x41\x69\x45\xc9\ +\x5e\x38\xe5\x4c\x4a\x8b\x87\xeb\x1c\x5d\x87\x70\x19\xb0\x0a\x6a\ +\x56\x10\x5a\x67\xe9\x17\x08\x23\xa1\xb4\xb5\xaf\x3d\xce\x8c\xe5\ +\x5c\x84\xc9\xac\xe6\xa6\xda\xbd\xc9\xe8\xe1\xf7\xfb\x9f\xf6\xfb\ +\xfd\x77\x47\x3a\x0e\x13\x11\x23\xe3\xe3\xe3\x03\xbd\x7b\xf7\x8e\ +\x74\x1c\xc6\x84\x95\xa8\x1e\xa8\xce\xb1\x31\x26\x12\x44\x44\x98\ +\x4a\x7b\x9c\x3a\x81\xdb\xd8\xc2\xc6\x03\xd5\x84\x94\x19\xe2\x22\ +\x8f\x4e\xb8\x49\xa1\x90\x0d\x7a\x97\x6e\xae\xb3\x38\xa6\x48\x12\ +\x42\x37\x3c\x6c\x67\x16\x1b\xb4\x91\xfd\x63\xe1\xf7\xfb\x5f\x07\ +\x36\xfa\x7c\xbe\x0b\x23\x1d\x8b\xa9\x5f\x22\xf2\x64\x46\x46\xc6\ +\x39\x0f\x3c\xf0\xc0\xc1\x97\x1e\x35\x61\x15\x08\x04\xf8\xf8\xe3\ +\x8f\x59\xb4\x68\xd1\xcd\x0b\x17\x2e\xcc\x8e\x74\x3c\xb1\xc6\x26\ +\x86\x18\xd3\xc0\x84\x92\xad\x5f\x42\x3f\xd5\x9f\x3b\x5d\x83\xc0\ +\xcf\xa1\x9f\xba\x8d\x63\x8e\xee\xc6\x29\x95\x04\x77\xd4\xf5\xdd\ +\x8d\x69\xb8\xbc\x5e\xef\xd8\xf4\xf4\x74\x4b\x00\x1b\x80\x92\x3a\ +\x81\x6e\xb7\xdb\xc6\x67\x86\x81\x25\x81\xc6\x18\x63\x4c\x88\x88\ +\xb4\x07\x3a\xdb\x78\x40\xd3\x18\x58\x12\x68\x8c\x31\x55\xb3\x3a\ +\x81\x8d\xd3\x28\xb7\xdb\x1d\x1c\x38\x70\xa0\x8d\x99\x6f\x00\x1a\ +\xd9\x28\x94\x7a\x67\x49\xa0\x31\xc6\x54\xc1\xea\x04\x36\x5a\x23\ +\x7b\xf7\xee\x1d\x88\x8f\x8f\xb7\x22\xd1\x0d\x80\xd5\x09\x0c\x2f\ +\x4b\x02\x8d\x31\xc6\x98\x90\xb8\xb8\xb8\xb1\xc3\x86\x0d\xb3\x04\ +\xb0\x01\xc9\xcb\xcb\x83\x92\xd2\x55\xa6\x4e\x59\x12\x68\x8c\x31\ +\xc6\x00\x22\x92\x24\x22\xfd\x6d\x3c\xa0\x69\x2c\x6c\xcc\x83\x31\ +\xc6\x54\xc1\xea\x04\x36\x4a\x47\xab\xaa\x6b\xf0\xe0\xc1\x91\x8e\ +\xc3\x98\x7a\x61\x49\xa0\x31\xc6\x54\xad\x1d\x4e\x01\x6e\xd3\x78\ +\x8c\xec\xd4\xa9\x53\x41\x72\x72\x72\xa4\xe3\x30\x21\x81\x40\x80\ +\x7b\xee\xb9\x87\x09\x13\x26\xf4\x8f\x74\x2c\xb1\xc8\x92\x40\x63\ +\x8c\x31\x06\xf0\x7a\xbd\xa3\x33\x32\x32\xe2\x23\x1d\x87\xd9\xcf\ +\xea\x04\x86\x97\x8d\x09\x34\xc6\x18\xd3\xe8\x89\x48\x9c\xcb\xe5\ +\x1a\x6e\xe3\x01\x4d\x63\x62\x49\xa0\x31\xc6\x54\xcd\xea\x04\x36\ +\x2e\xc3\x82\xc1\x60\xdc\x90\x21\x43\x22\x1d\x87\x29\xc3\xea\x04\ +\x86\x97\xad\x1d\x6c\x8c\x31\xa6\xd1\x13\x91\x9b\x5a\xb6\x6c\x79\ +\xc7\x6b\xaf\xbd\x16\x35\xe5\x61\x76\xef\xf6\xb0\x7d\xbb\x87\xae\ +\x5d\xf3\x23\x1d\x4a\xd8\x04\x83\x41\xc6\x8e\x1d\x4b\x30\x18\x3c\ +\x33\x3f\x3f\xff\xc5\x48\xc7\x13\x6b\x6c\x4c\xa0\x31\xc6\x98\x46\ +\xcf\xed\x76\x1f\x9f\x91\x91\x51\xab\xde\xb1\xc7\x1f\xef\xc8\xb4\ +\x69\xbd\xf8\xf6\xdb\xa6\x75\x15\x56\xb5\x5e\x79\xa5\x0d\x67\x9d\ +\x15\xfb\x2d\x97\x79\x79\x79\x14\x14\x14\x58\xab\x7c\x18\x58\x77\ +\xb0\x31\xc6\x98\x46\x4d\x44\xc4\xe3\xf1\x8c\x4c\x4b\x4b\x3b\xec\ +\x86\x91\x1d\x3b\xbc\x3c\xf1\x44\x47\x8a\x8b\x85\xf8\xf8\x20\xb7\ +\xdc\xf2\x43\x5d\x86\x68\x4c\x58\x58\x4b\xa0\x31\xc6\x54\xc1\xef\ +\xf7\x3f\xe3\xf7\xfb\xef\x8b\x74\x1c\xa6\x5e\x0c\x08\x04\x02\xcd\ +\x6b\x33\x29\xe4\xb5\xd7\x5a\x23\x02\x67\x9e\xb9\x89\xc5\x8b\x5b\ +\x91\x97\x67\x93\x59\x4d\xc3\x67\x2d\x81\xc6\x18\x53\xb5\x14\xa0\ +\x30\xd2\x41\x98\x7a\x31\x2a\x31\x31\x31\xd0\xbd\x7b\xf7\xc3\xfe\ +\x4c\x7c\xe5\x95\x36\x8c\x1c\xb9\x93\xb3\xcf\xfe\x85\x17\x5f\x6c\ +\xc7\xdb\x6f\xa7\x70\xda\x69\x5b\xca\x9d\x93\x9d\xdd\x83\xf6\xed\ +\x0b\x48\x4b\xdb\xcd\xbc\x79\x1d\xf8\xe1\x87\x26\x74\xec\x58\xc0\ +\xd5\x57\xff\xcc\x80\x01\x7b\xca\x9d\xbb\x64\x49\x0a\xcf\x3c\xd3\ +\x9e\x2d\x5b\xe2\xe9\xd7\x6f\x2f\x93\x26\xad\xe5\xe9\xa7\x53\xe9\ +\xd7\x6f\x2f\x7f\xfc\xe3\xc6\x6a\x63\x79\xf3\xcd\x56\xbc\xfc\x72\ +\x1b\xd6\xac\x49\xa4\x75\xeb\x42\x46\x8f\xde\xce\x39\xe7\x6c\xc4\ +\xe5\x8a\xbe\x39\x00\x25\x75\x02\x17\x2f\x5e\xdc\x2f\xd2\xb1\xc4\ +\x22\x6b\x09\x34\xc6\x18\xd3\xa8\x89\xc8\xa8\xb4\xb4\x34\x5c\xae\ +\xc3\xfb\x48\x5c\xbe\xbc\x29\x3f\xfc\x90\xc8\x84\x09\x5b\x48\x4d\ +\x75\x92\xbc\x97\x5f\x6e\x53\xe5\x79\x6f\xbc\xd1\x8a\x19\x33\x7a\ +\xd2\xb3\x67\x1e\x67\x9d\xf5\x0b\x9b\x36\xc5\x71\xcd\x35\xfd\xc8\ +\xcd\xdd\x9f\x7f\xbe\xf3\x4e\x0a\x53\xa7\xf6\xa6\xa0\xc0\xcd\xc5\ +\x17\xaf\x23\x29\x29\xc0\xf5\xd7\xf7\xe3\xa3\x8f\x5a\xf0\xf3\xcf\ +\x09\xd5\xc6\x32\x77\x6e\x17\x66\xce\xec\x41\x52\x52\x31\x57\x5d\ +\xf5\x33\x7d\xfa\xec\xe3\xf1\xc7\x3b\x91\x9d\xdd\xfd\xb0\xde\x5b\ +\xa4\x59\x9d\xc0\xf0\xb2\x96\x40\x63\x8c\x31\x8d\x9a\xc7\xe3\x19\ +\x33\x74\xe8\xd0\x5a\xb4\x02\xb6\xa5\x45\x8b\x22\x8e\x3e\x7a\x27\ +\x00\xa7\x9c\xb2\x85\x3b\xee\xe8\xc1\xcf\x3f\x27\xd0\xa5\x4b\xf9\ +\x99\xbb\x6b\xd6\x24\xf2\xcf\x7f\x7e\x4d\xd7\xae\x79\x00\xf4\xed\ +\xbb\x8f\x2b\xaf\xec\xcf\x7b\xef\xb5\xe4\xd4\x53\x9d\x96\xc3\x07\ +\x1f\xec\x4c\x9f\x3e\x7b\x79\xfa\xe9\xff\x01\xf0\xeb\x5f\x6f\xe1\ +\x83\x0f\x5a\x72\xe3\x8d\x7d\xaa\x8d\xe3\xfb\xef\x9b\xf0\xec\xb3\ +\x1d\xb8\xf8\xe2\xf5\x5c\x7a\xe9\x3a\x00\xc6\x8f\xdf\x46\xb7\x6e\ +\x79\xdc\x77\x5f\x57\xce\x3b\x6f\x43\x4c\xcf\x24\x36\x87\xce\x5a\ +\x02\x8d\x31\xa6\x6a\x67\x01\xd7\x46\x3a\x08\x13\x5e\x22\xd2\xb9\ +\xa8\xa8\xa8\xfd\xe1\x8e\x07\x2c\x2c\x74\xf1\xd6\x5b\xad\x18\x3f\ +\x7e\x1b\x1e\x8f\xd3\xdd\x3a\x66\xcc\x76\x12\x12\x82\xbc\xf2\x4a\ +\xe5\xd6\xc0\xee\xdd\xf3\x4a\x13\x40\x80\x41\x83\x76\x13\x17\x17\ +\x64\xd3\x26\xa7\x32\xcd\xce\x9d\x5e\xd6\xae\x4d\x60\xf8\xf0\xdc\ +\x72\xd7\x1d\x73\xcc\x0e\xe2\xe3\x83\xd5\xc6\xf2\xc9\x27\xc9\xa8\ +\xc2\xd0\xa1\xb9\xac\x59\x93\x58\xfa\xd3\xb7\xef\x5e\x00\x96\x2f\ +\x6f\x76\x58\xef\xd1\xc4\x2e\x6b\x09\x34\xc6\x98\x2a\xf8\x7c\xbe\ +\x1d\x91\x8e\xc1\xd4\x8b\x51\x1e\x8f\x27\xd8\xbf\x7f\xff\xc3\x6a\ +\x14\x59\xb2\xa4\x25\xbb\x77\xbb\x69\xd9\x32\xc0\xbb\xef\xb6\x2c\ +\xdd\xdf\xa3\x47\x1e\xaf\xbe\xda\x9a\x2b\xae\x58\x57\x6e\x2c\x5e\ +\xef\xde\xfb\xca\x5d\xef\xf5\x2a\x4d\x9b\x16\x53\x58\xe8\x3c\x7e\ +\xf3\x66\x2f\x00\xfd\xfb\xef\x2d\x77\x9e\x08\xb4\x6c\x59\x54\x6d\ +\x2c\xeb\xd7\x3b\x2b\xde\x5d\x77\x5d\xdf\x4a\xc7\x3c\x9e\x20\x5b\ +\xb6\x44\x4d\x09\xc4\x52\x5e\xaf\x97\xc9\x93\x27\x13\x0c\x06\x57\ +\x44\x3a\x96\x58\x64\x49\xa0\x31\xc6\x98\xc6\x6c\x64\xbf\x7e\xfd\ +\x02\x5e\xaf\xf7\xb0\x32\xa4\x92\xd6\xbe\x87\x1f\xee\x54\xe5\xf1\ +\xa5\x4b\x93\x4b\xbb\x89\x6b\xa2\x75\x6b\x27\xd1\x5b\xb9\xb2\x09\ +\x63\xc7\x6e\x2b\x77\x6c\xe7\x4e\x6f\xb5\xd7\xa6\xa4\x04\x88\x8b\ +\x0b\xb2\x78\xf1\x67\xb8\xdd\xd1\x37\x09\xe4\x40\xf2\xf2\xf2\xc0\ +\x56\xef\x09\x0b\xeb\x0e\x36\xc6\x18\xd3\x68\xc5\xc5\xc5\x8d\x1d\ +\x36\x6c\x58\xdc\xf6\xed\x5e\x0e\x75\x01\xad\x8d\x1b\xe3\xf9\xec\ +\xb3\x64\x7c\xbe\xb5\x2c\x5d\xfa\x71\xb9\x9f\x0f\x3f\xfc\x84\x94\ +\x94\xa2\x2a\xbb\x84\xab\x93\x92\x52\x44\x6a\x6a\x01\x9f\x7e\x9a\ +\x5c\x6e\xff\xd2\xa5\xc9\xe4\xe7\x57\xff\x91\x3d\x70\xe0\x1e\x0a\ +\x0a\x5c\x7c\xf8\x61\x8b\x43\x7b\x23\xa6\xd1\xb2\x96\x40\x63\x8c\ +\xa9\x82\xdf\xef\x7f\x06\xd8\xe2\xf3\xf9\x6c\x5c\x60\x8c\x12\x91\ +\x96\x40\xef\xb4\xb4\x34\x26\x4f\xee\x4b\x6e\xae\x87\x93\x4e\xda\ +\xca\x84\x09\x5b\xe9\xd8\xf1\xe0\x13\x28\x16\x2e\x6c\x0d\xc0\xb8\ +\x71\xdb\x2a\x1d\x73\xb9\x94\x13\x4f\xdc\xc6\xbf\xfe\xd5\x8e\x5d\ +\xbb\x3c\x24\x27\x07\x6a\x1c\xd7\xa4\x49\xeb\x98\x3e\xbd\x27\x97\ +\x5d\x36\x80\xb3\xce\xda\xc8\x97\x5f\x26\xb1\x64\x49\x0a\x49\x49\ +\xd5\xdf\xe3\xa8\xa3\x76\x32\x62\xc4\x2e\x72\x72\xba\x53\x58\x28\ +\x0c\x1f\x9e\x8b\xcb\xa5\xac\x5b\x97\xc0\x1b\x6f\xb4\xe2\x8f\x7f\ +\xdc\x48\xbb\x76\x56\xf5\xc8\xec\x67\x2d\x81\xc6\x18\x53\xb5\x14\ +\x20\xf9\xa0\x67\x99\x68\x76\x8c\x88\x30\x68\xd0\x20\x6e\xb9\x65\ +\x35\x63\xc6\x6c\xe7\xa5\x97\xda\xf0\xdb\xdf\x0e\xe1\xf2\xcb\x07\ +\xf0\x9f\xff\xb4\x65\xf7\xee\xaa\x2b\x93\xa8\xc2\xc2\x85\x6d\x18\ +\x34\x68\x37\x1d\x3a\x14\x54\x79\xce\xf8\xf1\xdb\x28\x2a\x12\xde\ +\x78\xa3\xf5\x21\x05\x35\x7e\xfc\x56\xa6\x4f\x5f\x4d\x7e\xbe\x9b\ +\xec\xec\x1e\xac\x5e\xdd\x84\x3b\xef\x5c\x49\x62\x62\x90\xe6\xcd\ +\xab\xef\x15\xcd\xc9\xf9\x9e\xe3\x8e\xdb\xc1\x2d\xb7\xf4\x62\xdc\ +\xb8\x61\x9c\x70\x42\x06\x17\x5f\x7c\x04\xdf\x7c\xd3\x8c\xb8\xb8\ +\xe8\xeb\x22\x2e\xa9\x13\x78\xca\x29\xa7\xf4\x8f\x74\x2c\xb1\x48\ +\xf4\x50\xdb\xbf\x8d\x31\xa6\x11\xf0\xfb\xfd\xaf\x03\x1b\x7d\x3e\ +\xdf\x85\x91\x8e\xc5\x84\x87\x88\xcc\xee\xd6\xad\xdb\x75\xcf\x3d\ +\xf7\x5c\x7c\xc9\xbe\x60\x10\x3e\xff\xbc\x39\xaf\xbd\xd6\x86\x25\ +\x4b\x5a\x12\x08\x08\x63\xc7\x6e\x67\xfa\xf4\xd5\x88\x44\x2e\xd6\ +\x9d\x3b\xbd\x4c\x98\x90\xce\x8d\x37\xfe\xc8\xc4\x89\x9b\x0f\x7a\ +\x7e\x51\x91\xb0\x61\x43\x02\xaa\xd0\xa6\x4d\x21\x4d\x9b\x46\xe7\ +\x90\xba\x82\x82\x02\xbe\xf9\xe6\x1b\x5e\x7f\xfd\xf5\x69\x0b\x16\ +\x2c\x98\x15\xe9\x78\x62\x8d\x75\x07\x1b\x63\x8c\x69\x94\xbc\x5e\ +\xef\x98\x8c\x8c\x8c\xf8\xb2\xfb\x5c\x2e\x18\x3e\x3c\x97\xe1\xc3\ +\x73\xb9\xe9\x26\x17\xef\xbe\x9b\xc2\xee\xdd\x9e\x7a\x4d\x00\x77\ +\xee\xf4\xf0\xfd\xf7\x4d\x19\x36\x6c\x17\x2e\x17\xe4\xe6\x7a\xb8\ +\xe3\x8e\xee\x34\x69\x52\xcc\x98\x31\xdb\x6b\x74\x0f\xaf\x57\xcb\ +\x95\xa2\x31\xa6\x2a\x96\x04\x1a\x63\x4c\xd5\xce\x02\xaa\x2f\xcc\ +\x66\xa2\x96\x88\x24\xb8\x5c\xae\xa1\xd5\xd5\x07\x4c\x4c\x0c\x72\ +\xd2\x49\x5b\x4b\xb7\xf3\xf2\xdc\xdc\x74\x53\x1f\x2e\xb8\x60\x7d\ +\xa5\x3a\x7e\x75\x69\xf7\x6e\x0f\xd7\x5e\xdb\x17\xb7\x5b\x49\x4a\ +\x2a\x66\xc7\x0e\x2f\xad\x5a\x15\x71\xc7\x1d\xdf\xd3\xa2\x45\xcd\ +\xc7\x16\xc6\x18\xeb\xb6\x0c\x03\xeb\x0e\x36\xc6\x18\xd3\xe8\x88\ +\xc8\xb1\xc0\xbb\x2f\xbf\xfc\x32\x6d\xda\xd4\x6c\x06\xef\xce\x9d\ +\x5e\x66\xcf\xee\xc6\x3b\xef\xa4\x30\x6e\xdc\x36\xae\xb9\x66\x4d\ +\x69\x49\x97\xba\xb6\x67\x8f\x9b\x55\xab\x9a\x90\x97\xe7\xa6\x4d\ +\x9b\x42\x3a\x77\xce\x3f\x68\xb1\xe8\x58\x54\x5c\x5c\xcc\x09\x27\ +\x9c\x40\x30\x18\x9c\x98\x9f\x9f\xff\xef\x48\xc7\x13\x6b\x6c\x62\ +\x88\x31\xc6\x98\xc6\x68\x54\x9b\x36\x6d\x0a\x6a\x9a\x00\x02\xb4\ +\x68\x51\xc4\xec\xd9\xdf\x73\xf7\xdd\xdf\xf1\xf5\xd7\xcd\xf8\xc3\ +\x1f\x86\xb0\x74\x69\x78\xe6\x0e\x35\x6b\x56\x4c\x5a\xda\x6e\x8e\ +\x3a\x6a\x27\xbd\x7a\xed\x6b\x94\x09\x60\x89\xbc\xbc\x3c\x0a\x0a\ +\x0a\xa2\x73\x50\x63\x03\x67\x49\xa0\x31\xc6\x98\x46\xc7\xed\x76\ +\x1f\x97\x91\x91\x71\x58\x05\xa2\x47\x8e\xdc\xc9\x73\xcf\x7d\xcd\ +\xb1\xc7\xee\xe0\xc6\x1b\xfb\xf2\xd6\x5b\xad\xea\x3a\x3c\x63\xea\ +\x85\x8d\x09\x34\xc6\x98\x2a\x58\x9d\xc0\xd8\x25\x22\x2e\xb7\xdb\ +\x7d\x4c\x5a\x5a\xda\x61\x4f\xf7\x48\x48\x08\x72\xeb\xad\xab\x69\ +\xde\x3c\xc0\xf4\xe9\xbd\xd8\xbb\xd7\xcd\xe9\xa7\x1f\x7c\xd6\xae\ +\x31\x0d\x89\x25\x81\xc6\x18\x53\xb5\x14\xc0\x2a\xeb\xc6\xa6\xc1\ +\xc5\xc5\xc5\x4d\xaa\x9b\x14\x52\x13\x22\x70\xfd\xf5\x6b\x68\xd1\ +\x22\x40\x6a\x6a\xd5\xb5\x02\x4d\xed\x94\xd4\x09\x5c\xbc\x78\xf1\ +\x00\xe0\xa5\x48\xc7\x13\x6b\x2c\x09\x34\xc6\x18\xd3\xd8\x8c\x6a\ +\xd6\xac\x59\x51\xd7\xae\x5d\xab\x5f\x8c\xb7\x86\x2e\xba\x68\x7d\ +\xe9\xeb\xed\xdb\xbd\xb4\x6c\x59\x14\xd1\x9a\x82\xb1\x26\x31\x31\ +\x11\xb7\xdb\x6d\xc3\xd7\xc2\xc0\x92\x40\x63\x8c\x89\x02\x32\x45\ +\x46\xe0\x22\x3d\xb4\x99\xaf\x39\xfa\x54\xb9\xe3\x59\x72\x21\x90\ +\x80\x90\xa7\xd9\xfa\x74\x7d\xc7\x57\xd7\x24\x4b\xde\x07\x7a\x03\ +\xbb\x34\x47\xfb\xd6\xe5\xbd\x5d\x2e\xd7\xa8\xa1\x43\x87\xd6\x79\ +\x52\x11\x0c\x0a\x3e\xdf\x00\x46\x8f\xde\xce\x15\x57\xac\xad\xeb\ +\xdb\x1b\x53\xe7\x2c\x09\x34\xc6\x98\xaa\x35\xac\x3a\x81\x6e\x7e\ +\x83\x32\xb5\x64\x53\x32\x65\x9b\xce\xd6\x97\x4b\x8f\x0b\xf7\xa0\ +\xa4\xa0\x6c\x01\xa2\x3e\x09\x04\xda\x00\xed\x50\xe2\x0f\x7a\xe6\ +\x21\x72\xb9\x5c\xa3\x87\x0e\x1d\x5a\xf5\x7a\x70\xb5\xba\xaf\x72\ +\xde\x79\x1b\x98\x35\xab\x07\xe9\xe9\xb9\x8c\x18\xb1\xab\xae\x1f\ +\xd1\xe8\x58\x19\xbb\xf0\xb2\x24\xd0\x18\x63\xaa\xe0\xf3\xf9\x76\ +\x44\x3a\x86\x6a\x09\xd9\x32\x43\x16\xea\x74\x6d\x38\x89\x6a\x14\ +\x10\x91\x1e\x40\xeb\xda\x8e\x07\x3c\x90\x53\x4f\xdd\xc2\xc7\x1f\ +\x27\x73\xdb\x6d\x3d\xf9\xdb\xdf\x96\xd1\xaa\x55\x78\xea\x08\x36\ +\x16\x1e\x8f\x87\xc9\x93\x27\x13\x0c\x06\x57\x44\x3a\x96\x58\x64\ +\x49\xa0\x31\xc6\x44\xa7\x23\x28\xe0\x1c\xe0\x6f\x07\x3b\x51\x6e\ +\x96\x23\x08\x72\x06\xd0\x13\x28\x02\x56\xe1\xe6\x19\xbd\x43\x4b\ +\xfb\x2c\x65\x9a\x74\xa5\x98\x8b\x42\x9b\x1f\xa0\xac\x04\xce\x46\ +\x48\x23\xc8\x0c\x84\x38\x84\x33\x00\x08\xf2\x3a\x42\x1e\xc2\x59\ +\x40\x53\x94\x57\x74\xb6\xbe\x21\x33\x24\x81\x7c\xce\x07\x8e\x46\ +\xd9\x82\xf0\x88\xe6\xe8\xaa\xd2\x67\x64\xca\x40\x84\x93\x50\xfa\ +\x22\x34\x0f\xc5\xb2\x1e\x17\x6f\xe8\x2c\x5d\x52\xd3\x37\x1e\xea\ +\x1a\x9f\x00\xf4\x40\xd8\x43\x90\x6f\x28\xe4\x09\xbd\x57\x6b\xb2\ +\x4e\xda\x28\xaf\xd7\x5b\xdc\xb7\x6f\xdf\x3a\x6f\x09\x2c\x91\x99\ +\xf9\x23\xe7\x9f\x3f\x88\xdb\x6e\xeb\xc9\x7d\xf7\x7d\x8b\xcb\x46\ +\xb3\xd5\x4a\x5e\x5e\x1e\x80\xd5\x09\x0c\x03\x4b\x02\x8d\x31\x26\ +\xfa\xac\x04\xfa\xa0\xdc\x2e\x33\xe4\x9f\x3a\x5d\x0f\x38\x8b\x59\ +\xa6\xca\x0c\x94\x9b\x81\xf2\x49\x4f\x31\xb7\xc8\x54\xf1\x69\xb6\ +\x3a\x49\x64\x80\xae\x08\xd3\x43\x47\x5f\x44\x38\x12\xe8\x04\x80\ +\x87\x47\x50\xba\xa0\xa1\xe3\x2e\x86\x03\xa3\x81\x44\xe7\x21\xfc\ +\x49\xa6\xca\xe5\xc0\xef\x80\x13\x43\xfb\x00\xae\x90\x69\x32\xa0\ +\x4c\xb2\x79\x29\x70\x1d\x15\x27\x4d\x04\x99\x22\x59\xf2\xa8\xe6\ +\xe8\xa4\x83\xbd\x71\xc9\x92\xfb\x70\x71\x75\xe9\x13\x34\xf4\x2a\ +\x9e\xeb\x64\xaa\x9c\xa2\xd9\xba\xf2\x20\xb7\x18\x79\xc4\x11\x47\ +\x04\xdd\x6e\x77\xd8\x92\xc0\xa6\x4d\x8b\x99\x39\x73\x15\x97\x5f\ +\x3e\x80\x79\xf3\x52\xb9\xf0\xc2\x0d\xe1\x7a\x54\x63\x62\xfd\xc2\ +\x61\x60\xdf\x4f\x8c\x31\xa6\x0a\x7e\xbf\xff\x19\xbf\xdf\x7f\x5f\ +\xa4\xe3\xa8\x92\x70\x37\xb0\x0b\xe8\x46\x1e\x07\x4c\x9c\x24\x53\ +\xc6\xa3\xdc\x8a\x93\x00\x6e\x43\xb9\x05\xb8\x1f\xc8\xc7\x69\xc1\ +\x7b\x44\xb2\xa4\x57\x15\x97\xfe\x16\xe8\x00\xbc\x84\xf0\x1c\x01\ +\xf6\x56\x38\x3e\x01\xe5\x43\x84\x07\x29\x19\x37\xa9\x3c\x8a\x32\ +\x0a\x61\x2e\xf0\x51\xe8\xbc\x66\x04\xb9\xa2\xf4\x2a\x17\x3f\x86\ +\x62\x18\x0f\xa4\xa3\xfc\x01\xf8\x3a\x74\xf4\x72\xc9\x94\xa3\xab\ +\x7d\xdb\x53\xe5\x02\xe0\x1a\x40\x50\x16\xa1\x4c\x40\xb8\x36\xf4\ +\x7e\x7a\xa1\x3c\x21\x52\xfd\xbc\x5c\xaf\xd7\x3b\x36\x3d\x3d\xbd\ +\x4e\x66\x05\x57\x67\xc0\x80\x3d\x4c\x9a\xb4\x8e\xc7\x1e\xeb\xc4\ +\xd7\x5f\x27\x85\xfb\x71\xc6\x1c\x16\x4b\x02\x8d\x31\xa6\x6a\x29\ +\x40\x78\xd6\x04\xab\xbd\x6d\xc0\x5d\x00\x08\xd3\x64\x86\x34\xab\ +\xf2\x2c\xe1\xb2\xd2\xd7\xfa\xff\xd9\x3b\xef\xf0\xa8\xaa\xad\x0f\ +\xbf\x6b\x32\x09\x10\x8a\xa0\x08\x41\x41\x9a\x20\x22\x88\x80\xbd\ +\x62\xd7\x6b\x47\x2c\x28\x28\xea\xb5\x60\xef\x3a\xf6\xca\x60\xef\ +\x46\xc4\x8a\xa0\xa8\x28\x5c\xaf\xd7\x4f\xbd\x82\x08\xe8\x45\x25\ +\x40\xa8\x52\xa5\xd7\x00\xa1\x27\x99\x4c\xd6\xf7\xc7\x3e\x93\x39\ +\x99\xcc\xa4\x31\x93\xba\xdf\xe7\x99\x27\x33\xfb\xec\x36\x69\xb3\ +\xce\xda\x6b\xfd\x16\x77\xeb\x50\x7d\x46\xfd\x7a\x07\xf0\x96\xd3\ +\xda\x00\xb8\x32\xca\xc8\x20\xd0\x59\xfd\x7a\x81\x0e\xd1\xfe\xfa\ +\x9c\xfe\x11\x71\x7d\xaa\x0e\xd5\xd3\x74\x88\xde\x0a\xac\x70\xad\ +\xe7\xd3\x21\x7a\x3b\x05\xdc\x59\xd8\x56\x40\xe7\xc2\x2d\x0c\xd1\ +\xd7\x69\xc0\x50\x60\x23\x42\x2b\x04\x41\x98\xec\x9a\xb7\x77\x89\ +\xef\x5a\x0b\x0d\xde\x7c\xe0\x0e\x1a\xf0\x3f\xea\x31\x02\xf8\xd1\ +\x69\x3f\x8e\x07\xe8\x1a\x6b\xb8\x88\xec\x1b\x08\x04\xda\x27\x2a\ +\x1e\x30\x92\x01\x03\xd6\x70\xee\xb9\x1b\xd9\xb6\xcd\x1e\xba\x55\ +\x94\x90\x4e\xe0\xb9\xe7\x9e\x1b\xf3\xe7\x6a\xa9\x38\xf6\x20\x7b\ +\x4c\x64\x00\x00\x20\x00\x49\x44\x41\x54\x37\xd3\x62\xb1\x58\x6a\ +\x22\xf9\xbc\x8a\x97\xdb\x80\x96\xe4\x70\x57\xb1\x23\x56\xc3\xc1\ +\x85\xcf\xbc\x8c\x2f\x7c\x2e\x4c\x42\xb9\xc7\x79\x1e\xed\xc3\x75\ +\x8a\xfa\x75\x69\xcc\xb5\x95\x29\xae\x57\xcb\x80\x76\x00\x04\x9d\ +\x76\x2f\xcb\x0b\xf3\xaa\x3d\x14\xba\xc1\xc4\x27\x97\x01\xaf\x02\ +\x69\x85\x87\x7b\xee\x43\x3e\x0f\xfb\xc5\x5c\xd3\xf4\x3d\xd8\x79\ +\x9f\x5e\x84\x39\xe4\x44\xe9\x23\x74\x06\xe6\xc6\x98\xe1\x78\x8f\ +\xc7\xa3\xdd\xba\x75\xab\x14\x15\x3f\x11\xf0\xf9\xfe\x2e\xd7\x98\ +\x35\x6b\xea\x11\x08\x18\xff\xcc\x7e\xfb\xe5\x90\x9c\x6c\x4f\x41\ +\x1d\x9d\xc0\x84\x1d\xdf\xd7\x65\xac\x11\x68\xb1\x58\x2c\x35\x10\ +\x7d\x41\x77\xca\x83\xf2\x34\xc2\x9b\xc0\xbd\x28\xd1\x8e\x38\xc3\ +\x89\x12\x05\xec\x05\x84\x54\x8d\xc3\x1e\x4e\x65\x57\xf1\xc9\xf9\ +\xb3\xc4\xc5\x3d\xac\x76\xbd\x0a\x9b\x62\xca\xaa\x58\x43\xe4\x7e\ +\x49\x23\x89\x4f\x80\x64\x60\x1b\xf0\x22\x30\x07\xe1\x48\x94\x07\ +\x9d\xf1\x25\x1b\x67\xc2\x6e\xa0\x29\xa6\x92\xcb\xd8\xa8\x7d\x94\ +\x4d\x25\xcc\x70\x7c\x87\x0e\x1d\xf2\x1a\x34\x68\x10\x77\xd9\x99\ +\xd2\x58\xbb\xb6\x1e\xad\x5a\x95\x5e\x55\xe4\xee\xbb\x0f\x62\xd9\ +\x32\x13\x6a\x39\x7a\xf4\x2c\xda\xb5\x2b\x4b\xae\x8b\xc5\x52\x31\ +\xac\x11\x68\xb1\x58\x2c\xd1\xa9\x5e\x3a\x81\xd1\xd8\xc2\xbb\x34\ +\xe3\x1e\x84\xf6\x31\x7a\xcc\x21\x74\xc4\xaa\x9c\x03\xcc\x73\x9e\ +\x9f\x51\xd8\x43\xa2\x7a\xcd\xe2\xff\xbe\x93\xe8\x0a\x85\x86\xea\ +\x18\xf5\xeb\xd3\x00\xf2\xa0\x9c\x5d\x8a\xe9\x17\x46\x98\x83\xd2\ +\x0a\x48\xc1\xc3\xb0\xc8\x8c\x62\x79\x48\x8e\x51\xbf\xfe\x2f\xc6\ +\x68\x92\x93\x93\x4f\x39\xe2\x88\x23\x2a\xdd\x00\x5c\xbe\xbc\x3e\ +\xfd\xfb\xf7\x60\xd8\xb0\x79\x74\xef\xbe\xbd\xb2\x97\xaf\xd1\x58\ +\x9d\xc0\xc4\x62\x8d\x40\x8b\xc5\x62\x89\x42\xb5\xd7\x09\x04\x74\ +\x98\x06\xc4\x27\x8f\x02\x23\xa3\x76\x10\x86\x3a\xc9\x17\xf5\x81\ +\xe7\xe5\x21\x39\x9d\x02\xf6\x41\x0a\x2b\x8f\xac\xa2\x80\xe1\x95\ +\xb4\xdd\x65\xae\x7d\x5d\x28\x3e\x59\x06\x1c\x8c\xd0\xaf\x1c\x73\ +\x3c\x09\x9c\x0a\x78\x28\x60\xb4\x3c\x24\x63\x51\xe6\x00\xed\x50\ +\x4e\x45\xe8\x42\x28\x63\x39\x02\x11\x69\x28\x22\xdd\x7b\xf4\xe8\ +\x51\xe1\x37\x50\x51\xda\xb6\xcd\xa1\x47\x8f\xed\x7c\xfc\x71\x2b\ +\x5e\x7c\x31\xbe\x46\xe0\xaa\x55\xf5\x59\xb2\xa4\x01\x5b\xb6\x24\ +\x93\x96\x96\x47\xa7\x4e\x3b\x8b\x69\x13\x2e\x5c\xd8\x90\x1d\x3b\ +\xcc\x69\x6a\xaf\x5e\xdb\xd8\xb0\x21\x85\x59\xb3\x1a\xa3\x6a\x5e\ +\x47\xd3\x32\x5c\xba\xb4\x01\xf3\xe7\x37\xa2\x55\xab\x5c\xba\x75\ +\xdb\xc1\xd6\xad\x5e\x56\xae\xac\xef\xbc\x9f\xdd\x85\x63\x66\xcc\ +\x68\x82\x2a\x34\x68\x10\xe4\xe0\x83\xc3\xf9\x43\xa1\xf6\x86\x0d\ +\x83\x1c\x74\x50\xd1\xbc\xa2\xec\xec\x64\x16\x2e\x4c\x65\xed\xda\ +\x7a\x34\x6d\x1a\xa0\x53\xa7\x5d\xc5\x6a\x2f\x2f\x5c\x98\xca\x8e\ +\x1d\x5e\xf2\xf3\x53\x79\xe0\x81\xfb\x51\xcd\x9f\x07\x20\xc2\x61\ +\x18\x6f\x30\xc0\x2f\xaa\xa8\x08\x4d\x81\x50\xa0\xe7\x72\x60\x15\ +\x70\x38\xd0\x03\x18\xa7\xca\xba\xf2\x7e\x5f\xeb\x0a\xd6\x08\xb4\ +\x58\x2c\x96\x9a\x4c\x7d\x3e\x23\x87\xfb\x81\x43\x23\x2f\xe9\x10\ +\xfd\x4b\x1e\x92\x8b\x51\x86\x01\xad\x51\x4e\x77\x79\xdd\x66\x03\ +\x57\xeb\x50\xad\x94\xb2\x16\xea\xd7\xa5\xf2\xa0\xbc\x8c\x70\x37\ +\xca\xde\xc0\x53\x40\x16\xf0\xb4\xf3\xbc\xf4\x39\x86\xe8\xaf\xf2\ +\xa0\x0c\x44\x78\x09\x13\x57\x18\xce\x8c\x36\xef\x2b\x56\x2c\x20\ +\xc0\xd1\xaa\x9a\x54\x15\x46\x20\xc0\xd5\x57\xaf\xe1\xae\xbb\x0e\ +\x62\xc9\x92\x06\x74\xec\xb8\xe7\x47\xbc\xdb\xb7\x27\xf1\xf2\xcb\ +\xed\xf8\xfe\xfb\xe6\xb8\x9d\x65\x29\x29\x05\x5c\x7d\xf5\x1a\xae\ +\xbd\x76\x75\x61\xfd\xe2\xe7\x9f\x6f\xc7\x9c\x39\x26\x77\xe8\xa1\ +\x87\x96\xf2\xfc\xf3\xed\xc9\xcf\x37\x17\x1b\x37\xce\xe7\xb5\xd7\ +\xfe\xa2\x6b\x57\x63\xa8\xa9\xc2\xeb\xaf\xb7\xe5\xb3\xcf\xd2\x0a\ +\xe7\xec\xd0\x61\x37\xc7\x1c\x93\xcd\xa8\x51\xad\x00\x78\xf4\xd1\ +\xa5\x9c\x73\xce\x46\x00\x06\x0f\x36\x61\xa7\x9d\x3a\xed\xe2\x93\ +\x4f\x66\x17\x8e\x09\xb5\x1f\x72\xc8\x0e\xde\x7f\x3f\xfc\x63\xf9\ +\xec\xb3\x34\xde\x7d\xb7\x35\xbb\x77\x87\x43\xfc\x3c\x1e\xa5\x7f\ +\xff\x75\xdc\x72\xcb\x4a\x3c\x1e\xf3\x66\x5e\x79\xa5\x2d\x33\x66\ +\x34\x71\x7a\x24\x01\x3b\x42\x3a\x81\xaf\x02\x27\x39\xcf\xeb\x03\ +\xb9\x40\x4f\x60\x82\xd3\xf6\x3a\xd0\x1d\x23\x61\x04\xc6\xfb\x6d\ +\x8d\xc0\x18\x58\x23\xd0\x62\xb1\x58\x6a\x02\x49\xbc\x47\x3e\xff\ +\x05\x20\x8f\x39\xa1\x66\x7d\x5c\x0b\xe4\x11\x39\x9f\xa0\x73\x24\ +\xac\x14\xd1\x0c\xd4\x21\xfa\x9d\xdc\x27\x5d\xf0\x70\x2c\x1e\x3a\ +\x22\x8e\x58\x74\x3d\x7e\xd5\xc7\x35\xdf\xd5\x35\x93\xd0\x07\xa7\ +\xb8\x32\x7e\x43\x08\xdf\xa3\xce\xf5\x20\x85\x02\xd0\x28\xf7\x23\ +\x3c\x07\x40\x43\x36\xcb\x03\xd2\x9a\x6c\x36\xb3\x77\xe1\x5c\x9b\ +\x0b\xbb\x0e\xd5\x7b\xe4\x21\x19\x43\x01\xbd\x9c\xb8\xc2\x5f\x51\ +\xf2\xa1\x30\x43\x38\xbc\x6e\x01\x57\xe1\x21\x15\x0f\x45\xdc\x54\ +\x3a\x54\x3f\x95\x27\xe5\x1b\x72\x38\x1a\xe8\x80\x92\x8c\xb0\x8e\ +\x20\x33\x49\x62\x9d\xf8\xe4\x38\x8c\x17\xa8\xb7\xf3\x35\x0d\x98\ +\xc9\x25\xd4\x6b\xba\xba\x69\x60\x67\xca\xce\xe4\xa6\x34\x45\xca\ +\x7c\x06\x1d\x1f\x8e\x3e\x3a\x9b\x4e\x9d\x76\x31\x6a\xd4\x7e\x3c\ +\xf6\xd8\x92\x3d\x9e\xef\xc5\x17\xdb\xf3\xc3\x0f\xfb\x00\xd0\xb4\ +\x69\x3e\xbd\x7b\x6f\x65\xd2\xa4\x66\xe4\xe5\x79\x18\x3e\xbc\x35\ +\x7b\xef\x1d\xe0\xa2\x8b\x36\x14\x1b\x37\x64\x48\x07\xda\xb6\xdd\ +\x0d\x08\xcb\x97\xd7\x67\xfb\x76\x2f\xc3\x86\xb5\xe1\xb5\xd7\xfe\ +\x02\x60\xfc\xf8\x7d\x0a\x0d\x40\x11\x38\xe6\x98\x6c\x16\x2c\x68\ +\x58\x68\x00\xee\x09\xdf\x7f\xdf\x9c\xd7\x5e\x6b\x0b\x40\xbb\x76\ +\xbb\x39\xe5\x94\xcd\xcc\x98\xd1\x84\x19\x33\x1a\x33\x6a\x54\x2b\ +\x9a\x35\x0b\x30\x60\xc0\xda\x3d\x5d\xe6\x66\x8c\x6d\x93\x85\xc9\ +\x22\xb7\x94\x80\x35\x02\x2d\x16\x8b\x25\x0a\xe9\xe9\xe9\x9f\x02\ +\x1b\x07\x0f\x1e\x7c\x47\x55\xef\x05\x40\x9f\xd6\xbf\x81\xa8\xa9\ +\xa6\xfa\x8c\x2e\xc7\x1c\x83\x45\x1f\xfb\x82\xee\x04\xfe\xeb\x3c\ +\xa2\xf7\x31\x1e\xc1\x89\x31\xaf\x3f\xab\xeb\x81\xf5\x51\xc6\xcd\ +\x76\xbf\x16\x9f\x8c\x66\x1f\x0e\x46\x19\x87\xf2\x05\x29\x4e\x1c\ +\x62\xa8\xff\x10\xfd\x1f\x61\x1d\xc1\x10\xc5\xd6\x8d\x22\x4b\x13\ +\xbe\xf6\xb8\xee\x00\x7e\x72\xad\x99\x4a\x12\xcf\x01\x83\x89\x14\ +\xc5\x36\x9c\x4c\x47\xc8\xee\x98\x4d\xbf\xff\xf6\xa3\x55\x6a\x2b\ +\x1e\xea\xf9\x10\x47\xec\x7b\x44\xac\x25\x12\xc2\x99\x67\x66\x31\ +\x62\xc4\x7e\xa8\x42\xc9\x6a\x86\x25\xb3\x7c\x79\xfd\x42\x03\xb0\ +\x79\xf3\x00\x5f\x7e\x39\x93\x06\x0d\x0a\x58\xb4\x28\x95\x81\x03\ +\xbb\x03\x30\x6c\x58\xeb\xa8\x46\x60\xff\xfe\x6b\xb9\xed\xb6\x15\ +\xe4\xe7\x7b\x38\xe7\x9c\x5e\x6c\xdf\x9e\xc4\x82\x05\x0d\x0b\xaf\ +\x7f\xfe\x79\xcb\xc2\xe7\x4f\x3d\xb5\x98\xd3\x4f\xdf\x44\x5e\x9e\ +\x87\x81\x03\xbb\xb3\x7c\x79\xfd\x98\x7b\x2a\xcb\xfb\x79\xe7\x1d\ +\xa3\x3d\x5e\xbf\x7e\x01\xef\xbc\x33\x9f\xa6\x4d\x03\x14\x14\xc0\ +\xf9\xe7\xf7\x24\x2b\x2b\x85\xf7\xdf\xdf\x9f\x2b\xae\x58\x1b\xa5\ +\xc2\x4a\xb9\xe2\x02\xbd\xc0\x55\xc0\x68\x55\x02\x22\x51\x13\xa6\ +\x2c\x0e\x56\x27\xd0\x62\xb1\x58\xa2\x53\x9d\x75\x02\xab\x2f\x41\ +\xae\xa1\x80\x97\x80\xde\x08\xdf\x93\xcb\x7a\x79\x50\xde\x93\x07\ +\xe5\x4c\x79\x52\xe2\xee\x78\x10\x9f\x1c\x8b\xf1\x62\xde\x4a\x71\ +\x03\x70\x05\x30\x15\x8a\x8a\x5d\xaf\xdd\xb5\x96\xdb\x7f\xbd\x9d\ +\x17\x67\xbd\x48\x4e\x30\x9a\xce\x4c\x62\x38\xfc\xf0\x6d\x6c\xdd\ +\xea\x65\xc9\x92\xd4\x3d\x9a\xc7\x3d\xfe\xf0\xc3\xb7\xd2\xa0\x81\ +\xc9\xe3\xe9\xd4\x69\x17\xcd\x9b\x1b\x47\x70\x76\x76\x32\x9b\x37\ +\x17\xb7\x7f\xce\x3e\x3b\x0b\x8f\xc7\x1c\x1b\xb7\x68\x11\xea\x1b\ +\xfe\xb1\xac\x58\x61\x42\x2a\x3d\x1e\xe5\x98\x63\xb2\x01\xd3\xf7\ +\xc8\x23\xb3\x4b\xdc\x93\xd7\x5b\xb2\xa1\xb6\x73\x67\x12\xeb\xd6\ +\x99\x9c\x1c\x11\xb8\xed\xb6\x2e\x0c\x1c\xd8\x9d\xab\xaf\xee\x5e\ +\x78\x34\xbc\x7b\x77\x12\xeb\xd7\x17\xcd\xdb\x69\xd2\x64\x37\xaf\ +\xbf\xfe\x0c\xe7\x9d\x77\xde\x21\x25\x2e\x10\x66\x96\x2a\x9f\xa8\ +\x1a\x0f\x72\xe8\xab\x25\x3a\xd6\x13\x68\xb1\x58\x2c\x96\xb8\xa1\ +\xcf\xeb\x22\x60\x08\x30\x44\xee\x97\x4e\x78\xb8\x04\xe1\x52\xe0\ +\x3a\x72\xd9\x2c\x0f\xca\x58\x84\x2f\xa8\xcf\x84\x88\xe3\xe8\x72\ +\x21\x3e\xa9\x87\x89\x25\xbc\x97\xb0\x43\x63\x03\x30\x0c\xf8\x03\ +\xf8\x53\xfd\xba\x1e\x40\x92\xe5\x28\x9a\x32\xf5\xb6\x67\x6f\x63\ +\x41\x60\x01\x3f\xae\xfa\x11\x45\x19\xb3\x74\x0c\x53\xd7\x4f\xe5\ +\xb1\x5e\x8f\x71\xe8\x3e\xc5\x42\x2a\xe3\x4e\xa7\x4e\x3b\x69\xdc\ +\x38\x9f\xe9\xd3\x9b\x70\xe0\x81\xc5\x95\x79\xca\x4a\x4e\x4e\xd8\ +\x7f\xd3\xb8\x71\xd1\x92\xba\x8d\x1a\x05\xc9\xca\x2a\xde\x2f\x84\ +\x7b\xdd\xa4\xa4\xe2\x86\x5b\x81\x93\x17\x2e\x02\x6e\x65\x3e\x6f\ +\x29\xd6\x42\xbe\xeb\x27\xb9\x7e\x7d\x4a\x89\x7b\xce\xcf\x97\x22\ +\x06\x6a\xfd\xfa\x05\xd4\xaf\x6f\x16\xde\xb6\xcd\x1b\x21\xa5\xa3\ +\x78\xbd\x5e\x3c\x1e\x4f\xc8\xd7\x78\x40\xc9\x3b\x29\x8c\x0d\xb4\ +\x94\x01\x6b\x04\x5a\x2c\x16\x8b\x25\x21\x94\x68\x10\xe6\xb0\x49\ +\x1e\x94\x71\x7b\x60\x10\x3e\x07\xb8\x8f\xea\x3f\x05\x6e\x57\xbf\ +\x16\xd7\x09\xcc\xe7\xb8\xbd\x02\x7b\xe5\x5d\xd9\xe3\xca\x14\x80\ +\xb3\xda\x9c\xc5\x90\x19\x43\xc8\xca\xc9\x62\xd5\xce\x55\xdc\xfe\ +\xdb\xed\x8c\x3c\x65\x24\xad\x1b\xb6\xae\xd8\x1b\x2d\x23\x1e\x0f\ +\xdc\x71\xc7\x0a\x3a\x74\xd8\xb3\xc4\x10\xb7\x76\x60\x46\x46\x93\ +\xc2\xe7\xd9\xd9\x5e\x96\x2f\x37\x9e\xbc\x7a\xf5\x0a\x48\x4b\x2b\ +\xae\x4b\x58\xfc\xa8\xb5\x28\x07\x1c\x90\xc3\xdc\xb9\x8d\x08\x06\ +\x85\x3f\xff\x6c\xc2\x89\x27\x6e\xa1\xa0\x40\xf8\xe3\x8f\xe8\x4e\ +\xf1\x06\x0d\x82\xec\xde\x9d\x54\xc4\xa8\x8b\xd6\x77\x9f\x7d\x02\ +\x34\x6e\x1c\x64\xfb\xf6\x24\x1a\x34\x08\x32\x66\x4c\x26\x0d\x1a\ +\x14\x35\x60\x73\x72\x3c\x85\xc6\x60\x6a\x6a\x71\x95\x22\x11\x3a\ +\x42\x4c\x39\xa4\x10\x56\x58\xb1\x1c\x58\x23\xd0\x62\xb1\x58\xa2\ +\x53\xfd\x75\x02\x6b\x10\xa5\x1a\x84\x3e\x19\x0b\x7c\x59\x16\x83\ +\x50\x7c\x72\x22\xa6\x86\x30\x98\x04\x80\xeb\xd4\xaf\xdf\xc4\xea\ +\xef\xf1\x78\x4e\xec\xd5\xab\x57\xa1\x5f\xeb\xd8\x96\xc7\xf2\xe9\ +\x29\x9f\xf2\x5c\xe6\x73\x8c\x5f\x3d\x9e\x9c\x60\x0e\x4f\x4d\x7f\ +\x8a\x77\x8e\x7f\x07\x8f\x24\x36\x4a\xea\xdc\x73\x37\x96\xb9\xef\ +\x23\x8f\x1c\x48\xbd\x7a\x45\x7f\x05\x2f\xbf\x7c\x1d\xa7\x9c\xb2\ +\x99\xce\x9d\x77\xb2\x70\x61\x43\x96\x2e\x6d\xc0\x7d\xf7\x75\xe6\ +\xd8\x63\xb3\x19\x3b\xb6\x45\x61\xa6\xf0\xb9\xe7\x6e\x2c\xd5\xe0\ +\x8b\x46\xdf\xbe\xeb\x99\x3b\xd7\x64\x12\xfb\x7c\x9d\x38\xe9\xa4\ +\x2d\xcc\x9f\xdf\x90\xb5\x6b\xa3\xcb\x2b\xb6\x69\x93\xc3\xc2\x85\ +\x0d\xc9\xca\x4a\x61\xc8\x90\xf6\xd4\xaf\x5f\xc0\xbf\xfe\xd5\x22\ +\x6a\xdf\xf3\xcf\xdf\xc0\xa8\x51\xad\xd8\xb6\xcd\xcb\xe3\x8f\x77\ +\xe4\xfc\xf3\x37\x90\x96\x96\xc7\xaa\x55\xf5\x99\x3c\xb9\x19\xcb\ +\x96\xd5\x2f\xcc\x24\x6e\xd3\xa6\xe8\x31\xfd\xaa\x55\xd7\x9f\x42\ +\xf8\x67\x6e\x89\x13\x5e\x11\x39\x09\x77\x69\xa1\xe2\x64\xa8\x6a\ +\xc9\xea\xf1\x35\x08\x11\xb9\x1b\xb8\xdf\x79\x79\xa5\xaa\x8e\x2f\ +\xa9\xbf\xc5\x62\xa9\x9b\xd4\x04\x9d\xc0\x9a\x4a\x09\x06\xe1\x3f\ +\x0b\x0d\xc2\x02\xbe\x20\x95\x9f\x23\x0d\x42\xf1\x49\x43\xe0\x43\ +\x28\x4c\xef\x1d\xa4\x7e\xfd\x4f\x49\xeb\x79\x3c\x9e\x93\x7a\xf6\ +\xec\x59\x24\x5e\xb0\x49\x4a\x13\x9e\x3e\xfc\x69\xb2\x72\xb2\xc8\ +\xdc\x94\xc9\xac\x4d\xb3\xf8\x74\xf1\xa7\x0c\xe8\x34\x20\x7e\x6f\ +\x34\x06\xaa\x90\x9f\xef\x21\x39\xb9\xe4\x7b\x8c\xc5\x8b\x8b\xc7\ +\x0e\x66\x65\x25\x93\x94\xa4\x3c\xf9\xe4\x12\xee\xbd\xf7\x20\x56\ +\xaf\xae\xc7\xe4\xc9\xcd\x98\x3c\xb9\x59\x61\x9f\x5e\xbd\xb6\x71\ +\xeb\xad\xc5\x13\xbc\xcb\xc2\xd9\x67\x67\x31\x63\x46\x13\xbe\xfd\ +\x76\x5f\x82\x41\x61\xc2\x84\xbd\x49\x4b\xcb\xe3\xdc\x73\x37\xf2\ +\xed\xb7\xfb\x02\x14\xca\xb8\x00\xf4\xef\xbf\x8e\x27\x9f\xec\x08\ +\xc0\x37\xdf\x18\xe3\xef\xd4\x53\x37\x33\x7e\xfc\xde\xc5\xe6\xbe\ +\xf1\xc6\x55\x2c\x59\xd2\x80\xa9\x53\x9b\x32\x69\x52\x33\x26\x4d\ +\x6a\x56\xe4\x7a\xe7\xce\xe1\xa3\xea\x8b\x2f\x5e\xcf\x57\x5f\xb5\ +\x60\xdb\xb6\x54\xee\xb8\xe3\x06\xf2\xf3\x3d\xa7\x61\x64\x8d\xb2\ +\x81\x2e\x15\x7a\x73\x96\x62\x78\x81\x01\xc0\x3f\x4b\xe8\xf3\x2c\ +\x94\x52\x42\xa8\x66\xd1\x10\x08\xa5\x3f\x55\xba\x72\xbc\xc5\x62\ +\xb1\x58\xc2\xc4\x34\x08\x3d\x31\x0d\xc2\xe7\x80\x0e\xce\xf0\x0f\ +\x4a\x33\x00\x45\xe4\x20\xa0\xe9\x61\x87\x1d\x56\xec\x9a\x47\x3c\ +\x3c\xd6\xeb\x31\x06\x4c\x18\xc0\xee\xe0\x6e\x86\xcd\x1f\xc6\xb1\ +\x69\xc7\xd2\xa1\x71\x87\xe2\x13\xc5\x91\xcb\x2f\xef\x41\xdf\xbe\ +\xeb\xb9\xec\xb2\xe2\xf2\x75\xfd\xfa\xad\x27\x3b\x3b\x76\x42\x6b\ +\xf7\xee\x3b\x00\x68\xdf\x7e\x37\x9f\x7d\x36\x8b\x6f\xbe\xd9\x97\ +\x25\x4b\x52\xd9\xb2\x25\x99\x96\x2d\x73\xe9\xde\x7d\x07\xa7\x9d\ +\x56\xf4\x44\xfc\xfc\xf3\x37\x70\xf4\xd1\xc5\xe5\x20\x2f\xba\x68\ +\x3d\x9b\x36\x15\x8d\xdf\xf3\x78\xe0\x91\x47\x96\x72\xfe\xf9\x1b\ +\x99\x37\xaf\x21\x2d\x5a\xe4\x71\xf8\xe1\xdb\x78\xe4\x91\x03\x0b\ +\xfb\xb4\x6e\x1d\x3e\x66\x3e\xfb\xec\x2c\x1a\x35\x0a\x32\x71\x62\ +\x33\x40\xe8\xd5\x6b\x2b\xff\xf8\x47\x16\xed\xdb\xef\x0f\x48\x61\ +\xf2\x09\x98\x04\x93\x57\x5f\x5d\xc0\xd4\xa9\x4d\xc9\xc8\x68\xc2\ +\xea\xd5\xf5\xf0\x78\x94\xe6\xcd\x03\x74\xeb\xb6\x83\x23\x8f\x0c\ +\xef\xb1\x4d\x9b\x1c\x3e\xfa\x68\x2e\x5f\x7d\xd5\x9c\xaf\xbf\x9e\ +\x0c\x34\xff\x10\x4e\xb9\x03\xb8\x98\x50\xad\xea\xb0\x04\xcc\xdf\ +\x18\x21\x71\x08\xcb\x0d\x59\xca\x80\x00\xc3\x09\x1b\x81\x9b\x80\ +\x1d\x11\x7d\xde\x50\xd5\x97\x2a\x75\x57\x09\x44\x44\x1e\x25\x2c\ +\x4c\x7a\x8e\xaa\x7e\x57\x95\xfb\xb1\x58\x2c\x16\x4b\x71\x22\x3c\ +\x84\x3d\x80\x2c\x94\x1f\x10\xae\xc0\x7c\x76\xad\x00\xba\xab\x5f\ +\xb7\x95\x38\x8f\xc8\x3f\xeb\xd7\xaf\x9f\x3e\x61\xc2\x04\xaf\x27\ +\xc6\xf9\xe8\x57\x7f\x7f\xc5\x0b\x99\x2f\x00\x26\x5e\xf0\x89\xde\ +\x4f\xc4\xf3\xad\x14\xe3\xaa\xab\xba\x71\xe4\x91\x15\xf7\xd6\x25\ +\x9a\x77\xdf\x6d\xcd\x19\x67\x6c\xa2\x6d\xdb\xdd\x64\x67\x27\xf3\ +\xdb\x6f\x4d\x19\x32\xa4\x3d\xc1\xa0\xd0\xa4\x49\x3e\xe3\xc6\xcd\ +\x24\x35\x35\x58\xfa\x44\x65\xe0\xfd\xf7\xf7\xa7\x63\xc7\xdd\xf4\ +\xe9\xb3\x39\xea\xf5\x40\x20\xc0\x09\x27\x9c\x00\x70\x9e\xaa\x7e\ +\x1b\x97\x45\x5d\xc8\x83\x72\x22\xc2\x75\x14\xe0\xd3\xe7\x74\x4d\ +\xbc\xe7\xaf\xee\x44\xc6\x04\x3e\xa8\xaa\xef\x45\xeb\x28\x22\x67\ +\x00\xc7\x3a\x2f\xc7\xa9\xea\x4c\xa7\xbd\x1b\x14\x96\xfd\xf9\xc3\ +\x6d\x54\x39\x63\x4e\xc2\x58\xed\x59\xc0\x74\x60\xa4\xaa\x06\x5d\ +\x7d\x2e\x05\xba\x3a\x2f\x5f\xc3\x88\x95\x9e\x09\xac\x01\x46\xab\ +\xea\x02\x11\x69\x07\x5c\x81\x39\xb6\x9e\x03\xbc\xae\xaa\xbb\x5d\ +\x73\x3c\x04\xa4\x60\x34\xac\x3e\x02\xae\xc3\x08\x85\xae\x01\x46\ +\xa9\x6a\x11\x9d\xaa\x58\x88\xc8\x3e\xc0\xd5\x40\x27\x8c\xc7\x70\ +\x11\xf0\x85\xaa\x2e\x88\xe8\xd7\x0e\x18\x88\xb9\x1b\x6d\x88\x29\ +\x86\xbe\x00\x98\xa0\xaa\x19\xa5\xac\x71\x01\x46\xdd\x1c\xe0\x1d\ +\x55\xb5\x4a\xe6\x16\x4b\x35\xa4\xba\xe9\x04\xd6\x35\x62\x78\x08\ +\xff\x49\xf8\x18\xf8\xb9\x92\x0c\x40\x79\x58\x0e\xa3\x80\x0b\xb9\ +\x84\xfe\x69\x81\x34\xc9\x27\x9f\x14\x8a\x67\xad\x02\xf4\x6d\xdf\ +\x97\x51\x8b\x46\xb1\x66\xd7\x1a\xfe\xca\xfe\x2b\xee\xef\x25\x92\ +\x86\x0d\x0b\xd8\xb5\x2b\x9a\x9c\x61\xf5\xe0\xcb\x2f\xd3\xf8\xe0\ +\x83\xfd\xa9\x57\xaf\x80\xbc\x3c\x4f\x61\x9c\xa1\xc7\xa3\x3c\xfc\ +\xf0\xd2\xb8\x19\x80\x00\x6b\xd6\xd4\x67\xf8\xf0\xd6\xf4\xee\xbd\ +\x8d\xbb\xee\x5a\xbe\x47\x59\xd3\x15\x42\xf0\x00\x57\xe1\xa1\xaf\ +\x3c\x28\x7e\x76\xf1\x92\xbe\xae\xc5\x33\x6a\x6a\x29\xe5\x49\x0c\ +\xc9\x04\x46\x60\x8e\x52\xaf\x14\x91\xc3\x80\x20\xf0\x05\xc6\x38\ +\xcb\x02\xde\x05\x10\x91\x64\xe0\x73\xe0\xa2\x28\xf3\xdc\x22\x22\ +\x67\xab\x16\x66\x70\x5d\x8a\x71\xef\x02\x1c\x02\x45\xea\x48\xde\ +\x2a\x22\xd7\x60\xbc\x95\x69\xae\xf6\x73\x80\x13\x5d\xaf\x1f\x06\ +\x52\x31\x62\xa9\x03\x81\x63\x5c\xd7\x6e\x17\x91\x0b\x54\xb5\xc4\ +\xb4\x71\x11\x39\x1b\xf8\x04\xd8\x27\xe2\xd2\xc3\x22\x72\x6b\xc8\ +\x38\x16\x91\x9e\xc0\x14\x67\xbd\x48\xbe\x01\x2e\x28\x69\x1d\xe0\ +\x42\x60\x90\xf3\x7c\x1c\xb6\x9c\x8d\xc5\x52\x5d\xd9\x1b\x8a\x56\ +\xdf\xb0\x54\x0d\x21\x83\x50\x7c\x52\x1f\x78\xd4\x69\x9e\x16\xab\ +\xbf\xf8\xe4\x2e\xe0\x79\xc0\x4b\x47\x58\xc6\x32\x06\x4e\x18\xc8\ +\x6b\xc7\xbd\x46\x5a\x83\xb4\xe2\xfd\x11\xba\x36\xeb\xca\x9a\x5d\ +\x6b\x58\xb1\x63\x05\xbb\xf3\x77\xd3\xc0\x1b\xb5\x04\x71\x5c\x48\ +\x4d\x0d\xb2\x73\x67\xf5\x95\xe9\xbd\xf8\xe2\x75\x64\x64\xec\xc5\ +\x86\x0d\x29\x04\x83\xd0\xaa\x95\xa9\x49\x7c\xc5\x15\xeb\x68\xdd\ +\x3a\x31\xba\x8a\x19\x19\x4d\xb8\xea\xaa\x6e\x5c\x78\xe1\x46\x6e\ +\xb8\x61\x25\x4d\x9b\x9a\x93\xde\xfc\xfc\x7c\x5e\x7f\xfd\x75\x7e\ +\xfa\xe9\xa7\x6e\x40\xdc\x3d\x81\x2e\x1a\x21\x3c\x4b\x2a\xff\x14\ +\x9f\xdc\xa7\x7e\xfd\x2a\x81\x6b\x55\x1b\x22\x7f\x0b\xd3\x45\x24\ +\x27\xe2\xd1\x0b\x40\x55\xd7\x63\xe2\x07\x0b\x80\x03\x81\x97\x31\ +\xb1\x19\x07\x63\xe4\xbc\xaf\x52\x2d\x74\xa5\x3e\x46\xd8\x00\x1c\ +\x8d\x29\xf8\x1d\x3a\x82\x3d\xc2\x19\x1b\x8d\xf3\x81\x77\x08\xeb\ +\xfc\x34\x07\xfe\x0d\x04\x80\xa1\x40\xa8\x9e\xcc\x09\x22\x72\x54\ +\x94\xf1\x6d\x81\xd6\xc0\x7d\xce\x38\x80\x46\xce\xfb\x8a\x69\xf0\ +\x8a\x48\x1a\x61\x03\x70\x3d\x70\x23\x70\x1e\xc6\xf0\xad\x07\xbc\ +\xe9\xc4\x95\x00\x5c\x83\x31\x00\x77\x61\x8c\xd7\x9e\x18\xa3\x74\ +\x08\xb8\x4a\x29\x59\x2c\x16\x8b\x25\xde\xf4\x76\xbe\xe6\x03\xb3\ +\xa2\x75\x90\x07\xe4\x70\xe0\x05\x22\x9c\x1c\xcb\x77\x2c\xe7\xa9\ +\x8c\xd8\x25\x8a\xbb\x34\x35\xb9\x06\x05\x5a\xc0\x82\xad\x0b\x62\ +\xf6\x8b\x07\x0d\x1b\x06\xd9\xb9\xb3\xfa\x7a\x02\x6f\xba\x69\x15\ +\xc3\x87\xcf\xe5\x5f\xff\x9a\xc1\xb7\xdf\xce\x60\xf8\xf0\xb9\xdc\ +\x7f\xff\xb2\x84\x19\x80\x21\x0a\x0a\x84\xaf\xbf\x6e\xc1\x25\x97\ +\x1c\xc6\xe8\xd1\x69\x85\xf5\x8d\xbd\x5e\x2f\x22\x7b\x52\x63\xa5\ +\x1c\x08\xed\x81\x31\xe2\x93\x9f\xe5\x41\xa9\x9a\x42\xd3\x95\x48\ +\xa4\x61\xe4\x8d\xd2\x56\x68\x28\xaa\xea\x4f\x22\x32\x14\x78\x08\ +\xb8\x81\x70\x2d\x97\x17\x54\xf5\xff\x5c\x63\x42\x45\xbd\x37\x01\ +\x77\x01\x39\x98\xa3\xe0\xbe\x40\x37\x60\xa0\x88\xdc\xe4\x3e\xd2\ +\x75\x78\x42\x55\xfd\x22\xd2\x9d\xa2\x7f\xe0\x7d\x54\x75\xa9\x88\ +\x04\x31\x5e\x3f\x80\xce\xc0\xef\x51\xde\xd3\xf9\xce\x51\xf5\x8b\ +\x22\x32\x0d\xf3\x4f\xa3\x33\xc6\xf8\x8c\x2c\x55\x14\xa2\x1f\x61\ +\x0f\xe0\x1b\x18\xef\x26\xc0\x8b\x18\xe3\xb0\x1e\xa6\x0c\xcd\xc3\ +\xce\x7b\x02\xa3\x4c\xbf\x3f\xc6\xfb\x38\xbe\x1c\xb1\x85\xff\x21\ +\x5c\x7a\xa9\x78\x4d\x1f\x8b\xc5\x62\xb1\xc4\xe2\x70\xe7\xeb\x7c\ +\xf5\x6b\x74\x8b\x44\xb8\x8c\xe8\xa5\xe3\x98\x9e\x35\x9d\x17\xc7\ +\xcd\x21\x95\xe2\x99\xab\xeb\xd8\xb7\xf0\xf9\x7b\x93\x7f\xa7\x2b\ +\xd1\x65\x4e\xe2\xc1\xb2\x0d\x2d\xd9\xb6\xb9\x11\x6f\x8f\xab\x73\ +\x21\x68\xc5\xf8\x6b\x45\xf1\x9a\xc4\xdb\xb7\x27\xf1\xea\xab\x6d\ +\x19\xf5\x65\x23\x2e\xbc\xee\xbf\xf4\x4c\x83\xac\xb4\xac\xae\xf2\ +\x90\x5c\x98\x80\x2d\x74\x8b\xd1\xde\x07\x61\xba\x3c\x24\xc3\x81\ +\x47\x75\x88\x96\x5d\xdb\xa7\x06\x11\x69\xf0\xbd\x85\xab\x1e\xa3\ +\x43\xa4\x77\xeb\x71\xe0\x6c\x8c\x07\x4c\x30\x29\xdb\x21\xc3\x0c\ +\x11\x69\x0e\x85\x7f\x4d\xfb\x10\xf6\xde\xb9\x11\x8c\x37\x71\x76\ +\x44\xfb\x14\xe7\xab\xbb\x3e\xe6\x5a\x55\x5d\xea\x3c\x77\xd7\xc6\ +\x6c\x42\x71\xb2\x30\xde\xbb\x10\x93\x08\xdf\x39\x76\x24\xb6\x11\ +\xe8\x96\xc8\x79\xc6\x79\x44\x12\xf2\x04\x7e\x80\x39\x8e\xa8\x07\ +\xbc\xee\xb4\x05\x44\xe4\x7f\xc0\xc3\xaa\x3a\x25\xca\xd8\x42\x54\ +\x75\x0c\x30\xa6\xa4\x3e\x16\x8b\xa5\x5a\x60\x75\x02\xab\x11\xe2\ +\x93\x06\x84\x3f\x5b\x56\xc5\xec\xe8\xe1\x80\x92\x4a\xcd\x8e\xf9\ +\xa4\x2b\xac\x3e\xa6\xf8\x85\x66\xdd\xe0\xc6\xc7\x01\x98\x36\xad\ +\x09\xd3\x7e\x8a\x16\xcd\x14\x5f\x46\x0c\x4d\xfc\x1a\x35\x99\x8d\ +\xab\xf7\xe1\xf3\x61\xc7\xd1\xf3\xf1\x6f\xd9\xd8\x6a\xe3\x00\x72\ +\x48\xbc\x7e\x4f\x51\x3c\x28\x83\x80\x25\x18\xef\x72\xad\x23\xd2\ +\x08\x9c\xa9\xaa\xe3\x4a\x19\x73\x20\xc6\xb3\x16\xa2\x33\xc6\x92\ +\x9e\xe9\xbc\xde\x8d\xf1\x10\x0a\xb0\x99\xd8\x05\xcb\xa3\xc5\xda\ +\x84\x6e\x8b\xdc\x77\x78\xab\x5d\xcf\x4b\xab\x22\x9d\x0a\x24\xbb\ +\xe6\x76\x1b\x8a\x25\xf9\xb1\xdd\x1e\xc9\x5f\x88\x1e\xa7\x37\x0b\ +\x40\x55\x57\x8a\x48\x0f\xe0\x5a\xe0\x28\xa0\xbb\xb3\xce\x89\xc0\ +\xdb\x40\xe2\x6b\x0f\x59\x2c\x96\x84\x63\x75\x02\xab\x17\xea\xd7\ +\xdd\xe2\x93\xc5\x98\xc4\xbd\xee\x31\x3b\x16\x30\xdb\xc9\x28\x2e\ +\x86\x88\x87\x7f\x7d\xbc\x9d\x54\xef\xaf\xc5\xae\x4d\x59\xff\x0b\ +\x4f\xcc\x30\xcf\xef\x1d\x94\xca\x59\x8f\x14\xef\x13\x2f\x46\x7c\ +\xd4\x86\x9f\x27\xec\xcb\x87\x23\xa6\x27\x6c\x8d\x9a\xc2\xf3\x43\ +\x3b\xf1\xe3\xf7\xc5\xbd\xae\x5e\xaf\xd2\xb7\xdf\x1a\xae\x1c\xb8\ +\x94\x7e\xfd\xee\x40\xeb\xe9\xc5\xdc\x49\xfc\xd5\x3c\x72\x38\x11\ +\xf8\x21\xc6\xd5\xb1\x78\xb9\x47\x9f\xd6\xbf\x63\x5c\xaf\xf1\x44\ +\x1a\x81\xc9\x22\x52\x3f\xa2\x2d\xa8\xaa\x01\x00\xe7\xda\xe7\x98\ +\x8c\xd8\x2c\x4c\x5c\x46\x1a\xf0\xb9\x88\xf4\x56\xd5\x1d\xaa\xba\ +\x53\x44\x96\x63\x32\x82\x9b\x00\x3e\xd5\xf0\x37\x50\x44\x3c\xc0\ +\x11\x91\x19\xb7\x71\x22\x15\x38\x0d\xf8\x4e\x44\x1a\x60\x32\x8d\ +\x43\x2c\x2c\x61\xdc\x1c\xd7\xf3\x45\xaa\x7a\xbd\xfb\xa2\x88\xec\ +\x8f\x73\xbc\x20\x22\x8d\x54\x75\x2e\x70\x8f\xf3\x3a\x09\xe3\x11\ +\xbc\x19\xe8\x2e\x22\x5d\x54\x35\x66\x7a\x99\x88\x3c\x02\x9c\xeb\ +\xbc\xbc\x4a\x55\x4b\xda\x97\xc5\x62\xb1\x58\xc2\x64\x60\x8c\xc0\ +\xd6\xe2\x93\x96\xa1\xda\xc0\x21\xc4\x27\xf5\x91\xd8\xc5\x0f\x2e\ +\xed\x70\x09\x2d\x1a\x45\x2f\x7f\xb6\x6c\xd7\xa2\xc2\xe7\x3d\xf6\ +\xed\x4a\xa3\xfa\x89\x2b\xa8\x75\xd3\x0d\x6b\xb9\xf9\xa6\xb5\xd8\ +\xa2\x5d\x90\x9c\x54\x3c\x41\xe6\xe8\xa3\xb3\xb9\xeb\xae\x15\xb4\ +\x6d\xbb\x9b\xbc\x3c\x0f\x81\xdd\x01\xd8\x4d\xae\x3e\x1e\x23\x04\ +\x60\x0f\x10\x9f\x44\x73\x48\xcd\x01\xee\x50\x7f\xc9\x09\xa5\xb5\ +\x81\xc8\xdf\xc0\xb7\x9d\x87\x9b\xaf\x08\x67\xec\xbe\x42\xd8\xd3\ +\x75\x2d\x90\x0b\x7c\x8f\xf1\x06\xbe\x8d\x89\x9b\x03\x73\x5c\xfa\ +\x89\x33\xff\x04\x11\x19\x0b\x2c\xc3\x1c\xc9\x9e\x8b\x49\xaa\x88\ +\x7d\x27\xb7\x67\xfc\x5b\x44\xbe\xc3\xc4\x00\x86\x44\xa1\x7f\x51\ +\xd5\xa8\x41\xc4\x0e\xa3\x31\x55\x44\x0e\x06\x06\x39\x89\x22\xe3\ +\x81\xbd\x80\xc3\x9c\x3d\x5f\x8a\xd1\xa5\x7a\x48\x44\xce\xc3\x78\ +\x38\x97\x61\x0c\xcf\xb3\x5d\x73\x45\x17\x3b\x0a\xd3\x11\xe3\x41\ +\x84\xe8\x19\xc6\x16\x8b\xc5\x62\x89\xce\x34\xe0\x72\xe7\x79\x6f\ +\x08\x7b\x86\xc4\x27\x07\x62\x42\x6d\xda\xa2\x3c\xe0\xc8\xc9\x74\ +\x0a\x5d\xef\xd7\xa1\x1f\xb7\x1c\x72\x4b\xcc\x89\x43\xd2\x30\x29\ +\x49\x29\x74\x68\x92\x58\xb1\xe8\x8a\x94\x73\xab\x0b\xb4\x69\x93\ +\xc3\x9d\x77\x2e\xe7\xb8\xe3\xb2\xab\x66\x03\xc2\x66\x0a\x78\x8c\ +\xa5\xbc\xa3\x5f\x68\xfc\x74\x70\xaa\x31\x65\xbe\x0d\x11\x91\x4b\ +\x80\x9b\x9c\x97\x6f\xab\xea\xbf\x9d\xf6\x57\x80\xbb\x31\xc9\x1e\ +\x3f\xa9\xea\x08\x55\x1d\xe9\x18\x52\x8f\x61\x3c\x82\x77\x45\x4c\ +\x17\xb3\xc6\xe3\x1e\x32\x1f\x13\x07\x78\xa3\xab\x6d\x21\x25\x57\ +\x44\x41\x55\x73\x44\xe4\x22\x8c\xc4\xcd\x89\x18\xa3\xef\x5c\x57\ +\x97\x6c\xc2\x09\x21\x05\x98\xe3\xef\xc8\x60\xd2\x7c\xe0\x21\x55\ +\xb5\xc9\x1e\x16\x4b\x2d\xc0\xea\x04\x56\x4b\xdc\x3a\xac\x27\xe3\ +\x18\x81\xe2\x93\x8b\x31\xf1\xda\x8b\x81\xde\x3a\x54\x97\xca\x93\ +\xf2\x32\x63\x3e\x79\x82\xdd\x4d\xee\x95\xf5\x17\xa6\xdc\xfc\xcd\ +\xcd\x92\xe2\x89\xae\x13\xb8\x2b\x7f\x17\xf3\xb6\x18\x39\xd9\x4e\ +\x4d\x3a\x91\x24\x89\xcd\xdc\xfd\xfe\xfb\xe6\x74\xed\xba\x83\x03\ +\x0e\x48\x6c\xb6\x6d\x4d\xa1\x61\xc3\x20\xd7\x5e\xbb\x9a\x4b\x2f\ +\x5d\x47\x72\x72\x69\x51\x5f\x09\x21\x88\xf0\x0e\x39\x3c\xa6\x2f\ +\x6b\x69\x8e\x9c\x5a\x85\x17\x13\xec\x38\xaa\x84\x3e\xa1\x8c\x98\ +\xa5\x84\x8f\x57\xa7\xba\xae\xfb\x08\xcb\xb1\xec\x0c\x35\xaa\xea\ +\x8b\x22\xf2\x11\xc6\x23\xd7\x01\xa3\x29\xb8\x0e\xf8\x5d\x55\xdd\ +\xc9\x22\x8f\x03\x6f\x3a\xcf\x43\xf1\x7f\x41\xd7\x5a\x6e\x31\xd0\ +\xff\xb8\xda\xa3\x1d\xa3\xe6\xab\xea\x4d\x22\xf2\x1e\x61\xb1\xe8\ +\x9f\x55\xd5\x5d\x05\x65\x04\xe1\xb2\x32\x85\xde\x41\xe7\x78\xfa\ +\x24\x11\x39\x1c\xe3\xd9\x6c\x81\x39\xf2\x5e\x8a\x11\xc1\x0e\x95\ +\xa7\x79\x14\x18\x89\xf1\x10\x36\xc7\x1c\x13\x6f\x00\x26\x46\xbc\ +\xaf\x58\x0c\x05\x3e\x76\x9e\x5b\x49\x19\x8b\xa5\xfa\x62\x75\x02\ +\xab\x1f\xd3\x30\x37\xe5\x4d\x81\xdb\xc5\x27\x9f\x62\x4e\xa0\xee\ +\x04\x86\x61\x8e\xf0\x72\x01\xf4\x71\xcd\x97\x27\x58\x05\x9a\xab\ +\x68\xbd\x39\x73\xe6\x70\xe4\x91\x47\x46\x9d\xf4\x8d\x39\x6f\xb0\ +\x2d\xcf\x7c\xd4\xf4\x6a\xde\x2b\xa1\x6f\xa0\xa0\x00\x9e\x7d\xb6\ +\x03\x0f\x3c\xf0\xb7\x35\x02\x81\x13\x4e\xd8\xcc\x2d\xb7\xac\x60\ +\xef\xbd\x03\x51\xaf\x47\xe8\x04\x16\x2b\x11\x28\x3e\x69\x4f\xb8\ +\x04\x6c\x10\x73\xd2\xb8\x43\xfd\x5a\xbc\x4e\x5e\x78\xcc\xbd\x84\ +\x32\xcd\x93\x78\x16\xe5\x30\x7d\x56\xe7\xc4\xea\x5f\x15\x88\x4f\ +\x7a\x02\x0f\x38\x2f\xbf\x50\xbf\x7e\x9d\x88\x75\xbc\x4e\x4c\x5a\ +\xa9\x71\x69\xb1\x2a\x61\xa8\x6a\x1e\x30\x31\xc6\xb5\x2c\xe0\xff\ +\xa2\x5d\x73\xf5\x99\x1b\xa5\x4d\xa3\xcd\xe9\x18\x59\xa5\x1a\x5a\ +\xaa\x3a\x8d\x18\x42\xa2\xaa\xba\x9c\xa2\x59\xc6\x65\x1e\xeb\xda\ +\xdb\x5f\xce\xa3\xdc\x38\xc6\x66\x62\x45\xa8\x2c\x16\x8b\xa5\x16\ +\xa2\x7e\xdd\x21\x3e\xb9\x03\x73\x23\x9d\x42\xf8\x86\x7e\xa0\xfa\ +\x75\x64\xf4\x51\xa2\xc9\xc9\xc9\x4b\x33\x33\x33\x3b\x44\x33\x02\ +\xff\xdc\xf8\x27\xe3\x96\x99\x7c\xc8\x56\xa9\xad\xb8\xe6\xa0\x6b\ +\x12\xb1\xf5\x42\xd6\xad\xab\x47\x20\x20\xb4\x6d\x1b\xa9\x90\x56\ +\x37\xe9\xd3\xa7\xf4\xfc\x2b\xaf\xd7\x8b\xc7\xe3\x89\xa5\x13\x18\ +\x0a\x49\x2b\x82\xf8\x64\x23\x26\xe1\xe3\x21\xf5\xeb\xca\x88\xcb\ +\x27\x60\x74\x89\x21\xc8\xed\xea\xaf\x9a\x13\x3c\xf1\xc9\x13\xc0\ +\xd1\xce\xcb\x81\xea\x2f\x22\x43\xb3\x1f\x70\x99\xf3\x7c\x0e\x90\ +\x18\x23\x50\x44\x12\x5f\x23\x27\xf1\x84\x92\x59\x3a\xd7\x92\xf7\ +\x63\xb1\x58\x12\x47\xae\xaa\xd6\x7a\x11\xd8\xda\x8a\xfa\x75\x84\ +\xf8\x64\x30\xe6\xc3\xb3\x21\x90\x1e\xdb\x00\x34\x04\x02\x81\x09\ +\xd3\xa7\x4f\x6f\x83\x51\x8f\x28\x64\x47\x60\x07\xcf\xce\x78\x16\ +\x45\x11\x84\x47\x7b\x3d\x4a\xaa\x37\xb1\xa1\xda\x2b\x57\x9a\x8f\ +\xab\x76\xed\xac\x17\x30\xc1\xec\x8b\x29\x70\xd1\x57\x7c\x72\x97\ +\xfa\xf5\x5d\xd7\xb5\xf1\x40\xc8\xfa\xac\xca\x1f\x44\x2f\x4c\x99\ +\x5c\x08\xdb\x31\x21\x56\x12\x3e\x35\x2c\x29\xa7\x61\x8f\xf0\x62\ +\x6a\xed\xd6\x74\xce\xc6\x1c\xcb\x6e\xc3\xc4\x04\x5a\x2c\x16\x4b\ +\x34\x7a\x63\xaa\x01\x95\x05\xab\x13\x58\xcd\x10\x9f\x78\x30\x21\ +\x44\x47\x62\x8e\xea\x53\x80\xc1\x8e\x86\xe0\x9d\x25\x1c\x01\x4e\ +\x99\x33\x67\xce\x35\xc1\x60\x90\xa4\x24\x13\xef\xf7\xe7\xc6\x3f\ +\x79\x76\xc6\xb3\xac\xdb\x65\x14\xc1\x2e\xe9\x78\x49\xc2\x8f\x82\ +\x01\x56\xac\xa8\x4f\xd3\xa6\x01\x1a\x37\xce\x2f\xbd\xb3\xa5\xbc\ +\x9c\x8a\x39\x2d\xec\x08\x0c\x06\xfe\x81\x49\xc0\x7c\x53\x7c\x32\ +\x55\xfd\x85\x09\xa2\x13\x08\x1b\x56\xbb\x01\xc4\x27\x8d\x08\x8b\ +\x91\xaf\xc6\x84\x82\xf5\x72\x1e\xff\xa7\x7e\x5d\xe1\xf4\x4b\x75\ +\xfa\x75\x74\xc6\xce\x57\xbf\xba\xf5\x89\x0b\x71\xe6\xec\xe5\xf4\ +\x15\x8c\xde\xe0\x54\xcc\xb1\xf5\xf1\x98\x90\xb2\x10\x47\x8b\x4f\ +\x3a\x02\xaa\x7e\xfd\x05\xa3\x85\xf9\x91\x73\xad\x98\x44\x8d\xf8\ +\xa4\x33\xd0\x15\x13\xba\xb6\x1c\x98\x19\x25\x5b\xbe\x17\x46\xa5\ +\x45\xd5\xaf\xbf\x88\x4f\xda\x00\xc7\x61\xe4\xf6\x26\xaa\x5f\xd7\ +\x7b\x55\x75\x68\xb4\xcd\xd7\x30\x6a\xc3\x7b\xb0\x58\x2c\x09\x46\ +\x44\x06\x51\x46\x23\xd0\xea\x04\x56\x2f\xc4\x27\x2d\x30\xf1\xeb\ +\x27\x00\xb7\x62\x62\x03\x47\x61\x3e\x5c\x07\x01\xa7\x8b\x4f\xae\ +\x57\xbf\x46\x0b\x41\x9a\x12\x08\x04\x92\x16\x2c\x58\x40\xbb\xce\ +\xed\x78\x63\xce\x1b\x8c\x5b\x36\x0e\x75\xa4\x67\xdb\x35\x6e\xc7\ +\x2d\x5d\x63\x67\x0e\xc7\x93\x85\x0b\x1b\x5a\x2f\x60\x39\x48\x4a\ +\x4a\xe2\x8e\x3b\xee\x40\xb5\x4c\x31\x7b\xab\xd4\xaf\x0b\x31\x49\ +\xa2\xdf\x8a\x4f\x46\x00\x03\x31\x1e\xe0\xa1\x18\xa3\x10\xe0\x59\ +\x42\xc7\xc1\x46\x45\x64\x03\x26\x93\xfc\x67\xa7\xed\x7d\xa7\x3d\ +\x94\x20\x7a\x01\xb0\x42\x7c\x72\x0e\x90\x0e\xb4\x71\x2f\x2a\x3e\ +\x19\x0b\x5c\xaf\x7e\xdd\xe4\x6a\x1b\x84\x29\xad\x1b\x29\x82\xf8\ +\x01\xa6\xb4\xed\xcf\x11\xed\xa1\x4a\x65\x05\x18\xa7\xd6\x31\x84\ +\x6b\x25\x3f\x8a\x53\xc4\x42\x7c\xb2\x37\xa6\xb2\xd9\x15\x11\xe3\ +\x77\x8b\x4f\x9e\x55\xbf\x3e\xeb\x6a\x1b\x86\x31\x58\x83\xe2\x93\ +\x9b\x31\xf9\x17\x21\x6f\xf8\x66\xf1\xc9\xe9\x56\xa4\xc8\x62\xb1\ +\x58\x2c\xd5\x1a\xf1\xc9\xf1\x18\x8d\xda\x3c\xe0\x38\xf5\x9b\x18\ +\x75\xf1\xc9\x3a\xcc\x87\x6a\x3b\x4c\x19\xcf\xef\xc4\x27\xbf\x63\ +\xe2\xba\x33\x38\x64\x64\x6b\x96\x9d\x2a\xdc\x46\x07\xcf\xaf\x9e\ +\x5d\xfe\xf9\xfe\xd4\x4d\xcb\x37\xb1\x39\x37\x9c\x00\x7a\x7e\xdb\ +\xf3\xb9\xa3\xfb\x1d\xd4\x4b\xaa\x47\xa2\x29\x28\x10\x26\x4f\x6e\ +\xc6\xe5\x97\x47\xab\x47\x60\x89\x45\x20\x10\x80\xd2\x8b\x45\x44\ +\x63\x28\xc6\x08\x84\xb0\x97\xaf\x2c\x5c\x8d\x39\x29\xdd\x4c\xd8\ +\x53\xd8\x0d\x13\x97\x97\x82\x49\x72\x1d\x05\xb4\x06\x2e\x01\x2e\ +\xc2\x78\xf7\x2e\x71\xfa\x9e\x01\x7c\xe8\x9a\x6f\x36\xa6\x22\xda\ +\x61\xce\xeb\x7c\x4c\x61\x8a\x6e\x84\x4b\xd6\x4e\xc5\xc8\xee\x95\ +\x26\x4d\x93\x0e\x85\x62\xe8\x1b\x30\xf9\x13\x17\x02\x0d\x80\x67\ +\xc4\x27\xeb\xd4\xaf\xef\x47\x8c\x49\xc2\x18\x84\xf3\x9d\xf7\xd5\ +\x09\x93\xf8\xf6\x94\x35\x02\x2d\x16\x8b\xc5\x52\x6d\x71\x32\x39\ +\xfd\x98\x24\xc3\xab\xd5\xaf\x85\x1e\x5a\xf5\xeb\xcf\xe2\x93\xee\ +\x98\x3a\xef\x21\x69\xb0\xa3\x08\x69\xb1\x9e\x57\x58\x65\xec\xc7\ +\x82\xe3\x0a\x58\xc4\x22\xf3\x31\x0b\xec\x5b\x7f\x5f\x1e\xee\xf9\ +\x30\x47\xb7\x0c\xc5\xe5\x27\x9e\x8c\x8c\xc6\x64\x67\x7b\x39\xf9\ +\xe4\x4d\xa5\x77\xb6\x44\x52\x11\x23\x70\x11\xe1\x0a\x66\xfb\x8a\ +\x4f\xf6\x56\x7f\x99\x24\x60\xbc\x98\x02\x10\x1f\xa8\x5f\x73\xc5\ +\x27\xc9\x18\xa3\x2f\xa4\x31\x74\x85\xfa\xf5\x67\x28\x3c\x1e\x3e\ +\x0f\xe8\x27\x3e\x39\x44\xfd\x3a\x17\x18\xe2\x9a\xeb\x16\xf5\x6b\ +\xa1\xfe\xb2\xf8\x24\x4d\xfd\xba\x0d\xe8\x23\x3e\xf9\x86\xf0\xc9\ +\xc4\xa5\x51\x12\x58\x8a\xe0\x18\xa2\x21\x03\x70\x25\xd0\x45\xfd\ +\xba\x4b\x7c\x72\x38\xf0\xa7\xd3\xfe\x14\xc6\x93\x19\xc9\xf3\xc0\ +\x83\x18\x63\x71\x1d\xd0\x18\xe8\x6d\x8d\x40\x8b\xc5\x62\x89\x42\ +\x7a\x7a\xfa\x18\x60\xc3\xe0\xc1\x83\x6f\xae\xea\xbd\xd4\x45\xc4\ +\x27\x4d\x31\x31\x51\xe7\x02\x0f\x01\x2f\xa8\x5f\x8b\x19\x02\xea\ +\xd7\x1d\xc0\x4d\xe2\x93\xaf\x9c\x7e\xa1\x38\xa8\xa8\xec\xdf\x70\ +\x7f\x8e\x6e\x71\x34\x37\x75\xbd\x89\xc6\xc9\x8d\x13\xb2\xf7\x58\ +\xb4\x6a\x95\xc7\x6d\xb7\xad\xa0\x6d\x5b\x7b\x1c\x5c\x49\xb4\xc4\ +\x18\x80\x60\x12\x40\xca\xaa\x42\xbd\x5c\xfd\x9a\x1e\x7a\xa1\x7e\ +\x0d\x38\x37\x1b\x60\x8c\xca\x57\xc4\x57\x98\xac\xdc\xd2\x35\xee\ +\x10\xf1\xc9\x02\xc2\x3a\xc2\x39\x98\xc2\x19\x85\xa8\x5f\xf7\xc4\ +\x0d\xec\x2e\xb2\xf1\x93\xfa\x75\x97\x33\xe7\x34\xf1\xc9\x06\xcc\ +\xd1\xf3\x7e\x31\x8c\xdd\x4f\x9c\xbf\x9f\x5d\xe2\x93\x35\xc0\x41\ +\x40\x73\x6b\x04\x5a\x2c\x16\x4b\x74\x1a\x01\x3b\x4a\xed\x65\x89\ +\x3b\x4e\x40\xfb\x97\x18\xaf\xc5\x29\xea\xd7\x52\x13\xfe\xd4\xaf\ +\xff\x05\xfe\x2b\x3e\x11\x8c\x64\x48\x6f\x56\x9e\x78\x2d\x3b\x5a\ +\x9d\xc8\xc1\x9f\x3f\xc2\x5c\xb6\xf3\x5f\xde\x7e\x65\xc4\x2b\x1c\ +\x70\xc0\x01\x89\x7d\x03\x31\x68\xdd\x3a\x87\x2b\xaf\x2c\x8b\x9c\ +\xac\x25\x44\x48\x27\x70\xfc\xf8\xf1\xdd\xa0\xdc\xb5\x83\xfb\xba\ +\x9e\xcf\x57\xbf\x96\x35\xd1\x2b\x5a\xb9\x38\x77\xda\x78\x5a\xc4\ +\xb5\x50\x42\x46\x63\x8c\xb7\x30\xe4\x31\xdc\x81\xd1\x2d\x8c\x17\ +\xee\x3d\x44\x1a\xb4\xdb\x08\xc7\x1f\xa6\x52\xb4\x7a\x59\x50\xfd\ +\x45\x62\x2a\x43\x59\x49\x62\x8d\x40\x8b\xc5\x62\xb1\x54\x1b\xc4\ +\x27\x37\x02\xaf\x01\xbf\x62\x8e\xdd\xd6\x97\x32\xa4\x08\x8e\xb7\ +\x63\x01\xb0\x40\x84\x26\xc0\xe1\x3a\x6e\xf4\xf3\x22\x92\x94\x94\ +\x94\xf4\x52\x66\x66\x66\x83\xaa\x30\x02\x57\xad\xaa\x4f\xf3\xe6\ +\x79\xd4\xaf\x6f\x13\xce\xcb\x8b\xd7\xeb\x45\x44\x62\xe9\x04\x16\ +\xc3\xb9\x11\x18\x80\x49\x00\x09\xf1\x4e\x39\x96\x8c\xe6\xaa\xfd\ +\x0b\x38\x00\xe3\x59\x3c\x5b\xfd\x3a\x23\x62\xcd\x06\x40\x8e\xfa\ +\x55\xc5\x27\x4b\x80\x03\x31\xd9\xbf\x27\x03\x3f\xc5\x58\xc7\xad\ +\x90\xdd\xa0\x0c\xfb\x9a\xef\x7a\x1e\x2a\x9c\x81\xf8\x24\xcd\x59\ +\x0f\x8c\x50\xf6\xaa\x52\xe6\x29\xf4\xa8\x17\x33\x02\x45\xe4\x3c\ +\xbc\xde\x74\x3c\x35\xac\xba\x61\x41\x41\x01\xf9\xf9\xd7\xaa\xea\ +\x8f\x55\xbd\x15\x8b\xc5\x62\xb1\x94\x0f\xf1\x49\x43\xcc\x07\xf5\ +\x95\x98\x98\xaa\xc7\xd5\x1f\xbf\xfa\xad\xaa\x1a\x4c\x4e\x4e\x9e\ +\x9a\x99\x99\xd9\xe7\xbc\xf3\xce\x2b\xb3\x41\x11\x2f\x1e\x7e\xf8\ +\x40\x3a\x77\xde\xc5\xc3\x0f\x2f\xad\xec\xa5\xeb\x12\x5f\x38\x06\ +\x60\x7b\x8c\x57\x2e\xc4\x77\x11\x3a\x81\x15\xe1\x3d\xe0\x0c\xe7\ +\xf9\x70\xf1\xc9\x6b\xc0\x0c\x8c\x61\xd8\x07\xb8\x0e\xe3\x21\x0c\ +\x60\x4a\xd0\x3e\xef\xf4\x1d\xe5\x54\xb6\xf9\x0d\x73\x4c\x5c\x5f\ +\xfd\x1a\xaa\x04\xe2\x2e\x5c\xf1\xae\xf8\x64\x12\xb0\x58\xfd\x3a\ +\x22\xc6\x1e\xfe\xc4\x48\xdb\x1c\x0a\x1c\xe6\x64\x25\xff\x40\xb8\ +\xa4\x2f\x98\x44\xa9\x32\x13\xcd\x13\xd8\x90\xfc\xfc\xfd\x79\xdc\ +\x5f\x9e\x79\xaa\x9e\x27\x7d\x50\xd4\x55\x6a\xb1\x58\x2c\x7b\xc2\ +\xc5\x54\x2c\x18\xdd\x52\x4e\xc4\x27\x07\x03\x63\x30\xf1\x55\xe7\ +\xc4\x90\x79\xd9\x63\xf2\xf3\xf3\x7f\x99\x36\x6d\xda\xb1\x84\xcb\ +\x8c\x55\x0a\xbf\xfe\xda\x94\x05\x0b\x1a\xf2\xc8\x23\xd6\x00\x4c\ +\x30\x91\x22\xf0\x59\xc0\x63\x18\xa3\x6c\x8f\x50\xbf\x7e\x29\x3e\ +\x79\x11\xb8\x1b\xa3\x37\x1a\xcb\x50\x03\x78\x09\x13\x9b\x7a\x39\ +\xe6\x88\xf6\x4e\xe7\x01\x45\x8d\xb4\x8f\x31\x09\x28\xf5\x80\x93\ +\x9c\xc7\x84\x58\x73\x3b\xb1\x89\x03\x80\x6f\x30\x19\xf1\x17\x3a\ +\x8f\x10\x13\x30\xa5\x7c\xcb\x4c\xec\xe3\xe0\xbb\x1e\x2c\xcf\x3c\ +\x55\xcf\x93\xe5\x7a\xdf\x16\x8b\xc5\x52\x22\x83\x07\x0f\xde\x59\ +\x7a\xaf\xea\x89\xf8\xc4\x8b\x91\x9e\xd8\x58\x8e\x38\xa8\xaa\xa4\ +\x3f\xb0\x1d\x73\xcc\xb6\x22\x81\xeb\x4c\x59\xb7\x6e\x5d\xbd\x2d\ +\x5b\xb6\xd0\xac\x59\xb3\x04\x2e\x53\x94\xf7\xdf\xdf\x9f\xe3\x8e\ +\xcb\xa6\x53\xa7\x78\x86\x87\xd5\x0d\xca\xa0\x13\xf8\x06\x61\xd1\ +\xe5\x3c\x4c\xe6\x6b\xe8\xb1\xd0\x49\x1c\x8a\xe4\x33\x8c\x17\x0f\ +\x20\xf4\x77\xbe\x16\x78\xd2\x79\xfe\x67\xb1\x11\x80\xfa\xf5\x3e\ +\xf1\xc9\x48\xcc\x0d\x62\x07\xc2\x99\xb6\xb3\x30\x82\xd2\x01\xa7\ +\x5f\x01\xd0\x5f\x7c\x92\x0e\x9c\x45\x51\xb1\xe8\x31\xae\xf9\x32\ +\x9d\x1b\xa0\x33\x31\xc6\xa2\x07\x23\x52\x0d\xa6\x9c\x6f\x68\x3f\ +\x93\x5c\x63\x66\x8b\x4f\xba\x02\xff\x04\x0e\x21\x2c\x16\xfd\x9b\ +\xfa\xf5\xcb\x88\x2d\xbf\x8b\xa9\xb7\x1c\xf9\x3f\xe0\x6d\xcc\x0d\ +\x57\x81\x68\x44\xb2\x95\x88\x5c\x0e\x7c\x46\x76\x0d\xbb\x01\x6e\ +\x2a\x00\x17\xa9\xea\xb8\xaa\xde\x8a\xc5\x62\xa9\x9e\x38\x62\xd1\ +\xef\xa8\x6a\x64\x89\xa6\x1a\x8f\x93\x4d\xfb\x34\x70\x1a\xe6\x43\ +\x27\x19\x73\x34\x35\x1d\x18\x1e\x45\x3b\x2c\xde\xeb\xb7\xc2\xe8\ +\xab\x01\xcc\x50\xbf\xfe\x50\x8e\xb1\x49\x80\x27\xf4\x21\x1a\xb7\ +\x3d\x09\x37\x01\x43\x55\x69\x6a\x5e\x4b\x43\x11\xd9\xea\xf7\xfb\ +\x93\xfa\xf4\xe9\x13\xcf\xa5\x62\x32\x69\x52\x33\xee\xbf\xbf\x33\ +\xc3\x87\xcf\xa5\x7b\x77\x9b\x67\x54\x5e\x72\x72\x72\x70\x7e\x56\ +\xe7\xa8\x6a\x79\x13\x43\x2c\xa5\x50\xb3\xe2\xfe\x2c\x16\x8b\xc5\ +\x52\x0c\xf1\xc9\x89\x98\xc0\xf5\x5b\x81\x2e\x84\xab\x02\x24\x63\ +\x34\xf3\x86\xc4\x18\x1a\x4f\x0e\xc0\xe8\xf9\xf9\x31\xe2\xb9\x65\ +\x46\xfd\x1a\x8c\xb7\x01\x18\x75\x1d\xd5\x9d\x5e\xaf\x77\x76\x66\ +\x66\xd4\x2a\x5f\x71\x67\xe7\xce\x24\x5e\x78\xa1\x1d\x67\x9e\xb9\ +\xc9\x1a\x80\x96\x6a\x89\xcd\x0e\xb6\x58\x2c\x96\x28\xd4\x14\x9d\ +\x40\xc7\x03\xf8\x29\x61\xbd\xb2\xf1\x18\xc1\xd8\xc5\x18\xc3\xec\ +\x64\x8a\x97\x98\x0a\x8d\x6d\x0c\xb4\xc2\x94\xdb\x2a\xd3\x59\xa5\ +\xf8\x64\x7f\x20\x57\xfd\x9a\xb5\x87\x5b\x0f\x65\x35\x26\x47\x8a\ +\xe4\x8a\x4f\x9a\x03\x4d\x31\x7a\x6d\x71\x35\x0e\x03\x81\xc0\xcf\ +\xd3\xa6\x4d\x3b\x98\x4a\x88\x0b\x7c\xe3\x8d\x03\x08\x06\x85\xbb\ +\xef\x5e\x96\xe8\xa5\x2c\x96\x0a\x61\x8d\x40\x8b\xc5\x62\x89\x4e\ +\x4d\xd1\x09\x7c\x04\x53\x32\x0d\xe0\x7f\xc0\xe9\x2e\x51\xe5\x35\ +\xc0\x54\xf1\xc9\x4b\xee\x01\xe2\x93\x7e\x98\xec\xc5\xf6\x4e\x93\ +\x3a\xe5\xd6\x6e\x50\xbf\xce\x76\xf5\x5b\xea\xf4\xd9\x80\x89\x83\ +\x1a\x09\xb4\x75\xae\xfd\x00\x5c\xae\x7e\xcd\x76\x62\x9f\xdc\x19\ +\x8a\x37\x3a\x52\x2f\x00\x3e\xf5\xeb\x50\xf1\xc9\x0c\x4c\xd9\xac\ +\x5c\x4c\x09\xaf\xb1\x18\x59\x8b\x7f\x01\x17\x3a\x71\x8c\xb7\x63\ +\x04\x9f\x43\xa5\xb4\xf2\x9d\xaa\x0a\xb7\xec\xa1\xc8\xae\x9b\x29\ +\x4b\x96\x2c\xb9\x73\xf7\xee\xdd\x34\x68\x50\x16\x55\x8e\x8a\xb1\ +\x7d\xbb\xd7\x39\x0a\x5e\xc6\x5e\x7b\xe5\x97\x3e\xc0\x12\x95\x3d\ +\xd4\x09\xb4\x94\x82\x3d\x0e\xb6\x58\x2c\xdb\xc8\x62\xca\x00\x00\ +\x20\x00\x49\x44\x41\x54\x96\x9a\xcd\x31\xae\xe7\xcf\xc7\xa8\xaa\ +\x91\x17\x7a\xee\x18\x67\x5f\x62\x8c\xbb\x9d\x98\x1a\xa6\x41\xe0\ +\x68\x8c\xc1\xd8\x2e\xca\x1a\xcd\x30\x1e\xc6\xfd\x5c\x6d\x67\x02\ +\x0f\x44\xe9\x5b\x1a\x5e\x4c\x16\xe3\x81\x11\xed\x6f\x62\xb2\x2a\ +\xf7\xc1\x18\x9d\x53\x9d\xbe\x7d\x81\xc9\x8e\x0e\x5b\x3c\xf8\xb5\ +\xa0\xa0\x40\xe6\xce\x9d\x1b\xa7\xe9\xa2\xd3\xb8\x71\x3e\x63\xc6\ +\x64\xd2\xa7\x4f\x59\xaa\x94\x59\x4a\xc2\xeb\xf5\xe2\xf1\x78\x2a\ +\x5d\xd6\xa7\x2e\x60\x8d\x40\x8b\xc5\x62\xa9\xd9\x74\x73\x3d\x5f\ +\x50\x52\x47\xf1\x49\x13\x4c\x9d\x5d\x80\x8d\xc0\x7e\xea\xd7\x3e\ +\x84\x85\x67\x53\x81\xe7\xa2\x0c\x4d\x06\xbe\x02\x5a\x03\x47\xb8\ +\xda\x4f\x07\x50\xbf\x0e\xc6\x18\x91\x21\x86\xa9\x5f\xc5\x79\x0c\ +\x8d\x98\x2b\x09\xd8\x04\x0c\xc4\x18\x95\x8f\x8a\x4f\x7a\x13\xae\ +\xfd\x3b\xc5\xd9\xd7\x31\x18\xcf\x20\x18\x83\xf1\x8e\x92\xde\x5b\ +\x59\x51\xd5\xf5\xc9\xc9\xc9\xcb\x13\x15\x17\x98\x9b\xeb\x61\xd1\ +\x22\xa3\x56\x96\x9a\x1a\x37\x99\x43\x8b\x25\x21\xd8\xe3\x60\x4b\ +\xa5\xe3\x28\xbf\xf7\xc1\x1c\x09\xed\x53\x72\xef\x2a\x61\x37\x26\ +\xe5\x7f\xbc\xaa\x6e\xab\xea\xcd\x58\xaa\x8c\x9a\xa2\x13\xe8\x8e\ +\x99\x2b\xed\x7f\xfa\x21\x98\x63\x6e\x30\xde\xb6\xa7\x5c\x35\x50\ +\x03\x84\x13\x49\xa2\xf1\x8c\xfa\x75\x03\xb0\x41\x7c\xb2\x19\xd8\ +\x9b\xa2\x9e\xc1\xf2\xf0\xb8\xfa\xf5\x0b\xe7\xf9\x5a\xf1\xc9\x2d\ +\xae\x6b\x01\xe0\x25\x67\x5f\x7b\xb9\xda\x63\xed\xab\xdc\x04\x02\ +\x81\x09\xd3\xa7\x4f\x1f\x70\xdd\x75\xd7\x25\x97\xde\xbb\xec\xa8\ +\xc2\x93\x4f\x76\x64\xee\xdc\x46\x8c\x19\x33\x93\xe4\xe4\x9a\xf0\ +\xeb\x63\xa9\xcb\x58\x23\xd0\x52\xa9\x88\x48\x6b\x92\x93\x3f\x25\ +\x10\x38\x81\x7d\x9a\x07\x68\x7d\x40\xf5\xd3\x30\xcb\xde\x02\x2b\ +\x96\xa5\xe0\xf5\xae\x17\x91\xfe\xaa\x3a\x71\x4f\xa6\x13\xe1\x30\ +\x8a\x7a\x49\xb6\x01\x7f\x03\x7f\xa8\x52\x27\x5c\x05\x22\x34\xc5\ +\xc9\x5e\x55\x0d\xeb\x64\x55\x67\x6a\x90\x4e\xe0\x1c\x8c\xc8\x2c\ +\x18\xb1\xdc\xd9\x25\xf4\x75\x1b\x6d\x87\x38\x8f\x48\x0e\x10\x9f\ +\x48\xc4\xb1\x72\xb6\xfa\x75\x9e\xeb\x75\xc8\xf0\x4c\x2a\xef\x66\ +\x31\x9a\x65\xdf\x47\xb4\xb5\x72\x3d\x3f\x19\x57\x49\x2c\xf7\xbe\ +\x2a\xb0\x56\x2c\xa6\xcc\x99\x33\x67\x60\x41\x41\x41\x5c\x8b\x63\ +\xbd\xfd\x76\x1b\x26\x4f\x6e\xca\x1b\x6f\xfc\x65\x0d\xc0\x38\xe1\ +\xd2\x09\x2c\xe9\xf7\xda\x52\x41\xac\x11\x68\xa9\x34\x44\x24\x89\ +\xe4\xe4\x71\xb4\xda\xbf\x07\x1f\x7e\x0e\xbd\x8f\x8c\xeb\x5d\x78\ +\x5c\xd9\xb0\x1e\x6e\xfb\x67\x0b\x7e\xfa\xbf\xef\x44\xa4\xab\xaa\ +\x2e\xdb\x83\xd9\xce\x04\x86\x62\xd4\xeb\x83\x98\xf8\xaa\x14\x4c\ +\x6d\xd3\xbe\xaa\xcc\x2b\x69\x70\x45\x10\xe1\x11\xe0\x1e\x55\x2a\ +\x4f\x11\xb7\x64\x3c\x98\xec\xd5\xc4\x45\xe2\xd7\x5d\x7e\x26\x6c\ +\x04\x3e\x24\x3e\xf9\x4a\xfd\xba\xdb\xdd\x41\x7c\x92\xe6\x24\x56\ +\x2c\x71\x35\xff\x04\xdc\x16\x6d\xc2\x28\x71\x85\x79\x11\xaf\xa3\ +\xdd\xbc\xb9\xdb\x4a\x32\x0e\x03\xea\x2f\xe6\x61\x77\xef\xeb\x75\ +\x20\x3d\xca\xb8\x68\xf5\x5c\x2b\xca\x94\xdc\xdc\x5c\xef\xa2\x45\ +\x8b\x38\xe8\xa0\x83\xf6\x78\x32\x55\x63\x00\x8e\x1c\xb9\x1f\x4f\ +\x3c\xb1\x98\xc3\x0e\xdb\x1e\x87\x2d\x5a\x42\x04\x02\x46\x83\xb9\ +\xaa\xf7\x51\x1b\xb1\x31\x81\x96\xca\xa4\x3f\xaa\x3d\xf9\xe2\x3f\ +\x5e\x7a\x1f\x59\xd5\x7b\x29\x99\x16\x2d\xe1\x93\xaf\x3c\xb4\xef\ +\x98\x8c\xc7\xf3\x6c\xe9\x03\xca\xc4\x11\xaa\xa4\x61\x8e\xc0\x07\ +\x00\x07\x51\xbe\xa2\xe6\xe5\xc1\x0b\xd4\x3a\x41\x64\x4b\x54\x9e\ +\xc3\x78\x59\x01\x0e\x06\x66\x88\x4f\xfe\x29\x3e\x39\x4e\x7c\x72\ +\xb9\xf8\xe4\x5d\x60\x9a\x73\x7d\x3e\xe1\x7a\xa5\x27\x3b\xfd\xff\ +\x56\xbf\xfe\x85\xc9\x84\xbe\x10\xe8\x57\xc1\x7d\xac\x75\x3d\x3f\ +\x59\x7c\x72\x91\xf8\xa4\x8f\x13\x87\x58\x1a\x13\x09\x1b\x79\x97\ +\x62\x8e\x9a\x17\x3a\x0f\x01\xae\xa7\xa8\x37\x7d\x8f\x50\xd5\x85\ +\x5e\xaf\x77\x4b\x3c\xe2\x02\x03\x01\x0f\x8f\x3d\x76\x20\xa3\x47\ +\xb7\xe2\x89\x27\x96\x70\xe6\x99\x9b\xe2\xb0\x43\x8b\xa5\x72\xb0\ +\x46\xa0\xa5\x32\x39\x96\xee\x87\x05\xe9\xd2\xb5\xaa\xf7\x51\x36\ +\x52\x52\xa0\xdf\x15\x5e\xbc\xc9\x27\x95\xde\xb9\xec\xa8\xb2\x43\ +\x95\x51\x98\x82\xe2\x47\x8a\x14\xf5\x9a\x88\x70\x98\x08\x4f\x88\ +\x30\x52\x84\x67\x44\xa2\x1e\xd9\x21\xc2\xe9\x22\x3c\x27\xc2\x68\ +\x11\xde\x12\xa1\x9f\x08\x22\xc2\x69\x98\x98\x4b\xaf\x33\xcf\x13\ +\x22\xdc\xe3\x8c\xf1\x88\x70\xaa\x08\xcf\x8a\x30\x4a\x84\xe1\x22\ +\xdc\x2a\x42\x4a\xc4\xdc\x47\x3b\xe3\xbc\x22\x0c\x10\xe1\x5d\x11\ +\xde\x14\xe1\xb8\x28\xfb\xf0\x3a\x73\x7c\xe4\xec\xf7\x30\x11\x8e\ +\x17\xe1\xe1\xd2\xbe\x17\x22\xa4\x88\x70\xbd\x08\xef\x38\x6b\x5c\ +\x17\xf9\xfd\xa8\x2a\xd2\xd3\xd3\xc7\xa4\xa7\xa7\xbf\x5d\xd5\xfb\ +\x28\x0d\xf5\x6b\x0e\x70\x09\x26\x8e\x15\xcc\xcd\xc5\x70\x4c\x82\ +\xc5\x67\x18\x03\x2a\xd9\xe9\x9b\x0b\x0c\xc2\xc8\xb4\x24\x01\x5f\ +\x03\x9b\xc5\x27\x3b\x81\x95\x18\xa1\xe7\x36\x15\xdc\xca\x6a\xd7\ +\x1e\x3a\x3a\x73\xff\x0c\x94\xfa\x07\xaf\x7e\xfd\x1b\xb8\x17\xe3\ +\xed\x49\x03\x7e\x05\x36\x63\xe2\x73\xe7\x61\xea\xb5\x36\xad\xe0\ +\xbe\xa2\x52\x50\x50\x30\x69\xc6\x8c\x19\x7b\x14\x8e\xb1\x7d\xbb\ +\x97\xdb\x6f\xef\xc2\xd4\xa9\x4d\x79\xed\xb5\xbf\x38\xf3\xcc\x3d\ +\x96\x4e\xb4\x58\x2a\x15\x6b\x04\x56\x33\x44\x38\x56\xa4\x48\xf6\ +\x5d\xed\x21\x29\xa9\x35\xed\x3b\x56\xdf\x23\xe0\x68\x1c\xd0\x16\ +\xf2\x03\x2d\x12\x34\x7b\x3d\x60\x2b\xae\x63\x34\x11\xee\xc4\xd4\ +\xad\xbc\x1a\xe3\x99\xb9\x0a\xc8\x10\xa1\xaf\x7b\xa0\x08\x6f\x01\ +\x3f\x62\x0a\x99\xaf\xc4\x1c\x31\x0f\xc7\x1c\x33\x37\xc3\x7c\x60\ +\x0a\xa6\xc8\x78\x3b\xc2\x1f\xec\x2d\x31\xfa\x6c\x9d\x31\x1a\x72\ +\xed\x80\x97\x81\xc9\x11\xc6\xd7\x31\xc0\xe3\x98\xda\x93\xaf\x60\ +\xbc\x8a\x97\x01\x13\x45\x38\xd1\xb5\x0f\x0f\xf0\x7f\x98\xfa\x9d\ +\x9d\x80\x43\x31\x75\x2e\xef\x87\x92\x8d\x40\x11\xf6\xc7\x78\xa8\ +\xde\xc2\xc4\xaa\xb5\x74\xd6\x9b\x28\x42\x75\xf8\x3d\x69\x84\xc9\ +\x96\xad\xf6\xa8\x5f\xe7\x60\x7e\x17\x6e\x03\xc6\x61\x3c\x83\xd9\ +\xc0\x5c\xe0\x13\xe0\x4a\x57\xdf\x89\x98\xaa\x22\x1f\x62\x8c\xb6\ +\x3c\x8c\xc1\x35\x15\xe3\x55\x7c\xcb\x35\xf5\xef\x18\x09\x99\x5f\ +\x23\x96\xfc\x5f\x64\xbb\x73\x84\x7c\x0e\xf0\x1a\xe6\x77\xe2\x17\ +\xe7\x11\x3a\xfa\x9d\xe6\xbc\x9e\x44\x14\xd4\xaf\x6f\x61\xbc\x7d\ +\x63\x09\x7b\x36\x57\x63\x0c\xc9\x87\x81\x6f\x4b\xfd\x46\x94\x83\ +\x82\x82\x82\x49\xd3\xa7\x4f\xdf\x23\x23\x70\xf3\x66\x2f\x3b\x77\ +\x26\xf1\xee\xbb\x73\xe9\xd5\xcb\xe6\x90\x25\x82\x90\x4e\xe0\x05\ +\x17\x5c\xd0\xad\xf4\xde\x96\xf2\x62\x63\x02\x01\x11\x5a\x60\x64\ +\x16\x9a\x62\x62\x53\xe6\xab\x16\x8b\x81\xa9\x8c\x7d\x9c\x8d\x29\ +\x2e\x7d\x6a\x65\xaf\x5d\x39\x58\x99\x27\x00\x11\x5a\x01\x97\x63\ +\x3e\xb4\xdf\x57\x35\xb1\x2e\x8e\xc7\xef\x05\x8c\x84\xc7\x43\xaa\ +\xa8\x63\x98\x7d\x09\xbc\x2e\xc2\x77\xaa\xe4\x88\x70\x01\x70\x33\ +\x70\x83\x2a\xc3\x5d\xf3\x36\x00\xf2\x54\xf9\xd2\x99\xeb\x20\x55\ +\x06\x45\x2c\x9f\x05\xa4\xa9\xb2\xcb\x35\xee\x14\x8c\x06\xdc\x15\ +\x18\x83\xc1\x4d\x23\xa0\xb5\x2a\xb9\xce\xfc\x6b\x30\x1e\x9b\xd0\ +\x07\xf9\x95\x98\x5a\xb5\xfd\x55\x19\xed\xcc\xd7\x0d\x63\x3c\x94\ +\xc6\xcb\x98\x60\xff\xd6\xaa\x6c\x70\xc6\x1e\x8e\x31\x82\xaf\xc7\ +\x14\x39\xb7\x94\x11\xf5\x6b\x3e\x46\x6b\xef\xcd\x32\xf4\x5d\x06\ +\x5c\x5b\x86\x7e\xfd\x63\xb4\x5f\x1c\xa3\x7d\x15\x70\x67\x8c\x6b\ +\xd7\x97\x61\xbd\x3f\xa0\xe8\x0d\x4f\x02\x99\xb2\x75\xeb\xd6\x94\ +\xd5\xab\x57\xb3\xff\xfe\xfb\x97\xde\xdb\x21\x37\xd7\xc3\x82\x05\ +\x0d\x39\xf4\xd0\xed\xb4\x6d\x9b\xc3\xc7\x1f\xcf\x46\xec\xbf\xb6\ +\x84\xe2\xe8\x04\x5a\xa7\x55\x02\xa8\xd3\xdf\x54\x11\x3a\x88\xf0\ +\x0b\xb0\x1e\xf3\x21\x38\x1a\x98\x09\xfc\x2d\xc2\x2d\x25\x0e\x8e\ +\xff\x5e\xf6\x07\x3e\x02\x06\xa9\x32\xb5\x32\xd7\xb6\x54\x1a\x0b\ +\x44\xc8\xc1\x78\x37\x5e\xc6\x78\x5d\xdc\x55\x16\xae\xc2\x78\x05\ +\x5f\x0d\x19\x86\x4e\xf6\xf0\x30\x4c\x45\x88\xee\x4e\xbf\xab\x81\ +\x05\x6e\x03\xd0\xe9\xbb\x3b\x34\x2e\x16\xaa\x04\x54\xd9\x25\xc2\ +\xde\x22\x1c\x2e\xc2\x99\x18\xef\x61\x16\xd0\x33\xca\x90\x0f\x55\ +\xc9\x0d\xcd\x8f\x11\xf9\xed\xec\xba\x7e\x21\x46\x70\xf8\x2b\xd7\ +\x1a\x73\x30\x55\x20\x62\x22\x42\x23\x4c\xec\xd7\x07\x21\x03\xd0\ +\x19\x3b\x0d\x63\x04\x9e\x5d\xd2\x78\x8b\x25\x0e\x4c\xf7\x78\x3c\ +\xb9\xe5\x89\x0b\x9c\x3d\xbb\x11\x03\x07\x76\xe7\xe1\x87\x0f\x24\ +\x10\x30\x96\x9f\x35\x00\x2d\x35\x99\x3a\x6b\x04\x3a\x9e\x92\x59\ +\x18\xd5\xfc\x8b\x30\xc1\xfa\xa9\x98\xe3\xac\x8f\x81\xfb\x2a\x79\ +\x4b\x17\x01\x8f\xa9\xf2\x65\x25\xaf\x6b\xa9\x3c\x6e\xc3\x78\x00\ +\x9f\xc0\x48\xc4\x5c\x08\xec\xeb\xba\xde\x09\xf3\x37\x99\x29\xc2\ +\xba\xd0\x03\x18\xe1\x5c\x0f\x55\x58\xe8\x8a\x91\x05\x29\x37\x4e\ +\xfc\xde\x07\x98\x1b\x9f\x3f\x81\x0f\x80\x57\x31\x1e\xbf\x96\x51\ +\x86\xfc\x12\xf1\x7a\x31\xe0\x0e\xf4\x6f\x0f\xfc\x4f\x95\xc8\xfa\ +\xae\x4b\x28\x99\xd0\x7b\xb9\xc6\xfd\x5e\x9d\xf7\xdb\x8d\xe2\xd5\ +\x24\xaa\x82\x8b\x31\x1e\x57\x4b\x2d\x44\x55\xf3\x3d\x1e\xcf\x1f\ +\x33\x67\xce\x2c\x35\xeb\x74\xe1\xc2\x86\xdc\x7f\x7f\x67\xae\xbf\ +\xfe\x10\xf6\xdb\x2f\x97\xf7\xde\x9b\x6b\x25\x60\x2c\xb5\x82\xba\ +\x7c\x1c\xfc\x2a\x46\xae\xe3\x08\x55\xd6\xbb\xda\x67\x03\xb3\x45\ +\x8a\x7a\x59\x44\xe8\x8a\x31\x10\xf7\x02\x56\x00\xbf\xb8\x8f\xd4\ +\x9c\x3e\x27\x62\x32\xef\x36\x60\x54\xf5\x0f\x01\x46\x61\x54\xf6\ +\x1b\x00\xd3\x31\x1f\x70\x87\x03\xd3\x55\xc9\x74\xc6\xb5\xc0\x18\ +\x05\x2d\x45\x38\x1a\xf8\xbd\x34\x8f\x8e\xa5\x46\xf2\xa3\x2a\xcb\ +\x80\x71\x22\x7c\x81\x89\x91\x7a\x13\x63\x6c\x80\xd1\x5e\x5b\x89\ +\x39\x96\x8d\xc6\x62\xe7\xeb\x2e\x2a\x9e\xf9\x7b\x1b\x70\x0d\xa6\ +\x5a\xc3\xbf\x55\xd9\x0a\x20\xc2\x5c\xa2\x9f\xd7\x97\x56\xf4\x74\ +\x1b\xd1\x05\x83\x1b\x96\x32\x2e\x64\x34\x3e\x87\xc9\x0c\x8d\x24\ +\x9e\x72\x20\x15\xa2\x06\xe9\x04\x5a\x2a\x48\x7e\x7e\xfe\xc4\x8c\ +\x8c\x8c\x23\x31\xf1\xb9\xc5\x58\xb8\xb0\x21\xef\xbd\xb7\x3f\x93\ +\x26\x35\xa3\x4b\x97\x9d\xbc\xf0\xc2\x42\x4e\x38\x61\x4b\x25\xef\ +\xb2\x6e\xe3\xf5\x7a\x43\x3a\x81\xb3\x4a\xef\x6d\x29\x2f\x75\xd2\ +\x08\x74\x62\x96\x4e\x03\x9e\x8a\x30\x00\x0b\x51\xe5\x6f\x57\xff\ +\x74\x4c\xfc\xcc\x52\x8c\xa7\xa6\x33\xb0\x54\x84\x73\x54\x0b\x03\ +\x98\xc1\xe8\x6e\xa5\x03\xa7\x00\x1d\x30\x41\xff\x3f\x01\x4f\x3a\ +\xaf\x7f\x07\x06\x63\x0c\xbe\xb7\x30\x1e\x9f\xeb\x31\x81\xf7\xc9\ +\xc0\x2a\xa7\xdf\x4f\x22\x5c\xaa\x8a\xfd\x6f\x53\x4b\x51\xe5\x2f\ +\x11\x1e\x05\x5e\x16\xa1\x8f\x2a\x13\x31\x9e\xe9\xbe\xc0\x52\xf7\ +\x11\x69\x14\x66\x03\xa7\x8b\x50\x2f\x74\x54\x1b\x85\x3c\x4c\x76\ +\x70\x72\x84\x97\xee\x28\x4c\xcc\xeb\xc8\x50\x83\x08\xcd\x30\x9e\ +\xb7\x8a\xe8\x65\xcc\x05\x6e\x16\x21\x4d\x95\x75\xae\xf6\xe3\x4b\ +\x19\xb7\x10\x93\xa1\xda\xd2\x86\x3f\x58\xaa\x90\x29\xab\x57\xaf\ +\x7e\x34\x3b\x3b\x9b\xa6\x4d\x8b\x26\x1f\x4f\x99\xd2\x94\x7b\xef\ +\x3d\x88\xae\x5d\x77\xf0\xd2\x4b\x0b\x38\xee\xb8\xec\x2a\xda\xa2\ +\xc5\xea\x04\x26\x8e\xba\x7a\x1c\xdc\xc5\xf9\xfa\x47\x19\xfb\x7f\ +\x8c\xf9\xb0\x3a\x58\x95\x83\x30\x12\x0c\xc9\x98\x2c\xb8\x48\x6e\ +\xc3\xc8\x32\xb4\x56\x65\x3f\xc2\xc7\x62\x3d\x31\x71\x5d\x5d\x55\ +\xe9\x00\xbc\x2a\xc2\x09\x98\x6c\xc8\xd7\x31\xc1\xfa\x1d\x31\xd2\ +\x1e\x47\x60\x32\x33\x2d\xb5\x9b\x74\x8c\xb6\xda\x13\xce\xeb\x61\ +\x98\x1b\x87\x8f\x44\xd8\x3b\xd4\x49\x84\x7a\x22\xf4\x17\x29\xbc\ +\x69\x7b\x15\x73\x74\xfb\x8a\x5b\xda\x45\x84\x9e\x4e\xb6\x2e\x18\ +\xaf\xa1\x17\x38\x4b\xa4\x88\x87\x6f\x32\x70\xa0\x08\xed\x9c\x31\ +\x29\x98\xcc\xde\x22\x12\x31\xe5\xe0\x55\x8c\xb7\xf0\x13\x47\x56\ +\xa6\x93\x08\x1f\x51\xb4\x9e\x6d\x31\x1c\xc3\xf4\x05\x8c\x01\x79\ +\xae\xfb\x9a\x08\x5d\x9c\xbf\x0d\x8b\x25\xd1\xfc\x4f\x44\x0a\x66\ +\xcd\x9a\xc5\xaf\xbf\x36\xe5\x9a\x6b\xba\xf1\xf7\xdf\x46\xcf\xbc\ +\x77\xef\xed\xa4\xa7\xcf\xe7\x83\x0f\xe6\x5a\x03\xd0\x52\x6b\xa9\ +\xab\x46\x60\x47\xe7\xeb\xca\xb2\x74\x56\x65\xaa\x2a\xd9\x00\x4e\ +\xb6\xe6\x0a\xe0\x7d\xe0\x64\xd7\x87\x6e\x88\xe5\xaa\x0c\x09\x79\ +\xf1\x54\x0b\xe5\x3f\x04\x13\xf3\x37\xdf\x69\x0f\x02\x3e\xcc\xd1\ +\xf1\x93\xae\xfe\xbf\x00\x5f\x60\x82\xff\x2d\x65\x61\xee\x2c\x78\ +\xfe\x69\x18\xff\x03\x04\x6b\x4e\x15\x36\x55\x72\x30\xc7\xa1\x27\ +\x39\xde\xc0\x2c\x8c\x27\xb0\x2b\xb0\x52\x84\xe9\x22\xcc\xc2\x24\ +\x6d\xbc\x8b\xf3\xf7\xaa\xca\x0c\xe0\x46\xcc\x91\xee\x7a\x11\xfe\ +\x10\x61\x19\xe6\x78\x39\x64\x28\xfe\x0b\x13\xf3\xf7\x0d\xb0\x43\ +\xa4\xd0\x63\x3d\x0a\xd8\x02\x2c\x16\xe1\x0f\xcc\xdf\x40\x0e\x61\ +\x31\xe1\xf2\xbe\x87\x45\x98\x04\x8f\x23\x31\xb2\x21\x7f\x61\xe2\ +\x1c\x5f\x83\xa2\xe1\x12\x51\x78\x06\x73\x83\xf5\x8d\x08\xcb\x44\ +\x98\x2a\xc2\x0a\x8c\xa0\xf1\xb1\x15\xd9\x4f\x3c\xa9\x29\x3a\x81\ +\x96\x8a\xa3\xaa\xdb\x93\x93\x93\xe7\x65\x66\x66\x22\x02\x07\x1d\ +\xb4\xb3\x30\xd6\xaf\x41\x83\x20\x3d\x7b\x5a\xd9\x17\x4b\xed\xa6\ +\x4e\x1e\x07\x63\x3e\x54\x81\xb2\x95\xd4\x12\xa1\x3d\xf0\x14\xe6\ +\x08\xb9\x05\x45\x8d\xe7\x96\x14\x55\xca\xff\x31\xc6\x34\xeb\x09\ +\x0b\xa9\x86\xe8\x8a\xf9\x00\xfe\x38\x22\xc3\xac\x2d\xd0\x34\xca\ +\x11\x9b\x25\xc4\x8a\x65\xf0\xe5\xa7\xf0\xd9\x88\x00\x8b\x17\x24\ +\xe3\xf5\x6e\x27\x3f\xbf\x31\x4d\x9b\x05\xb8\xf4\xca\x64\xfa\x5d\ +\x01\x47\x1e\x53\xd5\xbb\x0c\xf1\x29\x26\x14\x20\xda\xcf\xf2\x1d\ +\xcc\x31\xec\x2a\x00\x55\x26\x39\x49\x4b\xc7\x61\x12\x45\x02\x98\ +\xf0\x81\x49\x6e\xd9\x22\x55\xde\x13\xe1\xdf\x18\x5d\xb5\xf6\x98\ +\xdf\xe9\xf1\xa1\x3e\x8e\xa4\xcb\x51\x98\x63\xde\x34\x9c\xd8\x3e\ +\x55\xb2\x45\xe8\x82\xd1\x73\x6b\x00\x64\x00\x33\x30\x9e\x6a\x77\ +\xa9\xb1\x2f\x9d\xf6\xc8\x84\x8f\x61\x18\x1d\xba\x42\x54\x19\x2b\ +\xc2\xb7\x98\xdf\xe7\xd5\xaa\x64\x89\xf0\x21\x45\x6f\xb2\xb6\x61\ +\x2a\x54\xcc\x77\x8d\xcb\x05\x6e\x10\xe1\x55\xe0\x30\xcc\xdf\xd6\ +\x06\x60\xaa\x2a\x4b\xa3\x7c\xaf\x2a\x9b\x46\x18\xad\x46\x4b\x2d\ +\x26\x2f\x2f\x6f\x42\x46\x46\x46\xe7\xdb\x6e\xcb\x4e\x39\xf6\x58\ +\xeb\xf1\xab\x6e\x84\x74\x02\x27\x4c\x98\xd0\x8d\xe2\x35\xa7\x2d\ +\x7b\x48\x5d\x35\x02\x17\x38\x5f\x0f\xa4\x78\xf6\x63\x11\x1c\xcf\ +\xdf\x77\x18\x75\xfd\x47\x30\x59\x99\x2b\x80\x0b\x30\xc7\x79\x91\ +\xdf\xc3\x55\x31\xa6\x5a\x15\x25\xd9\xa3\xb1\xb3\x97\x99\x11\xed\ +\x33\x31\x9e\x9c\x58\xf1\x5e\x75\x93\xac\x8d\x30\xf6\x0b\x18\x3d\ +\x22\x40\xc6\x1f\xc9\x24\x27\x6f\x25\x3f\xff\x53\xe0\x33\xf2\xf3\ +\xa7\x00\x9d\xc8\xde\x72\x05\x1f\x0e\xbb\x8a\x77\xdf\x6c\xcf\x7e\ +\xad\xf3\xe8\x7f\x55\x0a\x97\x5c\x01\x5d\xa2\x16\xdd\xa8\x14\x54\ +\x59\x49\x0c\xaf\xb3\x63\x08\x4d\x8c\x68\xdb\x89\xb9\x99\x88\x75\ +\x43\x11\xea\xb7\x9e\x12\xa4\x58\x9c\xdf\xb7\x45\xce\xc3\xdd\xbe\ +\x05\xc2\x31\x81\x0e\xd3\x23\xfa\xac\x22\xca\xef\xb2\x63\x9c\x15\ +\x31\xd0\x44\x68\xa5\xca\x5a\x28\x4c\x74\x3a\x04\x23\x2c\xfd\x9a\ +\x6b\x5c\x3e\xd1\x13\x40\x70\x6a\x27\xc7\xbd\x7e\xb2\xc5\x52\x46\ +\xa6\x2c\x5a\xb4\xe8\xd6\xdc\xdc\x5c\xea\xd5\x8b\x9a\x1f\x62\xa9\ +\x62\xbc\x5e\x2f\x22\x52\x57\x4f\x2e\x13\x4a\x5d\x35\x02\x67\x60\ +\xbc\x77\xb7\x89\xf0\x41\x29\x99\xb8\x5d\x9c\xc7\xc0\x88\x60\xfa\ +\xb4\x38\xec\x63\x1e\x90\xaf\xca\xd0\x38\xcc\x55\x3b\xd9\xb9\x03\ +\xfe\x3d\x16\x3e\x1f\x19\xe4\x97\xf1\x1e\x44\x72\xd0\x82\xb1\xc0\ +\x28\x02\x81\x1f\x55\xd5\x9d\xbd\xba\x10\x13\x5f\xf7\x84\x88\xf4\ +\x66\xcd\xaa\x2b\x78\xfd\x85\x01\xbc\x34\xa4\x05\x5d\xba\xe6\xd1\ +\xff\xea\x14\x2e\xbe\x1c\x5a\x1f\x50\x25\x6f\xa5\x16\x33\xce\xa9\ +\xf0\xb1\x08\x23\xb8\x7e\x12\xc6\x20\xf4\x57\xe9\xae\x2c\x96\xb2\ +\x31\x25\x18\x0c\x7a\xe6\xcd\x9b\x47\xcf\x9e\xd1\xa4\x32\x2d\x96\ +\xda\x4b\x9d\xb4\xac\x1d\x4f\x8b\x0f\xe8\x01\xbc\x2d\x52\x54\x6e\ +\x43\x84\xae\x22\x85\x7a\x7d\xeb\x31\x99\x96\xfb\xb8\xae\x37\x07\ +\x6e\x88\xc3\x56\x3e\x06\xfa\x44\x06\xc6\x3b\x6b\xb4\x8d\xc3\xfc\ +\x35\x93\xbc\x3c\xf8\xee\x5f\x30\xe8\xd2\x02\xda\xef\x13\xe4\xe6\ +\x41\xf9\x4c\x9e\xf0\x03\x05\xc1\x2b\x08\xe6\x37\xd7\x60\xf0\x4a\ +\x55\xfd\x2e\xc2\x00\x2c\x82\xaa\x66\xa8\xea\x3d\x04\x02\xad\x80\ +\x93\x59\x30\xff\x63\x9e\x7e\x78\x3b\xdd\xdb\xc1\x19\xc7\x06\xf8\ +\xe0\x1d\xd8\x6c\x0b\xbd\xc7\x89\xeb\x31\x5a\x86\x7f\x63\x2a\x89\ +\x0c\x00\x8e\x55\xa5\xa6\x07\x54\x59\x9d\xc0\x3a\x80\xaa\xae\x4d\ +\x4e\x4e\x5e\x55\x1e\xd1\x68\x8b\xa5\xb6\x50\x57\x3d\x81\x60\x3e\ +\xb4\x5a\x60\x62\xfd\x2e\x14\xe1\x4f\x4c\x5c\x55\x0f\x8c\x1e\xe0\ +\x04\x00\x27\xbe\x69\x1c\xf0\x8c\x53\xd3\x77\x23\x26\x78\x7f\x0a\ +\xa6\x68\xfb\x9e\xf0\x3e\x26\x4e\xea\x1b\x27\xa6\x6a\x3e\xc6\x93\ +\xd2\xdb\xb9\x7e\xf8\x1e\xce\x5f\x73\x28\x28\x80\xdf\x26\xc1\x97\ +\x9f\x2a\x5f\x8d\x0e\xb2\x73\x47\x12\xde\xe4\xdf\x08\xe4\x8d\x00\ +\xc6\x68\x30\x58\x21\xb9\x1c\x55\x2d\xc0\x1c\x43\x4e\x14\x91\x5b\ +\x81\xb3\x98\xf6\xfb\x15\x64\xfc\x71\x21\xf7\xdd\x9a\xcc\xc9\xa7\ +\x17\x70\xd9\x40\x2f\xe7\x5c\x00\xa9\xa5\x49\xdb\x59\xa2\xa1\xca\ +\x2c\x8a\xc7\xbb\xd6\x78\xac\x4e\x60\xdd\x21\x3f\x3f\xff\xe7\xe9\ +\xd3\xa7\xf7\x1f\x34\x68\x50\x5d\xfe\x4c\xac\x96\x24\x25\x25\x85\ +\x74\x02\x67\x57\xf5\x5e\x6a\x23\x75\xf6\x17\xde\x39\x02\x7e\x41\ +\x84\xaf\x31\x41\xf2\xa1\xda\xc1\x3f\x00\xf7\x38\xba\x6d\x21\xfe\ +\x89\xa9\x87\xd9\x03\x13\x28\x3f\x00\x63\x30\xce\xc3\x48\x7a\x84\ +\x78\x9a\xe8\x31\x86\x5f\x10\x25\x09\xc5\xd9\xc3\x95\x22\x7c\x86\ +\xa9\x17\xdc\x19\x13\x40\xff\x25\xa6\x88\x7a\xed\x27\x73\xba\x49\ +\xf0\xf8\xfc\x93\x00\x1b\x37\x24\x93\x92\x32\x87\xbc\xbc\x8f\x81\ +\xd1\x9a\x97\xbb\x3a\x9e\x4b\xa9\x6a\x1e\x26\x5b\xf6\x1b\x11\x69\ +\x08\x5c\xc8\xc4\x9f\x06\x30\xe1\xc7\xd3\x49\x4e\x81\xf3\x2e\x12\ +\x2e\xb9\xd2\xc3\x29\x67\x40\x72\x72\x3c\x97\xb6\x58\x2c\xd5\x18\ +\x55\x9d\x3c\x6b\xd6\xac\xfe\x05\x05\x05\xd8\x12\xb5\xd5\x0f\xab\ +\x13\x98\x38\xea\xac\x11\x18\x42\x95\x25\x18\x9d\xbe\x92\xfa\x6c\ +\xc7\x18\x78\x91\x3c\x11\xd1\x2f\x5a\x1f\x4a\x2b\x05\xa7\xca\xb7\ +\xc0\xb7\x25\x6e\xb4\x36\xb1\x74\xb1\x93\xd9\xfb\x71\x1e\xcb\x96\ +\xa6\x90\x92\xb2\x9c\xbc\xbc\x8f\x80\xcf\x34\x37\x77\x41\x69\xc3\ +\xe3\x81\xaa\xee\xc4\xc8\xa5\x8c\x12\x91\x7d\xc8\xcd\xb9\x84\x7f\ +\x7d\x75\x15\x63\x3e\x3b\x9a\x26\x7b\xe5\xd3\xaf\x7f\x32\x97\x5c\ +\x01\x6a\xff\xef\x58\x2c\x75\x80\x29\x39\x39\x39\xde\x25\x4b\x96\ +\xd0\xa9\x53\xa7\xaa\xde\x8b\xc5\x52\x69\xd4\x79\x23\xd0\x52\xc9\ +\xfc\x67\x9c\xf2\xf5\xe7\x42\x72\xca\x46\x02\x79\x23\x81\x4f\x35\ +\x37\xb7\x42\x1a\x75\xf1\x42\x55\x37\x61\xa4\x5a\xde\x11\x91\x36\ +\x6c\xdb\x7a\x39\x23\x3f\xb8\x9a\x0f\xde\x39\x84\x94\x7a\x05\xa5\ +\x8d\xb7\x18\x81\x67\x60\x10\x90\xae\xca\xf2\x2a\xde\x4e\x5c\x48\ +\x4f\x4f\x1f\x03\x6c\x18\x3c\x78\xb0\x8d\x0b\xac\xfd\xfc\xe5\xf5\ +\x7a\xb7\x65\x66\x66\x36\xb1\x46\x60\xb5\xc5\xde\x91\x27\x00\xeb\ +\xf7\xb6\x54\x1e\xc1\xfc\x2d\xe4\xe5\x7d\x08\x9c\x4a\x20\x2f\x4d\ +\x55\xef\x56\xd5\x2a\x35\x00\x23\x51\xd5\x95\xaa\xfa\x82\xe6\xe6\ +\x76\x03\xba\x92\x97\xfb\x2c\xaa\x4b\x4a\x1d\x58\x87\x11\xa1\x01\ +\x30\x06\x48\xad\x2d\x06\xa0\x43\x23\x20\xb5\xaa\x37\x61\x49\x3c\ +\x6a\x98\x34\x73\xe6\x4c\x7b\xd3\x57\xcd\xc8\xcf\xcf\xe7\xed\xb7\ +\xdf\xa6\x6f\xdf\xbe\x87\x56\xf5\x5e\x6a\x23\xd6\x08\xb4\x54\x26\ +\x83\xb4\xa0\xe0\x3a\x55\x9d\xe0\x24\x6c\x54\x6b\x54\x75\xbe\xaa\ +\x3e\x86\x6a\xd7\x3d\x99\x47\x84\x17\x9c\x8a\x1e\xb5\x95\x37\x31\ +\x99\xc1\x77\x55\xf5\x46\x2c\x96\x8a\x12\x0c\x06\x27\x65\x64\x64\ +\xc4\x54\x1c\xb0\x58\x6a\x23\xd6\x08\xb4\x54\x1a\xaa\x35\x33\xc0\ +\x2e\x0e\xfb\xf6\x42\x51\x19\xa2\xda\x82\x08\x4d\x30\x35\xb8\x2f\ +\x77\x4a\x21\x5a\x2c\x35\x95\x29\x5b\xb6\x6c\x49\x59\xb7\xce\x16\ +\x69\xb2\xd4\x1d\x6c\x4c\xa0\xc5\x92\x40\x44\x38\x07\x53\xda\xad\ +\x91\x48\x61\x22\x51\x96\x2a\x6f\x3a\x71\x74\x97\x03\x6f\x00\xc7\ +\x63\xe4\x82\x02\xaa\xdc\xe7\x8c\x3d\x1e\x38\x0f\xd8\x1f\x58\x0c\ +\x8c\x54\x65\xb1\x6b\xee\x03\x31\x99\xea\xe9\x18\x59\xa1\xb3\x30\ +\xa5\xe0\xfe\xa3\x5a\xb4\xb4\x9b\xd3\xff\x22\xa7\xcf\x0e\x4c\x22\ +\xd2\x5a\x67\xfd\x57\x54\xd9\xea\xe8\x65\x3e\x08\x8c\x55\x25\xd3\ +\x35\xae\x39\x70\x2b\xf0\x89\x93\x48\x15\x6a\x6f\x82\x89\x03\xec\ +\x01\x74\x17\x61\x92\x2a\x5f\xec\xc1\xb7\xab\xba\x71\x31\x36\x0e\ +\xa9\x2e\x91\xe1\xf1\x78\xf2\x32\x33\x33\x53\xd2\xd2\xe2\x51\x0b\ +\xc0\x62\xa9\xfe\x58\x4f\xa0\xc5\x92\x58\xf6\x01\x9a\x60\xca\x0e\ +\xb6\x73\x1e\xfb\x3b\xd7\xba\x00\x8f\x03\x2f\x61\x64\x84\xf6\xc3\ +\xf1\x18\x8a\x70\x1f\x46\x78\xf9\x68\x8c\x1c\xd1\x25\xc0\x0c\x11\ +\xce\x72\xcd\x7d\xa0\x33\xde\xef\x8c\xdf\x07\x53\xdf\x7a\xac\x08\ +\xd7\xb9\x37\x21\xc2\x0b\xc0\x57\x4e\x1f\x2f\x30\x1c\x78\xd2\x19\ +\xbf\x97\xd3\xad\x81\xf3\xba\x47\xc4\x7b\xd8\xd7\x69\xef\xe8\x9a\ +\xaf\x1b\x46\x1b\xd0\x8f\x89\x9b\xeb\x0a\x7c\x2e\xc2\xe7\x65\xfe\ +\xce\x54\x73\x06\x0f\x1e\xbc\x73\xf0\xe0\xc1\xbb\xaa\x7a\x1f\x96\ +\xca\x41\x55\xf3\x92\x92\x92\x32\x66\xce\x8c\xac\xe2\x69\xa9\x4a\ +\x92\x92\x92\xb8\xf9\xe6\x9b\xf9\xfa\xeb\xaf\x6b\x9d\x16\x69\x75\ +\xc0\x7a\x02\x2d\x96\x04\xa2\xca\x08\x11\x7a\x02\xfd\x55\x19\x14\ +\xa3\x5b\x37\xe0\x00\xa7\x16\x70\xa8\x5a\xcc\x33\xc0\xdb\xaa\xdc\ +\xea\xb4\xd5\xc7\x88\x5e\xbf\x2d\x42\x17\x55\xf2\x5c\xe3\x0f\x05\ +\xf6\x53\x65\x9b\x53\xeb\xfa\x77\x8c\x47\xef\x7d\x67\x6c\x77\xe0\ +\x1e\xe0\x3e\x55\x5e\x72\xda\x9e\xa6\x82\x02\xcf\x22\x08\xc6\x88\ +\xcc\x03\x5a\xaa\xb2\xc3\x69\xbf\x18\x18\x23\xc2\x08\x55\xfe\x53\ +\x91\xb9\x2d\x96\xaa\x24\x10\x08\xfc\x3c\x6d\xda\xb4\x5e\x80\x2d\ +\x22\x6c\xa9\x13\x58\x4f\xa0\xc5\x52\xf5\x7c\x15\x32\x00\x1d\xce\ +\x03\x52\x80\x21\xa1\x06\x55\x72\x80\x17\x80\xf6\x84\x2b\xca\x84\ +\xf8\x34\x54\xa2\xcd\x89\xcb\xfb\x1e\x68\x2f\x52\x78\x93\xd7\x0f\ +\xc8\x01\xde\x72\xcd\x97\x05\xbc\x57\xc1\xfd\x76\xc5\x78\x28\xdf\ +\x0a\x19\x80\x0e\xe3\x30\x47\xcc\x67\x45\x1d\x65\xb1\x54\x7f\xa6\ +\xac\x5c\xb9\xb2\xde\xf6\xed\xdb\xab\x7a\x1f\x16\x4b\xa5\x60\x8d\ +\x40\x8b\xa5\xea\x99\x10\xf1\xba\x13\xb0\x43\x95\x35\x11\xed\x7f\ +\x39\x5f\xdb\x47\xb4\x47\x56\xa9\x59\x8c\x39\x7e\x0e\xd5\xc1\xeb\ +\x00\xac\x72\x0c\x49\x37\x0b\x2b\xb0\xd7\xd0\xfe\x00\x1e\x15\x61\ +\x5d\xe8\x01\xac\xc6\x1c\x37\xd7\x0a\xa1\xb5\xf4\xf4\xf4\x31\xe9\ +\xe9\xe9\x6f\x57\xf5\x3e\x2c\x95\xca\x6f\x22\xa2\xb6\x8e\xb0\xa5\ +\xae\x60\x8f\x83\x2d\x96\xaa\x27\x3b\xe2\x75\x0e\x90\x2c\x82\x38\ +\xa5\x05\x43\x84\x8e\xa8\x72\x23\xfa\x97\x26\x6b\x91\x83\xf1\x2c\ +\x46\x12\xd9\x16\x5a\x2b\xf2\xe6\xb0\x51\xc4\xeb\xd0\x51\xf4\xbd\ +\x84\x0d\x53\x37\x5b\xa3\xb4\xd5\x44\x1a\x41\x11\x4f\xa7\xa5\x96\ +\xa3\xaa\x5b\xeb\xd5\xab\xf7\x57\x66\x66\xe6\xc1\xc7\x1f\x7f\x7c\ +\x55\x6f\xc7\x42\x58\x27\xf0\xa7\x9f\x7e\x3a\x14\x53\xd6\xd5\x12\ +\x47\xac\x11\x68\xb1\x24\x9e\x3c\x4c\xd2\x45\x59\x59\x80\x31\xf8\ +\x0e\x01\xe6\xb8\xda\x0f\x77\xbe\x96\x57\xbc\x7a\x11\x30\x48\x84\ +\xe6\xce\x31\x70\x88\x5e\x11\xfd\xb6\x62\x0c\xc6\x9e\xc0\x47\xae\ +\xf6\xf3\x22\xfa\x85\x0a\xb9\x37\x55\x65\x6a\x39\xf7\x62\xb1\x54\ +\x6b\xf2\xf2\xf2\x26\x4c\x9f\x3e\xbd\x23\xd1\x6f\x9c\x2c\x96\x5a\ +\x85\x3d\x0e\xb6\x58\x12\xcf\x62\xa0\x89\x08\x27\x95\xb1\xff\x97\ +\xc0\x46\xe0\x45\x11\x53\xb1\xc2\x49\x16\x79\x08\x98\xa2\x4a\x79\ +\xd3\x17\x47\x00\x01\xe0\x39\x11\xf3\x37\x2f\x42\x2f\x28\x9a\xa8\ +\xe2\x78\x1d\xa7\x01\xe7\x38\xeb\xe1\xec\x79\x60\x44\xbf\x95\xc0\ +\x27\xc0\x63\x22\x1c\xed\xbe\x26\x42\x6f\x27\x11\xc6\x62\xa9\xa9\ +\x4c\x59\xb0\x60\x81\x37\x10\x08\x54\xf5\x3e\x2c\x45\xb1\x72\x4d\ +\x09\xc0\x1a\x81\x16\x4b\xe2\x19\x8d\xf1\xe8\x4d\x14\x61\x87\x08\ +\x7f\x94\xd4\x59\x95\xed\x18\xfd\xbf\xc3\x81\xd5\x22\x64\x60\x8e\ +\x5d\x77\x00\xd7\x96\x77\x71\x55\xd6\x01\xd7\x03\x57\x02\xcb\x44\ +\xf8\x1d\xf8\x0e\x78\x35\x4a\xf7\x47\x81\x34\x60\xa9\x08\xab\x9c\ +\x7e\xaf\x44\xe9\x77\x07\x26\x5b\xf9\x37\x11\x16\x89\xf0\xbb\x08\ +\x6b\x80\x3f\x31\xd2\x37\xb5\x81\x8b\x01\x5b\x37\xb8\x9a\x20\xc2\ +\xa1\x22\xcc\x14\xa1\x43\x82\x97\x9a\x92\x9f\x9f\xef\x99\x37\x6f\ +\x5e\x82\x97\xb1\x58\xaa\x1e\x7b\x1c\x6c\xb1\x24\x18\x55\xb6\x8b\ +\xd0\x03\x93\x30\xd1\x82\x70\x4c\xdf\x14\x8c\x40\xf4\x8a\x28\x63\ +\x7e\x14\xe1\x60\x8c\x88\x74\x48\x2c\xfa\x17\x55\x76\xbb\xba\xfd\ +\xe1\x8c\x5f\x1c\x31\xfc\x7b\xa7\xbd\x30\x9e\x4d\x95\x51\x22\xfc\ +\x06\xf4\x71\xda\x27\x01\xc7\x46\x59\x77\xa2\x23\x29\x73\xb2\xb3\ +\xcf\x89\xc0\x16\x8c\x9c\x4c\xa6\xab\xdf\x16\xa0\xaf\x08\xbd\x31\ +\x12\x37\x7b\x01\xeb\x80\xc9\xaa\xac\x2d\xf5\x9b\x52\x03\x18\x3c\ +\x78\xf0\xce\xaa\xde\x83\xa5\x08\xdb\x30\x1a\x96\x09\x2d\xed\xa6\ +\xaa\xab\x52\x52\x52\xd6\x66\x66\x66\xb6\xea\xd1\x23\x52\x32\xd3\ +\x52\xd9\x84\x74\x02\xa9\xa0\xa4\x95\xa5\x64\xac\x11\x68\xb1\x54\ +\x02\xaa\x14\x60\x62\xfd\x16\xb8\xda\xb2\x30\x46\x56\xac\x31\x1b\ +\x81\xb1\x25\x5c\xdf\x1c\x6d\xbc\xe3\xf9\x2b\x56\xfb\x4a\x95\xbf\ +\x31\x35\x7e\x01\x10\x89\x39\x6f\x91\x7e\x0e\x51\xf7\xa9\x4a\x06\ +\x90\x11\x6b\x8f\x16\x4b\xbc\x50\x65\x99\x08\x4b\x80\x1b\x80\x47\ +\x12\xb9\x56\x7e\x7e\xfe\xcf\x33\x66\xcc\xb8\xf4\xaa\xab\xae\xb2\ +\x9f\x91\x96\x5a\x8d\xfd\x05\xb7\x58\x2c\x16\x4b\xb5\xc7\x11\x29\ +\xbf\x03\x78\x57\x84\x7d\x31\x99\xa2\x91\x67\xb6\x3b\x54\x59\xb5\ +\xa7\x6b\xa9\xea\xe4\xcc\xcc\xcc\x4b\x54\x15\x89\x75\xb7\x64\xb1\ +\xd4\x02\x62\x1b\x81\x0f\xde\x59\x89\xdb\xb0\x58\x2c\x55\xc0\x62\ +\xe0\x35\xc0\x2a\xe3\x46\x21\x3d\x3d\x7d\x0c\xb0\x61\xf0\xe0\xc1\ +\x36\x2e\xb0\x7a\x90\x8a\xa9\x79\x0d\xc6\x1b\x78\x43\x94\x3e\xff\ +\x01\xce\x8d\xc3\x5a\x53\x76\xed\xda\x95\xbc\x74\xe9\x52\x3a\x76\ +\xec\x58\x7a\x6f\x8b\xa5\x86\x12\xcd\x08\xdc\x40\x72\xf2\xaf\x7c\ +\x38\xac\x66\x25\x8d\x24\x27\x17\x10\x08\x64\x95\xde\xd1\x62\xb1\ +\x00\xa8\x32\x1b\xb0\x77\x7b\xb1\xb1\x3a\x81\xd5\x8b\x1c\xe0\xa2\ +\x52\xfa\x14\x0b\x83\xa8\x20\x73\xbd\x5e\xef\xf6\xcc\xcc\xcc\xc6\ +\xd6\x08\xac\x5a\x22\x74\x02\x7f\xac\xea\xfd\xd4\x36\x8a\x19\x81\ +\xaa\x3a\x81\xe2\x15\x0c\x2c\x16\x8b\xc5\x62\xa9\x32\x9c\x92\x88\ +\xe3\x2a\x67\x2d\x55\xaf\xd7\xfb\x6b\x66\x66\xe6\x99\x7d\xfb\xf6\ +\xb5\xe7\xc1\x96\x5a\x4b\xcd\xf2\xf6\x59\x2c\x16\x8b\xc5\x52\x09\ +\x04\x83\xc1\x5f\x32\x32\x32\xac\x58\xa0\xa5\x56\x63\x13\x43\x2c\ +\x16\x8b\x25\x3a\x17\x63\x05\x6a\xab\x0d\x8e\x70\x7a\x64\x3d\xed\ +\x48\x7e\x50\xe5\xb2\x38\x2d\x39\x25\x2b\x2b\x2b\x65\xc3\x86\x0d\ +\xb4\x68\xd1\x22\x4e\x53\x5a\x2c\xd5\x0b\x6b\x04\x5a\x2c\x16\x4b\ +\x14\xac\x4e\x60\xb5\x23\x40\x74\x81\xf3\x9e\xc0\x59\x18\x41\xf6\ +\x7f\xc5\x71\xbd\x3f\x3d\x1e\x4f\x20\x33\x33\x33\xf9\xf4\xd3\x4f\ +\x8f\xe3\xb4\x96\xf2\xe0\xd2\x09\xcc\x2c\xad\xaf\xa5\xfc\x58\x23\ +\xd0\x62\xb1\x58\x2c\xd5\x1e\x55\x02\xc0\x13\xd1\xae\x89\xd0\x14\ +\x63\x04\xee\x8e\x76\xbd\x62\xeb\x69\x6e\x4a\x4a\xca\x8c\xcc\xcc\ +\xcc\x23\xad\x11\x68\xa9\xad\xd8\x98\x40\x8b\xc5\x62\xb1\xd4\x68\ +\x54\xc9\x06\x46\x12\xe7\x32\x7f\x81\x40\xe0\xe7\x69\xd3\xa6\xe5\ +\x96\xde\xd3\x62\xa9\x99\x58\x23\xd0\x62\xb1\x58\xa2\x90\x9e\x9e\ +\xfe\x4d\x7a\x7a\xfa\xf0\xaa\xde\x87\xa5\xcc\x04\x81\x03\xe3\x3c\ +\xe7\x94\xe5\xcb\x97\xa7\xec\xd8\x61\x95\x82\x2c\xb5\x13\x6b\x04\ +\x5a\x2c\x16\x4b\x74\x52\x80\xe4\xaa\xde\x84\x25\x8c\x08\xf5\xa3\ +\x3c\xda\x88\x30\x08\xb8\x1e\x98\x1d\xe7\x25\x7f\x55\x55\x66\xcf\ +\x8e\xf7\xb4\x96\xb2\x12\x0c\x06\x79\xfb\xed\xb7\xb9\xf8\xe2\x8b\ +\x6d\x21\xe7\x04\x60\x8d\x40\x8b\xc5\x62\xb1\x54\x7b\x44\x68\x88\ +\x89\xf9\x8b\x7c\xac\x00\x3e\x04\xb6\x10\x67\xf1\x73\x55\xdd\x92\ +\x92\x92\xb2\x28\x33\xd3\xe6\x24\x58\x6a\x27\x36\x31\xc4\x62\xb1\ +\x58\x2c\x35\x81\x5c\x60\x70\x94\xf6\x5d\x98\x12\x88\x53\x55\x29\ +\x88\xf7\xa2\x79\x79\x79\x13\x32\x32\x32\xda\x63\xbd\xc2\x96\x5a\ +\x88\x35\x02\x2d\x16\x8b\x25\x3a\xe7\x55\xf5\x06\x2c\x61\x54\xc9\ +\x07\xde\xa9\x82\xa5\xa7\xcc\x9f\x3f\xff\xfa\x40\x20\x40\x72\xb2\ +\xb5\x03\x2d\xb5\x8b\x62\x46\xa0\x88\xb4\x00\xba\x56\xc1\x5e\xe2\ +\xc1\x1c\x55\xb5\xf5\x83\x2d\x16\xcb\x1e\x33\x78\xf0\x60\x5b\x2d\ +\xa2\x1a\x22\x82\x00\x27\x00\x5d\x80\x0d\xaa\x8c\x13\x21\x09\xe8\ +\x04\xac\x54\x25\xde\xfa\x8e\x53\xf2\xf3\xf3\x93\xfe\xfa\xeb\x2f\ +\xba\x77\xef\x1e\xe7\xa9\x2d\xa5\x61\x75\x02\x13\x4b\x34\x4f\xe0\ +\x29\xc0\x67\x95\xbd\x91\x38\x71\x11\x95\x54\x5b\xd2\x62\xb1\x58\ +\x2c\x95\x8b\x08\xed\x81\x31\x40\x2f\x4c\x35\x97\xaf\x81\x71\xaa\ +\x04\x45\x18\x0b\x8c\x00\xfc\xf1\x5c\x53\x55\x97\xa7\xa4\xa4\x6c\ +\xc8\xcc\xcc\x6c\x61\x8d\x40\x4b\x6d\x23\xf6\x71\xf0\xf2\x2d\x95\ +\xb8\x8d\x38\xd0\xb6\x59\x55\xef\xc0\x62\xb1\x58\x2c\x89\xe5\x33\ +\xa0\x1e\xa6\xa4\x5f\x17\x8c\x31\xe8\xbe\x76\x26\x71\x36\x02\x01\ +\x82\xc1\xe0\xcf\x33\x66\xcc\xe8\x37\x60\xc0\x80\xa4\x78\xcf\x6d\ +\xb1\x54\x25\xb1\x8d\xc0\xbd\x9a\x56\xe2\x36\x2c\x16\x8b\xa5\x7a\ +\x91\x9e\x9e\xfe\x0d\xb0\x7e\xf0\xe0\xc1\xd7\x57\xf5\x5e\x2c\x20\ +\x42\x1b\xe0\x28\xe0\x7c\x55\xfe\x2d\xc2\x3d\x11\x5d\x16\x03\x83\ +\x12\xb1\x76\x41\x41\xc1\xe4\x99\x33\x67\xf6\x55\xd5\x24\x11\x49\ +\xc4\x12\x96\xd2\xb1\x75\xbc\x13\x80\x95\x88\xb1\x58\x2c\x96\xe8\ +\x58\x9d\xc0\xea\x45\x2b\x8c\x21\x30\x39\xc6\x75\x2f\xc4\x3f\x3b\ +\xd8\x61\xca\xce\x9d\x3b\x93\x97\x2f\x5f\x9e\xa0\xe9\x2d\xb1\x08\ +\xe9\x04\xf6\xeb\xd7\xcf\xea\x04\x26\x80\x3a\x67\x04\x8a\xb0\xaf\ +\x08\x5d\x5c\x8f\x56\x4e\xa0\x71\x9d\x41\x84\x16\x22\x8c\x16\xa1\ +\x77\x55\xef\xc5\x62\xb1\x58\xca\xc8\x02\x40\x80\x0b\x63\x5c\x3f\ +\x15\x58\x98\xa0\xb5\x67\x27\x25\x25\xed\xb4\x7a\x81\x96\xda\x46\ +\x9d\x33\x02\x81\xbb\x81\xf9\xae\xc7\x1a\x60\x87\x08\x6f\x3a\x62\ +\xa4\x71\x47\x84\x1b\x45\xf8\x34\x11\x73\x57\x90\x86\xc0\x65\xc0\ +\xfe\x55\xbd\x11\x8b\xc5\x62\x29\x0b\xaa\x6c\x05\xbe\x00\x1e\x17\ +\xe1\x5a\xa0\x01\x80\x08\x7b\x89\xf0\x28\x30\x10\x78\x3b\x31\x6b\ +\x6b\x81\x88\xfc\x6f\xe6\xcc\x99\xf6\x48\xd2\x52\xab\xa8\xcb\x3a\ +\x81\x47\x02\xdb\x81\x0e\x40\x7f\xe0\x16\xa7\xfd\xd6\x04\xac\x75\ +\x30\x70\x72\x02\xe6\xb5\x58\x2c\x89\xc3\xea\x04\x56\x3f\x6e\x02\ +\xc6\x02\xef\x63\x8e\x86\xf3\x30\x95\x42\x82\xc0\x93\xaa\x7c\x9b\ +\xa8\x85\xf3\xf3\xf3\x27\x66\x64\x64\x9c\x80\x49\x4c\xb1\x58\x6a\ +\x05\x75\xd9\x08\x5c\xa4\x4a\x36\xf0\x97\x08\x3f\x02\xa7\x63\xfe\ +\xe9\x17\x31\x02\x45\x68\x8c\x31\x18\xdb\x03\x4b\x80\xdf\x54\xc9\ +\x8d\x9c\x4c\x84\x34\xa0\x37\xd0\x06\xd8\x08\x4c\x54\x65\x93\x08\ +\x9d\x81\xd6\x40\x8a\x08\x7d\x9c\xee\x3b\x55\xf9\xd3\x35\xff\x71\ +\xc0\x01\x18\xa3\x74\xa6\x2a\xf3\x23\xe6\x6e\x07\xb4\x51\x65\xb2\ +\x08\x1d\x81\x63\x81\x1d\xc0\x04\xe7\xee\x38\x72\x2f\xbd\x80\x1e\ +\xc0\xdf\xc0\xef\x98\x58\x9a\x96\xaa\xfc\xaf\xb4\x6f\x8a\x08\x5d\ +\x81\xc3\x30\xff\x54\xff\x50\xe5\xef\xd2\xc6\x58\x2c\xb5\x11\xab\ +\x13\x58\xfd\x50\x65\x0b\xd0\x47\x84\x7f\x60\xfe\xdf\xa6\x61\x12\ +\x42\x7e\x50\x65\x5e\x82\x97\x9f\xb2\x61\xc3\x86\x7a\x59\x59\x59\ +\x34\x6f\xde\x3c\xc1\x4b\x59\x42\x58\x9d\xc0\xc4\x52\x97\x8d\xc0\ +\x42\x54\xc9\x17\x61\x19\xc6\xd0\x2b\x44\x84\x33\x31\x35\x29\xd3\ +\x30\xb1\x26\x07\x01\x73\x44\xb8\x48\x95\xc5\xae\x7e\xff\x04\x5e\ +\xc5\x18\x4e\x0b\x31\x06\x5d\x43\xa0\x11\x70\x35\x70\x06\x90\x0a\ +\x7c\xe4\x0c\x59\x0c\x9c\xe6\x18\x74\xf3\x81\xcd\xc0\x4a\xe0\x10\ +\xa0\x9e\x08\xcf\xa8\xf2\xb8\x6b\x2b\xd7\x00\xf7\x89\x70\x2f\xf0\ +\x26\xb0\x1a\x63\x58\x2e\x15\xe1\x38\x55\xd6\xb9\xf6\xf2\x32\x70\ +\x17\xb0\xd5\xd9\xcf\x4a\xe0\x4f\xe0\x1c\x60\xbf\x58\xdf\x03\x11\ +\x1a\x01\xe9\xc0\x00\x60\x3d\x26\x20\xbe\x89\x08\x8f\xa9\xc6\x5f\ +\x72\xc1\x62\xb1\x58\x2a\x8a\x2a\xdf\x01\xdf\x55\xf2\xb2\x7f\x88\ +\x48\x30\x33\x33\x33\xe9\xd4\x53\x4f\xad\xe4\xa5\xeb\x2e\xaa\xf6\ +\x04\x3e\x91\xd4\xc5\x98\xc0\x62\x88\x70\x02\x46\x7a\x60\xbc\xab\ +\xad\x35\xf0\x15\xf0\x0b\x70\x80\x2a\x5d\x80\x43\x31\x86\xf3\x3b\ +\xae\x7e\xc7\x00\xef\x02\xef\x01\xcd\x55\x39\x42\x95\x96\xc0\x59\ +\x00\xaa\x3c\x0c\x7c\x00\x6c\x54\xa5\x9d\xf3\x38\xcd\x19\xbe\x19\ +\x38\x5e\x95\x34\x55\x8e\x00\x9a\x63\x34\xae\x1e\x15\xe1\xf0\x88\ +\x6d\x36\x00\x2e\x05\x0e\x55\xa5\x0d\xd0\x07\x63\xb4\xde\xef\xda\ +\xcb\x39\x18\x03\xf0\x19\x8c\x21\x7a\x00\x30\x0a\xb8\xae\x0c\xdf\ +\x86\x21\x40\x5f\xe0\x6c\x4c\xac\x60\x6b\xe0\x29\x60\x88\x08\xc7\ +\x96\x61\xbc\xc5\x52\x26\x44\x68\x26\xc2\x4d\xce\xdf\x58\xa8\xed\ +\x1c\x11\xce\x76\xbd\x3e\xc0\xe9\xb3\x57\xd5\xec\xd2\x62\x29\x8a\ +\xaa\xee\xf6\x7a\xbd\x33\x6d\x72\x88\xa5\x36\x51\x97\x8d\xc0\x31\ +\x22\x7c\x2f\xc2\x62\x60\x12\xf0\x6f\x28\xa2\x3b\x75\x07\x50\x1f\ +\x78\x50\x95\x55\x00\xaa\xcc\xc6\x18\x80\xa7\x8a\x14\x26\x55\x3c\ +\x88\x39\x76\xbd\x57\x95\xc2\xe3\x23\x55\xa6\x94\xb6\x01\x55\xb6\ +\xa8\xf2\x87\xab\x29\x88\xf1\x28\xee\xc2\x54\x6e\x89\xe4\x65\x55\ +\xe6\x38\x63\x7f\x01\x66\x42\x91\x0c\xdf\x1b\x9d\xb1\x4f\xa9\xb2\ +\x4d\x95\x9d\xaa\xbc\x00\x45\xd6\x28\x86\x08\xcd\x80\x9b\x81\x51\ +\xaa\x7c\xaf\x4a\x50\x95\xdd\xc0\x50\x20\x0b\xe3\xcd\xb4\xd4\x50\ +\x44\xb8\x4d\x84\x75\x31\x1e\xe5\xfe\x44\x13\xa1\x83\x08\x0f\x8a\ +\xb0\x6f\x05\xb7\xd4\x0a\xe3\x75\x3e\xd8\xd5\x76\x07\x45\x43\x31\ +\xba\x39\x7d\x5a\x54\x70\x8d\x3d\x26\x3d\x3d\xfd\x9b\xf4\xf4\xf4\ +\xe1\x55\xb5\xbe\xa5\x28\x22\xa4\x8a\x90\x5d\xc2\x63\x93\x08\xb3\ +\x45\xf8\x3c\x51\xca\x07\x81\x40\xe0\xe7\x8c\x8c\x8c\x62\xe1\x40\ +\x16\x4b\x4d\xa5\x2e\x1f\x07\x2f\xc2\x04\x15\xa7\x02\x6d\x31\x59\ +\xc2\x1b\x5c\xd7\xbb\x62\xe2\xee\x9e\x8b\xd0\x06\x0d\xa9\x68\x77\ +\xc1\x1c\xcb\x76\x03\xa6\x3a\xc5\xcd\xcb\x8d\x08\x37\x01\x83\x81\ +\x03\x9d\xbd\x84\x68\x13\xd1\x35\x1f\xf8\x31\xa2\x2d\x03\x13\x4f\ +\x18\xa2\x13\x30\xc5\x6d\x8c\x3a\xcc\xc4\x78\x05\x63\xd1\x19\x48\ +\x02\x0e\x16\x61\x74\xc4\xb5\x3c\xcc\x7b\xb5\xd4\x5c\x1a\x01\x2d\ +\x31\x9e\xdd\xc8\x52\x40\x15\xa9\xb3\x7a\x10\xc6\x63\xfd\x1d\x26\ +\xfe\xb5\xbc\xac\xc3\x78\xac\x17\x54\x60\x6c\x65\x62\x75\x02\xab\ +\x17\x01\xe0\x2d\xcc\x0d\xc3\x22\xe0\x57\xcc\xef\x6f\x07\x4c\x3c\ +\xf7\xcf\x4e\xfb\xa9\xc0\x9f\x22\x9c\x94\x80\x3d\x4c\x59\xba\x74\ +\xe9\x3d\xbb\x76\xed\x22\x35\x35\xb5\xf4\xde\x96\x3d\x26\xa4\x13\ +\x38\x61\xc2\x84\x1e\xc0\x4f\x55\xbd\x9f\xda\x46\x5d\x36\x02\x7d\ +\x4e\x62\x08\x22\x5c\x09\x8c\xc4\xc4\xea\xbd\xe8\x5c\x6f\x04\x6c\ +\xc2\x18\x50\x91\x4c\x04\x56\x38\xcf\x53\x81\xdd\x15\xd9\x80\x08\ +\xd7\x60\xbc\x1d\xaf\x00\x0f\x63\xe2\x03\x77\x62\x3c\x77\x91\x3f\ +\x9b\x80\x2a\x39\x11\x6d\x91\xc2\xa8\x02\x51\x8d\xd1\xd2\x82\x2a\ +\x1a\x39\x5f\xe7\x02\xcb\x22\xae\xcd\x84\x70\xcc\xa1\xa5\x46\xf3\ +\xbe\x6a\xe1\xef\x6d\xa9\x38\xde\xee\x1c\x55\x36\x95\x67\x11\x11\ +\xbc\x98\x90\x82\x24\x60\x45\xe4\x0d\x92\x2a\x9b\x31\x1e\xef\x0a\ +\xe1\xe8\x7a\xb6\x05\xb2\x43\x7f\xc3\x96\xda\x8f\x2a\x01\x11\x0e\ +\x02\xc6\xaa\x32\xd0\x7d\x4d\x84\x9e\x98\xd0\x9d\x87\x30\x37\x18\ +\x5f\x63\x6e\x54\x46\xc6\x79\x1b\xbf\xaa\x2a\xb3\x67\xcf\xe6\xa8\ +\xa3\x8e\x8a\xf3\xd4\x16\x4b\xe5\x53\x97\x8d\xc0\x42\x54\x19\xe5\ +\xc4\xd3\x3d\x29\xc2\x28\x55\xd6\x62\x0c\xb2\x83\x80\xe7\x55\x4b\ +\x54\xa1\x9f\x8f\x49\xe8\x28\x89\x02\xa2\x7f\xaf\x2f\x04\xe6\x01\ +\xf7\xa8\x1a\x43\x4d\x84\x54\xcc\x71\x59\x45\x58\x0c\x9c\x24\x82\ +\x37\xe2\x83\xb7\x5b\x29\xe3\x42\xd9\xc8\x99\xaa\xa4\x57\x70\x6d\ +\x4b\x0d\x47\x04\x1f\xf0\x2c\x70\x38\x26\x1e\xb6\x9d\xd3\xfe\x0d\ +\xd0\x5f\x95\x5d\x22\x5c\x84\xf9\x80\x05\xc8\x74\x79\xc9\xdb\xaa\ +\xb2\x42\x84\x11\x98\xba\xae\x21\x37\x49\xae\x08\x43\x54\x79\xca\ +\xb5\x4e\x57\xcc\x0d\xc7\x19\xaa\xfc\xb7\x1c\xfb\xf3\x62\x6e\x96\ +\xee\x01\x1a\x3b\x6d\xd3\x80\x41\xaa\xcc\x2d\xff\x3b\xb6\xd4\x24\ +\x44\xd8\x07\xb8\x08\xe8\x1e\x79\x4d\x95\x19\x22\xfc\x0c\x5c\xea\ +\x3c\x7f\x13\xa3\x29\x18\x57\x54\x35\xab\x5e\xbd\x7a\x7f\x67\x66\ +\x66\x76\xb0\x46\x60\xa5\x63\x33\x44\x12\x40\x5d\x8e\x09\x8c\xe4\ +\x51\xcc\xf1\xcf\x03\xce\xeb\x11\x98\x78\xa4\xfb\x22\x3b\x8a\xd0\ +\xd6\xf5\x72\x14\x70\xb4\x08\x17\x44\xf4\x71\x6b\x49\xad\x04\x9a\ +\x47\x89\xa1\x5a\x01\xec\x85\xf1\x98\x84\x78\x80\x8a\x1b\xe7\xef\ +\x63\xbc\x7a\x0f\x88\x50\x5f\x84\x14\x11\x6e\x05\x8e\x2f\x69\x90\ +\x2a\x6b\x80\xff\x3a\xe3\x8a\x68\x1f\x88\x90\x2c\x52\x61\xa3\xd4\ +\x52\xbd\x68\x23\x42\xbb\x88\x47\xa4\xd6\x85\x60\xb2\xd8\x5f\x05\ +\x3a\x62\x3c\x2b\xe7\x63\xbc\x2b\x00\x3f\x60\xb2\xd5\xc1\x24\x11\ +\xb5\x77\x1e\xab\x9d\xb6\x05\x98\x78\xd6\xa6\x98\x9b\xa3\x57\x30\ +\x37\x57\x97\xc5\x61\xff\xaf\x61\xc4\xde\xfd\x98\x23\xc0\xb3\x31\ +\x71\xb4\xdf\x8b\x18\xe1\xe0\x38\x73\x1e\x60\xeb\x06\x57\x1f\xda\ +\x62\x3e\xb3\x1a\xc7\xb8\xbe\x17\xe1\x30\x9a\x2d\x25\xf4\xdb\x23\ +\x02\x81\xc0\xf8\xe9\xd3\xa7\x5b\xf9\x20\x4b\xad\xc0\x7a\x02\x1d\ +\x54\x59\x22\xc2\x48\xe0\x91\xe8\x35\xb9\x00\x00\x20\x00\x49\x44\ +\x41\x54\x46\x11\x9e\x53\xe5\x37\x11\x1e\xc7\x64\xc7\xfe\x03\x23\ +\xb3\x52\x1f\xf3\xc1\x76\x14\x61\x4f\xc7\x87\xc0\xb9\xc0\xd7\x22\ +\xfc\x1b\xf3\x21\xb8\x1f\x26\x2e\x25\x24\xc9\x32\x0e\x93\x7d\x3b\ +\x47\x84\x3f\x81\x65\xaa\xdc\x8a\xc9\x28\xbe\x15\xf8\x43\x84\xff\ +\x62\xee\x70\x1b\x63\x8c\xc6\x8a\xbc\x87\xb1\x22\xbc\x87\xc9\x0e\ +\xbe\x0d\x73\x34\xbc\x13\x73\x24\x72\x62\x29\xc3\x6f\xc2\x7c\xc0\ +\xff\xe5\x78\x7e\x36\x62\x8e\xf4\x4e\x03\x5e\x02\x5e\xa8\xc8\x9e\ +\x2a\x8a\x88\xa4\x61\xf4\x0a\x6b\x3a\xd9\x18\x63\x7f\xad\x56\xbd\ +\xd6\x41\xb4\x64\xa5\xcf\x80\x2b\x22\xda\x86\xa9\xf2\x96\xf3\xdc\ +\x2f\xc2\x55\x18\x99\xa3\x67\x1d\x6f\xe0\x7a\xe7\xda\x1a\xd5\xa2\ +\xe1\x03\xaa\x3c\xeb\x7a\xb9\x15\xf0\x39\x5e\xf6\xab\x80\xcf\x2b\ +\xba\x71\x11\x0e\xc4\xfc\x8e\xbe\xe2\x92\x2c\xfa\xdb\xd9\xcb\x74\ +\x8c\xe0\xfb\x07\x15\x9d\x3f\x1a\x56\x27\xb0\xda\x31\x17\xf3\xff\ +\xec\x71\x11\x06\x86\xc2\x14\x44\x48\xc2\x78\x08\x4f\x02\x6e\x77\ +\xfa\x1e\x48\xd1\x18\xef\xb8\xa1\xaa\x53\xe6\xcd\x9b\x77\x6d\x30\ +\x18\x24\x29\x29\xa9\xf4\x01\x96\x3d\xc2\xea\x04\x26\x96\xba\x68\ +\x04\xfe\x04\xe4\x42\xb1\xf8\x3a\x80\x27\x80\xe5\x98\x3b\xce\xb5\ +\xaa\x3c\x2d\x46\x48\xba\x2f\xe6\x9f\x4a\x0e\xa6\x78\x79\xa1\x2c\ +\x8b\x73\x54\x7c\x91\x73\x4c\x76\x32\xe6\x08\x79\x03\x26\xdb\x36\ +\xd4\xe7\x6f\x11\xba\x60\x64\x63\x5a\x62\x62\x0d\x51\x25\x53\x84\ +\x33\x30\x1f\x60\xfb\x01\xdf\x63\x0c\xc3\x6b\xa1\x88\x48\xf3\xcf\ +\x98\x04\x8d\x48\xfe\x0d\xcc\x72\x37\xa8\x72\xbd\x08\x1f\x63\x8e\ +\xf4\x96\x61\xe2\x17\x5f\xc7\x24\xbe\x84\xd8\x02\x3c\x89\x2b\x30\ +\x5f\x95\xa5\x22\x1c\x0a\xdc\x80\x31\x46\x3b\x63\xf4\x02\xef\x03\ +\xbe\x89\xb2\x76\x62\x69\xd8\xf0\x35\x76\xee\xbc\xb4\xd2\xd7\x4d\ +\x14\x1e\x4f\x9e\xa4\xa4\x7c\x47\x20\xf0\x2e\xf0\xa3\xaa\x06\xab\ +\x60\x17\xff\x00\xd6\x46\xb4\x45\x26\x8a\x80\xa9\xc8\xe0\x66\x0a\ +\x14\x0a\x9d\x97\x88\xe3\xed\xbe\x11\xe8\x85\xf9\x5d\x4f\xc2\x78\ +\xd4\xf7\xf4\xd4\xa1\x97\x33\x47\xc0\x49\xa6\x72\xb3\x95\x28\x47\ +\x84\x96\xda\x85\x2a\xb9\x22\x0c\x02\x46\x03\x1b\x45\x98\x85\xf1\ +\x40\x1f\x87\xf1\x02\x4e\x22\x2c\xdf\xd5\xd3\xe9\x97\x08\xa6\xe4\ +\xe5\xe5\x25\x2d\x58\xb0\x80\xae\x5d\xbb\x26\x68\x09\x4b\x88\xaa\ +\xbf\x77\xae\xdd\xd4\x39\x23\x50\x95\xf1\xb8\xf4\x00\x23\xae\x2d\ +\xc7\x18\x82\xee\xb6\xdf\x31\x55\x37\x4a\x9b\x77\x2c\xc5\x3f\x3c\ +\x23\xe7\x1e\xf6\xff\xed\x9d\x77\x78\x54\xd5\xd6\x87\xdf\x95\x64\ +\x12\xb8\x58\xb0\x5d\x01\x05\x11\xc5\xde\x0b\xf6\xf2\x89\x8d\xab\ +\xa8\x28\xa0\xd8\x88\xa0\xc2\x5c\xbc\x80\x1d\x90\x8b\xfd\xda\x45\ +\x50\x19\xae\x5e\x51\xb1\x03\xa2\xa2\x62\xa5\x08\xa1\x29\x09\x09\ +\x4d\xc4\x80\x44\xa4\xb7\x00\x81\x90\x99\xc9\xac\xef\x8f\x7d\x02\ +\x93\x61\x52\x49\x72\x32\x33\xfb\x7d\x9e\xf3\x24\xb3\xcf\xde\xfb\ +\xac\x49\x4e\x32\xeb\xec\xbd\xd6\x6f\x45\x69\xff\x01\x76\x8b\x8b\ +\x7a\x2d\xa2\xcf\x64\x8c\x33\x17\x39\x36\x6a\x89\x24\x47\x9e\x26\ +\x03\x40\x84\xfd\x31\x42\xd1\x1f\x85\x9d\xcf\x27\xe2\x7d\x3a\xed\ +\x85\x98\x2d\x37\xf7\xd9\xb6\x6d\x14\x29\x29\x37\xf0\xf5\x4f\xc9\ +\x1c\x13\xa3\xff\x68\xd7\xaf\x85\xcb\xce\x85\x76\xd7\xc0\xe9\x6d\ +\x52\xf9\x6c\x54\x7b\x32\x26\x5f\x4b\x6a\xea\x2a\x11\xb9\x55\x55\ +\x27\xd5\xb1\x45\x0b\x2a\x91\x18\xa2\x4e\x78\x40\x38\xdb\x29\x1d\ +\xb2\x10\x15\x47\x6a\xe8\x17\xcc\x16\xed\x0f\x98\x87\x97\x75\x98\ +\xed\xe3\xd6\x55\x37\xb7\x14\x25\xab\xea\x67\x60\x3e\xe0\xc3\x99\ +\xc9\xee\xce\xad\x25\x0e\x51\x65\x8c\x08\x27\x62\xc2\x02\x8e\xc7\ +\x3c\xb0\x4f\xc5\xec\xb6\xbc\x5b\x12\x0b\xad\x6a\xc2\x7a\xa2\x3c\ +\x30\xd4\x80\x0d\xba\x34\x35\x35\x75\x43\x4e\x4e\xce\x01\xd6\x09\ +\xb4\xc4\x3a\x09\xe7\x04\xc6\x3b\xce\xb6\xf2\x1c\x60\x29\x70\x00\ +\x70\x27\x26\x31\xe5\xe9\xf2\xc6\xd5\x37\x54\xf5\x53\xf1\xa4\xbe\ +\x4b\xaf\x3b\x6e\x66\xda\xdc\x06\xa4\xc5\x60\xb9\xce\x7d\x1b\xc3\ +\xf0\x91\x70\xcb\x75\xd0\xad\x27\x74\xeb\x99\xcc\x5f\x7f\x42\xbf\ +\x3e\x4d\xf9\xfa\x8b\x89\x92\x96\x36\x04\xbf\xff\x7e\x97\x56\x05\ +\x6b\x83\xf6\x98\x0f\xe5\xf3\x54\x99\x5e\xd2\x28\x42\x97\x1a\x98\ +\x7b\xa9\xf3\xf5\x41\xd5\xa8\x19\xfb\x35\x8e\xcf\xe7\x1b\x07\xac\ +\xf1\x7a\xbd\x36\x2e\xb0\x1e\x20\x42\x0b\x8c\xf3\xf7\xa2\xaa\xbb\ +\xb1\x9a\xc5\xc5\xc5\x93\xe7\xcc\x99\x73\x5d\x97\x2e\x5d\xec\x7e\ +\xb0\x25\xa6\xb1\x89\x21\xf1\xc7\x58\x8c\x08\xef\x1d\x98\x38\xc0\ +\xcf\x81\xe3\x9d\x8c\xe7\xd8\x22\x18\xe8\xcd\xf2\xbc\x35\x0c\x7a\ +\x30\x76\x9d\xa4\xcb\xff\x01\xe9\x77\xc3\x5d\xb7\xc0\xb6\x02\x38\ +\xb4\x05\xbc\xff\x99\x30\xec\x6d\x48\x4a\xbe\x87\xd4\xd4\x58\x14\ +\x23\x2e\x89\xb5\x6a\x19\xd1\x9e\x82\x79\xe0\x58\x56\xd2\xe0\x24\ +\x15\x5d\xca\x9e\x33\x03\xd8\x42\x58\x98\x45\x38\x8e\x6c\x4c\x4d\ +\x63\x75\x02\xeb\x17\x8d\x31\x1a\x81\xd1\x42\x79\xea\x94\x50\x28\ +\x34\x65\xce\x9c\x39\xe5\xa9\x46\x58\x6a\x88\x12\x9d\xc0\x8e\x1d\ +\x3b\x9e\xec\xb6\x2d\xf1\x88\x5d\x09\x8c\x33\x1c\x89\x97\xb8\x90\ +\x79\x51\xd5\x6d\x22\xd2\x91\x37\x87\xcd\xe4\xf2\xab\xa0\xed\x15\ +\x6e\x9b\x54\x3d\x9e\x7c\x01\xa6\x4e\x82\x87\xfb\xc0\x6b\x6f\x99\ +\xb6\x2e\x5d\xe1\x80\x83\x92\xb9\xa9\x7d\xba\xa4\xa4\x6c\xd4\x60\ +\xf0\x81\x3a\xb0\xe4\x51\x11\xb6\x46\x69\xef\x17\x45\x83\xb2\x3c\ +\x16\x62\xb6\x79\x9f\x12\xe1\x14\x8c\x73\xf6\x16\x30\x1a\x13\x7f\ +\xfa\x8e\x08\xff\xc5\x24\x4f\x0d\xc0\x24\x3a\xa5\xee\x89\xe1\xaa\ +\xac\x13\x53\x3b\xfb\xbf\x22\xec\x83\x79\xb8\xd9\x8a\x71\x44\xaf\ +\xc7\x64\x21\x47\x0d\x8f\xb0\xc4\x0d\xf3\x31\xf7\x5a\x27\xdc\xff\ +\x1f\x97\xb1\x75\xeb\x56\xcf\x9f\x7f\xfe\x49\x8b\x16\xe5\xe9\xf0\ +\x5b\x2c\xf5\x9b\xb2\x9d\xc0\x66\x7b\x55\xab\x02\x86\x8b\x58\x87\ +\x36\x0e\x51\xd5\xd9\x22\x32\x88\xee\x37\x0f\x22\xf3\xb7\x34\x0e\ +\x88\x54\x34\x89\x01\x1a\x34\x84\xff\x7d\x08\x6d\xcf\x82\x2b\xae\ +\x82\xf6\xd7\x9b\xf6\xcb\xff\x01\xff\x7e\x5a\x78\xf2\x91\x7b\x45\ +\x64\x9a\xaa\x96\x19\x53\xba\x87\xe4\x61\x84\x74\x8f\x28\xe3\x7c\ +\xc9\x96\xd6\x9f\x44\x89\x3d\xc5\xe8\x4f\xce\x2c\x79\xa1\x4a\xa1\ +\x93\xd0\x54\x22\x3f\x94\x0a\x7c\xa8\xca\x5a\x11\xba\x02\x83\x30\ +\x01\xfa\x73\x81\xfe\x18\xd9\x8e\x73\xc2\xe6\xdb\xe6\xd8\x13\x9e\ +\x94\x92\x83\x89\x25\x2c\x61\xa3\xd3\x67\x7b\xd8\x75\xdf\x14\xe1\ +\x77\x8c\x63\xf9\x3c\xd0\x08\x93\x18\x30\x11\x13\x02\x61\x89\x63\ +\x54\x09\x89\x70\x1b\xa6\x8a\x53\x3e\xf0\x83\x2a\xeb\x5d\x32\x27\ +\x27\x39\x39\xb9\x30\x27\x27\xa7\xa1\x75\x02\x2d\xb1\x8c\x44\x66\ +\xde\x88\xc8\xe1\x50\x2b\xe5\x76\xea\x82\x89\xaa\x5a\xe9\x8a\x08\ +\x96\xd8\x40\x44\x92\x48\x4d\x9b\xc6\x45\x97\x9c\xca\xe8\xf1\x31\ +\x18\x1c\xe8\xf0\xda\x4b\xf0\xd2\x7f\x60\xc6\x3c\x68\xd2\x6c\x57\ +\xfb\x3f\xd3\x95\x51\x1f\x6e\x21\x18\x38\x4e\x55\x23\x93\x32\x2c\ +\x35\x88\x88\xa4\x03\xc3\x55\xb5\x41\x45\x7d\x7d\x3e\x9f\x07\xac\ +\x54\x4c\x7d\xc1\x11\xd2\x5f\x0a\xec\x87\x79\xf0\x50\x76\x97\x81\ +\xf9\x21\xbc\x9a\x88\x93\x18\xf2\xac\xea\xce\x72\x9f\x35\x86\xc7\ +\xe3\x99\x78\xe5\x95\x57\x5e\x3c\x70\xe0\xc0\xda\x08\x45\xb0\x38\ +\x6c\xdc\xb8\x91\x65\xcb\x96\x31\x71\xe2\xc4\xfb\x47\x8f\x1e\xfd\ +\xb2\xdb\xf6\xc4\x1b\xbb\x39\x81\x16\x4b\x7d\x44\x44\x0e\x23\xc5\ +\xb3\x80\x17\x5e\x6d\xc4\x1d\x3d\xdc\x36\xa7\x7a\xa8\xc2\x75\x97\ +\x81\x08\x7c\xf6\xbd\xf9\x0a\x26\x56\xf0\xec\x13\x02\xac\x5e\x99\ +\x41\x20\xd0\xb6\x1e\xe8\x09\xc6\x2d\x55\x71\x02\x2d\xf5\x0b\x11\ +\x52\x31\x2b\xc0\xe5\xb1\x40\x95\x9d\x71\xb6\xb5\xe9\x04\x8a\xc8\ +\xa0\x26\x4d\x9a\x0c\xf8\xfc\xf3\xcf\x63\xf7\xc1\x34\x06\xd8\xbc\ +\x79\x33\x57\x5c\x71\x05\xc0\xa5\xaa\x1a\x55\xd9\xc3\x52\x7d\xec\ +\x16\xaa\x25\x26\x50\xd5\x3c\x11\xb9\x8b\x87\x7b\x8f\xe4\xfc\x8b\ +\x53\x68\x7d\xb4\xdb\x26\x55\x1d\x11\xf8\xef\x48\x38\xe7\x44\x18\ +\x36\x18\x7a\xdd\x67\xda\x1b\xed\x05\x23\x3e\xf6\x70\xc5\xf9\x17\ +\x63\x2a\x73\xd8\xa7\x5d\x8b\x25\x02\x55\xfc\x40\x5f\xb7\xed\x08\ +\x23\x63\xf5\xea\xd5\x69\x1b\x37\x6e\x64\xff\xfd\xf7\x77\xdb\x96\ +\xb8\x25\xec\x99\xd8\x3e\x1c\xd7\x02\x36\x3b\xd8\x12\x33\xa8\xea\ +\x47\x84\x42\x63\xb8\xbd\x63\x21\x81\x18\xdd\xa1\x6b\xd2\x0c\x86\ +\xbe\x09\x4f\x0c\x80\xf9\x61\x02\xf8\x67\x9e\x0d\x0f\x0f\x12\x92\ +\x92\x9e\x15\x91\x93\xdc\x33\xd0\x62\xb1\x54\x92\x99\x22\x52\x3c\ +\x77\xee\xdc\x8a\x7b\x5a\x2c\xf5\x14\xeb\x04\x5a\x62\x8b\x60\xb0\ +\x27\x4b\x16\xe7\xf3\xe4\x23\xb1\x2b\x1b\xd3\xfe\x7a\xe8\x7c\x2b\ +\xdc\x79\x0b\xec\x08\x4b\xca\x7d\xe0\x11\x38\xed\x4c\xc1\x93\x3a\ +\x5a\x44\xec\x76\xa5\xcb\xf8\x7c\xbe\x71\x3e\x9f\x2f\x16\x25\x7c\ +\xe2\x1a\x11\x5a\x88\xd0\x4b\x84\x97\x45\x18\x1e\x71\xf4\xaa\x2b\ +\x3b\x54\x75\xbb\xc7\xe3\x99\x9f\x93\x63\xab\x99\xd5\x36\x1e\x8f\ +\x87\x94\x94\x14\x1b\x7b\x59\x0b\x58\x27\xd0\x12\x53\xa8\xea\x66\ +\xfc\xfe\xce\xbc\xf6\x12\x64\x4c\x76\xdb\x9c\xea\xf3\xdc\x10\xf0\ +\x17\xc1\xa0\x07\x77\xb5\x25\x27\xc3\x5b\x1f\xa5\xe0\xf1\xb4\x42\ +\xa4\x4e\x6b\x35\x5b\xa2\x62\x75\x02\xeb\x19\x22\x74\xc4\x94\xbb\ +\x1c\x0c\xf4\x02\xae\x01\xba\x62\x4a\x15\x5e\x4f\x1d\x97\x0f\xf4\ +\xfb\xfd\x13\x33\x33\x33\xa3\x95\xf4\xb4\xd4\x10\xc5\xc5\xc5\x0c\ +\x19\x32\x84\x0e\x1d\x3a\xd8\x1d\x92\x5a\xc0\x3a\x81\x96\x98\x43\ +\x55\x33\x50\x7d\x96\xf4\x1b\x77\xb0\x39\xdf\x6d\x73\xaa\xc7\xdf\ +\x1a\xc1\x9b\x1f\xc0\xdb\xff\x85\x1f\xbe\xd9\xd5\x7e\xd8\xe1\xf0\ +\xb2\x2f\x05\xd5\x7b\x44\xa4\x9d\x7b\x06\x5a\x2c\xf5\x0b\x11\x3c\ +\xc0\x30\x8c\x1e\xe4\x61\xc0\x62\x4c\xad\xf3\x46\xc0\xad\x98\x1a\ +\xd2\xcf\xd6\xb1\x59\x19\xb9\xb9\xb9\x9e\xc2\xc2\xc2\x3a\xbe\xac\ +\xc5\x52\x33\x58\x27\xd0\x12\x9b\xa8\x3e\xc6\x96\xfc\x45\xf4\xea\ +\x56\xe4\xb6\x29\xd5\xe6\xf4\x36\xf0\xf0\xa3\xd0\xeb\x0e\x58\xbf\ +\x6e\x57\xfb\x4d\xb7\xc1\xf5\x37\x86\xf0\x78\xde\x17\x91\x83\x6a\ +\xeb\xf2\x22\x74\x10\xa1\x6d\x0d\xce\x77\xa4\x08\x3d\x45\xb0\x5b\ +\xd9\x96\xda\xe0\x08\xe0\x20\xe0\xf9\xb0\x0a\x48\x8d\x54\x09\xa9\ +\xf2\x01\xf0\x21\xf0\x64\x1d\xdb\x94\x11\x0a\x85\x64\xc1\x82\x05\ +\x75\x7c\x59\x8b\xa5\x66\xb0\x4e\xa0\x25\x26\x51\xd5\x20\x7e\x7f\ +\x67\xbe\x19\xa7\x7c\x3c\xd2\x6d\x73\xaa\xcf\x7d\xfd\xe1\x88\xa3\ +\xe0\x9e\xee\xa5\xdb\x07\x0f\x4f\xe2\x80\x83\xf6\x26\x25\xe5\xdd\ +\x5a\xbc\x7a\x3f\xa0\x7b\x85\xbd\x2a\xcf\x99\x98\x4a\x0e\xfb\x94\ +\x34\x88\x70\xaf\x08\x17\xd6\xe0\x35\xea\x92\xf6\xe0\x6e\x8d\x5a\ +\x4b\x29\xf6\xc3\x94\x25\xcc\x72\x5e\x6f\x04\x8e\x0b\x3b\x3f\x0f\ +\x38\xa3\x2e\x0d\x52\xd5\xb5\xa9\xa9\xa9\x79\xd9\xd9\x75\x52\xce\ +\x3a\x61\x09\x06\x83\x84\x42\x21\x9b\x1d\x5c\x0b\x58\x27\xd0\x12\ +\xb3\xa8\xea\xef\x14\x17\xdf\x43\x9f\x1e\x01\x96\x2d\x75\xdb\x9c\ +\xea\x91\x94\x04\x6f\xbc\x07\xd3\xa7\xc0\x88\xe1\xbb\xda\xf7\x6d\ +\x0c\x6f\x7d\xe8\xa1\xb8\xf8\x4a\x11\xf1\xba\x67\x60\x95\xc8\xc2\ +\x48\xdc\x84\x97\xa6\x7b\x1c\x88\xc9\x7a\x7f\x5e\xaf\x37\x60\x85\ +\xa2\xeb\x15\x7f\x62\x3e\xb3\x9a\x3a\xaf\x7f\x07\xce\x13\xa1\x44\ +\xa7\xaf\x1d\x50\xe7\x95\xae\x02\x81\xc0\xc4\x39\x73\xe6\xc4\x5a\ +\x85\xad\x98\x21\x39\x39\x99\xde\xbd\x7b\xf3\xe9\xa7\x9f\xda\x34\ +\xec\x5a\xc0\x3a\x81\x96\x98\x46\x55\xdf\xa2\x38\xf8\x0d\x5d\x3b\ +\x15\x52\x1c\xa3\x09\xc3\xcd\x0f\x83\x97\x86\xc1\x23\xf7\xc3\xe2\ +\x45\xbb\xda\xcf\xbb\x08\xee\xed\x27\x24\x27\xbf\x22\x22\xc7\xec\ +\xe9\x65\x44\xf0\x88\x70\xb8\x08\x95\xca\xb2\x13\xe1\x60\x11\x9a\ +\x47\xb4\xed\x2b\x42\x2b\x91\x9d\xa5\xe6\x76\xa2\xca\x6f\xaa\xbc\ +\xa2\x4a\x95\x02\xa4\x44\x68\x22\x42\xb3\x8a\x7b\x5a\x12\x19\x55\ +\x56\x00\xbf\x02\xd7\x3a\x4d\x6f\x00\xff\x07\xfc\x21\xc2\x7c\xa0\ +\x1b\x66\x4b\xb8\x8e\xed\xd2\xa9\xf3\xe7\xcf\x97\x50\x28\x54\xd7\ +\x97\xb6\x58\xf6\x18\xeb\x04\x26\x20\x22\x1c\xed\xc4\x6e\xc5\x47\ +\xe6\x63\x30\xd8\x8d\x85\xf3\x0a\x78\xfe\x89\x18\xf5\x02\x81\x4e\ +\x37\x43\xfb\x0e\x70\xd7\x2d\x94\xd2\x40\xec\xff\x38\x1c\x7f\x52\ +\x12\x1e\xcf\x28\x11\x49\xad\xee\xf4\x22\xf4\xc7\x04\xce\x2f\x05\ +\x36\x89\xec\xbe\xcd\xe9\x6c\xdd\xaa\x08\x67\x89\xb0\x04\x58\x0d\ +\x0c\x71\xce\x1d\x2f\xc2\x6c\x20\x1f\x58\x02\x14\x88\xf0\xb8\xc8\ +\x2e\xc1\x79\x11\xba\x38\xe3\xff\xee\xbc\xf6\x03\x7b\x03\x03\x9c\ +\x76\x15\xe1\xc1\x88\xfe\x2b\x80\x55\xc0\x0a\x11\x96\x8b\x70\x55\ +\x75\xdf\xa3\x25\x21\xb8\x14\x18\x0b\xa0\xca\xcf\xc0\x65\x98\x1a\ +\xd3\x39\xce\xb9\xba\x4e\x0c\x01\xc8\x28\x2a\x2a\x4a\x5e\xbc\x78\ +\xb1\x0b\x97\xb6\x58\xf6\x8c\x84\x73\x02\x45\xf8\x4a\x84\xd5\xce\ +\xb1\x4a\x84\x1c\x11\x3e\x14\xa9\xbd\x58\x12\x11\xee\x10\xe1\x9a\ +\xda\x9a\xbf\x1a\x9c\x8b\x89\xdd\x6a\xe8\xb6\x21\x35\x81\xaa\x6e\ +\x20\x10\xb8\x85\x17\x9e\x82\x9f\x67\xb8\x6d\x4e\xf5\x79\xf1\x75\ +\xd8\xb8\x01\x9e\x1a\xb8\xab\xcd\xe3\x81\x11\x1f\xa7\x90\x94\x74\ +\x1c\xf0\x54\x75\xa6\x15\xe1\x0e\xe0\x69\x60\x10\xb0\x3f\xe6\xf7\ +\x7f\x37\xa5\xe3\xa9\xc2\x79\xdf\x39\x8e\x04\xfa\x8b\xb0\x17\x30\ +\x11\x53\x61\xe8\x4c\xe0\x00\x60\xa0\x73\xf4\x2f\xe7\xd2\xad\x81\ +\x02\x4c\x46\xe7\xe1\xce\xf1\x5f\xc7\xa6\x5b\x31\xab\x36\xa3\x81\ +\xd3\x81\x53\x81\xe9\xc0\x17\x22\x1c\x5b\x9d\xf7\x59\xd3\x58\x9d\ +\xc0\xfa\x87\x2a\x2b\xc3\x92\x42\x50\x65\xa2\x2a\x5d\x54\xb9\x05\ +\x73\xff\xfc\xad\xee\x6d\xd2\xdf\x53\x52\x52\x36\x59\xbd\xc0\xda\ +\xc3\xea\x04\xd6\x1e\x09\xe7\x04\x62\x3e\xc0\x02\xc0\x63\xc0\x13\ +\xc0\x6c\xcc\x13\xe4\x74\x11\x4e\xab\xa5\x6b\xf6\x01\xba\xd4\xd2\ +\xdc\x16\x40\x55\x7f\x40\x75\x28\xb7\x77\x2c\xa4\x60\x6b\xc5\x03\ +\xea\x23\xfb\xec\x0b\x6f\xbe\x6f\x4a\xca\x85\x6b\x20\x1e\x79\x14\ +\x3c\x37\x34\x19\x91\x07\x44\xe4\xff\xaa\x31\x73\x7f\xe0\x6b\x55\ +\x5e\x54\x65\x93\x2a\x0b\x31\xda\x6a\x8d\xca\xe8\xff\xb6\x2a\x8f\ +\xaa\xb2\x44\x95\xdf\x30\xc9\x23\x07\x01\x37\xab\x32\x5b\x95\x8d\ +\xaa\xbc\x04\x7c\x0c\x3c\x54\x56\x36\xb0\x2a\x79\x98\x52\x4f\xf9\ +\xaa\x2c\x73\x8e\x2d\xce\x76\xf4\x0b\xc0\x34\x55\xfa\xaa\x92\xa5\ +\x4a\xb6\x63\x53\x01\x26\xae\xb0\x3e\x60\x75\x02\x63\x8b\xa1\xc0\ +\x27\x6e\x5c\x58\x55\xa7\x64\x67\x67\xdb\xfd\xe0\x5a\xc0\xea\x04\ +\xd6\x2e\x89\xe8\x04\x02\x6c\x50\x65\xb8\x2a\x3e\x55\xba\x03\xb7\ +\x60\xfe\xd9\x47\xcd\x04\x74\xe2\xa0\x2a\x8c\xa5\x12\xe1\x20\x67\ +\xab\xb5\xac\x0f\xd7\xb2\xc6\xed\x2f\xc2\x31\x22\x15\x17\x39\x17\ +\x21\x49\x84\x23\x44\xca\x5e\xc5\x13\x21\xcd\x89\xdb\xaa\xf2\x93\ +\x93\x33\x7f\x2b\x11\xf6\xae\xea\x58\xd7\x51\xed\xcf\x86\x75\xcb\ +\xe8\xdb\x23\x76\x65\x63\xce\x3e\x1f\xfa\x3e\x0c\x3d\x6e\x87\xfc\ +\x4d\xbb\xda\xd3\xef\x86\x2b\xaf\x56\x3c\x9e\x8f\x44\x64\xbf\xca\ +\x4e\xe7\xdc\x8b\xad\x81\x1f\xc3\xdb\x1d\x47\x70\x79\x19\xc3\xbe\ +\x8f\x78\x7d\x2a\x90\xe7\x8c\x09\x67\x3c\xb0\x17\x66\x85\xaf\x2a\ +\x34\x07\x9a\x60\xb6\x80\x7b\x96\x1c\x40\x3a\xf0\x07\x75\x2c\xf8\ +\x6b\xb1\xec\x29\xc5\xc5\xc5\x3f\x65\x65\x65\xc5\x6e\x38\x8a\x25\ +\x61\x49\x54\x27\x30\x92\x9f\x00\x3f\x94\x0e\x4e\x17\xe1\x1c\x11\ +\xe6\x61\xe2\xa0\x96\x02\x9b\x45\xe8\x1d\x39\x58\x84\x8e\x22\xac\ +\x04\xd6\x02\x8b\x80\x7c\x11\x5e\x76\xce\x2d\x02\x4e\x06\x6e\x0a\ +\x8b\x8b\xf2\x39\xe7\x2e\x15\x61\x31\xb0\x01\x13\xf0\xbc\x49\x84\ +\x59\x22\x1c\x1d\x31\xff\x4f\x22\x8c\x17\xc1\x8b\x91\x45\xc8\x05\ +\xb6\x8a\xd0\x2f\xa2\x9f\x88\xf0\x34\x26\x3b\x73\x89\x33\xdf\x9d\ +\xce\x9c\xe5\x06\x4c\x8b\xd0\x50\x84\xc1\x98\x95\x98\x25\xce\x7b\ +\x9d\x24\x42\xcb\x0a\x7f\x7a\xf5\x04\x55\x2d\x22\x10\xe8\xc4\xd8\ +\x51\xc2\x67\xa3\xdc\x36\xa7\xfa\x3c\xfc\x28\x34\x69\x0a\xf7\xf6\ +\x2c\xdd\xfe\xda\x88\x24\xf6\x6d\xbc\x3f\xc9\xc9\x55\xd9\xa2\x3c\ +\xd0\xf9\xba\x29\xca\xb9\x68\x6d\x60\xa4\x36\xc2\x39\x18\x73\xdf\ +\x45\x52\xd2\x76\x60\x94\x73\xe5\x51\xf2\x77\xd6\x0a\xb8\x2e\xe2\ +\x58\x83\xf9\x1b\xb2\x58\x62\x89\x8c\xcd\x9b\x37\x7b\x56\xac\x58\ +\xe1\xb6\x1d\x16\x4b\x95\x48\xa9\xb8\x4b\x42\x70\x05\x66\xeb\x67\ +\x7a\x49\x83\x08\x27\x01\x53\x80\x2f\x31\xdb\x53\x4b\x80\x9e\xc0\ +\x10\x11\xd6\xaa\xf2\xb1\xd3\xaf\x03\x26\xae\xe9\x4d\xe0\x45\x60\ +\x25\x70\x12\xec\x8c\x6b\x6a\x0b\xfc\x80\x71\xdc\x4a\x1c\xc8\x2d\ +\xce\x57\xc5\xc4\x79\x4d\xc6\x04\xed\x5f\x86\x11\x3b\xfd\x48\x84\ +\x33\x54\x09\xdf\x5e\x38\x07\xd8\x17\x93\x01\xb7\x18\x13\xdf\xf5\ +\x8c\x08\x3f\xaa\x32\xdb\xe9\xd3\x13\xa3\xfd\xf6\x26\xf0\x32\x70\ +\x0a\x30\x00\x23\xb2\xba\xa4\x82\x9f\xc1\x7b\xc0\x05\x4e\xff\x31\ +\x40\x1b\x8c\xbc\xc7\x97\x22\x9c\xa2\x4a\x9d\x3d\xe5\x8a\xc8\x49\ +\x98\xf7\x59\x3d\x42\xc5\xd3\xe9\x71\xdb\xf9\xb4\x39\x27\x85\x43\ +\x9a\x57\xdc\xbf\xbe\x91\x92\x62\xaa\x89\x5c\x70\x2a\x7c\x3c\x12\ +\x6e\xba\xdd\xb4\x1f\x70\x20\xbc\xf1\xbe\x87\x1b\xae\xbc\x41\x44\ +\xd2\x55\xf5\x9d\x4a\xcc\xb6\x12\x28\x66\x97\xac\x46\x38\x4d\x61\ +\xb7\xd5\x3d\x30\xf7\x65\x38\xcb\x30\xab\x81\x91\x94\x38\x73\x7f\ +\x95\x73\x7d\x85\xdd\x56\xa4\x4b\xee\xc5\xb7\x54\x19\x4e\xfd\xa5\ +\xbd\xdb\x06\x58\x62\x86\x39\xc9\xc9\xc9\x3b\xb2\xb3\xb3\x1b\x1c\ +\x72\xc8\x21\x6e\xdb\x12\x77\x04\x83\x41\x54\xd5\x6e\xb7\xd7\x02\ +\x89\xea\x04\xfe\xdd\x59\x45\x13\xe0\x2c\xe0\x72\x8c\x03\xf8\x5e\ +\x58\x9f\x67\x31\xce\xda\x2d\x61\x92\x17\x0f\x8b\x70\x01\xf0\x20\ +\x26\x1e\x0a\x8c\xe3\x37\x59\x95\xbb\xc3\xc6\x4e\x77\x0e\x54\x59\ +\xe1\x64\x49\x6e\x53\x65\x59\xb8\x11\xaa\x4c\x88\xb0\x6b\x8c\x93\ +\xb1\xfb\x21\x70\x02\x10\xae\x8b\xd4\x18\xb8\x5d\xd5\x7c\x80\x3a\ +\x59\x96\x9d\x30\x8e\x63\x89\x13\xd8\x0f\xc8\x52\xa5\x64\x09\x69\ +\xb1\x93\xd1\xf9\x7b\x79\x3f\x0c\x11\xce\x06\x6e\x00\x1e\x52\xe5\ +\x15\xa7\xf9\x2f\x11\xb6\x03\xdf\x60\x9c\xe4\xf1\xe5\xcd\x51\xc3\ +\xcc\x27\x35\xed\x0c\x84\x73\xe9\xd0\xb9\xea\x7f\xf8\x0a\x64\x67\ +\x26\xd1\xe3\x76\x18\x37\xc1\x68\xf1\xc5\x1a\xad\x8e\x34\xf5\x85\ +\x1f\xb8\x07\xce\xb9\xc0\x94\x93\x03\xb8\xe4\x72\xe8\xd9\x07\xde\ +\x78\x75\x98\x88\x4c\x55\xd5\x72\x9d\x7b\x55\x02\x22\xcc\x02\x3a\ +\x89\xf0\xbc\xaa\x71\xf0\x44\xb8\x0c\x4c\x16\x6f\x25\x98\x0a\xf4\ +\x14\xa1\x6d\xc4\x3d\x7b\x3b\x66\x4b\xf9\xcf\x72\xc6\xae\x83\xd2\ +\xab\xc9\xaa\xac\x13\x61\x0e\x70\xb7\x08\xff\x53\x2d\xad\xed\x26\ +\x82\x94\xd8\xe9\x26\x56\x23\xd0\x52\x59\x54\x35\x98\x9a\x9a\xfa\ +\x4b\x4e\x4e\xce\x05\x57\x5d\x65\x13\xdc\x6b\x92\x12\x9d\x40\x4a\ +\x7f\x1e\x5a\x6a\x88\x44\x75\x02\xf7\x03\x6e\x02\xd2\x80\xa3\x81\ +\xed\x40\x6f\x55\x56\x86\xf5\x39\x13\xb3\xe2\xd6\x55\x4a\xaf\x63\ +\xac\x03\x2e\x17\x21\xc9\x99\xa7\x15\xec\x74\x9c\xaa\x8c\x08\xed\ +\x80\xce\x98\x38\xa9\xbd\xd8\x15\x88\xde\x92\xd2\x37\xfd\xbc\x12\ +\x07\x10\x4c\xd0\xbd\x08\xcb\x71\x56\x63\x44\xd8\x07\x68\xc1\x2e\ +\xe7\xb4\xa4\xdf\x52\xa7\x5f\x79\xb4\x71\xbe\x7a\x9c\xd8\xac\x12\ +\x92\x31\xe2\xab\x27\x51\x87\x4e\xa0\xaa\x86\x44\xa4\x0b\x1e\xcf\ +\x42\xce\x3a\x6f\x2f\xee\xe8\x51\xf5\x49\xd6\xac\x86\xf3\x4e\x82\ +\xa1\x2f\x98\x18\xbb\x58\xe4\xd6\x6e\xf0\xfd\x78\xb8\xfb\x56\x18\ +\x3f\x05\x92\x1d\x69\xbe\xc7\x9e\x85\x89\xdf\xa5\xb0\x34\xf7\x63\ +\x11\x39\x47\x55\x2b\x12\xaa\x1d\x88\x59\x8d\x1e\x25\xc2\x08\xcc\ +\x0a\xe0\x00\x8c\x04\x4c\x65\xf8\x18\xb3\x1a\x3e\x4a\x84\x47\x31\ +\x2b\x7f\x37\x63\x56\x8e\x6f\xac\x60\x95\x78\x32\xd0\x51\x84\x21\ +\x98\x78\xbf\xa9\xaa\x64\x02\x3d\x30\x61\x18\x19\x22\x0c\x77\x6c\ +\x69\x86\x79\xa8\xf9\x15\x93\xb4\x65\xb1\x20\x42\x37\xcc\x4e\x4d\ +\x45\x1c\x8b\x09\xdd\x71\x85\x40\x20\x30\x29\x33\x33\xb3\x0d\xec\ +\x14\xaf\xb6\xd4\x00\xaa\xae\x3f\x0f\xc6\x35\x89\xea\x04\xfe\xa6\ +\xca\x29\x00\x8e\xa6\xd9\xe7\xc0\x44\x11\x8e\x55\x65\xa5\x08\xa9\ +\x98\x38\xa7\x8d\x98\x38\xa5\x48\x7e\xc2\xc8\xab\x94\x6c\x87\xad\ +\x8b\xd2\xa7\x42\x9c\xd5\xc8\x67\x30\xba\x57\xd3\x30\x2b\x76\xfb\ +\x00\xa7\xb1\xbb\x7c\x4b\xb4\x2d\xb7\x42\xd8\x29\xda\x5b\x92\x54\ +\x92\x17\xa5\xdf\x96\x28\x6d\xe1\x34\xc5\x94\x63\x8a\x56\xde\x6b\ +\x02\xd1\xe3\xc1\x6a\x15\x55\x5d\x2e\x22\xdd\x79\xb8\xf7\x07\x9c\ +\x7f\x71\x0a\xad\x8f\xae\x78\x50\x38\x07\x37\x81\x57\xff\x07\x5d\ +\x3b\xc1\xc5\x97\xc2\x29\xa7\xd7\x8e\xa1\xb5\xcd\x90\x37\xe0\xdc\ +\x93\xe0\x85\xa7\xa0\xdf\xa3\xa6\x2d\x2d\x0d\xde\x19\xe5\xe1\xc2\ +\xd3\x4e\x05\xfe\x0d\x3c\x5a\xde\x14\xaa\x4c\x12\xe1\x4a\x4c\x46\ +\xfc\x3b\x18\x4d\xb5\xdb\x9c\x63\x55\x58\xd7\xbf\x30\xf7\x76\x28\ +\x62\x7c\x48\x84\x8b\x31\xab\xe3\xff\xc4\xfc\x6d\x2c\x02\xda\xa9\ +\xf2\x5d\x58\xd7\xb5\xec\x8a\xaf\x2d\xe1\x01\xcc\x96\xf4\x29\x98\ +\xd8\xd8\xd5\x40\xa6\x2a\xbf\x38\x21\x17\x4f\x63\x1c\xd2\xbf\x3b\ +\xe3\x67\x52\xb7\xab\xce\x96\xfa\xcf\x10\xcc\x03\x72\x65\xf8\xba\ +\x36\x0d\xa9\x80\x8c\x15\x2b\x56\x0c\xca\xcf\xcf\xa7\x71\xe3\x0a\ +\x73\xfc\x2c\x96\x7a\x41\xb9\x4e\xa0\x88\x9c\x83\x89\x69\x3b\x82\ +\xdd\xe3\x7a\xdc\x26\x84\x89\x2d\x9a\xa0\xaa\x33\xab\x3b\x89\x2a\ +\x6b\x45\xe8\x82\x59\x75\x1b\x02\x74\x52\xc5\x2f\xc2\x5f\xc0\x14\ +\xd5\xb2\x6b\x87\x3a\x82\xba\x0a\x1c\x56\xcd\xcb\xff\x0b\xf8\x4a\ +\x95\x1b\xc2\xe6\x3c\xbb\x9a\x73\xad\xc0\x48\xdf\x5c\x80\xd1\x65\ +\x2b\x99\x2f\x09\xb3\xca\x38\xbf\x9c\xb1\x4b\x31\x49\x42\xe9\xaa\ +\x95\x5e\x1d\xaa\x75\x54\x75\x94\xa4\xa6\x5d\x4b\xd7\x4e\xd7\xf3\ +\x53\x66\x03\x3c\x55\x54\xeb\x68\x77\x0d\xdc\x72\x87\x11\x60\x9e\ +\x92\x05\x0d\xeb\x5c\x42\x6c\xcf\xd9\x6f\x7f\x18\xfe\x2e\x74\x6c\ +\x07\x6d\xaf\x80\x33\x9d\xdb\xe3\xd8\x13\xe0\xc9\x17\x93\xe9\xdf\ +\x77\xa0\x88\x7c\xa7\xaa\xd3\xcb\x9b\x46\x95\x1f\x89\xc8\x10\x06\ +\x66\x44\xf4\x19\x8d\x89\x6f\x8d\x36\x7e\x1b\xe6\x7e\x2d\xef\x1a\ +\x13\xa0\x74\x88\x83\x2a\xf9\x98\xf8\xd5\x68\xfd\x73\x81\x1b\xcb\ +\x9b\xd3\x4d\x7c\x3e\xdf\x38\x60\x8d\xd7\xeb\xb5\xf5\x83\xdd\xe5\ +\x5c\xd8\xbd\x42\x4d\x19\x6c\xae\x4d\x43\x2a\x60\x86\x88\x84\xe6\ +\xce\x9d\x9b\x74\xe1\x85\xb1\x5a\x2e\xbb\x7e\xe2\x31\xff\xfb\xeb\ +\x9b\x0f\x12\x17\x44\x75\x02\x45\xc4\x83\xc8\xeb\xc0\x5d\x1c\xdc\ +\xd4\xcf\x09\x27\x27\x93\xea\xa9\x5f\xbf\x00\x7f\x40\x99\x9f\x53\ +\xcc\x9a\x55\x4f\x49\x52\xd2\x9b\xa8\x7a\x55\xb5\x5a\xc9\x0b\xce\ +\xd6\xea\xcb\xc0\x63\x22\x9c\xaa\xca\x1c\xe0\x5b\xe0\x06\x11\x06\ +\xaa\xb2\x26\xbc\x7f\x49\xcc\x92\x2a\xdb\x45\x98\x06\x74\x13\xe1\ +\x65\x55\xca\x8a\x21\x5a\x4b\x84\x8c\x86\x23\xdf\x92\xc4\xee\x09\ +\x1b\xb7\x55\xf3\x3d\x14\x8b\xf0\x2d\x70\x89\x08\x07\x87\xd9\x7c\ +\x17\x54\x28\x3d\x33\x09\xb3\x7a\xd3\x0b\xb3\xb2\x54\x0a\x57\x63\ +\xb4\x02\xfe\x9e\x2c\x59\x7c\x11\x4f\x0d\x6c\xca\xe3\xcf\x55\x3d\ +\xb8\xef\x3f\x2f\xc3\x85\xa7\xc1\x80\xfb\x60\x70\x7d\xce\x41\x28\ +\x87\x8b\xda\x42\x8f\xde\x66\x5b\x38\x23\x1b\x1a\x39\x8b\x22\x3d\ +\xfe\x05\xdf\x7d\xa5\x64\x4c\xfe\x44\x44\x8e\x57\xd5\x8a\x56\x7c\ +\x2d\x55\xc3\xea\x04\xd6\x03\x54\x77\xcb\x56\xaf\x97\xa8\x6a\x41\ +\x5a\x5a\xda\xc2\x9c\x9c\x9c\x13\xac\x13\x58\x73\x94\xe8\x04\x4e\ +\x9a\x34\xe9\x64\x8c\x68\xbd\xa5\x06\x29\x6b\x25\x70\x20\xa9\xa9\ +\x77\x30\x7c\x24\x74\xe8\x5c\xed\x52\x55\x75\x40\x32\x63\x3e\x02\ +\x6f\xd7\x6e\x04\x02\xcb\x31\x99\xb5\xd5\xe5\x15\xa0\x2f\x66\x6b\ +\xed\x3a\x8c\xc0\x6e\x3b\x60\x86\xe3\x20\xe6\x62\xb6\xc1\xce\xc6\ +\x08\x4e\x97\x88\x3f\xdf\x87\xc9\x22\x9e\x21\xc2\xeb\x18\x89\x8b\ +\x63\x80\x66\xaa\x3c\xe0\xf4\xf9\x09\x78\x54\x84\xff\x62\xe2\x9d\ +\xe6\xaa\x32\x51\x84\x77\x31\x01\xf7\xab\x30\x5b\x74\xd7\x10\x7d\ +\x4b\xb6\xb2\xf4\x77\x6c\xf9\x43\x84\x91\x98\x8c\xce\x7d\x1d\xdb\ +\xcb\x4c\xb0\x50\x25\x57\x84\x27\x80\x27\x44\x68\x8a\x71\x80\x8b\ +\x30\xf1\x8e\x37\x61\xb2\x9a\x7f\xd9\x03\xbb\xaa\x8d\xaa\x6e\x15\ +\x91\x4e\xbc\xfa\xe2\x54\x2e\x6b\x07\xe7\x5f\x5c\xb5\x09\x1a\xfe\ +\xcd\x64\xda\x5e\x7e\x2e\x5c\xfe\x0f\xb3\x3a\x18\x8b\x0c\xfa\x0f\ +\xfc\x34\x01\x1e\xfc\x17\x0c\x7b\xdb\xb4\x89\xc0\xf0\x91\xc9\xb4\ +\x39\xb6\x09\x5b\xb7\xbc\x4e\x35\x1f\x20\x2c\x16\x4b\xcd\xe0\xf7\ +\xfb\x27\x66\x66\x66\x1e\x45\xe5\x62\x18\x2d\x16\xd7\xd9\x6d\x65\ +\x45\x44\x1a\x21\x49\x03\x78\xfc\xb9\x14\x3a\x74\x76\xc3\xa6\xaa\ +\xd1\xb1\x0b\x3c\xf2\x64\x32\x92\x34\x48\x44\x2a\x23\xd2\x9c\xc5\ +\xae\x6c\xda\x9d\xa8\xb2\x19\x13\x40\xbf\xaf\x08\x4d\x55\x59\x8f\ +\x11\xad\xfd\x06\x53\x62\xeb\x63\x8c\x93\xd9\x1c\xf8\x28\x6c\xdc\ +\x2f\x98\x78\xa7\xa5\xce\xf8\xf7\x31\xe2\xd3\x0b\xc2\xa6\x7f\x11\ +\x78\x04\x53\x75\xe1\x5a\x4c\x6c\x14\xc0\x4b\x98\xf8\xa7\x7b\x31\ +\x92\x2e\x49\xc0\x3f\x30\x4e\xe3\xda\xb0\xf1\x73\xd8\x5d\xbb\x0d\ +\x60\x16\x61\x99\xbf\xaa\x2c\xc0\x24\xb4\xf8\x30\x71\x7e\xdf\x01\ +\x97\x38\xa7\xc3\xe7\x5b\xed\x5c\x23\x18\x36\xf6\x69\xa0\x03\x66\ +\xeb\x7f\x28\xf0\x16\xa6\x82\xc3\x14\x2a\x96\x97\xa9\x55\x54\x75\ +\x06\xf0\x34\x77\xdc\x58\x54\x4a\x40\xb9\xb2\x9c\x72\x3a\x0c\x78\ +\x02\xee\xe9\x6e\x12\x46\x62\x91\xd4\x54\xe3\xcc\x8e\xfd\x04\xbe\ +\x18\xb3\xab\xfd\xe0\x26\x30\xfc\xdd\x14\x42\xa1\x5b\x45\xa4\xde\ +\x6e\xad\x5a\x2c\x09\x42\xc6\xef\xbf\xff\x9e\x52\x54\x14\xbb\x7a\ +\xf5\xf5\x15\x11\xb1\x19\x22\xb5\x80\x44\x66\xde\x88\xc8\x79\x40\ +\x06\x73\xff\x80\x16\x2d\x5d\x31\xaa\xca\xe4\xfd\x01\x27\xb7\x02\ +\x38\xaf\xa2\xd8\xa8\x44\x43\x84\xc3\x31\x59\xce\x7d\x54\x77\xc5\ +\x0a\xc6\x1a\x22\x92\x4c\x5a\x83\x9f\xb9\xe2\x1f\x27\x32\xf2\xd3\ +\xaa\x6f\xd1\x85\x42\xd0\xfe\x12\x68\xd0\x00\xc6\x7c\x63\x56\xd1\ +\x62\x91\x37\x5f\x87\xa7\xff\x0d\xd3\xe7\x42\xb3\x43\x77\xb5\xf7\ +\xed\xa1\xbc\x3f\x62\x1b\xc1\xe0\x71\xaa\x5a\x51\x36\x78\xc2\x22\ +\x22\xe9\xc0\x70\x55\x8d\x5a\xea\x2e\x1c\x9f\xcf\xe7\x01\x2b\x15\ +\x13\xcb\x38\x6a\x07\xcf\xaa\x56\x5c\x8d\xa9\x66\xae\x27\x4d\x81\ +\x95\x3e\x9f\x8f\x53\x4f\x8d\x26\xad\x69\xa9\x2a\xeb\xd7\xaf\x67\ +\xe9\xd2\xa5\x4c\x99\x32\xa5\xcf\xe8\xd1\xa3\x87\xba\x6d\x4f\xbc\ +\x11\xcd\x09\xbc\x09\xf8\x88\xfc\x18\x73\xba\x1b\x0b\x40\x07\x55\ +\xfd\xdc\x6d\x53\xdc\x42\x84\x03\x80\x87\x31\x02\xd7\xeb\x30\xab\ +\x7a\xcf\x60\xb6\xb1\x5b\x3b\xc1\xfd\x31\x8b\x88\xb4\x22\xc5\x33\ +\x9f\x57\xdf\x6c\x48\x97\xae\x55\x9f\x60\xc5\x72\x93\x69\x7b\xcb\ +\x1d\x70\x5e\x0c\xc7\xec\xbc\xf8\x14\xf8\x03\xf0\xee\x68\x38\xa2\ +\xb5\x71\x68\x0b\xb7\xc3\xb9\x27\x05\x58\x9e\x37\x8b\x60\xf0\x22\ +\x2b\xac\x1a\x9d\xaa\x38\x81\x96\xd8\xa7\xae\x9d\x40\x80\xb4\xb4\ +\xb4\xe5\xdd\xba\x75\x3b\x34\x3d\x3d\xbd\xae\x2e\x19\xd7\x6c\xda\ +\xb4\x89\x76\xed\xda\x01\xfc\x9f\xaa\x4e\x76\xd9\x9c\xb8\x23\x51\ +\x25\x62\xe2\x95\x62\x4c\x4c\x61\x5f\x4c\x40\xfb\x66\x4c\x06\xe8\ +\x75\xb1\xee\x00\x02\xa8\xea\x52\x11\xf9\x27\xf7\xf6\x7c\x83\x73\ +\x2e\xf0\xd0\xb2\x55\xd5\x26\x38\xa4\xb9\xc9\xb4\x7d\xe5\x79\x18\ +\x36\xb8\x76\x8c\xac\x4b\xce\x38\x1a\xf6\xd9\x17\x4e\x3a\xd5\x6c\ +\x79\xf7\x79\xc8\xc3\xfd\xff\x3c\x17\x78\x08\x23\xe7\x62\xb1\x58\ +\xea\x98\x40\x20\x30\x31\x2b\x2b\xeb\xe6\xf4\xf4\x74\xfb\xf9\x5a\ +\x03\x58\x9d\xc0\xda\xc5\xde\xa4\x71\x84\x23\xc7\x71\x36\x80\x08\ +\x7f\x53\x65\xbb\xcb\x26\xd5\x38\xaa\xfa\x8e\xa4\x35\xb8\x96\xf4\ +\xce\xed\x98\x30\x2b\x6d\xa7\x80\x72\x65\x69\x77\x0d\x5c\xda\x0e\ +\x8a\x63\xbc\xd6\x7b\x71\x10\x7e\x5d\x00\xd9\x99\xe6\x98\xf8\x3d\ +\xbc\xf6\x12\x9c\x76\x66\x12\xd9\x99\x4f\x89\xc8\x0f\xaa\x9a\xe9\ +\xb6\x99\x16\x4b\xa2\xa1\xaa\x53\xe7\xce\x9d\x7b\x73\x28\x14\x22\ +\x29\x16\xab\x15\x59\x12\x0a\xeb\x04\xc6\x29\xf1\xe8\x00\xee\xc4\ +\x5f\xd4\x8d\x5f\xe7\x2f\xe2\xf9\x27\x0e\xa2\xff\xe3\x55\x0f\xee\ +\xf3\x78\xa8\xb2\xe6\x60\x7d\xe4\x8c\xb3\xcc\x51\xc2\xe7\xa3\xe1\ +\xfe\x7f\x82\xc7\x93\x44\xb0\xf8\x4b\x11\x39\x52\x55\xe3\xf7\x3e\ +\xa8\x65\x7c\x3e\xdf\xb7\xc0\x6a\xaf\xd7\x9b\xee\xb6\x2d\x96\x98\ +\x22\x63\xc7\x8e\x1d\x29\xb9\xb9\xb9\x1c\x75\xd4\x51\x6e\xdb\x12\ +\x17\x58\x9d\xc0\xda\xc3\x3e\xa6\x58\x62\x0e\x55\xdd\x44\x51\x51\ +\x17\x5e\x78\x5a\xf9\x79\x46\xc5\x03\x12\x85\xeb\x3a\xc1\xcc\x05\ +\x70\x61\x5b\xa1\x38\xd8\x14\x11\x37\xab\x27\x58\x2c\x09\x89\xaa\ +\x2e\x4a\x49\x49\xd9\x9c\x93\x93\xe3\xb6\x29\x71\x41\x89\x4e\x60\ +\x87\x0e\x1d\x4e\xae\xb8\xb7\xa5\xaa\x58\x27\xd0\x12\x93\xa8\xea\ +\x44\x84\xc1\x74\xed\x54\x44\xc1\x56\xb7\xcd\xa9\x3f\x1c\xf4\x77\ +\x18\xfd\xb5\xd1\x44\x54\xbd\x58\x44\xba\xbb\x6d\x92\xc5\x92\x68\ +\xa8\xea\xd4\xec\xec\x6c\x9b\x9c\x65\xa9\xf7\x24\x9c\x13\x28\xc2\ +\xed\x22\x9c\xeb\xe2\xf5\x6f\x14\xe1\x02\xb7\xae\x1f\x57\x14\x17\ +\x0f\x60\xd3\x86\x25\xdc\xe7\x0d\x56\xdc\x39\xc1\x18\xf9\x29\xec\ +\xbd\x0f\x88\xbc\x22\x22\x09\xf7\x77\x6e\xb1\xb8\x49\x71\x71\xf1\ +\x4f\x59\x59\x59\xf6\xff\x92\xa5\xde\x93\x88\x1f\x0e\xcf\x01\x6e\ +\xaa\x60\x3f\x0e\xdc\xec\xe2\xf5\xe3\x06\x55\xf5\xb3\x63\x47\x47\ +\x3e\xfd\x24\xc4\xd8\x4f\xdc\x36\xa7\x7e\xd1\xa0\x01\xbc\x3f\x16\ +\xa0\x11\xd0\xc3\x65\x6b\x62\x12\xaf\xd7\x7b\xa5\x8d\x07\xb4\x54\ +\x93\x8c\x4d\x9b\x36\xa5\xae\x5a\xb5\xca\x6d\x3b\xe2\x82\x60\x30\ +\x48\x28\x14\xb2\x2b\xab\xb5\x40\x22\x3a\x81\x96\x38\x42\x55\x7f\ +\xa5\x38\x78\x2f\xf7\x74\x0f\xb0\xc2\x6a\x24\x97\xe2\xa2\xb6\x70\ +\x5b\xf7\x22\x24\xe9\x5e\xb7\x4d\xb1\x58\x12\x8c\xcc\xa4\xa4\x24\ +\xbf\x8d\x0b\xdc\x73\x92\x93\x93\xe9\xdd\xbb\x37\x63\xc6\x8c\x99\ +\xeb\xb6\x2d\xf1\x48\x42\x3b\x81\x22\xa4\x8a\xd0\x52\xa4\xec\xac\ +\x23\x11\x92\x45\x38\x42\x84\x7d\x2a\x31\x9f\x47\x84\x63\x45\x76\ +\x15\x9d\xaf\xcc\x35\x9c\x7e\x4d\x44\x38\x4e\x84\x43\x2b\xea\x6b\ +\x29\x8d\xaa\x0e\xa3\x38\x38\x89\x3b\x6e\x2a\xc2\x3e\x2c\x96\xa6\ +\x5d\xfb\x06\x68\xe8\x48\x11\xa9\xf0\xfe\xb5\x58\x2c\x35\x83\xaa\ +\x06\x92\x93\x93\x67\x5b\x27\x70\xcf\x09\xd3\x09\xb4\x95\x7b\x6a\ +\x81\x44\x75\x02\x45\x84\xd7\x80\x2d\xc0\x1f\xc0\x1a\x11\xda\x97\ +\xee\x80\x47\x84\x67\x80\x6d\x40\x2e\xb0\x59\x84\x19\x22\x1c\x1d\ +\xd1\x6f\x87\x08\x4f\x88\xf0\x86\x33\xdf\x42\xa0\x95\x08\x49\x22\ +\x3c\x1d\x76\x8d\xf5\x22\xdc\xb4\xbb\x21\x9c\x2c\xc2\x5c\x60\x15\ +\xa6\xde\xf0\x72\x60\x85\x08\xcd\x6b\xfa\x4d\xc7\x35\x45\x45\xb7\ +\x91\x3d\xbb\x90\x21\xcf\x5b\x65\xd1\x70\x4e\x3d\x03\x8c\xb4\x82\ +\xad\x61\x55\x0d\x4a\x4a\xc7\x59\x2c\x55\x25\x10\x08\x4c\x9a\x3d\ +\x7b\xb6\xdf\x6d\x3b\x62\x9d\xfc\xfc\xfc\x92\x6f\xd7\xb8\x69\x47\ +\xbc\x92\xa8\x4e\x60\x3a\xb0\x0f\xa6\xac\xda\xa1\xc0\xf7\xc0\xe7\ +\x22\x1c\x1f\xd6\x67\x10\x70\x3f\xf0\x20\x70\x00\xd0\x06\x68\x0c\ +\x4c\x10\xe1\x6f\x11\xf3\xdd\x03\xb4\x00\xae\x03\x8e\x06\x56\x00\ +\x7d\x30\x25\xdc\xee\x03\xf6\x03\xda\x02\x03\x60\x37\xe7\x6e\x04\ +\x10\x04\x4e\xc7\xc4\x6f\xb5\x00\x06\x02\xf6\x9f\x47\x15\x50\xd5\ +\xb5\xf8\xfd\xb7\xf0\xd4\xc0\x10\xd9\x56\x23\x79\x27\x4d\x9a\xc1\ +\xfe\x07\xf8\x81\xd3\xdc\x36\x25\xd6\xf0\xf9\x7c\xfd\x00\xbb\x94\ +\x63\xa9\x2e\x19\xcb\x97\x2f\x4f\xdd\xb2\x65\x8b\xdb\x76\xc4\x34\ +\xeb\xd7\xaf\x27\x25\x25\x05\x60\xa5\xdb\xb6\xc4\x23\x89\xea\x04\ +\x6e\x07\xee\x54\x65\x85\x2a\x2b\x80\x3b\x81\xb5\x98\x72\x5b\x88\ +\xd0\x10\xb8\x17\x78\x47\x95\x57\x55\xd9\xa8\xca\x2f\xc0\x6d\xc0\ +\x21\x40\xa4\xec\x46\x12\x70\x95\x2a\xdf\xa9\xb2\x18\xb3\x7a\xf8\ +\x30\xf0\xb1\x2a\xc3\x54\xc9\x57\x25\x1b\xb8\x1b\x76\x73\x20\x9b\ +\x03\x5f\xa9\x92\xa5\xca\x76\x55\x96\xab\x32\x42\xd5\x3e\xf5\x54\ +\x15\x55\x1d\x8f\xc8\x9b\xdc\xde\xb1\x88\x42\xab\x91\xbc\x93\xa3\ +\x8f\xdd\x06\x58\x8d\xad\xaa\xb3\x01\x68\xe6\xb6\x11\x96\x98\x65\ +\xba\x88\xe8\xdc\xb9\x36\x94\x6d\x4f\xd8\xbe\x7d\x3b\x2f\xbc\xf0\ +\x82\x5a\xe1\xfb\xda\x21\x9a\x13\x58\x00\xc0\xd6\x18\x7a\x7a\xd9\ +\xb2\xb9\xe4\xbb\x1d\x95\x1c\x31\x45\x75\xd7\x4a\x9b\x2a\x3b\x80\ +\x9f\xd8\xb5\x65\xd6\x1a\xb3\x2a\xf7\x4d\xf8\x20\x55\x66\x63\x9c\ +\xc5\x13\x23\xe6\x9b\xa0\x4a\x78\x1d\xb2\xa6\xc0\xc1\xc0\x8f\x11\ +\xe3\x67\x62\xb6\x87\xc3\x19\x0d\x3c\x20\xc2\x87\x22\x5c\x2f\x42\ +\x5a\x25\xdf\x83\x25\x1a\xc1\xe0\x7d\xac\x59\xbd\x82\x87\x7a\x5b\ +\x79\x86\x12\xd6\xae\x69\x80\x59\x9d\xb6\x54\x8d\xd5\xc0\xbe\x3e\ +\x9f\xaf\x91\xdb\x86\x58\x62\x0f\x55\xdd\xe2\xf1\x78\x7e\xb3\x71\ +\x81\x7b\x46\x51\x51\x11\x05\x05\x05\xf6\xff\x79\x2d\x11\xcd\x09\ +\x9c\x03\xc0\xec\x59\x75\x6b\xc9\x9e\x30\x73\x5a\xc9\x77\xf3\x2a\ +\x39\x62\x63\x19\x6d\x07\x39\xdf\x1f\x5c\xc9\x7e\x65\x5d\xb7\xe4\ +\xfc\xa6\x4a\x5c\xfb\x5e\xcc\x76\xf2\xb1\xc0\x18\xe0\x4f\x27\xc6\ +\x30\x51\x57\x69\xf7\x08\x55\x2d\xa4\x68\xc7\x0d\x7c\xf0\x8e\xf0\ +\xf5\xe7\x6e\x9b\xe3\x3e\x85\xdb\xe1\x8f\x25\x0d\x00\xbb\x47\x5e\ +\x75\x56\x61\x1e\x2c\xff\xee\xb6\x21\x96\xd8\xc4\xef\xf7\x4f\xc8\ +\xca\xca\xb2\x09\x0d\x7b\x40\x71\x71\x31\xdb\xb7\x6f\xb7\xab\x80\ +\xb5\xc4\x6e\x8e\x86\xaa\xae\x20\xc5\x33\x9d\xfe\xf7\x06\xd8\x9c\ +\x1f\x6d\x4c\xfd\x62\xd3\x46\xe8\xd7\x27\x88\xc7\x93\xa1\xaa\x95\ +\x5d\xed\x88\xb6\xc5\xd3\x0c\x93\x94\x01\x90\xe7\x7c\x3d\x24\xbc\ +\x83\x93\xb5\xdb\x14\xf8\x2b\x62\x6c\x64\x32\x42\xc9\x3c\x4d\x23\ +\xc6\x27\x01\x4d\x4a\x0d\x54\xfc\xce\xf6\xef\xa9\xc0\xe1\xc0\xdb\ +\xc0\xbf\x81\x2b\x2a\x7e\x1b\x96\x68\xa8\x6a\x36\xa1\xe2\x7e\x78\ +\xd3\xfd\xac\x4e\x70\x9d\xae\x9c\x39\x10\x0a\x09\xd6\x09\xac\x32\ +\x5e\xaf\x77\xb6\xd7\xeb\x6d\xe8\xf5\x7a\xff\x70\xdb\x16\x4b\xcc\ +\x92\xf1\xdb\x6f\xbf\x25\x07\x02\xd6\x0f\xac\x2e\x7e\xbf\x5f\x0b\ +\x0a\x0a\x36\xb8\x6d\x47\xbc\x92\x12\xb5\x35\x18\xe8\xca\x92\xc5\ +\x33\x38\xfd\xa8\xc6\x74\xf7\xa6\x70\xec\x09\xe0\xa9\x67\x49\x72\ +\x81\x00\xfc\x3a\x1f\xde\xf2\x05\xd9\x9c\x9f\x4f\x20\x70\x5b\x15\ +\x46\xb7\x15\x61\x7f\x55\xb3\x2a\x27\xc2\x41\xc0\x65\x80\xcf\x39\ +\xbf\x14\xb3\x7d\x76\x0b\xf0\x61\xd8\xb8\x6b\x81\x7d\x81\x8c\xf2\ +\x26\x57\x65\xa3\x08\x0b\x30\xa2\xd4\xc3\xc3\x4e\x5d\x0f\x34\x28\ +\x67\x5c\x9e\x08\x8f\x61\x92\x4a\xda\x12\xb1\x1d\x6d\xa9\x12\x2f\ +\x51\x54\x74\x2d\x77\xdf\xda\x86\x2f\x7e\x4c\x45\x12\x54\x75\x27\ +\x73\x56\x88\xa4\xa4\xcd\x5a\x5c\x9c\x57\x71\x67\x8b\xc5\x52\xc3\ +\x64\x04\x83\xc1\xa4\x85\x0b\x17\x72\xf2\xc9\x36\x2c\xb7\x3a\x8c\ +\x1b\x37\xce\xff\xeb\xaf\xbf\x8e\x19\x3a\x74\xa8\xdb\xa6\xc4\x25\ +\x51\x9d\x40\x55\xcd\x15\x91\xa3\xd9\xb8\xe1\x19\x06\x3f\xd7\x0e\ +\x7f\x51\x7d\x94\x2b\x51\xd2\xd2\x96\x13\x08\x7c\x4b\x28\xd4\x5f\ +\x55\xa3\x6d\xdd\x96\xc5\x4a\xe0\x7b\x47\x02\x06\xe0\x11\xa0\x08\ +\x78\x01\x40\x95\xa0\x08\xfd\x80\xf7\x44\x78\x0f\xb3\x4d\xdb\x12\ +\x78\x02\x98\x06\x8c\xaa\xc4\x35\x1e\x01\x3e\x13\x61\x24\xc6\x91\ +\x6c\x09\x3c\x80\x09\x36\x07\x40\x84\xc6\xce\x7c\xef\x61\xb6\x94\ +\xd3\x80\x4e\xce\xd7\x6f\xab\xf0\x7e\x2c\x11\xa8\xaa\x8a\xc8\x4d\ +\xcc\xc8\xf8\x15\xdf\x2b\xa9\xfc\x33\x01\xf5\x92\xf3\x37\xc1\x4b\ +\xff\x09\x10\x0a\x7d\xe9\xb6\x29\x16\x4b\x22\xa2\xaa\x7f\xa5\xa5\ +\xa5\xad\xca\xc9\xc9\x69\x6a\x9d\xc0\xaa\x13\x0a\x85\x58\xbe\x7c\ +\x79\x12\xbb\x76\xe7\x2c\x35\x4c\x99\x71\x67\xaa\xba\x51\x8b\x8b\ +\x7b\x68\xd1\x8e\x16\xaa\x2a\xf5\xf0\x48\xd2\x1d\x3b\x0e\xd3\xe2\ +\xe2\x1e\x55\x74\x00\xa7\x03\x43\x81\x21\x18\x09\x98\xd7\x31\x4e\ +\x61\x9b\xf0\x8c\x5c\x55\xde\x07\xae\xc1\x38\x6f\xff\xc3\x94\xde\ +\x7a\x0b\xb8\x4c\xb5\xd4\xf6\xef\x14\x60\xd9\xee\x3f\x3f\xbe\xc0\ +\x48\xc6\xb4\x06\xde\x71\xe6\xea\x08\x8c\x07\x16\x3b\xdd\x0a\x81\ +\x49\x40\x17\x60\x24\x66\xd5\xb0\x39\x70\xbd\x6a\xe9\xa4\x12\x4b\ +\xd5\x51\xd5\x15\x04\xfc\xdd\x18\xf4\x50\x31\x0b\x12\x30\x43\xaf\ +\x5f\x1f\xd8\x56\x50\x88\xb9\xcf\x2d\xd5\xc4\xe7\xf3\x1d\xeb\xb6\ +\x0d\x96\xd8\x25\x18\x0c\x4e\x9c\x33\x67\x4e\x71\xc5\x3d\x2d\x91\ +\x2c\x58\xb0\x80\x82\x82\x02\x0f\xf0\x9d\xdb\xb6\xc4\x2b\x12\xa6\ +\xc6\x6d\xb1\xc4\x25\x92\x9a\xfa\x2e\x2d\x5a\xde\xc8\xb4\xb9\x69\ +\x34\x28\x73\x37\x3e\xbe\x18\xff\x05\xdc\x7c\x1d\xc0\x75\xaa\xfa\ +\x85\xdb\xe6\xd4\x17\x44\x24\x1d\x18\xae\xaa\x95\xba\x11\x7c\x3e\ +\xdf\xa5\x18\x1d\xd1\x43\xbc\x5e\x6f\x82\x07\x98\xc6\x1e\x22\xf4\ +\x04\x9e\x55\xa5\xb1\x7b\x36\x48\x8f\x86\x0d\x1b\xbe\x36\x71\xe2\ +\xc4\x14\x49\xd4\xb0\x94\x6a\x32\x62\xc4\x08\x46\x8f\x1e\xbd\x64\ +\xe3\xc6\x8d\x47\xba\x6d\x4b\xbc\x62\x33\x50\x2d\xf1\x4f\x20\xd0\ +\x8b\xbf\x96\xaf\xe3\xdf\x0f\x26\xc6\xd3\xf8\xe7\xa3\xa1\x7b\x97\ +\x1d\xc0\x48\xeb\x00\xee\x31\x53\x31\xba\x9f\xd7\xb8\x6d\x88\x25\ +\x66\xc9\x28\x2c\x2c\x4c\x59\xba\x74\xa9\xdb\x76\xc4\x1c\x2d\x5b\ +\xb6\xd4\xce\x9d\x3b\xaf\x75\xdb\x8e\x78\xc6\x3a\x81\x96\xb8\x47\ +\x55\x0b\x28\xda\xd1\x89\xb7\x86\xc1\x0f\x71\x9c\x6b\xb3\x69\x23\ +\xdc\x79\x33\xa4\x77\x86\xc2\xc2\x4f\x30\xd2\x43\x96\x3d\xc0\xeb\ +\xf5\x16\x61\x56\x02\xaf\x75\xdb\x16\x4b\xcc\xb2\x30\x25\x25\xa5\ +\xc0\xea\x05\x56\x8d\xc5\x8b\x17\xd3\xb8\x71\x63\xd9\xb4\x69\xd3\ +\xff\xdc\xb6\x25\x9e\xb1\x4e\xa0\x25\x21\x50\xd5\x99\xa8\x3e\xc9\ +\xdd\xb7\xfa\x59\xbf\xce\x6d\x73\x6a\x8e\x6d\x05\x30\x63\x2a\xbc\ +\xfe\x32\x9c\x71\x8c\x9f\x2f\xc7\x6e\x00\xda\xab\x6a\xba\xaa\x6e\ +\x75\xdb\xbc\x38\x61\x14\xbb\x8b\xbc\x5b\x2c\x95\x42\x4d\xcc\x55\ +\x46\x76\x76\xb6\x8d\xbd\xaa\x02\xb9\xb9\xb9\x6c\xdd\xba\x35\xb4\ +\x6d\xdb\xc4\x92\xaf\xb6\x00\x00\x0b\x1d\x49\x44\x41\x54\xb6\x77\ +\xdc\xb6\x25\x9e\x89\x2e\x11\x63\xb1\xc4\x23\xaa\x4f\x51\xb8\xfd\ +\x6a\x6e\xbe\xf6\x14\x0e\x6d\x11\xdb\xf7\x7e\x30\xa8\xcc\xcb\x09\ +\xb2\x6c\x49\x0a\xaa\x82\x27\x75\x0b\x01\xff\x18\xe0\x01\x55\x8d\ +\x26\x52\x6e\xa9\x26\x5e\xaf\xf7\x13\xe0\x13\xb7\xed\xb0\xc4\x2e\ +\xc1\x60\x70\x72\x66\x66\xe6\x25\x40\xaa\xdb\xb6\xc4\x0a\xf3\xe7\ +\xcf\x2f\x6e\xd0\xa0\xc1\xec\xaf\xbe\xfa\x2a\xe4\xb6\x2d\xf1\x4c\ +\x6c\x7f\x10\x5a\x2c\x55\x40\x55\x8b\x45\xa4\x3d\x3f\xcf\xb8\x8b\ +\x9f\x67\x9c\xee\xb6\x3d\x7b\x48\x31\xb0\x08\x23\x02\x9d\xa9\xfe\ +\x22\x2b\xa1\x60\xb1\xd4\x5f\x32\x36\x6c\xd8\x90\xba\x66\xcd\x1a\ +\x0e\x3e\xf8\xe0\x8a\x7b\x27\x38\xab\x56\xad\x62\xec\xd8\xb1\xc9\ +\xc0\xe3\x1f\x7c\xf0\x81\xdb\xe6\xc4\x35\xd6\x09\xb4\x24\x14\xaa\ +\xba\x1a\x78\xd2\x6d\x3b\x2c\x16\x4b\x42\x31\x3b\x29\x29\x29\x90\ +\x93\x93\xe3\xb9\xfc\xf2\xcb\xdd\xb6\xa5\xde\xf3\xee\xbb\xef\xaa\ +\xc7\xe3\x59\x19\x08\x04\xac\x54\x5a\x2d\x63\x63\x02\x63\x0c\x11\ +\x3a\x88\xd0\x36\xec\xf5\xd1\x22\xf4\x14\xa1\x9e\x95\x74\xb1\x58\ +\xe2\x0b\x9f\xcf\xd7\xc1\xe7\xf3\xf9\x2a\xee\x69\xb1\x94\x46\x55\ +\x8b\x52\x52\x52\xe6\xd8\xe4\x90\x8a\xc9\xcb\xcb\x63\xdc\xb8\x71\ +\x1a\x08\x04\x1e\x56\x55\x5b\x6f\xaf\x96\xb1\x4e\x60\xec\xd1\x0f\ +\xe8\x1e\xf6\xfa\x5c\x4c\xb9\xbb\x86\xee\x98\x63\xb1\x24\x0c\x01\ +\xa0\xa7\xcf\xe7\x3b\xdf\x6d\x43\x2c\xb1\x87\xdf\xef\x9f\x98\x99\ +\x99\xe9\x77\xdb\x8e\xfa\x4e\x76\x76\xb6\x5e\x7d\xf5\xd5\xeb\x28\ +\x5d\xb2\xd5\x52\x4b\x58\x27\x30\xf6\x99\x05\xdc\x0b\xec\x70\xdb\ +\x10\x8b\x25\x9e\xf1\x7a\xbd\x5f\x61\x2a\x04\x3d\xef\xb6\x2d\x96\ +\x98\x24\x23\x2f\x2f\xcf\x53\x50\x50\xe0\xb6\x1d\xf5\x96\xb9\x73\ +\xe7\xd2\xbc\x79\x73\x69\xd0\xa0\xc1\x50\xb5\x95\x2c\xea\x84\x84\ +\x74\x02\x45\x48\x12\xe1\x10\x11\x5a\x8b\x90\x56\x89\xfe\x0d\x44\ +\x38\x4e\x04\x89\x68\x17\x67\x8e\xbd\x23\xda\x9b\x8b\x50\x61\xf4\ +\xaf\x63\xc7\x11\x22\x65\xaf\xe2\x89\xe0\x11\xe1\xf0\xc8\x6b\x97\ +\xa0\xca\x42\x55\x5e\x51\xc5\x1f\x31\xae\xa1\x63\x5b\x6b\x11\xf6\ +\xaa\xc8\x16\x8b\xc5\x52\x29\x1e\x06\x4e\xf1\xf9\x7c\xc7\xb9\x6d\ +\x88\x25\xe6\x98\xae\xaa\xcc\x9b\x37\xcf\x6d\x3b\xea\x2d\x7f\xfd\ +\xf5\x97\xe6\xe5\xe5\xe5\x7f\xf2\xc9\x27\xff\x71\xdb\x96\x44\x21\ +\xe1\x9c\x40\x11\xfe\x03\x6c\x00\xfe\xc2\xd4\xf0\xdd\x2e\xc2\xeb\ +\xe1\xce\xa0\x08\x07\x8b\xa0\x22\x78\x45\xf8\x1c\xd8\x0a\x2c\x00\ +\xd2\x44\x98\x29\xc2\x67\x22\xdc\x0f\xe4\x3b\x73\xfc\xc3\x19\x97\ +\x2e\xc2\x06\xe0\x4f\x60\xb5\x08\xcb\x44\xb8\x2c\xe2\xfa\x93\x45\ +\xf8\xc6\x29\x67\xb4\x11\xc8\x05\xb6\x8a\xd0\x2f\x8a\xad\xfd\x81\ +\xcd\xc0\x52\x60\x93\x08\x77\x45\xe9\x73\x87\x63\xeb\x3e\x61\x6d\ +\xcf\x3b\x73\x2f\x76\x8e\x4d\x22\x3c\x53\xdd\x9f\x99\xc5\x62\x31\ +\x78\xbd\xde\x99\xc0\xa1\x5e\xaf\x77\xa1\xdb\xb6\x58\x62\x0b\x55\ +\xdd\x94\x9a\x9a\x9a\x6b\xe3\x02\xa3\x33\x75\xea\x54\x92\x92\x92\ +\x24\x37\x37\xb7\xb7\xdb\xb6\x24\x12\x89\x98\x1d\xbc\x0a\xb8\x1e\ +\x98\x0b\xec\x0d\x74\x00\x5e\x04\x56\x00\x91\x4f\x1f\x4f\x01\x3f\ +\x00\x17\x01\x05\xb0\x73\xb5\xed\x22\xe0\x30\xa0\x17\xa6\xac\x54\ +\x91\x08\x57\x03\x6f\x03\xc3\x9c\x79\x1a\x00\x43\x80\x6f\x44\x38\ +\x49\x95\xf0\x0f\x8d\xb3\x81\x7d\x80\x6e\x18\x27\x6d\x10\xf0\x8c\ +\x08\x3f\xaa\x32\x1b\x8c\x73\x07\x3c\x0d\x3c\x04\xbc\x05\x34\x05\ +\xde\x05\x8e\x01\x96\x94\xf5\xe6\x44\xb8\x06\x78\x10\xe8\x0d\x8c\ +\xc1\x94\xbc\x3a\x0e\x38\xb4\xb2\x3f\x20\x8b\xc5\x52\x36\x5e\xaf\ +\x77\xa3\xdb\x36\x58\x62\x93\x40\x20\x30\x21\x2b\x2b\xab\x25\xd8\ +\x44\xbe\x70\xb6\x6d\xdb\xc6\xe0\xc1\x83\x03\x6b\xd7\xae\x1d\x17\ +\x08\x04\xde\x73\xdb\x9e\x44\x22\xe1\x56\x02\x55\x79\x55\x95\x49\ +\xaa\x6c\x50\x65\x99\x2a\x83\x81\x2f\x81\xdb\xa2\x74\x5f\xa5\xca\ +\x4d\xaa\x4c\x57\x65\xae\x2a\x25\xa2\x95\xfb\x01\x9d\x55\x79\x5f\ +\x95\x3c\x55\x56\x03\x03\x80\xb9\xaa\xf4\x52\x65\x85\x2a\x4b\x80\ +\x2e\x98\x55\xc4\x01\x11\xf3\x36\x06\xba\xaa\x32\x56\x95\xf9\x18\ +\xa7\x0d\x20\x5c\x3b\xa0\x3f\xf0\xb5\x2a\x2f\xaa\xb2\xc9\x71\x22\ +\xbb\x02\x8d\x2a\x78\x8b\xcd\x31\xf1\x81\x6f\xa9\xb2\x4a\x95\x2d\ +\xaa\xcc\x54\x65\x4c\xa5\x7e\x40\x16\x8b\xa5\xd2\xf8\x7c\x3e\x9b\ +\x90\x65\xa9\x34\xaa\x9a\xb1\x70\xe1\xc2\xe4\x40\xc0\x26\xbd\x96\ +\x10\x0a\x85\x18\x38\x70\x60\xf1\xda\xb5\x6b\xf3\x83\xc1\xa0\x5d\ +\x05\xac\x63\x12\xce\x09\x14\x61\x2f\x11\xfa\x88\x30\x4a\x84\xa9\ +\x22\xcc\x04\x4e\x01\x5a\x46\xe9\xfe\x7d\x19\xd3\x2c\x55\x25\x37\ +\x6c\x4e\x01\x4e\x06\xbe\x0d\xef\xa4\xca\x56\x4c\x20\xf9\x49\x11\ +\xe3\xe7\x85\x8f\x57\x25\x0f\x58\x0e\x34\x73\xe6\x6b\x04\xb4\x06\ +\x4a\x69\x24\x39\x8e\xe0\xf2\x0a\xde\xe2\x58\xcc\x53\xe6\xcf\x22\ +\x3c\x22\xc2\x51\x15\xf4\xb7\x58\x2c\xd5\xc0\xe7\xf3\x9d\x03\x2c\ +\xf5\xf9\x7c\xc7\xb8\x6d\x8b\x25\x66\xc8\x08\x06\x83\x49\x8b\x16\ +\x2d\x72\xdb\x8e\x7a\xc3\x7b\xef\xbd\xc7\xac\x59\xb3\x42\xc1\x60\ +\xf0\x2a\x55\x5d\xe9\xb6\x3d\x89\x46\x42\x39\x81\x8e\x96\xde\x04\ +\xcc\x2a\x5b\x01\xf0\x39\xf0\x0a\x66\x4b\xb7\x41\x94\x21\x65\x45\ +\xf0\x46\xb6\xef\x0d\xfc\x0d\x13\x87\x17\xc9\x46\xe0\xc0\x88\xb6\ +\x15\x51\xfa\x6d\x07\x92\x9d\xef\x4b\xfa\x47\x2b\xff\x55\x6e\x49\ +\x30\x55\x56\x01\x27\x62\xb2\x86\x1f\x04\x16\x89\xf0\x9d\x08\x67\ +\x96\x37\xce\x62\xb1\x54\x99\x2c\x60\x19\xf0\xa5\xcf\xe7\xdb\xcf\ +\x65\x5b\x2c\x31\x80\xaa\xe6\x79\x3c\x9e\x35\x36\x2e\xd0\x30\x79\ +\xf2\x64\x4e\x3c\xf1\x44\xce\x3b\xef\xbc\x47\x55\xf5\x17\xb7\xed\ +\x49\x44\x12\xca\x09\x04\xce\x02\xda\x00\x0f\xa8\xd2\x4d\x95\x97\ +\x54\xf9\x18\x58\x57\x46\xff\xb2\x52\xd4\x4b\xb5\xab\xb2\x05\xe3\ +\x9c\x35\x8b\xd2\xf7\x10\x4c\x12\x4a\x55\x58\x89\x29\x0b\xd6\x34\ +\xca\xb9\x68\x6d\xa5\x8d\x53\x7e\x55\xa5\x3b\x70\x10\xd0\x1e\x68\ +\x01\xbc\x5a\x45\x1b\x2c\x16\x4b\x39\x78\xbd\xde\x22\x4c\x7c\x71\ +\x43\x60\x94\xcf\xe7\x8b\x9a\xc1\x6f\xb1\x84\x53\x5c\x5c\x3c\x39\ +\x3b\x3b\xbb\xd8\x6d\x3b\xdc\x66\xde\xbc\x79\x34\x6a\xd4\x88\x39\ +\x73\xe6\x4c\x9b\x32\x65\x8a\x4d\x5c\x74\x89\x44\x73\x02\x4b\x56\ +\xda\x76\x26\x56\x88\xd0\x00\xe8\x54\x03\x73\x4f\x05\x3a\x46\x64\ +\x19\xb7\x00\x2e\x06\xa6\x55\x65\x22\x55\x02\x98\x95\xbc\x4e\xe1\ +\xd2\x30\x4e\xa6\xf1\xdf\xcb\x1b\x1b\xde\x5f\x95\x80\x2a\x5f\x03\ +\xa3\x80\xb3\xac\x54\x8c\xc5\x52\xb3\x78\xbd\xde\x55\x98\xe4\xb2\ +\xb7\xbd\x5e\xaf\xd5\x35\xb3\x54\x48\x28\x14\x9a\x32\x67\xce\x9c\ +\x50\x22\xcb\xe0\xad\x5d\xbb\x96\x35\x6b\xd6\xe8\xb2\x65\xcb\xd6\ +\xac\x5c\xb9\xf2\x42\xb7\xed\x49\x64\x12\x2d\x3b\x78\x0a\x46\x6e\ +\x65\xa8\x08\x43\x80\x22\xe0\x7e\x60\x4b\x0d\xcc\x3d\x10\xf8\x19\ +\xf8\x51\x84\xd7\x80\x34\xe0\xdf\x98\x15\xc2\xa7\xab\x39\xdf\x0f\ +\xc0\x28\x11\x46\x60\x56\x00\x07\x00\xab\x2b\x18\xf7\x8c\x08\xcd\ +\x9c\xb1\x2b\x81\xe3\x81\x1e\xc0\x14\x55\xac\x4a\xa9\xc5\x52\xc3\ +\x78\xbd\xde\x5f\x00\xbb\x95\x65\xa9\x2c\x19\xdb\xb6\x6d\xf3\x2c\ +\x5b\xb6\x8c\xc3\x0f\x3f\xdc\x6d\x5b\xea\x9c\x15\x2b\x56\xd0\xb7\ +\x6f\xdf\x40\x4a\x4a\xca\x5f\x27\x9f\x7c\xf2\xb9\x5f\x7d\xf5\x55\ +\xa8\xe2\x51\x96\xda\x22\xa1\x9c\x40\x55\xd4\x91\x5e\x79\x0e\x13\ +\x0b\xb8\x08\x23\xeb\xb2\x1e\xf8\x57\x58\x57\x3f\xf0\x13\xd1\x1d\ +\xae\x2c\x8c\xce\x60\xe4\xdc\xf3\x9c\xb8\xbb\xe7\x81\x97\x9d\x39\ +\x66\x01\xf7\xa9\xb2\x3e\xac\x6b\x36\xc6\xf9\x8c\xe4\x67\x8c\x5c\ +\x4c\xc9\x7c\x93\x44\xb8\x12\x78\x0c\x78\x07\xc8\xc1\x64\x30\xdf\ +\x86\x91\xb9\x29\x61\xb5\x63\x6b\xd0\x79\x3d\x05\x23\x5d\xf3\x34\ +\xb0\xaf\xf3\xde\xc6\x38\xf3\x58\x2c\x96\x5a\xc6\xe7\xf3\xb5\x06\ +\x56\x79\xbd\x5e\xfb\xd0\x65\x89\xc6\xfc\xe4\xe4\xe4\x6d\x39\x39\ +\x39\x8d\x12\xcd\x09\xcc\xca\xca\xe2\xa1\x87\x1e\x0a\xee\xd8\xb1\ +\x63\x7e\x30\x18\xbc\x7a\xe9\xd2\xa5\x15\x2d\x6a\x58\x6a\x19\x49\ +\xe4\x25\x69\x8b\xc5\x92\x58\x88\x48\x3a\x30\x5c\x55\xa3\x25\x82\ +\xd5\x08\x3e\x9f\x6f\x16\x26\xd1\xec\x1a\xaf\xd7\x9b\x57\x5b\xd7\ +\xb1\xec\x8e\x13\xde\x13\xce\x5d\xc0\x93\x40\x93\x88\xf6\xa0\xea\ +\xce\x07\xe7\x3a\x27\x35\x35\xf5\xfb\x4b\x2f\xbd\xf4\xd2\x47\x1f\ +\x7d\x34\x61\xe2\x48\x7f\xfc\xf1\x47\x46\x8e\x1c\x19\xca\xcd\xcd\ +\x1d\x1d\x0a\x85\xd2\x55\xd5\x96\x3a\xad\x07\x24\x5a\x4c\xa0\xc5\ +\x62\xb1\xd4\x36\x9d\x31\xc9\x63\xbf\xf8\x7c\xbe\xf3\xdd\x36\x26\ +\xc1\xf8\x16\x28\x0c\x3b\x86\x62\x76\x44\x0a\x23\x8e\xcb\xca\x9a\ +\xa0\x2e\x08\x04\x02\x93\x33\x33\x33\x13\x42\x2c\x30\x18\x0c\xf2\ +\xe5\x97\x5f\xb2\xdf\x7e\xfb\xd1\xa6\x4d\x9b\xf1\xc5\xc5\xc5\x37\ +\x59\x07\xb0\xfe\x60\x9d\x40\x8b\xc5\x62\xa9\x41\x9c\xd5\xbf\xf3\ +\x30\x09\x61\x5d\x5c\x36\x27\xd1\xe8\x03\x54\x14\x63\xf6\x8d\x2a\ +\xdf\xd4\x85\x31\xe5\x90\xb1\x76\xed\xda\xd4\xf5\xeb\xd7\x57\xdc\ +\x33\x86\xd9\xb2\x65\x0b\xdf\x7e\xfb\xad\x1e\x78\xe0\x81\x64\x64\ +\x64\x3c\xf3\xde\x7b\xef\xb5\x77\xdb\x26\x4b\x69\xac\x13\x68\xb1\ +\x58\x2c\x35\x8c\xd7\xeb\xdd\x86\x91\x8f\xe9\xe3\xb6\x2d\x89\x84\ +\x2a\x39\xc0\x9b\xe5\x74\x09\x00\xf7\xd6\x91\x39\xe5\xf1\x73\x52\ +\x52\x52\x30\x5e\xf5\x02\x03\x81\x00\xa3\x47\x8f\xe6\x86\x1b\x6e\ +\x08\x4c\x9b\x36\x6d\xf3\xd4\xa9\x53\x6f\xf8\xf0\xc3\x0f\x23\x2b\ +\x67\x59\xea\x01\x36\x26\xd0\x62\xb1\x24\x0c\x75\x11\x13\x58\x16\ +\x3e\x9f\xef\x40\x4c\x9d\xf2\x27\xbd\x5e\x6f\x99\xf5\xbf\x2d\x7b\ +\x86\x08\x07\x02\xbf\x63\xca\x73\x46\xf2\x8a\x6a\xbd\x70\x02\x49\ +\x4b\x4b\x9b\x7d\xed\xb5\xd7\x9e\x7e\xff\xfd\xf7\xbb\x6d\x4a\x8d\ +\xa1\xaa\x4c\x98\x30\x81\xa1\x43\x87\x06\xd6\xaf\x5f\xaf\xa1\x50\ +\x68\x30\xf0\x8c\xaa\x6e\x76\xdb\x36\x4b\x74\xec\x4a\xa0\xc5\x62\ +\x49\x18\x54\xf5\x1d\x37\x1c\x40\x87\x43\x81\x73\x80\x5f\x7d\x3e\ +\xdf\x6b\x3e\x9f\xaf\x5c\xcd\x4f\x4b\xf5\x70\xd4\x18\x1e\x8b\x72\ +\x6a\x3d\xf0\x78\xdd\x5a\x53\x36\x7e\xbf\x7f\x62\x56\x56\x96\xdf\ +\x6d\x3b\x6a\x8a\x9f\x7f\xfe\x99\xef\xbf\xff\x5e\x53\x53\x53\xd9\ +\xbc\x79\xf3\x47\xa1\x50\xe8\x08\x55\xed\x67\x1d\xc0\xfa\x8d\x75\ +\x02\x2d\x16\x8b\xa5\x0e\xf0\x7a\xbd\xd9\x18\xdd\xce\xde\xc0\x0d\ +\x18\xb9\x27\x4b\xed\xf0\x3a\xf0\x6b\x44\xdb\x40\x55\xf2\xdd\x30\ +\xa6\x0c\x32\xfe\xf8\xe3\x0f\xcf\xf6\xed\xdb\xdd\xb6\xa3\xda\x04\ +\x02\x01\xa6\x4f\x9f\xce\xd8\xb1\x63\x35\x25\x25\x85\xfc\xfc\xfc\ +\x35\x19\x19\x19\x57\xef\xd8\xb1\xa3\xab\xaa\x56\xb5\x52\x96\xc5\ +\x05\xec\x76\xb0\xc5\x62\xb1\xd4\x31\x3e\x9f\xaf\x11\x10\x74\x4a\ +\xcf\x95\xb4\x75\x07\x16\x02\x33\x6d\xf5\x91\x3d\x47\x84\xcb\x81\ +\xef\x9c\x97\x73\x81\xd3\x54\xa9\x37\xe5\xda\x44\xe4\x00\x60\xdd\ +\x90\x21\x43\xe4\xac\xb3\xce\x72\xdb\x9c\x4a\x93\x9f\x9f\xcf\xac\ +\x59\xb3\x98\x34\x69\x52\x68\xc6\x8c\x19\xea\xf7\xfb\x93\x2e\xbc\ +\xf0\xc2\xc5\x07\x1e\x78\xe0\x90\x31\x63\xc6\xf8\xdc\xb6\xcf\x52\ +\x35\xac\x13\x68\xb1\x58\x2c\x2e\xe3\xf3\xf9\x92\x81\xf9\xc0\x31\ +\x18\x01\xf8\x71\xc0\xbf\xbc\x5e\x6f\xdc\x6c\x17\xba\x81\x08\xe3\ +\x30\xf5\xd3\x2f\x51\x65\x92\xdb\xf6\x44\x92\x96\x96\xb6\xe4\xd6\ +\x5b\x6f\x6d\x75\xf7\xdd\x77\xbb\x6d\x4a\x99\x14\x16\x16\xb2\x72\ +\xe5\x4a\x72\x73\x73\x09\x04\x02\xda\xa4\x49\x13\x99\x36\x6d\x5a\ +\x68\xf4\xe8\xd1\x3f\x06\x83\xc1\x4f\x81\x71\xaa\x6a\x45\x9f\x63\ +\x14\xeb\x04\x5a\x2c\x16\x4b\x3d\xc1\xe7\xf3\x1d\x0f\x5c\x03\x1c\ +\xef\xf5\x7a\x6f\x0d\x6b\x6f\x82\x71\x0c\x57\x3b\xc7\x62\xaf\xd7\ +\xfb\x62\xd8\xf9\xbd\x81\xab\xc2\xa6\xda\xe2\xf5\x7a\xc7\x87\x9d\ +\x6f\x0c\x5c\x19\x76\x7e\x93\xd7\xeb\xfd\x2e\x8e\xce\x1f\x40\x69\ +\xed\xbf\xf5\x5e\xaf\xf7\x47\x11\x8e\x04\x9e\x18\x36\xcc\xf7\xaf\ +\x68\xe7\x2b\x1a\x5f\xdb\xe7\x93\x92\x92\xde\x38\xe2\x88\x23\xba\ +\xa5\xa7\xa7\x27\xa7\xa6\xa6\xee\x3c\x19\x0a\x85\x08\x04\x76\xc9\ +\x08\x26\x25\x25\xe1\xf1\x78\x6a\xed\x3c\x98\xa4\x0e\xbf\xdf\x4f\ +\x28\x14\x62\xed\xda\xb5\xc5\xe3\xc7\x8f\x0f\x6e\xd8\xb0\x21\xb9\ +\xa8\xa8\x28\xe5\x84\x13\x4e\x20\x3d\x3d\x5d\xff\xfc\xf3\xcf\x3f\ +\xd7\xaf\x5f\xff\xd9\xf6\xed\xdb\x5f\xf8\xec\xb3\xcf\x56\x62\x89\ +\x79\x12\xaa\x6c\x9c\xc5\x62\xb1\xd4\x67\xbc\x5e\xef\x02\x60\x41\ +\x94\x53\x0a\x4c\x06\x9a\x01\x47\x02\x7f\xc7\x64\x1a\x97\xd0\x14\ +\x53\x5e\xb2\x84\xdf\x80\xf1\x61\xaf\x5b\x44\x9c\xcf\x61\xd7\x56\ +\x69\x3c\x9c\x3f\x22\xe2\xfc\x2c\xe0\x47\x55\x72\x45\xe8\x0a\x9c\ +\x1a\xed\x7c\x45\xe3\x6b\xfb\xbc\xaa\xfe\xb4\x64\xc9\x92\xf4\x11\ +\x23\x46\x68\xdf\xbe\x7d\x77\x7e\x1e\xe7\xe5\xe5\xe9\xe0\xc1\x83\ +\x77\x56\x34\x69\xdd\xba\xb5\xf4\xea\xd5\x6b\xe7\xf9\x25\x4b\x96\ +\xe8\xab\xaf\xbe\x5a\x63\xe7\x5b\xb5\x6a\xc5\x9d\x77\xde\x99\x1c\ +\x08\x04\x76\x14\x15\x15\x6d\x29\x28\x28\x58\xba\x72\xe5\xca\xf1\ +\x98\xfa\xf3\xab\x96\x2c\x59\xb2\xfa\xd3\x4f\x3f\x5d\x34\x7d\xfa\ +\x74\x2b\xf2\x1c\x67\xfc\x3f\x33\x70\xd6\xbb\x9a\x5f\x6a\xf3\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\xcf\x3f\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x02\x77\x00\x00\x01\x56\x08\x06\x00\x00\x00\x0b\xd2\xbb\x6c\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x12\x74\x00\x00\x12\x74\ +\x01\xde\x66\x1f\x78\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x20\x00\x49\x44\ +\x41\x54\x78\x9c\xec\xdd\x79\x5c\x55\x65\xfe\xc0\xf1\xcf\xf7\x2e\ +\xac\x22\x22\x20\xe2\x82\x8a\xb8\x90\x98\xb8\xa0\x96\x89\x9a\x8e\ +\x9a\xa6\x2d\xd3\x62\x65\x35\x35\x35\x76\xc6\xca\x6a\x32\x01\xeb\ +\x57\xb6\x88\xda\xb4\x37\x9d\x76\x67\xaa\x69\xda\x66\xb2\xd5\x6c\ +\xb7\x7d\xdf\x73\xab\x2c\xd3\xf4\xa2\x82\xe4\x8e\xc0\x7d\x7e\x7f\ +\x9c\x8b\x5e\x90\x4d\xb9\x97\xc3\xe5\x3e\xef\xd7\x8b\x97\xdc\x73\ +\x9f\x73\xce\xf7\x02\x72\xbf\x3c\xcb\xf7\x11\xa5\x14\x9a\xa6\x69\ +\x9a\x16\x2a\x4c\xd3\x74\x01\x89\x40\x12\xd0\xd6\x30\x8c\x0f\xfd\ +\x9e\x8b\x05\x4c\xa0\xbd\xef\x23\x02\x28\x07\x4a\x7c\x1f\xcf\x19\ +\x86\xf1\x8c\x5f\xfb\x4e\xbe\x6b\x6d\x05\x8a\x0d\xc3\xd8\xd7\x5c\ +\xaf\x43\xd3\x82\xc5\x61\x77\x00\x9a\xa6\x69\x9a\x56\x17\xd3\x34\ +\x1d\x35\x1e\x47\x02\xfb\x00\x0f\xf0\x1d\xf0\x76\x8d\x53\xf6\x61\ +\x25\x6b\xc5\xc0\x07\xc0\x12\xe0\x5d\x60\x33\xd0\x0e\x68\x5b\xa3\ +\xfd\x9f\x81\x6f\x80\x8d\x40\x99\x69\x9a\x85\x81\x7d\x05\x9a\xd6\ +\xfc\x44\xf7\xdc\x69\x9a\xa6\x69\x2d\x89\x69\x9a\x13\x81\x63\x80\ +\xa3\x80\x1c\x20\xcd\x30\x8c\x52\xbf\xe7\xa7\x00\xa5\xf8\x7a\xe3\ +\x0c\xc3\xd8\xd4\x84\x7b\xc5\x03\x9d\x39\xd0\xd3\xb7\xc6\x30\x8c\ +\x55\x7e\xcf\xdf\x08\x8c\x04\x3e\xc4\x4a\x16\x97\x1b\x86\xf1\xfb\ +\xe1\xde\x4f\xd3\x9a\x83\xcb\xee\x00\x34\x4d\xd3\xb4\xf0\x65\x9a\ +\x66\x14\x50\x61\x18\x46\x85\xdf\xe1\x85\x40\x14\xf0\x3e\xf0\x6f\ +\xc0\xff\x39\x0c\xc3\x78\x21\x50\xf7\xf7\x25\x6a\xf5\x25\x6b\xef\ +\x03\x1d\x80\x29\xc0\x55\xc0\x49\xc0\x73\x55\x4f\x9a\xa6\x29\x86\ +\x61\xe8\x5e\x12\xad\x45\xd1\xc9\x9d\xa6\x69\x9a\xd6\xec\x4c\xd3\ +\x1c\x02\x9c\x0f\x9c\x01\x5c\x00\xfc\xd7\xef\xe9\xe1\x86\x61\xec\ +\xb1\x25\xb0\x1a\x0c\xc3\x58\x0a\x2c\x05\x30\x4d\xb3\x3d\x50\x33\ +\xae\x77\x4d\xd3\xfc\x19\x78\x08\xab\x57\x4f\x27\x7a\x9a\xed\xf4\ +\xb0\xac\xa6\x69\x9a\xd6\xac\x4c\xd3\xfc\x3f\x60\x1e\xb0\x02\x78\ +\x00\x78\xc4\x30\x8c\x12\xff\x36\x22\xc4\x29\xc5\x0e\x3b\xe2\x6b\ +\x2c\xd3\x34\x05\xf8\x0b\xd6\xbc\xbd\x1c\x60\x35\x70\xa4\x5e\x94\ +\xa1\xd9\x4d\x27\x77\x9a\xa6\x69\x5a\xd0\xf8\x16\x44\x74\x37\x0c\ +\x63\xad\xdf\xb1\x9e\x40\x8a\x61\x18\x1f\xd4\x6c\x2f\x42\x26\x70\ +\x3b\xf0\xac\x52\xdc\xdb\x7c\x91\x36\x8d\x69\x9a\xfd\x81\xa3\x0c\ +\xc3\xb8\xdf\xef\x58\x24\xa0\x74\xb2\xa7\x35\x37\x9d\xdc\x69\x9a\ +\xa6\x69\x01\x67\x9a\x66\x37\xac\x61\xd7\x3f\x01\x02\x74\xab\x6f\ +\xc8\x52\x84\x76\xc0\x75\xc0\x4c\xac\x29\x43\x46\x28\x25\x77\xb5\ +\x31\x4d\xf3\x2f\xc0\x8d\xc0\x23\xc0\x03\x86\x61\xac\xb6\x39\x24\ +\x2d\x4c\xe8\x52\x28\x9a\xa6\x69\x5a\x40\x99\xa6\x19\x03\x7c\x09\ +\xcc\x00\x9e\x04\xc6\xd7\x95\xd8\x89\xe0\x10\x61\x06\xf0\x03\x30\ +\x8b\xd6\x35\x17\x7c\x29\x70\x0f\x70\x2a\xb0\xc2\x34\xcd\x73\x6c\ +\x8e\x47\x0b\x13\xba\xe7\x4e\xd3\x34\x4d\x0b\x38\xd3\x34\xb3\x81\ +\xef\x6a\xac\x82\xad\x46\x84\x51\xc0\x1d\xc0\x80\x5a\x9e\x0e\xf9\ +\x9e\xbb\x2a\xbe\xa1\xe9\x33\x80\xd7\x0c\xc3\xd8\x6c\x77\x3c\x5a\ +\xeb\xa7\x93\x3b\x4d\xd3\x34\xed\xb0\xf9\x12\x97\xe9\x40\x1b\xc3\ +\x30\xee\x69\xcc\x39\x22\xa3\xe6\xc1\xfc\xe9\x30\x22\xbd\xee\x56\ +\xab\x36\xc1\xcf\xdb\x02\x13\x65\xcb\xe3\x74\x8a\xe3\xb8\xe3\x9e\ +\xd8\xf4\xd1\x47\x2f\xfd\x69\xcb\x96\x2d\xbf\xda\x1d\x8f\xd6\xba\ +\xb4\xa6\xee\x6f\x4d\xd3\x34\xad\x19\x99\xa6\x39\x01\x58\x04\xf4\ +\x03\xee\x6a\xcc\x39\x22\x22\x4e\xe7\xc4\x2b\x1c\x8e\x0e\xb1\xe5\ +\xe5\x75\xb7\x8b\x8c\x8c\xe9\xe8\x72\x75\xe8\x18\x90\x40\x5b\xa0\ +\x98\x98\x68\xe9\xdd\xbb\x57\xdf\x21\x43\x2e\xfe\xf9\xc4\x13\x4f\ +\xbc\xff\xb9\xe7\x9e\xfb\xab\xd2\xbd\x2d\x5a\x80\xe8\xe4\x4e\xd3\ +\x34\x4d\x3b\x64\xbe\x79\x75\x8f\x00\x9f\x01\x67\x1a\x86\xf1\x7d\ +\x23\x4f\xcd\xac\xac\x7c\xa5\xcd\x83\x0f\x7e\xcc\x77\xdf\x45\xf0\ +\xc0\x03\x9d\xd9\xbe\xfd\xe0\xb7\xa2\x59\xb3\x2a\xe5\xe4\x93\xeb\ +\x1c\xd1\x0d\x79\xaf\xbc\xf2\x34\x4e\xa7\x13\xa5\x1c\x8e\xf1\xe3\ +\xc7\x5f\x54\x56\x56\x36\x41\x44\x8e\x57\x4a\xad\xb0\x3b\x36\x2d\ +\xf4\xe9\x05\x15\x9a\xa6\x69\xda\x21\x33\x0c\x63\x37\x56\x4d\xb7\ +\xc9\x87\x90\xd8\x01\x8c\x8a\x8a\x8a\xaa\xe8\xd3\xa7\x27\xa7\x9e\ +\xea\xe1\x99\x67\xbe\xe6\x94\x53\x8a\x70\x38\xc2\xa7\xd3\x4a\x29\ +\x45\x51\x51\x11\x5d\xbb\x76\x65\xfc\xf8\xf1\xc4\xc4\xc4\xf0\xeb\ +\xaf\xbf\x76\x75\x38\x1c\x5f\x8b\xc8\x3c\x11\x89\xb4\x3b\x46\x2d\ +\xb4\xe9\xe4\x4e\xd3\x34\x4d\x6b\x90\x69\x9a\x63\x4d\xd3\x9c\xeb\ +\x7f\xcc\x30\x8c\xa2\x43\xbd\x8e\x88\x8c\xca\xce\xce\xc6\xe1\xb0\ +\xde\x7e\xda\xb6\xad\xe0\xca\x2b\x7f\xe1\xb1\xc7\xbe\x25\x27\xa7\ +\x79\xb6\x6c\xdd\xb3\xc7\xc1\xba\x75\xd1\x54\x54\x48\xb3\xdc\xaf\ +\xa6\xe2\xe2\x62\xca\xcb\xcb\x49\x49\x49\x01\x20\x33\x33\x93\x07\ +\x1f\x7c\xd0\x75\xc9\x25\x97\xb8\x22\x22\x22\xe6\xc6\xc7\xc7\xaf\ +\x3c\xff\xfc\xf3\xf3\x6c\x09\x4e\x6b\x15\x74\x72\xa7\x69\x9a\xa6\ +\xd5\x4a\x84\x13\x9c\x4e\xf5\x54\x7a\x7a\xd1\xca\x87\x1e\xfa\xc3\ +\xeb\x77\xdc\x31\xf5\x22\x87\x83\x27\x45\x78\x42\x04\xf3\x30\xae\ +\x37\xc4\xe9\xec\x31\x6e\xf0\xe0\xc1\x07\x8d\xc3\xa6\xa7\xef\xe1\ +\xae\xbb\x56\x71\xf3\xcd\x6b\xe8\xd2\x65\x6f\x60\x5e\x40\x1d\xbe\ +\xfa\xaa\x2d\xa7\x9f\x7e\x24\x1b\x37\xda\xd3\x41\xe6\xf1\x78\x88\ +\x8c\x8c\x24\x21\x21\x61\xff\x31\x87\xc3\xc1\x19\x67\x9c\xc1\x93\ +\x4f\x3e\xe9\x9c\x32\x65\x4a\xb7\x9c\x9c\x9c\xc2\x99\x33\x67\xae\ +\x18\x3e\x7c\x78\xab\x9d\x77\xa8\x05\x8f\x9e\x73\xa7\x69\x9a\xa6\ +\xd5\x25\xd3\xeb\x95\x53\x63\x63\xf7\x56\x6e\xda\xd4\xfe\xb3\x8d\ +\x1b\xdb\xff\xd4\xb4\xcb\x79\x5f\xaf\xa8\x38\x37\x3e\x3b\xbb\x53\ +\x9d\x2d\x46\x8e\xdc\xc6\xf0\xe1\xa5\x14\x17\xbb\x9b\x76\xab\x7a\ +\x24\x26\xee\x63\xdc\xb8\x62\x62\x63\x2b\x83\x76\x8f\xfa\x14\x15\ +\x15\xed\xef\xb5\xab\x29\x35\x35\x95\x8b\x2f\xbe\xd8\xf1\xf6\xdb\ +\x6f\xd3\xb3\x67\xcf\xcc\xe4\xe4\xe4\x0d\x7d\xfb\xf6\x9d\xb9\x6a\ +\xd5\xaa\xfb\x9a\x39\x4c\x2d\x84\xe9\xe4\x4e\xd3\x34\x4d\xab\x57\ +\xaf\x5e\x9b\x26\xfc\xef\x7f\xdd\xde\x68\xfa\x95\xca\x5d\x0e\x87\ +\x53\x65\x66\x66\xd6\x3b\x1e\xea\x76\x2b\x3a\x76\x0c\xde\x8e\x5d\ +\xbd\x7b\xef\xe6\xc6\x1b\x7f\x0c\xda\xf5\x1b\xe2\xf1\x78\xc8\xca\ +\xca\xaa\xb7\xcd\xe8\xd1\xa3\x29\x29\x29\xe1\xed\xb7\xdf\x76\xfe\ +\xf0\xc3\x0f\xf7\xba\xdd\xee\xf1\x15\x15\x15\xe7\x28\xa5\x76\x35\ +\x53\x98\x5a\x08\xd3\xc9\x9d\xa6\x69\x9a\xb6\x9f\x69\x9a\x11\x35\ +\xf7\x42\x7d\xf6\xd9\xe1\x75\x66\x42\x22\xb8\x80\xc5\xc0\x1e\x60\ +\x86\x52\x28\xdf\xf1\x0e\xc0\xa3\xc0\xab\x4a\x71\x8b\x08\x6f\x82\ +\x2b\xda\xe5\x3a\x9f\x4b\x2e\x89\x05\xe0\xc4\x13\xb7\x30\x61\xc2\ +\x56\x00\xd6\xaf\x8f\xe2\xfe\xfb\xbb\xb0\x62\x45\x1b\x2a\x2b\x21\ +\x3b\x7b\x07\x33\x67\xae\x27\x39\xf9\x40\x28\x37\xdc\x90\x4e\x7a\ +\xfa\x1e\x7a\xf7\xde\xc5\x23\x8f\x74\xe2\x87\x1f\x62\xe8\xd1\x63\ +\x0f\x97\x5e\xfa\x2b\x99\x99\x07\x72\x9e\xf5\xeb\xa3\xb8\xef\xbe\ +\x2e\x7c\xf7\x5d\x1c\xbb\x76\x39\x69\xdf\xbe\x9c\x81\x03\xb7\x93\ +\x97\xf7\x33\x00\xdf\x7f\xdf\x86\xbb\xef\xee\xca\xbc\x79\x3f\xd1\ +\xa1\xc3\x81\xeb\x3f\xff\x7c\x32\x2f\xbc\x90\xcc\xfa\xf5\xd1\x74\ +\xea\x54\xc6\x1f\xfe\xb0\x95\x69\xd3\x3c\x88\x2f\x15\xdd\xbe\xdd\ +\xc5\x9c\x39\xbd\xb8\xe0\x82\xdf\xf8\xe9\xa7\x18\x5e\x7a\x29\x89\ +\xe2\xe2\x08\x06\x0d\xda\xce\x15\x57\xac\xa3\x5d\xbb\x7a\x6a\xbb\ +\xf8\xfc\xfe\xfb\xef\xec\xd9\xb3\x87\x8e\x1d\x1b\x1e\x6d\x6d\xdf\ +\xbe\x3d\x27\x9f\x7c\x32\x5d\xbb\x76\xe5\xea\xab\xaf\x9e\xba\x7b\ +\xf7\xee\x4f\x45\x64\x92\x52\xea\x97\x06\x4f\xd6\xc2\x9a\x9e\x73\ +\xa7\x69\x9a\xa6\x01\x60\x9a\xe6\x51\xc0\x4a\x5f\xfd\xba\x46\x51\ +\x8a\x0a\xe0\x3e\xac\x7d\x64\xe7\x00\x88\x20\xc0\x63\x40\x5f\xe0\ +\x61\x5f\xd3\x7f\x41\x99\xa4\xa6\x6e\x96\xe3\x8f\xdf\xca\xf1\xc7\ +\x6f\x25\x23\x63\x37\x00\xdf\x7d\xd7\x86\xb3\xcf\xee\xcf\xfa\xf5\ +\x51\x9c\x72\x8a\x87\xd3\x4f\xf7\xf0\xfd\xf7\x6d\x38\xfb\xec\x2c\ +\x7e\xff\xfd\x40\x1f\xc4\xca\x95\x6d\x78\xe9\xa5\x64\x6e\xba\xa9\ +\x27\x99\x99\xbb\x38\xe7\x9c\x4d\x78\x3c\x91\x5c\x76\x59\x5f\x76\ +\xef\x76\x02\xe0\xf5\x0a\x97\x5e\xda\x97\x75\xeb\xa2\x39\xe7\x9c\ +\xdf\xb8\xfe\xfa\x1f\x39\xe3\x8c\x4d\xd5\xca\xad\x6c\xdf\xee\xe2\ +\xcb\x2f\xdb\xb2\x77\xef\x81\xb7\xc0\x7b\xef\xed\xc2\xfc\xf9\xe9\ +\xf4\xee\xbd\x9b\x82\x82\xb5\x0c\x1e\xfc\x3b\x77\xdd\xd5\x8d\xc2\ +\xc2\x1e\xfb\xdb\x94\x97\x0b\x5f\x7e\xd9\x96\xbb\xee\x4a\xe3\xb9\ +\xe7\x3a\x30\x79\xf2\x56\xc6\x8d\x2b\xe6\xbd\xf7\xda\x71\xfd\xf5\ +\xf5\xd4\x63\xf6\xe3\xf1\x78\x70\x3a\x9d\x24\x27\x27\x37\xf6\x4b\ +\x4c\x4e\x4e\x0e\x8f\x3c\xf2\x88\xab\x5b\xb7\x6e\xbd\xce\x3d\xf7\ +\xdc\xd5\x67\x9c\x71\xc6\xe5\x8d\x3e\x59\x0b\x4b\xba\xe7\x4e\xd3\ +\x34\x2d\xcc\x99\xa6\x29\x40\x01\x70\x1d\xf0\x3a\xf0\x55\x8d\x26\ +\xef\x89\x50\x73\x82\xda\x32\xa5\x98\x01\xa0\x14\xef\x89\x70\x0d\ +\x70\x83\x08\xef\x01\x23\x81\x31\x40\xae\x52\xf8\x76\x99\x90\xd7\ +\xa1\x44\xfa\xf5\x2b\x67\xf2\xe4\x2d\xd5\x2e\x74\xeb\xad\xdd\x48\ +\x4a\xda\xc7\xe2\xc5\xdf\xed\xef\x25\x9b\x34\x69\x2b\x93\x27\x0f\ +\xe2\xb1\xc7\x3a\x31\x73\xe6\x81\x0d\x1c\xd6\xae\x8d\x66\xc9\x92\ +\x2f\xf7\x0f\xdb\xf6\xec\xb9\x9b\x59\xb3\xfa\xf2\xe1\x87\xed\x18\ +\x3b\xb6\x98\x4d\x9b\x22\xd8\xb4\x29\x92\x45\x8b\xd6\x90\x9b\x7b\ +\x60\x83\x8b\x13\x4f\xac\x7b\xd7\xaf\xe2\x62\x37\x8f\x3f\x9e\xca\ +\xb4\x69\x1e\x2e\xbb\x6c\x1d\x00\xb9\xb9\xdb\x88\x8a\xf2\xf2\xe0\ +\x83\x5d\x38\xfd\xf4\x22\x7a\xf6\xdc\xbd\xbf\xfd\xee\xdd\x4e\x9e\ +\x7a\xea\xeb\xfd\x8f\x5d\x2e\xc5\x63\x8f\xa5\xb2\x7d\xbb\x8b\xb6\ +\x6d\xeb\xaf\xcd\x17\x11\x11\x41\x9f\x3e\x7d\xf6\xaf\x16\x6e\xac\ +\x94\x94\x14\x1e\x78\xe0\x01\xd7\xab\xaf\xbe\xaa\xba\x74\xe9\x72\ +\xeb\xac\x59\xb3\xc6\xf7\xed\xdb\xf7\x78\xc3\x30\xec\x99\x38\xa8\ +\xb5\x68\xba\xe7\x4e\xd3\x34\x4d\x3b\x12\xc8\x07\x66\x03\x93\x6a\ +\x29\x71\xf2\x30\x70\x7b\x8d\x8f\x17\x6a\xb4\x59\x00\xbc\x01\xfc\ +\x17\xb8\x1e\x98\xab\x14\x1f\xfa\x3d\x9f\x0b\x1c\xd4\x63\xf5\xfb\ +\xef\x2e\x56\xac\x68\xc3\xc8\x91\xdb\xf8\xf5\xd7\x68\xd6\xad\xb3\ +\x3e\x4a\x4b\xdd\x64\x66\xee\x64\xc5\x8a\xd8\x6a\xed\x8f\x38\x62\ +\x57\xb5\xf9\x78\x47\x1e\xb9\x03\x87\x43\xe1\xf1\x44\x00\xd0\xa9\ +\x53\x19\x9d\x3a\x95\xb1\x78\x71\x67\xde\x78\x23\x91\x3d\x7b\x9c\ +\x0d\xbe\xf8\x15\x2b\xda\xb0\x6f\x9f\x83\x49\x93\xaa\x27\x9d\x53\ +\xa7\x6e\x41\x29\xf8\xfa\xeb\x36\xd5\x8e\x8f\x19\x53\x52\xed\xf1\ +\xc0\x81\xdb\x01\xf6\xc7\x50\x9f\x1e\x3d\x7a\x70\xf4\xd1\x47\x37\ +\xd8\xae\x36\xd1\xd1\xd1\x4c\x9d\x3a\x55\x36\x6c\xd8\x40\xcf\x9e\ +\x3d\x27\x7e\xf9\xe5\x97\x9f\x8b\x88\xee\xa4\xd1\x0e\xa2\x7f\x28\ +\x34\x4d\xd3\xc2\x9c\x61\x18\x5f\x9b\xa6\xd9\xdd\x30\x8c\xad\x75\ +\x34\x79\x58\x29\xd6\xd5\x77\x0d\xa5\x50\x22\x5c\x0b\x7c\x04\x6c\ +\x04\xfe\x5e\xa3\x49\xae\xd3\xe9\xc4\xe5\xaa\xfe\xb6\xb3\x7e\x7d\ +\x14\x00\xcf\x3c\xd3\x91\x67\x9e\x39\x78\x05\x69\x5a\x5a\xf5\xb2\ +\x28\x55\x43\xb9\x55\xa2\xa3\xbd\x44\x46\x2a\xca\xcb\xad\xbe\x0a\ +\x11\x98\x37\xef\x47\x1e\x7a\xa8\x33\x73\xe7\x66\x10\x11\xe1\x65\ +\xc2\x84\x62\xa6\x4d\xf3\x54\xeb\x7d\xf3\x57\x55\x12\x25\x39\xb9\ +\xfa\x9c\xb9\xe4\xe4\x7d\xb8\xdd\x8a\xcd\x9b\xab\x97\x4c\xe9\xd5\ +\xab\xfa\x75\xe2\xe3\xad\xde\xba\xaa\x18\x82\x49\x44\x38\xe1\x84\ +\x13\x78\xf7\xdd\x77\x59\xb2\x64\x49\x96\xcb\xe5\x7a\x4b\x44\x4e\ +\x52\x4a\xd5\xf5\xbd\xd3\xc2\x90\x4e\xee\x34\x4d\xd3\x34\xea\x49\ +\xec\x1a\x45\x84\x08\xe0\x6e\xe0\x67\x20\x0d\xf8\x1b\x70\x73\xd5\ +\xf3\x6e\xb7\x7b\x9c\xc8\xc1\xbd\x68\x09\x09\x56\x62\x74\xed\xb5\ +\x3f\x31\x6e\x5c\x71\x23\xee\xd4\xf0\x4e\x16\xfd\xfb\xef\xe4\xf6\ +\xdb\x57\x53\x54\x14\xc1\xf2\xe5\xed\x79\xf6\xd9\x0e\x5c\x78\xe1\ +\x11\xbc\xf4\xd2\x17\x44\x47\x7b\x0f\x6a\xdf\xbe\xbd\x95\xd4\x6d\ +\xdf\xee\x24\x21\xe1\x40\x82\xb7\x73\xa7\x93\xf2\x72\x21\x3e\xbe\ +\xe1\x85\x12\xcd\x6d\xe4\xc8\x91\xa4\xa6\xa6\x3a\x2f\xbf\xfc\xf2\ +\x61\xdb\xb6\x6d\xfb\x4a\x44\x8e\x53\x4a\x7d\x6b\x77\x5c\x5a\xcb\ +\xa0\x87\x65\x35\x4d\xd3\xc2\x8c\x69\x9a\x5d\x4d\xd3\x7c\xcb\x34\ +\xcd\x9e\x01\xbc\xec\xcd\x40\x26\x30\x19\x6b\x58\xf6\x26\x11\x86\ +\x02\x88\x48\x52\x79\x79\x79\x46\x4c\x8c\x97\xd2\xd2\xea\x7d\x0a\ +\xa9\xa9\x7b\x69\xd7\xae\x9c\x37\xdf\x6c\x1f\xc0\x50\x2c\x29\x29\ +\xfb\x38\xed\x34\x0f\x37\xdc\xf0\x23\xbb\x77\x3b\xf9\xe0\x83\x84\ +\x5a\xdb\x55\xf5\x06\x7e\xf2\x49\xbb\x6a\xc7\x3f\xf8\xc0\x7a\x9c\ +\x9e\xbe\x27\xe0\xb1\x05\x42\x46\x46\x06\x8f\x3e\xfa\xa8\x3b\x33\ +\x33\x33\xe5\x98\x63\x8e\xf9\x2c\x27\x27\xe7\xaf\x76\xc7\xa4\xb5\ +\x0c\xba\xe7\x4e\xd3\x34\x2d\x8c\x98\xa6\x99\x09\x2c\x03\x76\x02\ +\x8d\x2d\x26\x37\x5e\x84\x2d\xb5\x1c\x7f\x51\x29\x2a\x44\x38\x09\ +\xb8\x14\x38\x57\x29\x56\x8a\x70\x23\xd6\x82\x8a\x27\x44\x18\x08\ +\xe4\x8a\x88\xea\xd5\xab\x5c\x3e\xfa\x28\x9e\xe5\xcb\x13\x48\x4d\ +\x2d\x23\x39\xb9\x9c\x84\x84\x72\x2e\xbd\xf4\x57\xae\xbf\xbe\x27\ +\x77\xde\x99\xc6\x29\xa7\x14\x91\x94\x54\xce\xd6\xad\x6e\x3e\xf9\ +\x24\x9e\xa8\x28\x2f\x13\x27\x36\xbe\x53\x71\xf5\xea\x58\x96\x2f\ +\x4f\x60\xdc\xb8\x62\xba\x76\xdd\x4b\x49\x89\x9b\x25\x4b\x3a\x20\ +\x02\x5d\xbb\xd6\xbe\xf3\x45\x8f\x1e\x7b\x18\x3d\x7a\x1b\x0f\x3c\ +\xd0\x99\x4e\x9d\xf6\x32\x70\xe0\x0e\x56\xae\x8c\xe5\x8e\x3b\xba\ +\xd1\xbf\xff\x4e\x86\x0d\x0b\xcc\xb6\x68\xc5\xc5\xc5\x24\x24\x24\ +\x1c\xf2\x62\x8a\xfa\xb4\x6b\xd7\x8e\x7b\xee\xb9\xc7\xf5\xee\xbb\ +\xef\xe2\x72\xb9\xfe\x31\x64\xc8\x90\xbe\x9f\x7d\xf6\xd9\xa5\x01\ +\xbb\x81\x16\x92\x74\x72\xa7\x69\x9a\x16\x26\x4c\xd3\x4c\x03\xde\ +\x05\x7e\x04\x26\x1b\x86\xd1\x98\x71\x50\x80\xfb\xeb\x38\xde\x4e\ +\x84\x04\xac\x05\x17\xff\x52\x8a\x47\x00\x94\xc2\x2b\xc2\x59\xc0\ +\xd7\xc0\x03\xc0\xc6\xf4\xf4\xf4\x7d\x97\x5d\xf6\x5b\xe4\xc2\x85\ +\xdd\x99\x37\xaf\x27\xbb\x77\x3b\x31\x8c\xf5\x9c\x7b\xee\x46\x26\ +\x4d\xda\x8a\xc3\x01\xb7\xdf\x9e\xc6\xe3\x8f\xa7\xee\xbf\x78\xc7\ +\x8e\x65\xcc\x9a\xf5\x6b\x6d\xf7\xad\x93\x88\xe2\xe5\x97\x93\x79\ +\xf8\xe1\xce\x88\x80\x52\xd6\xfe\xb5\xb3\x67\xff\x42\xef\xde\x75\ +\xd7\xff\xbd\xfa\xea\x9f\x28\x2c\xec\xc1\x95\x57\xf6\x41\xf9\x46\ +\x7e\x87\x0f\x2f\xe5\xda\x6b\xd7\x1e\xd2\xfd\xeb\x52\x5e\x5e\xce\ +\x92\x25\x4b\x18\x3b\x76\x2c\xdd\xbb\x77\x0f\xc8\x35\xab\xb8\xdd\ +\x6e\x46\x8f\x1e\xcd\xfb\xef\xbf\xcf\x59\x67\x9d\x75\xc9\x98\x31\ +\x63\x62\xde\x7a\xeb\xad\x0b\x02\x7a\x13\x2d\xa4\x88\x52\x0d\xcf\ +\x5f\xd0\x34\x4d\xd3\x5a\x07\xd3\x34\x2f\x06\x16\x1b\x86\xd1\x6c\ +\x3b\x1d\x44\x44\x44\x7c\x7b\xca\x29\xa7\x64\xcd\x9a\x35\xab\xc1\ +\xb6\x5b\xb7\x46\x50\x52\xe2\xa2\x7d\xfb\x0a\x92\x92\x0e\x7f\x97\ +\x8a\xad\x5b\xdd\x94\x94\xb8\x89\x8e\xf6\xd2\xb1\xe3\x3e\xdc\xee\ +\x83\xe7\xda\xd5\x66\xcf\x1e\x27\x1b\x37\x46\x92\x92\x52\x46\x9b\ +\x36\x81\xab\x32\xf2\xdb\x6f\xbf\xb1\x74\xe9\x52\xce\x3a\xeb\x2c\ +\xa2\xa3\xa3\x03\x76\x5d\x7f\x4a\x29\x96\x2f\x5f\xce\xe2\xc5\x8b\ +\x59\xbd\x7a\xf5\x15\x4a\xa9\xdb\x82\x72\x23\xad\xc5\xd3\x3d\x77\ +\x9a\xa6\x69\x61\xc4\x30\x8c\xbb\x9b\xf3\x7e\x22\x12\x2f\x22\xfd\ +\x06\x0e\x1c\xd8\xa8\xf6\x49\x49\xfb\x9a\x94\xd4\x1d\xb8\x4e\x39\ +\x49\x49\x87\xbe\x10\x22\x3a\xba\xb2\xce\x55\xb5\x4d\xe1\xf1\x78\ +\x88\x8f\x8f\x0f\x5a\x62\x07\xd6\x4a\xda\xd1\xa3\x47\xb3\x61\xc3\ +\x06\x56\xaf\x5e\x7d\xab\x88\x94\x29\xa5\xee\x09\xda\x0d\xb5\x16\ +\x4b\x2f\xa8\xd0\x34\x4d\x6b\xc5\x4c\xd3\x9c\x68\x9a\x66\x8c\x8d\ +\x21\x8c\x50\x4a\xc9\x80\x01\x03\x6c\x0c\xc1\x7e\x1e\x8f\x87\x94\ +\x94\x83\x4b\xbd\x04\xc3\xf4\xe9\xd3\x99\x31\x63\x06\xc0\xdd\x29\ +\x29\x29\x97\x34\xcb\x4d\xb5\x16\x45\xf7\xdc\x69\x9a\xa6\xb5\x52\ +\xa6\x69\x1e\x0f\x2c\x01\x66\x00\x0f\xd9\x14\x46\x6e\x5a\x5a\x5a\ +\x59\x7c\x7c\x7c\x64\xc3\x4d\x5b\x27\xaf\xd7\xcb\x96\x2d\x5b\xe8\ +\xd5\xab\x57\xb3\xdd\xf3\xbc\xf3\xce\x43\x29\x25\x19\x19\x19\x77\ +\x9e\x77\xde\x79\xd9\x8b\x17\x2f\xfe\x73\xb3\xdd\x5c\xb3\x9d\xee\ +\xb9\xd3\x34\x4d\x6b\x85\x4c\xd3\x1c\x0a\x3c\x09\x3c\x60\x18\x86\ +\x5d\x89\x1d\x2e\x97\xeb\xd8\x9c\x9c\x9c\xb0\x4d\xec\x00\xb6\x6c\ +\xd9\x42\x45\x45\x45\xb3\xf5\xdc\x55\x39\xff\xfc\xf3\x29\x2d\x2d\ +\x65\xc8\x90\x21\xe7\x9f\x7a\xea\xa9\x0b\x9a\xf5\xe6\x9a\xad\x74\ +\x72\xa7\x69\x9a\xd6\x3a\x15\x02\xaf\x02\x33\xed\x0a\x40\x44\x62\ +\x2a\x2b\x2b\x07\x35\x76\xbe\x5d\x6b\x55\x54\x54\x44\x74\x74\x34\ +\xf1\xf1\xf1\xcd\x7e\xef\xa9\x53\xa7\xb2\x79\xf3\x66\x8e\x39\xe6\ +\x98\x39\x83\x07\x0f\xbe\xa8\xd9\x03\xd0\x6c\xa1\x93\x3b\x4d\xd3\ +\xb4\xd6\xe9\x8f\xc0\x19\x86\x61\x34\x6e\x99\x68\x70\x0c\x57\x4a\ +\x39\xb3\xb3\xb3\x6d\x0c\xc1\x7e\x1e\x8f\x87\x8e\x1d\x3b\xda\x76\ +\xff\xe3\x8e\x3b\x8e\x1f\x7e\xf8\x41\x7d\xf5\xd5\x57\x77\x89\xc8\ +\x24\xdb\x02\xd1\x9a\x8d\x9e\x73\xa7\x69\x9a\xd6\x0a\x19\x86\x51\ +\x6a\x77\x0c\x40\x6e\x4a\x4a\x4a\x59\x52\x52\x52\x58\x0f\xcb\x16\ +\x15\x15\x61\x67\xef\xa5\x88\x30\x7d\xfa\x74\xf9\xf5\xd7\x5f\x9d\ +\x2f\xbd\xf4\xd2\x12\x11\x99\xa4\x94\x7a\xdd\xb6\x80\xb4\xa0\xd3\ +\x3d\x77\x9a\xa6\x69\xad\x80\x69\x9a\x11\xa6\x69\xfe\xd1\xee\x38\ +\xfc\xf9\xe6\xdb\x45\xd8\x1d\x87\x9d\x4a\x4a\x4a\x28\x2b\x2b\xb3\ +\xb5\xe7\x0e\xac\x04\x2f\x3f\x3f\x5f\xc6\x8f\x1f\xef\x8a\x8c\x8c\ +\x7c\x31\x2d\x2d\x6d\xb8\xad\x01\x69\x41\xa5\x8b\x18\x6b\x9a\xa6\ +\x85\x38\xd3\x34\x05\xf8\x37\x70\x3c\xd0\xc7\x30\x8c\x4d\x36\x87\ +\x84\x88\x44\x38\x1c\x8e\x1d\x73\xe7\xce\x8d\x98\x3c\x79\xb2\xdd\ +\xe1\xd8\xa6\xb2\xb2\x92\xcd\x9b\x37\x93\x92\x92\x12\xd0\x6d\xc7\ +\x0e\x97\xd7\xeb\xe5\xf9\xe7\x9f\x57\x7b\xf7\xee\x2d\x7b\xe6\x99\ +\x67\xba\xad\x5f\xbf\x7e\xb3\xdd\x31\x69\x81\x67\xff\x4f\x9a\xa6\ +\x69\x9a\xd6\x54\x0b\x81\x53\x80\x3f\xb6\x84\xc4\xce\x67\x88\xd7\ +\xeb\x8d\x18\x34\x68\x90\xdd\x71\xd8\xca\xe9\x74\x92\x9a\x9a\xda\ +\x22\x12\x3b\x00\x87\xc3\xc1\x51\x47\x1d\x25\xdd\xbb\x77\x8f\x9a\ +\x32\x65\xca\x57\x22\xd2\x32\x02\xd3\x02\x4a\x7f\x53\x35\x4d\xd3\ +\x42\x98\x6f\xbf\xd8\x8b\x80\xf3\x0d\xc3\x78\xcd\xee\x78\xfc\x8c\ +\x6a\xdf\xbe\x7d\x59\x6a\x6a\x6a\xc3\x2d\xb5\x66\x95\x92\x92\x42\ +\x9b\x36\x6d\xe8\xd7\xaf\x5f\xea\xb4\x69\xd3\x96\xda\x1d\x8f\x16\ +\x78\x3a\xb9\xd3\x34\x4d\x0b\x61\x86\x61\xfc\x0a\xa4\x1b\x86\xf1\ +\x98\xdd\xb1\xf8\x73\x3a\x9d\x63\x86\x0c\x19\xe2\xb6\x3b\x0e\xad\ +\x76\x59\x59\x59\x94\x96\x96\xb2\x64\xc9\x92\xf1\x22\x72\xb2\xdd\ +\xf1\x68\x81\xa5\x93\x3b\x4d\xd3\xb4\x10\x67\x18\xc6\x56\xbb\x63\ +\xf0\x27\x22\x4e\x60\xc4\xa0\x41\x83\xf4\x7b\x4c\x0b\x36\x6e\xdc\ +\x38\x26\x4d\x9a\xa4\x9c\x4e\xe7\x63\x22\x92\x69\x77\x3c\x5a\xe0\ +\xe8\xff\x78\x9a\xa6\x69\x21\xc6\x34\x4d\x87\x69\x9a\x7d\xed\x8e\ +\xa3\x1e\xd9\x95\x95\x95\x31\xe1\x5e\xbc\x78\xe5\xca\x95\xac\x59\ +\xb3\xc6\xee\x30\xea\x75\xf9\xe5\x97\x4b\x9f\x3e\x7d\xdc\x2e\x97\ +\xeb\xa5\xd8\xd8\xd8\xe6\xaf\xb2\xac\x05\x85\x4e\xee\x34\x4d\xd3\ +\x42\xcf\x1c\xe0\x13\xd3\x34\xdb\xd9\x1d\x48\x1d\x72\xe3\xe2\xe2\ +\xf6\x75\xeb\xd6\xcd\xee\x38\x6c\xb5\x72\xe5\x4a\x4a\x4a\x4a\xec\ +\x0e\xa3\x5e\x6e\xb7\x9b\x45\x8b\x16\xb9\x4e\x3b\xed\xb4\x6e\xd3\ +\xa6\x4d\xfb\x52\x44\xc4\xee\x98\xb4\xa6\xd3\x45\x8c\x35\x4d\xd3\ +\x42\x88\x69\x9a\x47\x01\xd7\x03\x57\xb5\x90\x42\xc5\x07\x71\x38\ +\x1c\xa3\x07\x0f\x1e\xec\xb4\x3b\x0e\x3b\x95\x95\x95\x51\x52\x52\ +\x42\x28\xac\x16\x4e\x4a\x4a\x22\x37\x37\xd7\xe1\xf5\x7a\x7b\x6c\ +\xd8\xb0\xe1\x51\x60\xba\xdd\x31\x69\x4d\xa3\x7b\xee\x6c\x22\xf9\ +\x72\xb1\xcc\x91\x38\xbb\xe3\xd0\x34\x2d\x74\x98\xa6\x19\x0d\x3c\ +\x0e\xbc\x62\x18\xc6\x6d\x76\xc7\x53\x1b\x11\x11\x87\xc3\x31\x6a\ +\xd0\xa0\x41\x61\x9d\xdc\x15\x15\x15\x01\xd6\xca\xd4\x50\x90\x9d\ +\x9d\xcd\x8e\x1d\x3b\x18\x37\x6e\xdc\x59\xfd\xfa\xf5\xd3\xc9\x5d\ +\x88\xd3\xc9\x9d\x0d\x24\x5f\xba\x03\x37\xe3\x60\xae\xcd\xa1\x68\ +\x9a\x16\x42\x0c\xc3\xd8\x03\x5c\x05\xfc\xc9\xe6\x50\xea\x73\x44\ +\x45\x45\x45\x7c\xb8\xef\x27\x5b\x54\x54\x44\x7c\x7c\x3c\xd1\xd1\ +\xd1\x76\x87\xd2\x68\x23\x47\x8e\x64\xe7\xce\x9d\x6a\xfb\xf6\xed\ +\xf7\x89\x48\x4f\xbb\xe3\xd1\x0e\x9f\x4e\xee\xec\xa0\xb8\x05\x88\ +\x02\x2e\x97\xab\xf4\x7f\x20\x4d\xd3\x1a\xcf\x30\x8c\xa7\x0d\xc3\ +\x28\xb6\x3b\x8e\x7a\xe4\x46\x47\x47\x97\x67\x64\x64\xd8\x1d\x87\ +\xad\x3c\x1e\x8f\xed\x5b\x8e\x1d\x2a\x87\xc3\xc1\xd8\xb1\x63\xc5\ +\xed\x76\xbb\x5d\x2e\xd7\x63\x7a\xfe\x5d\xe8\xd2\xc9\x5d\x33\x93\ +\xb9\x32\x06\xa1\xaa\xa6\x50\x04\x4e\x6e\xb5\x35\x20\x4d\xd3\xb4\ +\x00\x12\x91\x51\xd9\xd9\xd9\xd2\x52\x76\x64\xb0\x43\x45\x45\x05\ +\x5b\xb6\x6c\x09\xb9\xe4\x0e\x20\x32\x32\x92\xeb\xae\xbb\xce\xed\ +\xf5\x7a\x87\x02\x33\xed\x8e\x47\x3b\x3c\xe1\xfb\xbf\xcf\x06\x72\ +\x9a\x38\xf1\x72\x47\x8d\xc3\x53\x65\x8e\xfc\xc1\x96\x80\x34\x4d\ +\x6b\xf1\x4c\xd3\x8c\x36\x4d\x73\x89\x69\x9a\x59\x76\xc7\xd2\x18\ +\x4e\xa7\xf3\xd8\xc1\x83\x07\x87\xf5\x62\xbd\x2d\x5b\xb6\xe0\xf5\ +\x7a\x43\x32\xb9\x03\xe8\xd3\xa7\x0f\xd3\xa7\x4f\x77\xe4\xe4\xe4\ +\xdc\x32\x62\xc4\x88\x01\x76\xc7\xa3\x1d\x3a\x9d\xdc\x35\xa7\x9e\ +\xcc\x00\xfa\x1f\x74\xdc\xc1\xed\x32\x4f\x42\xe2\x97\xa1\x08\xbd\ +\x44\xe8\xeb\xfb\xe8\x25\x42\x1b\xbb\x63\x6a\xad\x44\x98\x27\xc2\ +\x2c\xbf\xc7\xc3\x45\x78\x42\x84\x04\xbf\x63\xf7\x88\x70\x96\x3d\ +\x11\x6a\xcd\xe4\x36\x60\x24\xf0\xbb\xdd\x81\x34\x44\x44\x7a\x56\ +\x54\x54\x24\x87\x7b\x7d\x3b\x8f\xc7\x43\x4c\x4c\x0c\x71\x71\xa1\ +\xbb\x66\xee\xfc\xf3\xcf\xe7\xe4\x93\x4f\x76\x0f\x1b\x36\xac\x25\ +\x6d\x69\xa7\x35\x92\x4e\xee\x9a\x89\xe4\x4b\x02\x56\xf9\x82\xda\ +\x1c\x41\x19\x7f\x6d\xce\x78\x9a\xe0\x33\x60\xa5\xef\x63\x0d\xb0\ +\x43\x84\x55\x22\xfc\xd1\xde\xb0\x5a\x1e\x11\xfe\x25\xc2\x8c\x26\ +\x5c\xe2\x0f\xc0\xd1\x7e\x8f\xbb\x02\xa7\x03\xfe\x33\xb4\x4f\x00\ +\xf4\x5f\xd6\xad\x94\x69\x9a\x27\x00\x7f\xc1\xda\x37\x76\xbd\xdd\ +\xf1\x34\xc2\xa8\x88\x88\x88\xca\xbe\x7d\x5b\x72\x7d\xe5\xe0\x0b\ +\xc5\xf9\x76\x35\x45\x45\x45\x91\x90\x90\x20\x3d\x7b\xf6\x4c\x3e\ +\xf7\xdc\x73\x1f\xb6\x3b\x1e\xed\xd0\xe8\xe4\xae\xf9\x5c\x0f\x24\ +\xd6\xf9\xac\xe2\x3a\xb9\x52\x92\x9a\x2f\x9c\x26\x79\x1e\xe8\x01\ +\xf4\xc6\x7a\xe3\x51\xc0\x13\x22\x0c\xb1\x35\xaa\x96\x67\x14\xd0\ +\x94\x77\xb9\x69\xc0\xe5\x01\x8a\x45\x0b\x4d\x43\x80\xc7\x0c\xc3\ +\x78\xce\xee\x40\x1a\x29\x37\x2b\x2b\xcb\xeb\x74\x86\x75\x15\x14\ +\x00\x3a\x75\xea\x64\x77\x08\x4d\x96\x9d\x9d\xcd\x6f\xbf\xfd\x46\ +\xbf\x7e\xfd\xfe\xd4\xbd\x7b\xf7\xae\x76\xc7\xa3\x35\x5e\x48\x0c\ +\x05\x86\x3a\xc9\x93\x7e\x08\x17\x35\xd0\x2c\x01\x37\x37\x00\x46\ +\x73\xc4\xd4\x44\xbb\x94\xe2\x17\xdf\xe7\x3f\x88\x50\x0a\x3c\x05\ +\x4c\xc4\xea\xd9\x03\x40\x84\xb6\xc0\x68\xa0\x1b\xb0\x1d\xf8\x5c\ +\x29\xbe\xf3\x7b\xbe\x23\x56\xf2\xf3\xb1\x52\xec\xf1\xbf\x81\x08\ +\x69\x58\x09\xe4\x7b\x4a\x51\xe9\x3b\x16\x07\x1c\x03\xf4\xc4\xea\ +\x35\x7c\x4f\x29\x76\xfb\x9d\x13\x0b\xe4\x00\x5f\x01\x02\x8c\x01\ +\x12\x80\xe5\x4a\xf1\x63\x63\x5e\x98\x08\x0e\xdf\x35\xb2\x81\x62\ +\xe0\x1d\xa5\xd8\xec\xf7\xbc\xcb\x17\xc3\x4a\x60\x17\x56\x02\xd7\ +\x19\xf8\xa0\xc6\x6b\x3b\x06\x6b\x45\x74\x17\x11\x46\xfb\x0e\xaf\ +\x53\x8a\x9f\x7d\xcf\xf7\x06\x86\x62\x25\xfc\xbf\xfa\x62\xac\x59\ +\xca\x3e\x11\x28\x03\x36\x36\x26\xf6\x1a\xaf\xa3\x33\x30\x1c\x48\ +\xc2\xfa\xba\x7f\xd6\xc0\x29\x5a\x0b\x64\x18\xc6\x35\xa6\x69\x86\ +\xcc\x1f\xe1\x6e\xb7\x7b\xdc\x90\x21\x43\xdc\x76\xc7\x61\xb7\xe3\ +\x8e\x3b\xce\xee\x10\x02\x66\xdc\xb8\x71\x5c\x72\xc9\x25\x95\x1b\ +\x36\x6c\xb8\x13\x38\xc9\xee\x78\xb4\xc6\xd1\xc9\x5d\x73\x70\xa0\ +\x80\x53\xab\x1d\x53\x3c\x85\x70\x2f\xf0\xa6\xdf\xd1\x8a\xe6\x0c\ +\x2b\x80\xd6\xfa\xfe\xdd\xff\xe7\xba\x2f\xb9\xf8\x19\xd8\x86\x95\ +\xbc\x1c\x01\x44\x8b\xf0\x77\xa5\xb8\xca\xd7\x2c\x1a\x78\x03\x2b\ +\xa1\xbd\xbf\xc6\x35\x1f\x04\xda\x2b\x65\xf5\x06\x8a\x70\x14\xf0\ +\x24\x56\xb2\xb2\x1a\x2b\x29\x5c\x2f\xc2\x29\x4a\xf1\x8d\xef\x9c\ +\x1e\xc0\x5b\xc0\x15\x40\x3e\xd6\xd7\x33\x19\xa8\x14\xe1\x74\xa5\ +\xa8\xb7\xf7\xc3\x97\x50\x3e\x86\x35\xbf\xe9\x67\x20\x15\xd8\x27\ +\xc2\x9f\x95\xe2\x19\x5f\xb3\x38\xdf\x3d\xae\x05\xce\xf5\x3d\x8e\ +\x03\x22\x44\xb8\x48\x29\x1e\xf0\xb5\xbb\xc7\x17\xeb\x78\xac\x64\ +\xb1\xea\xd8\x22\x11\x66\x03\x85\xbe\x7b\xec\xc1\x9a\x87\xb9\xc5\ +\xf7\x5a\xde\xf1\x0b\xe9\x1f\xc0\x7a\xac\xa1\xd8\x46\x13\x21\x1f\ +\xb8\xce\xf7\xfa\xb7\x00\xdd\x44\x78\x06\x38\x5b\x29\xf6\x1e\xca\ +\xb5\x34\xfb\x19\x86\xe1\xb5\x3b\x86\xc6\x10\x91\x2e\x40\xe7\x70\ +\x9f\x6f\xd7\xda\xc4\xc6\xc6\x32\x63\xc6\x0c\xd7\xac\x59\xb3\x4e\ +\x14\x91\x3f\x2a\xa5\xfe\x6b\x77\x4c\x5a\xc3\x74\x72\x77\x88\x24\ +\x5f\xda\x01\x55\x93\x29\x36\xa9\x42\xd5\xe0\x24\x67\x35\x5f\xad\ +\x00\x56\xd4\xb8\x8e\x17\xc5\x17\xaa\x50\x2d\x09\x42\x98\xcd\x46\ +\x84\x28\x0e\x2c\x97\x7f\xdd\xef\xa9\x1d\xc0\x68\xa5\xf8\xc0\xaf\ +\xdd\x6c\xe0\x7a\x11\x5e\x54\x8a\x77\x94\xe2\x67\x11\x5e\x01\x66\ +\xe0\x97\xdc\x89\x90\x0e\x8c\xf3\x1d\x47\x04\x37\x56\xd2\xe5\x01\ +\x06\x29\xc5\x56\x5f\xf2\xf8\x26\xf0\x98\x08\xd9\x4a\xe1\xff\x06\ +\x58\x80\x55\xe4\x75\x29\xd0\x09\x6b\x18\xf9\x16\xa8\x3f\xb9\x03\ +\xfe\x85\xf5\xbd\x1d\xa6\x14\x9f\x88\x90\x08\x2c\x02\x16\x8b\xf0\ +\x81\x52\xd5\x7a\xd0\xf2\xb1\x92\xbb\x67\x81\x78\xac\x5d\x03\x16\ +\x8a\xf0\xa8\x52\xec\x55\x8a\x23\x45\xf8\x05\x78\x56\xa9\x83\x86\ +\x56\x5f\x05\x1e\x53\x8a\x4d\xbe\xd7\xd7\x05\xf8\x2f\xf0\x90\x08\ +\x7d\xab\x7a\x2a\x0f\x87\x08\x27\x01\xf3\x81\xbf\x61\x7d\x4d\x77\ +\x01\x13\x7c\xaf\xfd\x4a\xe0\xc6\xc3\xbd\xb6\xd6\x7c\x4c\xd3\x8c\ +\xf6\x15\x2c\x0e\x25\xb9\x2e\x97\xcb\xdb\xaf\x5f\xbf\x90\xe9\x69\ +\xd4\x1a\x67\xd8\xb0\x61\x4c\x9e\x3c\xd9\xbb\x6c\xd9\xb2\xfb\x44\ +\xe4\x2d\xa5\x54\xcb\xde\x30\x57\x6b\xfa\x9c\x3b\xc9\x97\x64\xc9\ +\x97\x27\xfc\x3e\xc6\xd7\x78\xfe\x4c\xbf\xe7\x86\x37\xf5\x7e\x2d\ +\xc0\x99\x1c\x58\x50\x70\x9a\xcd\xb1\xd8\x65\xb4\x08\xaf\x88\xf0\ +\x06\xb0\x15\xeb\xeb\x70\x09\x58\x89\x1c\x80\x52\x6c\xaf\x4a\xec\ +\xaa\x0e\x01\x77\x01\xa5\xc0\xb1\x7e\xc7\xef\x01\x06\xd5\x98\xaf\ +\x77\x01\xb0\x13\xf8\x8f\xef\xf1\x44\x20\x1d\xb8\x4a\x29\xb6\xfa\ +\xae\xff\x1b\x70\x0d\x56\xaf\xd7\xa8\x1a\xf1\x2d\x51\x8a\x97\x94\ +\xc2\xab\x14\x1b\x80\x25\x40\x4f\xdf\x30\x71\xad\x44\x18\x86\x35\ +\x84\x7c\x9b\x52\x7c\xe2\xbb\x47\x31\xd6\x5c\xc9\x58\xe0\x94\x1a\ +\xa7\xbc\xa5\x14\x4f\x29\x45\xb9\x2f\xa6\x27\xb1\x86\x80\x7b\xd4\ +\x75\x8f\xfd\x5f\x08\xc5\xd7\x7e\x89\x9d\x03\xeb\x6b\x78\x17\x90\ +\x81\xb5\x68\xa2\x29\xf2\x80\x95\x4a\x71\xab\x52\xec\x54\x0a\xa5\ +\x14\xaf\x60\x25\xba\x7f\x6a\xe2\xb5\xb5\x66\x60\x9a\xe6\x19\xc0\ +\x4a\xd3\x34\x43\x6d\xa9\x65\x6e\x9f\x3e\x7d\x2a\x22\x22\x22\xec\ +\x8e\x43\x0b\x82\xcb\x2e\xbb\xcc\x31\x7a\xf4\xe8\x76\x93\x27\x4f\ +\x7e\xd1\xee\x58\xb4\x86\x05\xa2\xe7\xae\x0d\xd5\x87\x8d\x06\x48\ +\xbe\x64\xa9\x42\x55\xd5\xfb\x30\xc0\xef\xf9\xff\x01\x1f\x05\xe0\ +\x9e\x9a\xbd\xb6\x03\xab\x80\xb6\x58\xf3\xdf\xda\x00\x6b\x94\x42\ +\xf9\x37\x12\xe1\xcf\xc0\xc5\x40\x2f\xac\x04\xa9\x4a\x17\xbf\xcf\ +\x97\x02\xbf\x60\xf5\xd2\x7d\xe6\x9b\xd3\x76\x1e\xf0\x6f\xa5\xd8\ +\xe9\x6b\x53\xb5\x28\xa1\xe6\xbc\xb1\xf7\x7d\xff\x66\x60\x0d\x95\ +\x56\x79\xa9\x46\xbb\xaf\x7c\xff\x26\xf9\x62\xaf\x4d\x55\x89\x9a\ +\x49\x22\x07\x25\x8b\x7b\x7c\xf7\xf0\x57\xd7\x3d\x92\xb1\x12\xff\ +\x3a\x89\x90\x84\x35\xac\x7b\x02\x56\xcf\xa2\xff\xec\xf3\x2e\xb0\ +\x7f\x3e\xe3\x21\x11\x41\x80\x2c\xac\xe1\xea\x27\x6a\x3c\xdd\x0d\ +\xe8\x2e\x82\x4b\xa9\x90\x1d\xfe\x6f\xf5\x7c\x09\xdd\xdf\x81\xa5\ +\x86\x61\xec\xb0\x3b\x9e\x43\xe1\x76\xbb\xc7\xe5\xe4\xe4\x84\x75\ +\x66\x57\x59\x59\x89\x88\xd0\x1a\x0b\x38\xc7\xc5\xc5\x31\x79\xf2\ +\x64\xa7\xd7\xeb\x3d\xaa\x4f\x9f\x3e\xd3\x56\xaf\x5e\x5d\xf3\x77\ +\x8c\xd6\x82\x04\xe3\x27\xb0\x2f\x70\x4e\x10\xae\xab\xb5\x1c\x5f\ +\x28\xc5\x65\x4a\x71\x3e\x56\x72\xf7\x3d\xf0\x94\x08\xfb\x97\x87\ +\x89\x30\x0d\x6b\xde\xdc\x7b\x58\xbd\x9d\xbd\xb1\xe6\xb0\xad\xc1\ +\xef\x8f\x0a\xdf\x70\xea\x7d\xc0\x19\xbe\x05\x13\x53\xb0\x86\x46\ +\xef\xf3\xbb\x5f\x34\x56\xcf\xdf\xbe\x1a\x71\x54\x0d\x5b\x45\xd5\ +\x38\x5e\xf3\x4d\xb1\x6a\xc8\xb6\xbe\xad\x74\xda\xf9\xfe\xfd\x14\ +\x2b\x51\xf3\xff\xb8\x01\x2b\x09\x6d\xcc\x3d\x1a\xe3\x51\xac\xaf\ +\x49\x21\x56\x2f\x66\x17\xac\xde\x49\x68\xda\x1f\x5c\x91\x58\x5f\ +\x8b\x5f\x38\xf8\x35\x3c\x09\x5c\x4d\xfd\x5f\x03\xcd\x7e\xd7\x62\ +\x7d\x1f\xe7\xd8\x1d\xc8\xa1\x10\x91\xe4\xf2\xf2\xf2\x9e\xe1\x3e\ +\xdf\x6e\xed\xda\xb5\x3c\xf6\xd8\x63\x78\xbd\x21\x31\x4d\xf2\x90\ +\x0d\x1b\x36\x0c\xaf\xd7\xcb\xc8\x91\x23\x1f\x16\x91\xd8\x86\xcf\ +\xd0\xec\x12\xac\x39\x77\xd7\x49\xbe\x3c\xae\x0a\x55\x59\x7d\x8d\ +\x24\x5f\x06\x00\x73\xb1\x7a\x4d\x92\x81\x9f\x80\xb7\x81\x9b\x54\ +\xa1\xda\xee\xd7\xee\x9f\x40\x77\xa0\x1c\x6b\x61\xc2\x6d\x58\x43\ +\x68\x6f\xaa\x42\xf5\x67\xc9\x97\xe7\xb1\x7a\x91\x8a\xb0\x7e\x39\ +\xde\x02\x0c\x02\x3e\x07\xae\x51\x85\xea\x4b\xc9\x97\x7c\xac\xd2\ +\x12\x09\x58\x6f\xd4\xb3\xab\xee\x21\xf9\xd2\x16\xb8\x1d\xab\x97\ +\x31\x15\xab\x97\x69\x13\x56\x0f\xcc\x6d\xaa\x50\xf9\x4f\x72\xaf\ +\xef\xf5\x0c\xc6\x9a\x8b\x95\x85\xb5\xd2\x71\x15\xd6\x9b\xea\x3d\ +\xaa\x50\xb5\xca\xff\xed\x4a\x51\xe9\x2b\xa2\xbb\x0a\xb8\x19\xf6\ +\x17\xd4\x3d\x11\xeb\xfb\x39\xab\x6a\x3e\x9c\xaf\x57\x2e\xb5\x96\ +\xcb\x3c\x04\xcc\xf3\x9d\x7b\x02\xf0\x89\x52\xfb\x7b\xc2\x00\x7e\ +\xc4\x4a\x4a\x7a\x61\x25\x92\x55\xfa\xf9\xfe\xfd\x25\x00\x2f\xa5\ +\x6a\x4e\xe4\xab\x4a\x05\xac\x77\xb9\x92\x1a\xff\xc7\x44\x88\xc1\ +\x5a\x64\x71\x83\x52\x98\x7e\xc7\x47\x34\xf5\x66\x4a\xb1\x57\x84\ +\x9f\x81\x12\xa5\x58\xd0\xd4\xeb\x69\xb6\xa8\x04\x66\xb7\xf0\xbd\ +\x63\x6b\x33\x52\x44\xd4\x91\x47\x1e\x19\xd6\x7f\x3c\x78\x3c\x1e\ +\xda\xb5\x6b\xd7\x2a\x7b\xee\xc0\xda\x7b\xb6\x47\x8f\x1e\xb8\x5c\ +\xae\xe8\xd4\xd4\xd4\x6b\x61\xff\xe2\x38\xad\x85\x09\xf4\x4f\xe0\ +\xa7\x58\xc3\x5e\x69\x50\x7f\xe9\x0f\xc9\x97\xe9\x58\xc9\xd7\xa9\ +\x58\xbd\x7d\x89\x58\xa5\x21\xae\x02\x56\x48\xbe\x74\xf0\x6b\x3e\ +\x14\x6b\x5e\xd5\x68\x60\x19\xd6\xdc\xa1\xee\xb0\x7f\x77\x84\x11\ +\xbe\xe7\x27\x62\x25\x87\x93\xb0\x7a\x7f\x26\x03\x2f\x49\xbe\x2c\ +\xc6\x9a\x64\x7e\x24\xd6\x9c\xa6\xbf\x00\x77\xfa\x5d\x3f\x0e\x6b\ +\x28\x70\x10\xd6\xe4\xf8\x68\xa0\x0f\x56\x82\xb2\x5c\xf2\x65\x5c\ +\x43\x2f\x5c\xf2\x65\x06\xf0\x09\xf0\x47\xdf\xb9\xf1\x58\x25\x33\ +\xee\xc2\x1a\x8e\x6e\xb5\x7c\xf3\xda\xfe\x01\x4c\x13\x21\xd3\x77\ +\xf8\x57\xac\x84\xdb\x3f\xb9\xb9\x02\xeb\x6b\x5d\xf3\xfc\x2d\xc0\ +\xd3\x58\xdf\xfb\xf1\x54\xef\xb5\x03\x78\x0d\xab\xa7\x6c\x76\xd5\ +\x01\x11\x9c\x58\xf3\xcb\xb6\x02\x8d\x4a\xbe\x1b\xb0\x1c\x58\x07\ +\xdc\x28\x42\xa4\xff\x13\x22\xb4\xf1\xdf\x15\xe2\x10\x14\x61\xad\ +\x12\xf6\x57\xe6\x3b\xde\xde\xef\xfa\x31\x04\xee\x97\xe4\xbf\x80\ +\x53\x7d\x73\x08\xab\xf1\xad\x06\xd6\x5a\x30\xc3\x30\xe6\x18\x86\ +\xb1\xd8\xee\x38\x0e\x43\x6e\x46\x46\xc6\xbe\xe8\xe8\xe8\x86\x5b\ +\xb6\x62\x45\x45\x45\x21\x5f\xbc\xb8\x21\x5d\xba\x74\x61\xf5\xea\ +\xd5\x6c\xde\xbc\x79\xa6\x48\xc8\xd4\x66\x0d\x3b\x81\x4e\xee\xb6\ +\x62\xcd\x17\x01\x98\x2b\xf9\x52\xeb\xd6\x54\x92\x2f\xc9\x58\x49\ +\x8f\x13\x6b\x68\xed\x52\xac\xde\xae\xa7\x7c\x4d\x3a\x63\xf5\xa4\ +\xd5\xe4\xc2\xea\xad\xb9\x1f\x6b\x58\xab\xe6\x92\xec\xb6\x58\x3d\ +\x30\xc7\x61\x25\x79\x60\xf5\x14\x9d\x8d\x95\xdc\x9d\xc4\x81\xe1\ +\xb4\x33\x25\x5f\xaa\x5e\xff\x2e\xac\x39\x5f\x29\xaa\x50\xc5\x62\ +\x25\x8d\xfe\x3b\x2e\xe4\xd7\xf5\x82\x7d\xaf\xa7\x3b\x56\x6f\xa2\ +\x03\x2b\x41\x18\x80\xf5\xe6\x7d\xaf\xaf\xc9\x09\x92\x2f\x67\xd4\ +\x77\x8d\x56\xe0\x66\xac\xef\xe5\x35\xbe\xc7\x0f\x61\xf5\xc6\x7e\ +\x2a\xc2\x42\x11\x9e\xc7\xfa\x9a\xae\xad\xe3\x7c\x13\x6b\x31\xc2\ +\x0e\xa8\x3e\x5f\xcc\x97\xfc\x5d\x09\x4c\x17\xe1\x6d\x11\x6e\xc1\ +\x9a\x6f\x37\x0e\xb8\x58\xa9\xa6\x6f\xcb\xa4\x14\xbb\xb0\xfe\x68\ +\x18\x08\xac\x12\xc1\x14\xe1\x66\x11\x9e\xc6\xaa\x33\x77\x38\x05\ +\x9a\x9f\x02\x8e\x15\xe1\x5b\x11\x96\x88\x70\xb6\x6f\x25\xec\x62\ +\x60\x86\xef\xd8\x22\xe0\x4b\xe0\x87\xa6\xbe\x06\x9f\x85\x58\xab\ +\x88\xdf\x13\xe1\x19\x11\x16\x88\xf0\xa0\x08\xdf\x62\x25\xe0\x9a\ +\x16\x70\x6e\xb7\x7b\x6c\x4e\x4e\x4e\x64\xc3\x2d\x5b\xaf\xbd\x7b\ +\xf7\x52\x5a\x5a\xda\xea\x93\x3b\x80\xd3\x4f\x3f\x9d\xd8\xd8\xd8\ +\x08\x11\x99\x6b\x77\x2c\x5a\xed\x82\x31\x2c\x7b\x1b\xd6\x24\xfa\ +\x0e\xd4\x5d\x5d\x7f\x04\x07\xe6\x38\xbd\xa1\x0a\xd5\x5d\x00\x92\ +\x2f\x33\xb1\x7a\xf2\x04\xab\xf7\xad\x36\x97\xa9\x42\xf5\x60\x3d\ +\xf7\x9f\xa9\x0a\xd5\x4a\xc9\x97\x5e\xb0\xbf\x78\xec\x17\xaa\x50\ +\xcd\xf5\xdd\xe3\x63\xac\xa4\xc0\x8d\x95\xf8\xfd\xa6\x0a\x55\xa9\ +\xe4\xcb\x7f\x80\x13\x25\x5f\xd2\x7d\xb1\x3b\xb1\x56\x6c\xb6\xc1\ +\x1a\x0e\xac\xcf\xb1\x1c\xd8\x12\xea\x3d\xac\x95\x9d\xe9\x54\x1f\ +\x42\x9c\xca\x81\xd5\x9f\xa1\xac\x90\x5a\x12\x11\x5f\x79\x92\x3f\ +\x01\x99\x22\xb8\x95\x62\xb5\x08\x63\x80\xe9\x58\x73\xca\xde\xc2\ +\x9a\x83\x77\x26\x56\xcf\x55\x4d\x9f\x02\xbb\xb1\x4a\x84\xec\xae\ +\xf9\xa4\x52\xdc\xef\x4b\x50\x4e\xc5\xea\xb5\x7d\x17\xb8\xa8\xc6\ +\xf0\xed\x66\xac\xe1\xdd\x9a\x09\xe4\x1a\xdf\xf1\x7a\x97\xef\x2b\ +\xc5\xdb\xbe\x9e\xc7\x0b\xb1\x7a\x93\x93\x81\xdf\xb0\x86\x8b\xab\ +\x7a\x07\xf7\xf8\xae\xf5\x75\x8d\xd3\x37\xf9\x8e\xaf\xf3\xbb\xde\ +\xed\x22\x7c\x89\x95\x30\xc6\x73\xa0\x18\xf1\x3c\x5f\xac\x47\x63\ +\xfd\xdc\xcc\x06\x3e\xc6\xaa\xdf\xf7\x8b\xdf\x35\x1f\xa2\xfa\x7e\ +\xa2\xdf\xfb\xce\xf5\x9f\xef\x77\x0b\xf0\xad\xdf\x3d\xf7\x01\x13\ +\x44\x38\x1d\xeb\xff\x59\x5f\xdf\xeb\x7e\x88\x56\xde\x83\x1c\xaa\ +\x4c\xd3\x6c\x0b\xb8\x43\x70\x28\x16\x00\x11\x89\x17\x91\x7e\xe1\ +\x3e\xdf\xae\xa8\xc8\xfa\xb5\x96\x92\x92\x62\x73\x24\xc1\x17\x1d\ +\x1d\xcd\x85\x17\x5e\xe8\xba\xed\xb6\xdb\x66\x8a\xc8\xed\x4a\xa9\ +\x75\x0d\x9f\xa5\x35\xa7\x80\x27\x77\xaa\x50\xed\x94\x7c\xb9\x11\ +\x6b\xd8\xf3\x4a\xac\xe1\xb6\x9a\xfc\x57\x1e\x1e\x28\x9f\x51\xa8\ +\xb6\x4a\xbe\xfc\x80\x35\xf9\x3e\x5e\xf2\x25\x59\x15\xaa\x2d\x35\ +\xce\x7d\xa5\x9e\xdb\x97\x62\xcd\xfd\x02\xab\xf8\x6b\x95\x0f\xfd\ +\x3e\xf7\x7f\xb3\x8c\x04\x90\x7c\xc9\xc1\xaa\xd1\x56\x57\xa9\x8c\ +\xf6\x75\x1c\xaf\xe2\xff\x7a\xce\x82\x5a\x37\x72\xef\xd3\xc0\x35\ +\x42\x42\x7d\x73\xb9\xfc\x0a\xfd\x56\x3d\x7e\x9b\x03\x3d\xa8\x55\ +\x6a\x0e\xb9\x56\xb9\x10\x88\xc0\xea\xd1\xad\xeb\xfa\x1f\x52\xfd\ +\x7b\x59\xf3\xf9\xcd\x58\xc5\x7b\x6b\x1e\x5f\x53\xdb\xf1\x7a\xae\ +\x71\x53\x3d\xcf\xef\xad\xe3\x1e\x9e\x3a\x8e\x2f\xc7\x1a\xf2\xf5\ +\x3f\xb6\x0f\xb8\xc3\xf7\xe1\xef\xba\x1a\xed\x1e\xaa\xf1\x78\x45\ +\x2d\x6d\x6e\xad\x23\xce\x27\xb1\xe6\x7b\x6a\x2d\xdf\x4d\xc0\xb1\ +\xa6\x69\x66\x19\x86\xa1\x1a\x6c\xdd\xf2\x1c\xa3\x94\x92\x01\x03\ +\xc2\x7b\x8b\x63\x8f\xc7\x43\xfb\xf6\xed\x89\x8c\x0c\x8f\x0e\xcc\ +\x13\x4f\x3c\x91\x15\x2b\x56\x38\xd2\xd3\xd3\x5f\xc3\x7a\xcf\xd6\ +\x5a\x90\x60\x2d\xa8\xb8\x0f\x6b\x7e\x55\x77\xac\x9e\x9b\x9a\x36\ +\xf9\x7d\xbe\x7f\xef\x4d\xc9\x97\x68\xac\x92\x0d\x60\xcd\x4d\xaa\ +\xd9\xd3\xb2\x4f\x15\xaa\x0d\xf5\xdc\x77\x87\x2a\x54\x55\xbf\x1c\ +\xfd\x0b\xc1\xfa\x27\x74\xb5\x4d\xf8\xbd\x91\x03\x89\xdd\x6c\xac\ +\xe1\xb4\x9d\x58\x3d\x54\x0d\x25\x76\x50\x3d\x91\x7c\x82\x1a\x6f\ +\xe6\x3e\xdb\x1a\x71\x9d\xb0\xe3\x5b\x48\x70\x0c\xd6\x1f\x02\x77\ +\x2b\xc5\x6a\x9b\x43\x3a\x88\x08\x47\x03\x7b\x95\xe2\x0b\xbb\x63\ +\xd1\x5a\x17\xd3\x34\x3b\x63\xcd\x01\xfe\x5b\x88\x26\x76\x00\xb9\ +\x69\x69\x69\x65\x6d\xdb\xb6\x0d\x8f\xac\xa6\x0e\xe1\x30\xdf\xce\ +\x9f\xdb\xed\x66\xd4\xa8\x51\xce\xb8\xb8\xb8\x5e\x27\x9d\x74\xd2\ +\x09\xcf\x3e\xfb\x6c\xa8\xec\x7f\x1c\x16\x82\xb2\xa4\x47\x15\xaa\ +\x7d\xc0\xff\xf9\x1e\xd6\xf6\x1f\xfe\x73\x0e\x94\x8e\x18\x2f\xf9\ +\x72\x84\x6f\xfe\xdb\x5f\xfc\xda\x7f\xe1\x57\x2b\x2f\xd8\xaa\x0a\ +\xc7\x56\x02\xff\x54\x85\xea\x57\xac\x2d\xa8\x1a\x93\xd8\x41\xf5\ +\xda\x7d\x7d\x80\x87\x55\xa1\xba\x57\x15\xaa\x7b\xb1\xe6\x07\xfe\ +\xc6\x61\xec\x0f\x1a\x26\xfe\x80\xb5\x42\xf6\x5e\xac\x95\xce\x2d\ +\xd1\xf9\x58\x35\xf8\xfe\x23\x42\x4f\xbb\x83\xd1\x5a\x95\x39\x58\ +\x5b\xc4\x3d\xd0\x50\xc3\x96\xca\xed\x76\x8f\x1d\x3a\x74\x68\x58\ +\x27\x76\x15\x15\x15\x6c\xdd\xba\x35\x2c\x86\x64\xfd\xe5\xe6\xe6\ +\x52\x5c\x5c\xac\xd2\xd2\xd2\xcc\x86\x5b\x6b\xcd\x29\x98\xeb\xb5\ +\xff\x0d\x07\x36\x52\xf7\xa7\x0a\xd5\x2a\x0e\x0c\x49\x75\xf4\xb5\ +\xfb\x8d\x03\x8b\x28\x2a\xb0\x76\x3c\x68\x2e\x55\xc9\x99\x13\xf8\ +\x4c\xf2\xe5\x2d\xe0\x19\xac\xde\xc3\x06\xa9\x42\xf5\x25\xd6\x7c\ +\x32\xb0\xe6\x57\x15\x4b\xbe\xbc\x28\xf9\xf2\x3a\xd6\xeb\x7a\x1e\ +\xf6\xaf\x22\xd5\xfc\x28\xc5\x75\x4a\x71\xb4\x52\x5c\xa3\x54\x9d\ +\x05\x86\xe7\x5b\xb9\x5e\x00\x00\x20\x00\x49\x44\x41\x54\x6d\xa5\ +\x14\x17\x60\x25\xa0\xfd\x81\x95\x22\xdc\x25\x42\x87\x06\x4e\xd3\ +\xb4\xc6\x58\x0b\xcc\x35\x0c\xa3\x51\xbf\x6b\x5a\x1a\x11\x89\xa9\ +\xa8\xa8\xc8\x0e\xf7\xf9\x76\x5b\xb6\x6c\xc1\xeb\xf5\x86\x55\xcf\ +\x1d\x58\xa5\x51\xe2\xe3\xe3\xa5\x4b\x97\x2e\xa9\x3d\x7a\xf4\x98\ +\x60\x77\x3c\xda\x01\x41\x4b\xee\x7c\x75\xdd\x0a\xea\x69\x32\x1b\ +\x6b\xc1\x45\x29\xd6\x50\x69\xd5\xff\x8a\xaf\x80\x5c\x55\xa8\x3e\ +\x0f\x56\x6c\xb5\xc8\xe3\xc0\x6e\x07\xdd\xb0\x4a\xa2\x4c\xa3\xfa\ +\x70\x6b\x43\x66\x62\xfd\x15\xbe\x0d\x6b\x11\xc6\x64\x60\x2c\x56\ +\x5d\xbd\x57\xb1\x56\x44\x6a\x21\x4a\x29\x5e\xc0\x2a\xa5\x33\x03\ +\x2b\xd1\xfb\x49\x84\xeb\x44\xa8\x75\x45\xb8\xa6\x35\x86\x61\x18\ +\xb7\x1b\x86\xf1\x2f\xbb\xe3\x68\x82\xa3\x94\x52\xce\xec\xec\x6c\ +\xbb\xe3\xb0\x95\xc7\xe3\x21\x2e\x2e\x8e\xd8\xd8\xf0\xab\xeb\x3b\ +\x6c\xd8\x30\x9e\x7c\xf2\xc9\x8a\x0d\x1b\x36\x5c\x67\x77\x2c\xda\ +\x01\xa2\x94\xbd\xd3\x3c\x24\x5f\x04\x6b\xd5\x6a\x22\xb0\xce\xbf\ +\x78\xb1\x0d\xb1\xa4\x61\x0d\x0b\xff\xe8\x37\x77\xef\x70\xae\x93\ +\x82\xf5\x9a\x4a\x00\x8f\x6f\x98\xba\x66\x9b\xbd\xc0\x45\xaa\x50\ +\xfd\xf3\x70\xef\xa3\xd9\x43\x84\x28\xac\x15\xe1\x05\x58\x85\xb5\ +\x6f\x00\xee\x53\x8a\x72\x5b\x03\xd3\xb4\x66\x26\x22\xf3\x52\x53\ +\x53\xe7\x3c\xfb\xec\xb3\x61\x3d\x2c\x5b\x5c\x5c\xcc\x8e\x1d\x3b\ +\xe8\xde\xbd\xbb\xdd\xa1\xd8\xe2\xdb\x6f\xbf\xe5\xc2\x0b\x2f\x04\ +\x98\xa2\x94\xd2\x7b\xcf\xb6\x00\xb6\x27\x77\xe1\x4a\x27\x77\xa1\ +\x4f\x84\x76\x58\xbd\xbe\x97\x62\x2d\x12\xba\x1a\x78\xa2\xe6\x1e\ +\xbb\x9a\x56\x93\x69\x9a\x91\xa1\x3a\x14\xeb\xcf\xed\x76\xbf\x3b\ +\x69\xd2\xa4\x11\x05\x05\x05\x61\xbd\x33\x85\x06\xb3\x67\xcf\xae\ +\xfc\xf0\xc3\x0f\x7f\xa8\xa8\xa8\xe8\xa7\x54\xeb\xdc\x91\x29\x94\ +\xb4\xce\x3d\x52\x34\xad\x19\x28\x45\xa9\x52\xe4\x61\xd5\x41\x7c\ +\x13\x6b\xcf\xd8\xcf\x45\x18\x6f\x6f\x64\x5a\x4b\x66\x9a\x66\x07\ +\x60\xbd\x69\x9a\x23\xed\x8e\xa5\x29\x44\x24\xc2\xeb\xf5\x0e\x1d\ +\x38\x70\xa0\x4e\xec\x34\x0c\xc3\x70\x9e\x74\xd2\x49\x7d\x07\x0f\ +\x1e\xac\xb7\x24\x6b\x01\x74\x72\xa7\x69\x4d\xa4\x14\xbf\x29\xc5\ +\x85\x58\x0b\x2e\xd6\x01\xcb\x44\x78\x5d\x84\xc1\x36\x87\xa6\xb5\ +\x4c\x57\x61\xad\xcc\xff\xcc\xee\x40\x9a\x28\xc7\xeb\xf5\x46\x84\ +\xfb\x62\x0a\xcd\x92\x9e\x9e\xce\x90\x21\x43\x18\x32\x64\xc8\xff\ +\x89\x48\xb0\xca\xac\x69\x8d\x14\xb6\xdf\x00\x11\xe9\x09\x4c\xb1\ +\x2d\x80\x39\x38\xf9\x82\xf1\x22\xd2\xae\xe1\xc6\x5a\x08\x59\x0e\ +\x17\xae\x83\xb9\x53\xa0\xdb\xa7\x22\x5f\x7f\x0d\xb3\x5f\x82\xd7\ +\xb6\x36\xf1\xba\x3b\xb1\x86\x7e\xd7\x03\xdf\xe9\x61\x8f\xd0\xe4\ +\xeb\xb5\x33\xb0\x56\xc8\xee\xb1\x3b\x9e\x26\xca\x4d\x4c\x4c\x2c\ +\xeb\xd8\xb1\x63\x58\xcf\xb7\xd3\x0e\x48\x4b\x4b\xa3\x4d\x9b\x36\ +\xd1\x39\x39\x39\x97\x60\xed\x56\xa5\xd9\x24\x6c\x93\x3b\xac\x5e\ +\x16\xfb\x7e\xf8\xbc\x80\x87\x33\x80\xd6\xbe\xe7\x6c\x18\x7a\xc0\ +\xf7\x31\x05\x28\xcc\x86\x97\xb2\xad\xc7\xd7\x53\xfb\xce\x6b\x87\ +\x6c\xb3\x88\xbc\x08\x3c\xac\x94\x7a\xbf\xc1\xd6\x5a\x4b\xd2\x13\ +\x6b\xbb\xb8\xba\x76\x6a\x09\x19\x4e\xa7\x73\xcc\x90\x21\x43\xdc\ +\x76\xc7\x61\xb7\xaf\xbe\xfa\x8a\x8c\x8c\x0c\xda\xb4\xd1\x0b\xe7\ +\x7b\xf4\xe8\xc1\xba\x75\xeb\xe8\xdf\xbf\x7f\x1e\x3a\xb9\xb3\x95\ +\x1e\x96\xd5\xb4\xa0\xa9\xaa\x9e\xf2\x17\xac\x44\xef\x27\xac\x04\ +\x2f\xae\xa9\x17\xee\x80\x55\x58\xf9\x5d\x11\xb9\x53\x44\x62\x9a\ +\x7a\x41\xad\x79\x18\x86\xf1\xa1\x61\x18\xc3\x43\xbd\xd7\x4e\x44\ +\x9c\xc0\x88\x41\x83\x06\x85\xf5\x7b\x48\x69\x69\x29\x9f\x7d\xf6\ +\x19\xbb\x77\x1f\xb4\x1d\x76\xd8\x4a\x48\x48\xe0\x91\x47\x1e\xe9\ +\x20\x22\x39\x76\xc7\x12\xce\xc2\xb9\xe7\x6e\x39\x70\x94\x6d\x77\ +\x77\xf0\x0e\xfd\x58\xc8\xb7\xbc\x64\x5b\x0c\x5a\x33\xf0\x02\xff\ +\x04\x96\x47\xc0\x93\xa7\x42\xfe\x39\x90\xe7\x85\xcf\xfe\x09\x7f\ +\xfc\x1f\x6c\x6a\x6c\xf9\x94\xb6\x40\x67\x60\x00\x70\x22\x56\x3d\ +\x46\xc1\x2a\xf6\x3d\x49\x44\xce\x53\x4a\xbd\x1b\xf8\xf8\x35\xad\ +\x56\x03\x2b\x2b\x2b\x63\x74\x7d\x3b\x0f\x2e\x97\x8b\xa4\xa4\x24\ +\xbb\x43\x69\x31\x06\x0c\x18\x40\x8f\x1e\x3d\xca\xd7\xae\x5d\x7b\ +\x05\x7a\x64\xca\x36\xba\x14\x8a\x4d\x74\x29\x94\xf0\xe4\x2b\x9f\ +\x32\x07\x98\x05\x78\x80\x6b\x80\xc7\x0f\xb5\x7c\x8a\x88\x4c\x05\ +\x4c\x88\xeb\x64\xf5\x0a\x3e\xee\x05\x16\x29\xa5\xf2\x03\x1d\xb3\ +\xa6\xd5\x24\x22\x57\xb4\x6d\xdb\xb6\xf0\xd5\x57\x5f\x8d\xb0\x3b\ +\x16\x3b\xbd\xfd\xf6\xdb\xec\xda\xb5\x8b\xc9\x93\x27\xdb\x1d\x4a\ +\x8b\xf2\xca\x2b\xaf\x30\x6f\xde\xbc\x4a\xa5\x54\x9a\x52\x4a\x6f\ +\xbd\x69\x83\xb0\xee\x52\xd7\xb4\xe6\xe6\x2b\x9f\x92\x8f\x55\x3e\ +\xe5\x0d\xe0\x5f\xc0\x97\x22\x4c\x3c\xc4\x2b\x7d\x02\xdb\x9f\x02\ +\xcf\x3e\xab\x9e\x32\x0e\x20\x4f\x44\x4e\x0f\x70\xc8\x5a\x00\x98\ +\xa6\x79\xb1\x69\x9a\xb7\xd8\x1d\x47\xa0\x38\x1c\x8e\xd1\x83\x06\ +\x0d\x72\xda\x1d\x87\xdd\x8a\x8a\x8a\xc2\x6e\xcb\xb1\xc6\x18\x3b\ +\x76\x2c\x3d\x7b\xf6\x54\x7f\xf8\xc3\x1f\x6e\x6f\xb8\xb5\x16\x0c\ +\x3a\xb9\xd3\x34\x1b\xf8\x95\x4f\xc9\x02\x7e\x06\x96\x8a\xf0\xa6\ +\x08\x0d\xce\x53\x11\x61\x0e\xf0\x0b\xc4\x5d\x06\x31\x11\xd0\xe9\ +\x23\xac\xd2\x1a\x00\xff\x10\x91\xf0\xda\xbd\xbc\x85\x33\x4d\x53\ +\xb0\x7a\x6a\x5b\xc5\xef\x5b\x11\x11\x87\xc3\x91\x3b\x78\xf0\xe0\ +\xb0\x4e\xee\x76\xef\xde\xcd\x8e\x1d\x3b\x74\x72\x57\x0b\xb7\xdb\ +\xcd\x99\x67\x9e\xe9\x9a\x30\x61\xc2\x29\x53\xa6\x4c\xd1\x15\x21\ +\x6c\xd0\x2a\x7e\xd9\x68\x5a\xa8\x52\x8a\x55\x4a\x71\x12\x70\x34\ +\xd6\x1c\xd8\x4f\x44\x78\x5a\x84\xde\xf5\x9c\x76\x37\xe0\xb7\xc5\ +\x4f\xb7\xaf\x81\x45\xbe\x07\x89\xc0\xfd\xc1\x89\x56\x3b\x4c\xc7\ +\x02\x19\xb4\x82\x15\xb2\x3e\xfd\x2a\x2a\x2a\xe2\xc3\xbd\xbe\x9d\ +\xc7\xe3\xc1\xe1\x70\xd0\xa1\x43\x07\xbb\x43\x69\x91\x86\x0d\x1b\ +\x46\x54\x54\x94\xb4\x6d\xdb\xb6\xd5\xf4\x58\x87\x12\x9d\xdc\x69\ +\x5a\x0b\xa0\x14\x1f\x2a\x45\x2e\xd6\x04\xba\xbe\xc0\xf7\x22\x98\ +\x22\xa4\xd6\xd2\xbc\x02\x6b\x58\x77\x15\xb0\x15\xd8\x0c\x5c\x07\ +\x7c\xe7\x7b\x7e\xaa\x88\x9c\x53\xdb\x7d\xe4\x34\x09\xeb\xde\x16\ +\x9b\x9c\x06\x2c\x37\x0c\x63\x95\xdd\x81\x04\x48\x6e\x4c\x4c\x4c\ +\x79\x7a\x7a\xba\xdd\x71\xd8\xaa\xa8\xa8\x88\xc4\xc4\x44\xdc\xee\ +\xb0\xaf\x06\x53\xab\xc4\xc4\x44\x36\x6f\xde\x4c\xf7\xee\xdd\xf5\ +\xa2\x0a\x1b\xe8\xe4\x4e\xd3\x5a\x10\xa5\x78\x11\x6b\x45\xec\x85\ +\xc0\x64\xe0\x47\x11\x6e\x14\xa1\xad\x5f\xb3\xf9\x40\xba\xef\xf9\ +\xfe\xc0\x2b\x4a\xa9\x7d\xc0\xb9\x58\x89\x1f\x58\x8b\x36\x0e\x96\ +\xce\x59\x92\x27\x0f\xcb\x5c\x3d\x74\xdb\x8c\xfe\x4a\x2b\x5a\x35\ +\x28\x22\xa3\xb2\xb3\xb3\xc5\xe1\x08\xef\xb7\x0f\x8f\xc7\xa3\x87\ +\x64\x1b\xd0\xb3\x67\x4f\x96\x2d\x5b\x16\x2d\x22\xc7\xda\x1d\x4b\ +\xb8\x09\xef\xff\x9d\x36\x90\x79\xd2\x56\x0a\xe4\x32\xac\x21\xb8\ +\x53\xa5\x40\x86\xd9\x1d\x93\xd6\xb2\x28\x85\x57\x29\xfe\x89\xd5\ +\x3b\xf7\x7f\x58\x3b\x1a\xac\x15\xe1\x72\xdf\xc2\x8b\xcb\x81\x59\ +\x4a\xb1\x56\x29\x3c\x4a\xf1\x81\x75\x9e\xfa\x02\x78\xda\x77\x99\ +\x23\x44\x24\xe3\xa0\x8b\x0b\x0e\x84\xf3\xf0\xf2\x83\xe4\xcb\x6c\ +\x99\x27\x61\xbd\xda\xb1\x39\x18\x86\x51\x69\x18\xc6\x26\xbb\xe3\ +\x08\x14\xa7\xd3\x79\xec\xe0\xc1\x83\xc3\xb9\x8c\x16\xe5\xe5\xe5\ +\x94\x94\x94\x90\x92\xa2\xff\x46\xaa\x4f\x9f\x3e\x7d\xf0\x7a\xbd\ +\x15\x2e\x97\xeb\x6f\x76\xc7\x12\x6e\x74\x72\xd7\x8c\xa4\x40\x8e\ +\x60\x2f\xdf\xa1\xb8\x0d\x70\x02\x93\x50\x7c\x20\xf9\xa2\xcb\x57\ +\x68\x07\x51\x8a\x32\xa5\xb8\x05\x6b\x57\x83\x07\x80\x1b\xb1\x56\ +\xd7\x3e\xa7\x14\x0f\xd7\x71\xda\xd3\x7e\x9f\xd7\x57\x9f\x21\x0e\ +\x58\xc4\x5e\xbe\x93\x02\x39\x3e\x20\x01\x6b\xad\x9e\x88\x64\x54\ +\x54\x54\x24\x85\xfb\x7c\xbb\xd2\xd2\x52\x9c\x4e\xa7\xee\xb9\x6b\ +\x84\x33\xcf\x3c\xd3\x55\x59\x59\x79\x5c\xad\x7f\x6c\x6a\x41\xa3\ +\x93\xbb\xe6\xb5\x18\xe8\x5a\xe3\x98\x03\xb8\x51\xf2\xe4\x68\x1b\ +\xe2\xd1\x42\x80\x5f\xf9\x94\x57\xb1\xaa\x22\x5f\x58\x4f\xf3\x4f\ +\xfd\x3e\x6f\xcc\x2f\xd3\x5e\x28\x5e\x90\x02\x79\x45\x0a\xa4\x6f\ +\x53\xe2\xd4\xaa\x33\x4d\x33\xdb\x34\xcd\xd6\x56\xa5\x3f\x37\x32\ +\x32\xb2\xa2\x4f\x9f\x3e\x76\xc7\x61\xab\xe4\xe4\x64\xce\x39\xe7\ +\x1c\xa2\xa2\xa2\xec\x0e\xa5\xc5\x1b\x31\x62\x04\x29\x29\x29\x15\ +\x31\x31\x31\x97\xdb\x1d\x4b\x38\x09\xeb\xae\xf5\xe6\x24\x79\x92\ +\x86\x30\xb4\x8e\xa7\x1d\x08\x73\x25\x4f\x1e\x6d\xd6\xa0\xb4\xd0\ +\xb1\xec\xde\xe1\x30\xe3\x44\x86\xde\xbc\x90\x31\x57\x8d\x93\xbc\ +\x3a\xda\xfd\x0d\x07\xb7\xe0\x05\x1c\x24\x30\x54\xf2\x64\x5a\x8d\ +\x16\xc3\x90\x5a\xce\x53\x4c\x00\xbe\x95\x3c\xb9\x9b\x68\xe6\xa9\ +\x6b\x55\x69\x40\xe3\x0f\x4f\xd7\x03\x91\xc0\x04\xbb\x03\x09\xa0\ +\xdc\xac\xac\x2c\xe5\x74\xea\x75\x39\xe1\x3e\xe7\xb0\xb1\x1c\x0e\ +\x07\x33\x67\xce\x74\xef\xda\xb5\xeb\x22\x11\xb9\x4a\x29\xb5\xcb\ +\xee\x98\xc2\x81\x4e\xee\x9a\x8b\x83\xce\x0d\xec\x41\x30\x11\x61\ +\x6c\x33\x45\xd3\x1c\x9c\x58\xdb\x63\x55\x34\xd4\x50\x6b\x84\xb1\ +\x7f\x83\x2e\xef\x97\x93\xf5\xe8\x65\xf5\xb6\x73\x03\x91\x38\x28\ +\x03\xe2\x18\x82\xf0\xcf\x1a\x2d\xea\x7b\x57\x76\x21\x9c\xcd\x5e\ +\x3e\x01\xfe\xd3\xa4\x78\xc3\x9c\x69\x9a\x5d\x80\x49\xc0\xa9\x76\ +\xc7\x12\x48\x6e\xb7\x7b\xdc\x90\x21\x43\xf4\xf2\x50\xed\x90\x64\ +\x65\x65\xb1\x69\xd3\x26\x47\x6e\x6e\xee\x65\xc0\x4d\x76\xc7\x13\ +\x0e\x74\x72\xd7\x5c\x2a\xf9\x0e\x87\xaf\x47\xa5\x36\x8a\x6b\xd4\ +\x02\x35\xbf\x79\x83\x0a\x1e\xc9\x93\xd3\x10\x9e\x40\x31\x4e\x2d\ +\x50\xef\xd9\x1d\x4f\xeb\xf1\x48\xbd\xcf\x8a\x48\x14\x60\x6d\x4a\ +\xff\x2b\x4f\xaa\x42\x75\x66\xb5\xe7\xf3\xe5\x4f\x58\xd3\x03\x6a\ +\xaa\x00\xee\x01\xae\x53\x85\x6a\x5b\x20\x22\x0d\x73\x17\x62\x95\ +\xa8\x79\xc1\xee\x40\x02\x45\x44\xba\x02\x9d\xc3\x7d\x3f\x59\xed\ +\xd0\xa5\xa6\xa6\xb2\x7a\xf5\x6a\x32\x33\x33\x67\xa0\x93\xbb\x66\ +\xa1\xfb\x95\x9b\x8b\x93\xb1\x40\x5d\x9b\xc4\x6f\x64\x1f\xf7\x36\ +\x67\x38\xc1\xa6\x16\xa8\xa7\x80\x37\x10\xfe\xa1\x6b\xab\x35\xab\ +\x2e\x7e\x9f\x37\x6e\x85\xa6\xb0\x0c\x2f\x47\xaa\x42\x35\x4b\x27\ +\x76\x01\xf3\x0e\x30\xdb\x30\x8c\xd6\xd4\x73\x9d\xeb\x72\xb9\xbc\ +\x59\x59\x59\x76\xc7\xa1\x85\x20\x87\xc3\x41\x64\x64\x64\x17\x11\ +\x49\xb4\x3b\x96\x70\xa0\x7b\xee\x82\x4c\xe6\x89\x8b\x3d\x14\x22\ +\x5c\x89\x62\x31\xb0\x03\xe1\x62\x0e\x24\xd6\xdf\xa0\x38\x53\xdd\ +\xaa\x4a\x6c\x0c\x33\x38\x84\x4b\x50\x7c\x43\x06\x33\x81\x3b\xed\ +\x0e\x27\x4c\x8c\xf3\xfb\xfc\x9b\x06\xda\xae\x41\xf8\x9b\x9a\xaf\ +\x5e\x6c\xa0\x9d\x76\x88\x0c\xc3\x78\xc3\xee\x18\x82\x20\x37\x33\ +\x33\xb3\xc2\xed\x76\x87\x75\xf9\x9c\x37\xde\x78\x83\xf8\xf8\x78\ +\x86\x0c\x19\x62\x77\x28\x21\x25\x27\x27\x87\xb9\x73\xe7\x7a\x81\ +\x53\x68\x3d\xbb\xb5\xb4\x58\xba\xe7\x2e\x88\xe4\x6a\xe9\xcc\x5e\ +\xde\x42\xf8\x2b\xc2\x9f\xd4\x02\x75\xbe\x5a\xa0\x66\x51\x46\x32\ +\x30\x06\x21\x93\x28\x06\xaa\x05\xea\x7b\xbb\x63\x0d\x06\x35\x5f\ +\xad\x02\x6e\x45\x71\xbd\x2e\x9a\xdb\x6c\xaa\x16\x50\x54\x52\x6d\ +\x8b\xb2\x6a\x7e\x07\xae\xa4\x84\x2c\x9d\xd8\x69\x8d\xe5\x9b\x6f\ +\x17\xd6\x89\x1d\xc0\xc6\x8d\x1b\x89\x8e\x8e\xb6\x3b\x8c\x90\x13\ +\x1d\x1d\x4d\x6e\x6e\xae\xb8\xdd\xee\x73\xed\x8e\x25\x1c\xe8\x9e\ +\xbb\x20\x91\x7c\x19\x07\x3c\x0e\x94\xe0\x60\x98\xba\x49\x55\x6d\ +\x0d\x85\xaf\x97\xee\x6d\xbb\x62\x6b\x56\x15\xdc\x80\x8b\x33\xf1\ +\xb2\x08\x6b\x07\x05\x2d\x48\x44\xe4\x34\x60\x94\xef\xe1\x7b\x4a\ +\xa9\xe2\x83\x1b\xf1\x11\xe5\xf4\x56\x37\xab\xcd\xcd\x1a\x9c\x16\ +\xd2\x44\xa4\x03\x90\xae\xeb\xdb\x95\x52\x56\x56\xa6\x8b\x17\x1f\ +\xa6\x09\x13\x26\x38\xde\x78\xe3\x8d\xe1\x22\xd2\x45\x29\xb5\xc1\ +\xee\x78\x5a\x33\x9d\xdc\x05\x98\xcc\x13\x07\x7b\xb8\x1a\xe1\x5a\ +\x84\x67\xa8\xe4\x02\x55\xa8\x76\xd8\x1d\x97\x5d\xd4\xcd\x6a\x97\ +\x14\xc8\x15\x28\x9e\x96\x3c\x79\x40\x2f\xae\x08\x0e\xdf\x9b\xef\ +\x3f\x7c\x0f\xbd\xc0\xdc\xda\xda\xf9\x7a\x53\xb5\x20\x31\x4d\xf3\ +\x7c\xe0\x02\x60\x84\x61\x18\xf5\xaf\x8f\x0f\x2d\x23\x1d\x0e\x87\ +\xea\xdf\xbf\x7f\x6d\x85\x74\xc2\x86\xc7\xe3\xc1\xed\x76\x93\x98\ +\xa8\xa7\x8d\x1d\x8e\xa3\x8e\x3a\x8a\x61\xc3\x86\x79\x13\x13\x13\ +\x6f\x00\xce\xb3\x3b\x9e\xd6\x4c\x0f\xcb\x06\x90\x5c\x29\x49\xec\ +\x65\x29\xc2\x5c\x60\x96\x9a\xaf\x4e\x57\x0b\xc3\x37\xb1\xab\xa2\ +\xe6\xab\x67\x10\x5e\xd3\x8b\x2b\x82\xea\x5e\x20\xc9\xf7\xf9\xad\ +\x4a\xa9\xf7\xed\x0c\x26\x8c\xfd\x11\x28\x6e\x65\x89\x1d\x40\x6e\ +\x46\x46\xc6\xbe\x70\x1f\x8e\xf4\x78\x3c\x74\xe8\xd0\x01\x91\xb0\ +\xce\x71\x0f\x9b\xdb\xed\xe6\xd8\x63\x8f\x75\x66\x67\x67\x9f\x66\ +\x77\x2c\xad\x9d\x4e\xee\x02\x44\x0a\xe4\x28\xdc\x7c\x09\xf4\xc1\ +\xcb\x48\x55\xa8\xee\xb6\x3b\xa6\x16\xe6\x62\xa0\xaf\x6f\x71\x85\ +\x16\x20\x22\x12\x29\x22\xb7\x00\x27\xf9\x0e\xad\x04\xae\xb1\x31\ +\xa4\xb0\x65\x9a\x66\x5b\xac\x05\x2d\xcf\xda\x1d\x4b\xa0\xb9\xdd\ +\xee\xb1\x39\x39\x39\x91\x76\xc7\x61\x37\x8f\xc7\xa3\xb7\x1c\x6b\ +\xa2\xce\x9d\x3b\xd3\xb9\x73\xe7\x98\xd1\xa3\x47\xe7\xda\x1d\x4b\ +\x6b\xa6\x93\xbb\x00\x90\x7c\xb9\x1c\xc5\x72\xe0\x1b\xca\x18\xa4\ +\x16\xaa\x4f\xec\x8e\xa9\xa5\x51\xf3\xd5\x1a\xe0\x16\xbd\xb8\x22\ +\x70\x44\x24\x07\xf8\x12\xb8\xc2\x77\xa8\x02\x38\x57\x29\xb5\xd7\ +\xbe\xa8\xc2\xda\x70\xdf\xbf\xcf\xd9\x1a\x45\x80\x89\x48\xbb\x8a\ +\x8a\x8a\x23\xc2\x7d\xbe\xdd\xae\x5d\xbb\xd8\xb9\x73\xa7\x4e\xee\ +\x9a\x68\xe0\xc0\x81\x94\x95\x95\xd1\xb1\x63\xc7\xba\xf6\xd9\xd1\ +\x02\x40\x27\x77\x4d\x20\xf3\xa4\xad\xe4\xc9\x7f\x81\x9b\x51\x5c\ +\xc7\x02\x8e\x6f\x95\x25\x4d\x02\x25\x8a\x1b\x81\xdf\xf1\x72\xb3\ +\xdd\xa1\x84\x32\x11\x49\x13\x91\x85\xc0\x87\x40\xa6\xef\x70\x11\ +\x70\xb2\x52\xea\xd3\xba\xcf\xd4\x82\xc9\x30\x8c\x57\x81\x0e\x86\ +\x61\x1c\xbc\x90\x25\xb4\x8d\x00\x18\x30\x60\x80\xdd\x71\xd8\xca\ +\xe3\xf1\xe0\x70\x38\x48\x4e\x4e\xb6\x3b\x94\x90\xe6\x74\x3a\xf9\ +\xf9\xe7\x9f\xf9\xf0\xc3\x0f\x75\x35\xec\x20\x0a\xdb\x05\x15\x22\ +\xd2\x0b\x6b\x7e\xcc\xe1\x49\x22\x95\x3e\x9c\x85\x83\x48\x7e\xe2\ +\x61\x36\xe2\x05\xe6\xe8\xb9\x18\x0d\x18\xc9\x3b\x8c\xe0\x6c\xc9\ +\x96\xdd\x7c\xcd\x2f\x76\x87\x13\x42\xe2\xb1\x0a\x14\xf7\x05\x06\ +\x43\xb5\x1d\x62\x9f\x06\xfe\xaa\x94\xda\x6a\x47\x60\xda\x01\x86\ +\x61\xfc\x6e\x77\x0c\x41\x90\x9b\x96\x96\xb6\x2f\x2e\x2e\x2e\xac\ +\x87\x65\x3d\x1e\x0f\x89\x89\x89\xb8\x5c\x61\xfb\xb6\x19\x30\x03\ +\x07\x0e\xe4\xae\xbb\xee\x4a\x15\x91\x1c\xfd\x07\x69\x70\x84\xf3\ +\x4f\x69\x3f\xa0\xf0\xb0\xcf\xde\xea\xfb\xb0\x5c\xd8\xf4\x70\xc2\ +\xc4\xbb\x40\x27\x60\x30\x33\xf8\x06\x1a\xd8\x6f\x57\xab\x5f\x31\ +\x70\xb1\x52\xea\x09\xbb\x03\xd1\x5a\x2f\xb7\xdb\x3d\x76\xe8\xd0\ +\xa1\x61\x9d\xd8\x81\x95\xdc\x75\xe9\xd2\xa5\xe1\x86\x5a\x83\x8e\ +\x38\xe2\x08\x3a\x76\xec\x58\xee\xf1\x78\xce\x04\x74\x72\x17\x04\ +\x7a\x58\x56\x6b\x7e\xaf\x02\x89\x58\xfd\x4f\xda\xa1\x2a\x05\xfe\ +\x0b\x9c\x03\x64\xe8\xc4\xae\x65\x30\x4d\xf3\x28\xd3\x34\xe3\xed\ +\x8e\x23\xd0\x44\x24\xb6\xa2\xa2\x22\x3b\xdc\xe7\xdb\x01\x64\x64\ +\x64\xd0\xa3\x47\x0f\xbb\xc3\x68\x35\x8e\x3b\xee\x38\xb7\xcb\xe5\ +\x9a\x2e\x7a\xb8\x2b\x28\xc2\xb9\xe7\xee\x2d\xa0\xf1\xbf\xb1\x06\ +\xd0\x8d\x01\xdc\x8c\x83\x14\x36\x70\x0d\xaf\xf3\x4e\xf0\x42\x6b\ +\xe5\xb6\x01\xbf\x33\x93\xb1\x4c\x63\x37\x27\xb2\x82\xd6\x36\x47\ +\x29\x18\x76\x02\x9b\x94\x52\xbb\xec\x0e\x44\xab\xce\x34\x4d\x17\ +\xd6\x6e\x20\x8b\x80\x85\x36\x87\x13\x68\x47\x29\xa5\x9c\xd9\xd9\ +\x7a\x7a\x54\xb8\xcf\x39\x0c\xb4\x51\xa3\x46\x91\x91\x91\x91\xf4\ +\xc8\x23\x8f\x8c\x04\xfd\x7e\x1a\x68\x61\x9b\xdc\x29\xa5\x7e\x07\ +\xbe\x6a\x4c\x5b\xc9\x93\xd3\x10\x1e\x04\x56\x01\xe3\xd5\x62\xf5\ +\x4b\x30\x63\x0b\x07\x32\x4f\x66\xb1\x97\x3f\x30\x95\x73\xd5\xf7\ +\xea\x1c\xbb\xe3\xd1\xb4\x26\x18\x0d\xb4\x07\xfe\x67\x73\x1c\xc1\ +\x90\xdb\xa9\x53\xa7\xb2\xf6\xed\xdb\x87\xfd\xb0\xac\x16\x58\xbd\ +\x7a\xf5\x62\xc7\x8e\x1d\x64\x65\x65\xcd\x44\x27\x77\x01\xa7\x87\ +\x65\xeb\x21\xf3\x24\x42\x0a\xe4\x4e\x84\x27\x81\x47\x89\xe2\x18\ +\x55\xa8\x13\xbb\x40\x50\xd7\xaa\xdd\x08\x97\x01\x67\x4b\x81\x8c\ +\xb4\x3b\x1e\x4d\x6b\x82\x93\x80\xef\x0c\xc3\xf8\xc1\xee\x40\x02\ +\xcd\xe5\x72\x1d\x9b\x93\x93\x13\xf6\xfb\xc9\x6a\x81\xe7\x74\x3a\ +\x29\x29\x29\x21\x2d\x2d\x6d\xac\xdd\xb1\xb4\x46\xcd\x9e\xdc\xc9\ +\x95\x92\x24\x57\x48\x68\x94\x39\x2f\x27\x15\xc5\x89\x28\xce\x50\ +\x85\x6a\xa6\xba\x56\xed\xb3\x3b\xa4\xd6\x44\xcd\x57\x4b\x80\xa5\ +\x28\xee\xd6\x3b\x57\x68\x21\x6c\x2d\x07\xb6\x7e\x6b\x35\x44\x24\ +\xc2\xeb\xf5\xe6\x0c\x1c\x38\x50\xcf\x89\xd2\x82\x22\x2a\x2a\x8a\ +\x94\x94\x94\xc4\x8c\x8c\x8c\x38\xbb\x63\x69\x6d\x44\xa9\xe0\x2f\ +\x57\x94\x7c\x39\x0b\xb8\x18\x45\x5f\x84\x76\xbe\xc3\x1b\x51\x3c\ +\x85\x97\x85\x6a\x91\xf2\x04\xf5\xfe\x05\x72\x2e\x5e\x52\x01\x58\ +\xc8\x42\x75\x08\x2f\x5a\xe6\x49\x84\x4e\xea\x82\x47\xf2\x25\x03\ +\xf8\x0e\xc5\x1c\xb5\x40\xdd\x61\x77\x3c\x9a\xa6\x59\x44\xe4\x18\ +\xe0\xdd\x25\x4b\x96\x84\x75\xe1\xde\x1d\x3b\x76\xb0\x7d\xfb\x76\ +\x3a\x77\xee\x6c\x77\x28\xad\x4e\x71\x71\x31\x27\x9c\x70\x02\x15\ +\x15\x15\x93\x94\x52\x4b\xed\x8e\xa7\x35\x09\x6a\xcf\x9d\xcc\x96\ +\x58\xc9\x93\x37\x81\xc7\x80\xe1\x7e\x89\x1d\x40\x27\x84\xcb\x70\ +\x30\x2c\x98\x31\x00\xa0\xb8\x04\xa1\x10\xa1\x90\x53\x0f\xed\x35\ +\xeb\xc4\x2e\xb8\x54\xa1\xfa\x11\x58\x84\x70\xbd\x5c\x25\xe1\xfb\ +\x0e\xa2\x69\x2d\x4f\x6e\x62\x62\x62\x59\x38\x27\x76\x00\x6b\xd7\ +\xae\xe5\xdd\x77\xdf\xb5\x3b\x8c\x56\x29\x31\x31\x91\xb4\xb4\xb4\ +\x72\x60\xbc\xdd\xb1\xb4\x36\xc1\x1d\x96\x75\x31\x1f\x61\x8c\xef\ +\xd1\x36\xac\x7a\x70\xbd\x80\x5e\xbe\xe1\xce\xb7\x6a\x3b\x4d\x66\ +\x88\x5b\x0a\xa4\xaf\x5c\x2d\x5d\x1b\x7b\x2b\x99\x23\x71\x52\x20\ +\x7d\x65\x9e\x34\x79\x91\x88\xcc\x93\x18\xc9\x93\x01\x35\xaf\x25\ +\x57\x48\xb4\xcc\x95\x2c\x99\x2d\x1d\x9a\x7a\x0f\xcd\x4f\x19\x85\ +\x40\x09\x4e\x16\xd9\x1d\x8a\xa6\x69\x16\xa7\xd3\x39\x26\x27\x27\ +\xc7\x6d\x77\x1c\x76\xd3\xfb\xc9\x06\xd7\x88\x11\x23\xdc\x11\x11\ +\x11\x53\xec\x8e\xa3\xb5\x09\xda\xb0\xac\x14\x48\x5f\x14\x2b\xb0\ +\x2a\xe9\x7b\x81\xe1\xaa\xf0\xe0\x4a\xd4\xfe\xc3\x9e\x92\x27\x69\ +\xc0\x6d\x08\x53\x39\xb0\x92\x77\x1b\x8a\x6b\x58\xc8\x3d\x55\xc3\ +\xa9\x92\x2f\xb3\x61\x7f\x22\x70\x21\xc2\x58\x14\xa7\x02\x4e\x84\ +\x12\xbc\x9c\xa9\x16\xa8\x65\x32\x57\xb2\xf0\xf2\x6d\x1d\x21\x6e\ +\x50\x85\xaa\xab\x14\xc8\x9f\x51\x3c\x08\x80\xe2\x32\x84\x23\x81\ +\xb3\x01\x37\x5e\xba\xaa\x85\x6a\x83\xe4\xcb\x40\xe0\x4e\xac\x6d\ +\x78\xaa\xe6\x9f\xac\x43\x31\x4b\x2d\x50\xad\x6a\x1f\x49\xbb\x48\ +\x81\x4c\x45\xf1\x1c\x42\xae\x9a\xaf\xf4\x9f\xc9\x5a\x8b\xe7\xab\ +\x6b\xb7\x08\xb8\xc9\x30\x8c\x5f\xed\x8e\x27\x90\x44\xc4\xe9\x74\ +\x3a\xb7\xcf\x99\x33\x27\x66\xea\xd4\xa9\x76\x87\x63\x1b\xa5\x14\ +\x8f\x3e\xfa\x28\x39\x39\x39\x64\x66\x66\x36\x7c\x82\x76\xc8\x3e\ +\xfd\xf4\x53\x6e\xb8\xe1\x06\x32\x32\x32\x8e\x78\xff\xfd\xf7\x57\ +\xda\x1d\x4f\x6b\x11\xbc\x9e\x3b\x2f\x43\x38\x90\x08\x2d\xab\x2d\ +\xb1\x83\x03\xc3\x9e\x52\x20\xc9\x08\x9f\x21\x9c\x8c\x95\xd8\x7d\ +\x0e\x6c\x04\x12\x10\xee\x26\x8f\xab\xeb\xb8\xd3\x6d\x28\xa6\x01\ +\x95\xd6\x05\x69\x8f\xf0\x4f\x99\x27\x51\x87\x1c\xb3\x90\x0f\x9c\ +\x0f\xec\xff\x6b\x55\xe6\x4a\x36\xf0\x31\x70\x0c\xd6\x7e\x0a\xef\ +\x01\xbf\x03\xdd\x10\x96\x48\xbe\x9c\x74\xc8\xf7\xd1\x0e\xa2\xe6\ +\xab\xe7\x81\x97\x50\xfc\x23\x50\x8b\x2b\x24\x5f\x2e\x92\xb9\x92\ +\x15\x88\x6b\x35\x95\x5c\x25\xbd\x24\x5f\x2e\x92\x4b\x45\x97\x94\ +\x68\x3d\x8e\x01\xfe\x02\x94\xd9\x1d\x48\x10\x0c\xac\xac\xac\x8c\ +\x09\xf7\xfa\x76\xdb\xb6\x6d\x63\xdf\xbe\x7d\xba\xe7\x2e\x88\x06\ +\x0c\x18\xc0\xd5\x57\x5f\x4d\xcf\x9e\x3d\x67\xdb\x1d\x4b\x6b\x12\ +\xbc\xe4\x4e\x38\xc2\xef\xd1\xaa\x06\xdb\x7b\xb9\x09\x48\xf6\x9d\ +\xfb\x17\x55\xa8\x86\x10\x45\x37\x84\x4f\x7c\x2d\xe6\xca\x5c\x49\ +\xad\xe5\xcc\xdd\x78\x19\xcf\x2e\xda\x02\xef\xfb\x8e\x75\x64\x37\ +\xd9\xea\x26\xf5\x9d\x2a\x54\x82\x95\x28\x5a\x7e\xc2\xa5\x0a\x95\ +\xa8\x42\x55\xdb\x90\x6f\x12\x8a\x45\x78\xe9\x8b\x83\x01\xc4\x50\ +\x82\x97\x7f\x50\x95\xec\x29\x46\xaa\x42\x35\x92\x28\xba\xc0\xfe\ +\xc2\xbb\x77\xe9\x0a\xdb\x01\x52\xc9\x2c\xa0\x17\xe9\x5c\x5c\xf3\ +\x29\xc9\x93\x63\x24\x5f\x3c\xbe\x8f\x4d\x92\x2f\xab\xa4\x40\x5e\ +\x95\x3c\x79\x50\xe6\xca\x41\x4b\xe9\x7d\xdf\x13\x13\xc5\xb1\xcd\ +\x11\xba\x5f\x9c\x53\x24\x4f\x0e\xae\xdb\x67\xcd\x2d\x35\x69\x43\ +\x9b\xe6\x8c\x47\x0b\xaa\x5c\x60\xa5\x61\x18\x45\x76\x07\x12\x04\ +\xb9\xf1\xf1\xf1\xfb\xd2\xd2\xd2\xec\x8e\xc3\x56\x1e\x8f\x87\xc8\ +\xc8\x48\x12\x12\x12\xec\x0e\xa5\xd5\x8a\x88\x88\xa0\xa4\xa4\x44\ +\xc5\xc7\xc7\x8f\x69\xb8\xb5\xd6\x58\xc1\x4c\xee\xca\xfd\x1e\x35\ +\x3c\x6f\x43\x18\xee\xfb\xcc\x0b\x0c\x90\x7c\xb9\x9d\xbd\xfc\xdd\ +\xaf\x45\x24\xaa\xd6\x0d\xab\x9e\x57\x0b\xd5\x6b\xea\x4e\x55\x06\ +\xbc\xe9\x77\xbd\xc3\xf9\xad\xf4\xb1\x5a\xa0\xe6\xa8\x85\x6a\xb5\ +\xba\x49\x7d\x03\xec\x03\x86\x00\xa0\x28\x45\x38\xcd\x17\xd7\x8d\ +\x08\xa5\xbe\x73\x3a\x93\x47\xb7\xc3\xb8\x97\x56\x83\x5a\xa4\x7e\ +\x42\xea\x58\x5c\x21\x44\x00\x29\x58\x5b\x6f\xe5\xa3\xb8\x03\x2f\ +\x5f\x23\x1c\x81\x97\xd7\x25\x5f\xde\x90\x3c\xd9\xbf\xfd\x93\x6f\ +\x08\xdf\x40\xfc\x7e\x26\x9a\x83\x83\x69\xc8\xc1\xc9\x29\x5e\x3e\ +\x06\x0c\x76\xb2\xb3\x59\xe3\xd1\x82\x29\x17\x58\x6e\x77\x10\xc1\ +\xe0\x70\x38\x46\x0f\x1e\x3c\x38\xec\xcb\x13\x79\x3c\x1e\x3a\x74\ +\xd0\x53\xac\x83\xcd\xe9\x74\x4a\xc7\x8e\x1d\xd3\x74\x47\x49\xe0\ +\x04\x6f\x87\x0a\x6b\xbe\x5d\x95\xc6\xec\xdb\x52\xd5\x2b\xe7\x40\ +\x31\xd3\xef\x3a\xfe\xd2\x6b\x39\xef\xfd\xfd\x9f\x29\x76\x73\xe0\ +\x47\xe3\x70\x5e\xdb\xab\xd5\x1e\xed\xa4\x3d\x2e\xac\x02\x9e\xd6\ +\x4a\xdf\x59\xf5\xc4\xf5\xcb\x61\xdc\x4f\xab\x29\x92\x42\xf6\x70\ +\x36\x4e\x6e\xc6\x9a\xfb\x58\xd3\xdb\xaa\x50\x3d\xed\x7f\x40\xf2\ +\x64\x1a\xc2\xe3\xc0\x2d\xc0\x05\x55\xc7\x55\xa1\xba\xb7\xbe\x5b\ +\xc9\x55\xd2\x0b\x17\xa5\x6a\xbe\xda\xb2\xff\xd8\x3c\x69\x4b\x19\ +\x5d\x28\xe6\x07\x75\x9f\x2a\xaf\xf3\xdc\x2b\x25\x89\x48\x3a\xe1\ +\x65\xbd\x2a\x54\xdb\x1a\x7a\x59\x6a\x91\xfa\x01\xa8\xb5\xc8\xad\ +\xcc\x96\x58\x22\xe8\xc1\x1e\x7e\x52\xb7\xaa\x3d\xf5\xc6\x5c\x20\ +\x89\x54\xd0\x8e\x9b\x59\x7b\x28\x25\x7d\xb4\xa0\x98\x0b\xad\x6f\ +\xeb\x3c\x11\x11\x97\xcb\x35\x6a\xd0\xa0\x41\x3a\xb9\xf3\x78\xe8\ +\xd7\xaf\x9f\xdd\x61\xb4\x7a\xdd\xba\x75\xe3\xe3\x8f\x3f\x76\x24\ +\x27\x27\x0f\x07\x3e\xb4\x3b\x9e\xd6\x20\x98\xab\x65\x3f\xc6\xea\ +\xf9\x02\x18\x29\x79\x32\xb9\x66\x03\x99\x27\x11\x72\x85\xb4\xf7\ +\x3d\x5c\xed\xfb\xb7\x12\xc5\x28\x84\xcc\x83\x3e\x14\x8f\x1e\x74\ +\x17\xc5\x81\x52\x25\xe2\x9b\x77\x77\xd0\x8d\xfc\x52\xb1\x7e\xd4\ +\xf7\x0b\xab\xda\x2f\x6a\x75\xb3\xda\x8c\xda\xdf\x43\xb7\x19\x45\ +\x56\xad\x71\x45\xf1\x51\x3d\xd7\xd4\x0e\x81\xba\x56\xed\xc5\x4a\ +\xa2\x4f\x95\x39\xd2\xa5\x51\xe7\x2c\x50\x4f\x00\x8b\x11\xfe\x2c\ +\x73\xa4\x0f\x58\x6f\x50\x92\x2f\x4a\x0a\xe4\xd2\xaa\x76\x52\x20\ +\xf7\x4a\xbe\xac\x94\x02\x99\x2a\xf9\xb2\x05\x27\x6b\x50\x5c\x02\ +\x20\x73\x24\x53\xf2\xe5\x7d\xf6\x52\x8a\xe2\x7b\xda\xb3\x43\xf2\ +\xe5\xc6\x83\x56\x4c\x17\xc8\x28\xc9\x97\x35\xb8\xd9\x82\x97\xaf\ +\x81\x62\xc9\x93\xff\x02\x48\xbe\xbc\x84\xe2\x4c\x20\x47\xf2\x45\ +\xf9\x3e\xde\x01\x90\x3c\x99\xee\x8b\x27\xd1\xef\x5a\xc9\x92\x27\ +\xcf\xe2\x62\x3b\x5e\xbe\x25\x92\x1d\x52\x20\xff\xf6\xef\x81\x94\ +\x3c\xe9\xe7\xbb\xce\x1f\xa5\x40\x5e\x45\xb1\x05\x27\x3f\x92\xc7\ +\x1a\xc9\x13\xfd\xae\x63\x23\xc3\x30\xde\x34\x0c\xe3\x6b\xbb\xe3\ +\x08\x82\xac\x8a\x8a\x8a\xb6\x03\x07\x36\x7e\xeb\xed\xd6\x68\xfb\ +\xf6\xed\xec\xde\xbd\x9b\x94\x94\x14\xbb\x43\x69\xf5\x7a\xf7\xee\ +\xcd\xe3\x8f\x3f\x5e\xbe\x65\xcb\x96\xd1\x76\xc7\xd2\x5a\x04\x2d\ +\xb9\xf3\x6d\xd3\x75\xdd\xfe\x03\xc2\xb3\x92\x2f\x8b\x24\x4f\x26\ +\x48\xbe\x8c\x97\x02\xb9\x8a\xbd\xac\x21\x82\xaa\xad\xa7\x5e\xf2\ +\xfd\xeb\x44\x38\x1f\x07\xbb\xd4\x7c\xb5\x8a\x72\xd6\x03\x19\x28\ +\xee\x68\x4c\x0f\x49\xed\xc1\xb0\x71\xff\xe7\x7b\x29\x90\xb9\x32\ +\x46\x0a\xa4\x6f\xa3\xce\x95\xfd\x71\x75\x40\x38\x05\xd8\xa2\xe6\ +\xab\x55\x44\xe2\xc1\xcb\x50\x14\x05\xea\x5a\xb5\xfb\xb0\xe2\xd2\ +\x6a\xa5\x16\xa8\x17\x70\xd2\x53\x2d\x54\x1b\x1a\x7d\x92\xf0\x2c\ +\x00\x4e\xfa\x37\xd0\xb2\x0b\x8a\x5b\x10\x6e\xc2\x49\x77\x5c\x2c\ +\x96\xd9\xd2\x01\x07\x1f\x01\xfb\x50\x9c\x84\x93\x2e\x28\xae\x03\ +\x2e\x67\x2f\x73\xf6\xdf\x62\xae\x0c\x42\xf1\x06\xb0\xca\x97\xd4\ +\xc7\xa2\x18\x48\xd5\xbe\x88\x15\x9c\x07\x3c\x07\x7c\x03\xf4\x00\ +\x7a\x50\xc9\x69\x75\xbf\x50\x9e\x46\x38\x1a\xc5\x54\x14\xed\x10\ +\x4e\x43\x71\x3c\x52\xcb\x1f\x31\x70\x37\x8a\x6f\xf0\xd2\x0f\x98\ +\x06\x44\x23\x98\x8d\xfb\xe2\x68\xda\x21\xc9\x8d\x89\x89\x29\x4f\ +\x4f\xaf\x6d\xa0\x24\x7c\x78\x3c\x1e\x9c\x4e\x27\xc9\xc9\xc9\x76\ +\x87\x12\x16\x8e\x3e\xfa\x68\x97\xdb\xed\x3e\xa8\x13\x48\x3b\x3c\ +\xc1\x1b\x96\x05\xf8\x89\x45\x64\xd0\x15\xc5\x0c\xac\x79\x77\xb3\ +\x11\xac\x15\x31\x35\x07\x94\x4a\xf8\x3b\xed\x39\x09\xc8\x01\xce\ +\xa5\x92\x73\x25\x5f\x8a\x71\x91\x78\x50\xdb\x43\xb7\x14\xa8\x5a\ +\xcf\x7f\x2d\x5e\xc0\x2a\xac\x5c\xdb\xb0\x5f\x75\x15\x5c\x81\x8b\ +\x31\x40\x27\xe0\x3a\x14\xd7\x48\x81\xfc\xee\x5b\x95\x0b\x54\x1b\ +\x7e\xd6\x02\x44\xdd\xa8\x7e\x3b\xa4\x13\x2a\xf9\x09\x07\xe0\xa5\ +\xa1\xa4\xbd\x0d\x70\x95\x9a\xaf\x9e\xad\x3a\x20\x79\x72\x1b\x10\ +\x83\x93\xe9\x7e\xf7\x5d\x20\xf9\x92\x09\xcc\x11\x91\xf9\x4a\x29\ +\x85\x97\x85\xc0\x3a\xa2\x38\xc5\xaf\xb8\xf5\xd7\xbe\x0f\xd4\xcd\ +\x6a\xb3\x14\xc8\x2e\x14\x65\x0d\xed\x41\x2c\x79\x72\x34\xc2\x28\ +\x14\x67\xab\x05\xaa\xea\x0f\x88\xff\x49\x81\xa4\xa1\xb8\x4d\xe6\ +\x4a\xb6\xba\x49\x7d\xe5\x77\xca\x27\xaa\x50\x5d\xe9\xfb\x7c\xa5\ +\xe4\xc9\x50\x84\x2b\x64\x9e\x44\xf9\x7a\x3b\x35\x2d\x20\x44\x64\ +\xd4\xc0\x81\x03\xc3\x7e\xfa\x53\x51\x51\x11\x49\x49\x49\x38\x9d\ +\x61\x3f\x3a\xdd\x2c\x86\x0f\x1f\x2e\x4b\x97\x2e\x1d\x26\x22\xb1\ +\x4a\xa9\x5d\x76\xc7\x13\xea\x82\x9a\xdc\xa9\xa7\x54\x25\xf0\x57\ +\x99\x23\xff\xc4\x81\x01\xf4\xc5\x2a\x62\xbc\x13\xf8\x09\xc5\xff\ +\x88\xb6\x0a\x19\xab\xfb\x54\xb9\xcc\x90\x11\x24\xf0\x57\x5f\x0f\ +\x59\x3a\x10\x09\x7c\x8f\xf0\x35\x5e\x0e\x6c\x4d\xa2\x58\x8f\xf8\ +\x26\x32\x3b\x29\x6a\xf0\x78\x14\xf7\xb3\x17\x2f\x30\x8e\xaa\x15\ +\xb9\x8a\xaa\x7a\x3a\x9b\x38\x30\x29\xfa\xa0\x84\x42\xdd\xac\x36\ +\xcb\x1c\xe9\x8b\x93\x3c\x60\x1c\x8a\x1e\x28\xbc\x58\x6f\xe8\x1f\ +\x03\xcf\xd6\x3c\x47\xb3\x81\xec\x9f\x1b\xd9\x50\x59\x8a\x72\xbc\ +\xbc\x5e\xe3\xdc\xe1\xc0\xcf\x54\x32\x45\xf2\xab\xbd\xa1\x55\x00\ +\x71\x5c\x45\x67\x60\x03\x30\x14\xc5\xc3\x01\xda\xb5\x64\xa0\xef\ +\x0e\xaf\x54\x3b\xaa\x78\x1e\xb8\x8d\x4a\x8e\x04\xfc\x93\xbb\xea\ +\x3f\x67\x0e\x3e\x44\x01\x15\xa4\x02\x3f\x07\x20\x1e\xad\x91\x4c\ +\xd3\x8c\x00\x3e\x01\xfe\x6a\x18\xc6\x07\x76\xc7\x13\x68\x4e\xa7\ +\x73\xcc\xe0\xc1\x83\x83\xfb\x87\x7f\x08\x18\x31\x62\x04\x7b\xf6\ +\xd4\x3b\x05\x56\x0b\xa0\x01\x03\x06\x90\x9b\x9b\xeb\x5a\xb7\x6e\ +\xdd\x44\xac\x85\x73\x5a\x13\x34\xcb\x7f\x60\xb5\x50\x7d\x02\xfb\ +\x4b\x9a\xd4\xdd\xce\x9a\xc0\x7e\x87\xef\xa3\xee\x76\xd6\x1c\xab\ +\x27\x1a\x7d\xfc\x5a\xe5\x05\xee\xf7\x7d\x54\x7f\x6e\xbe\x7a\x19\ +\x78\xb9\xde\xfb\x2d\x54\x3b\xb0\x26\x4f\xcf\xad\xaf\x9d\x66\x23\ +\x21\xc3\xf7\xef\xea\x06\x5a\xae\xf5\x7d\x3f\xfd\xa5\x01\x95\x08\ +\x27\xd6\xd2\x7e\x19\x0e\x22\x64\xb6\xc4\xe2\xa2\x2d\xb0\xa5\x96\ +\x36\x87\x4e\xb0\x26\xf2\xfc\x4a\xf5\xa9\x06\x5e\xb6\xe0\x00\x1c\ +\x24\xd5\x38\x63\x43\x8d\x76\x7b\x10\xa0\xa2\xde\x39\xa4\x5a\x70\ +\x0c\xc5\x5a\x24\x16\xd4\x3d\xb1\xed\x20\x22\xbd\x80\xa4\x70\xaf\ +\x6f\x07\xe0\x70\x38\x88\x8d\x8d\xb5\x3b\x8c\xb0\x91\x98\x98\xc8\ +\x29\xa7\x9c\xc2\x2b\xaf\xbc\x72\x32\x3a\xb9\x6b\xb2\xb0\xff\xeb\ +\x4c\x6b\x35\x2e\x00\xca\x71\xf0\x65\x03\xed\x6a\x1b\xe4\x5f\x8b\ +\xb0\x47\xcd\x57\x13\xeb\x3b\x51\xf2\xc5\x83\xe3\xb0\x4a\xec\xd4\ +\xe6\x17\x00\x7a\xd3\x09\x58\xbf\xff\xa8\x8b\x6e\x78\x01\x2f\x8d\ +\x9f\x6f\xa8\x35\xb7\xd1\xc0\x6f\x86\x61\xac\xb5\x3b\x90\x20\xc8\ +\x8d\x8c\x8c\xac\xe8\xdb\xb7\xaf\x7e\x6f\xd0\x9a\x95\xd3\xe9\xa4\ +\xb4\xb4\x94\x8e\x1d\x3b\x06\x7f\xbf\xf9\x30\x10\xdc\xbd\x65\x35\ +\x2d\xc8\x64\x9e\x44\x49\xbe\x5c\x07\x4c\x04\x16\xa8\x1b\xd5\xfa\ +\x06\x4e\xa9\xcd\x2b\x28\x46\xd5\xb6\xfa\xb4\xc6\xc4\xa3\x57\xf1\ +\x72\xba\x14\x48\xdd\x33\xac\x15\x25\x40\xf7\x06\xef\x28\x7c\x00\ +\x78\xa9\x64\x7a\xb5\xe3\x95\x9c\x07\x94\xfb\x15\xef\xd6\x5a\x9e\ +\x91\x54\x2d\xa2\x69\x7d\x72\xfb\xf7\xef\xaf\x1c\x0e\xfd\xd6\xa0\ +\x35\xbf\xca\xca\x4a\x3a\x77\xee\x1c\xde\x95\xb3\x03\x44\xff\x75\ +\xa6\x85\x16\xc5\x99\x92\x2f\x83\x81\x68\xac\x79\x99\x83\x81\x24\ +\xe0\x1e\xa2\xb8\xf1\xb0\xae\xb9\x8b\xbf\x13\xcb\x69\x08\x6f\x4b\ +\x9e\xdc\x82\x83\x6f\x50\xc4\x21\x64\x93\xc7\x70\xc0\xaa\x9c\xee\ +\x25\x1f\x07\x93\xf0\xf2\xb1\xe4\xcb\x22\x14\xeb\x10\xba\x01\xc3\ +\x54\xa1\x3a\xcf\x17\xdf\xfb\x08\x17\x4b\x81\xfc\x1b\xf8\x1c\xc5\ +\xfa\x9a\x75\xf9\x00\xd4\x7c\xb5\x4a\x0a\xe4\x01\x14\xd7\x4b\xbe\ +\x44\xa3\xf8\x14\xc8\x45\xb8\x1c\xc5\xcd\x6a\x41\xfd\x0b\x32\x34\ +\x5b\x9d\x04\xc4\x37\xd8\x2a\x04\xb9\xdd\xee\x71\x43\x86\x0c\x69\ +\xb8\xe8\xbc\xa6\x05\x41\xbb\x76\xed\x78\xf1\xc5\x17\xdd\x22\x92\ +\xa8\x94\x6a\x75\x35\x24\x9b\x93\xfe\xf3\x4c\x0b\x0d\x0e\x4a\x81\ +\xe5\x08\x09\xc0\x30\xac\xbd\x7d\x7f\x46\xb8\x15\x17\x7d\x54\xa1\ +\x9a\xe9\xbf\xd0\xc1\x57\xe0\x77\x39\xaa\xda\x22\x99\x35\xd4\x32\ +\xf7\x53\xdd\xa9\xca\x28\x63\x38\xf0\x00\x70\x2a\x8a\xc7\x80\x9b\ +\xb1\x12\xc7\x7f\xed\x6f\xb7\x50\x6d\xa4\x92\xfe\xc0\xdb\x58\xb5\ +\xf8\x1e\x07\x2e\x46\xf9\xcd\xf3\x5b\xc8\x93\xc0\x0c\x14\x6e\x14\ +\x53\xb0\xf6\x1f\x05\x45\x11\xb0\x9c\x48\xbf\x9d\x5b\x0a\x31\x80\ +\x02\xe0\x78\x1c\xfc\x13\x07\xa3\x81\x8b\xd5\x02\xb5\xbf\xfc\x0a\ +\xc2\x2e\xac\x05\x3f\xd5\xe7\xe6\x29\x8a\x81\xe5\x38\xd1\x33\xbe\ +\x9b\x99\x61\x18\xbb\x0d\xc3\xd8\x64\x77\x1c\x81\x26\x22\x5d\xcb\ +\xcb\xcb\x3b\x85\x7b\x7d\xbb\x8a\x8a\x0a\x5e\x7c\xf1\x45\xb6\x6d\ +\x3b\xbc\xca\x5b\xda\xe1\xeb\xdd\xbb\x37\xaf\xbd\xf6\x1a\xc0\x20\ +\xbb\x63\x09\x75\xa2\x8b\xdc\x6b\x9a\xa6\x69\x22\x72\x96\xcb\xe5\ +\xfa\xd7\x5b\x6f\xbd\xe5\x74\xbb\xc3\xb7\xf3\x6e\xe3\xc6\x8d\xbc\ +\xfc\xf2\xcb\x9c\x75\xd6\x59\x44\x47\x47\xdb\x1d\x4e\xd8\x99\x3c\ +\x79\xf2\xbe\xe2\xe2\xe2\x6b\x95\x52\x0b\xec\x8e\x25\x94\xe9\x9e\ +\x3b\x4d\xd3\xb4\x46\xf2\x95\x41\x69\xad\x72\x8f\x38\xe2\x88\xca\ +\x70\x4e\xec\xc0\x2a\x5e\xdc\xb6\x6d\x5b\x9d\xd8\xd9\x24\x2b\x2b\ +\xcb\xe5\x74\x3a\x87\xda\x1d\x47\xa8\xd3\xc9\x9d\xa6\x69\x5a\xe3\ +\xbd\x63\x9a\xe6\x0d\x76\x07\x11\x0c\xbe\xf9\x76\xad\x39\x79\x6d\ +\x14\x8f\xc7\x43\xc7\x8e\x1d\xed\x0e\x23\x6c\x0d\x1e\x3c\xd8\x71\ +\xe6\x99\x67\x4e\xb0\x3b\x8e\x50\xa7\x93\x3b\x4d\xd3\xb4\x46\x30\ +\x4d\x53\x80\x23\x80\x5f\xed\x8e\x25\xd0\x44\xa4\x43\x79\x79\x79\ +\x7a\xb8\xcf\xb7\xf3\x7a\xbd\x6c\xde\xbc\x59\xef\x27\x6b\xa3\x1e\ +\x3d\x7a\x30\x7c\xf8\xf0\x98\x51\xa3\x46\x75\xb5\x3b\x96\x50\xa6\ +\x93\x3b\x4d\xd3\xb4\xc6\xe9\x0a\xc4\x01\xdf\xdb\x1d\x48\x10\xe4\ +\x3a\x1c\x0e\x95\x95\x95\x65\x77\x1c\xb6\xda\xba\x75\x2b\x15\x15\ +\x15\x87\xdd\x73\xb7\x6e\x5d\x34\xff\xfb\x5f\x07\xbe\xfb\xae\x4d\ +\x80\x23\xab\xdd\xa6\x4d\x91\x4c\x9a\x34\x88\x4f\x3e\x69\x3d\x8b\ +\xb7\xd3\xd3\xd3\x11\x11\xda\xb4\x69\x73\x82\xdd\xb1\x84\x32\x9d\ +\xdc\x69\x9a\xa6\x35\x4e\x37\xa0\x8c\xd6\xb9\x9f\x74\x6e\xaf\x5e\ +\xbd\xf6\x85\xfb\x3c\xb3\xa2\xa2\x22\xa2\xa2\xa2\x88\x8f\x3f\xbc\ +\x64\xe9\x81\x07\x3a\xb3\x68\x51\x0f\x16\x2e\xec\x11\xe0\xc8\x6a\ +\xe7\xf5\x0a\x25\x25\x6e\xf6\xed\x6b\x3d\xfb\x00\x27\x26\x26\x52\ +\x51\x51\x41\x4c\x4c\xcc\x28\xbb\x63\x09\x65\x3a\xb9\xd3\x34\x4d\ +\x6b\x04\xc3\x30\xde\x05\x62\x0d\xc3\x28\xb5\x3b\x96\x40\x73\xbb\ +\xdd\xe3\x72\x72\x72\x22\xed\x8e\xc3\x6e\x1e\x8f\xe7\xb0\x87\x64\ +\xb7\x6f\x77\xb1\x7c\x79\x02\x39\x39\xdb\xf9\xe1\x87\x18\x56\xaf\ +\xd6\x5b\x97\x1d\xae\xcf\x3f\xff\x5c\x7d\xf6\xd9\x67\x6d\xed\x8e\ +\x23\x94\xe9\x22\xc6\x9a\xa6\x69\x8d\x64\x18\x46\xa5\xdd\x31\x04\ +\x9a\x88\xb4\x13\x91\xbe\x7a\x3f\x59\x2b\xb9\x3b\xdc\xaf\xc3\xb2\ +\x65\x89\x78\xbd\xc2\xff\xfd\xdf\x4f\x9c\x7d\x76\x16\x2f\xbe\x98\ +\x4c\x9f\x3e\xbb\xaa\xb5\xf9\xf2\xcb\xb6\x7c\xfb\x6d\x1b\xa6\x4f\ +\xdf\xc4\x8b\x2f\x26\xf1\xc5\x17\x6d\x69\xd3\xa6\x92\x29\x53\xb6\ +\x1c\xd4\x76\xdf\x3e\x07\x4f\x3d\x95\xc2\xaa\x55\xb1\x74\xed\xba\ +\x97\x09\x13\x8a\xd9\xba\xd5\xcd\xaa\x55\xb1\x4c\x9f\x5e\x7f\x99\ +\xc5\xbd\x7b\x1d\xbc\xf8\x62\x32\x2b\x57\xc6\xe2\x70\xc0\xa0\x41\ +\xdb\x99\x38\x71\x2b\x12\x22\x1d\x7c\x6d\xda\xb4\x91\x8d\x1b\x37\ +\x86\xf7\x1c\x81\x26\xd2\x3d\x77\x9a\xa6\x69\xe1\xed\x18\x80\x01\ +\x03\x06\xd8\x1d\x87\xad\xb6\x6d\xdb\x46\x59\x59\xd9\x61\xcf\xb7\ +\x7b\xe1\x85\x64\x8e\x3a\xea\x77\x92\x93\xf7\x31\x71\x62\x31\xcb\ +\x96\x25\x52\x5e\x5e\xfd\x2d\xf6\x8b\x2f\xe2\x58\xbc\xb8\x13\xd7\ +\x5e\xdb\x93\xfb\xef\xef\x02\xc0\xb2\x65\x49\x5c\x70\x41\x3f\x7e\ +\xf8\x21\x66\x7f\xbb\xf2\x72\x07\x17\x5d\x94\xc9\xdd\x77\xa7\xf1\ +\xfb\xef\x6e\x4a\x4a\xdc\x5c\x7e\x79\x1f\x1e\x7f\x3c\x95\xc7\x1e\ +\x4b\xad\x37\x8e\xdf\x7e\x8b\xe2\xec\xb3\xfb\x73\xe7\x9d\x69\xec\ +\xde\xed\x64\xeb\x56\x37\xd7\x5f\xdf\x93\x2b\xae\xe8\x83\xd7\x7b\ +\x58\x2f\xad\xd9\x65\x66\x66\xb2\x6f\xdf\xbe\x4e\x22\xd2\xde\xee\ +\x58\x42\x95\xee\xb9\xd3\x34\x4d\x6b\x80\x69\x9a\x0e\xac\x39\x77\ +\xbf\x18\x86\xd1\xda\x2a\xbf\xe7\x76\xef\xde\x7d\x5f\x5c\x5c\x5c\ +\x58\x0f\xcb\x7a\xbd\x5e\xd2\xd2\xd2\x48\x4c\x4c\x3c\xe4\x73\xd7\ +\xac\x89\x65\xcd\x9a\x58\xce\x3d\xf7\x07\x00\x26\x4d\xda\xc2\x13\ +\x4f\x74\xe4\x9d\x77\x12\x18\x3b\xb6\xfa\x2e\x5a\x7b\xf6\x38\x69\ +\xd3\xa6\x92\xe7\x9e\xfb\x0a\xa7\x53\xb1\x6b\x97\x93\x89\x13\x07\ +\xf1\xe4\x93\x1d\xb9\xfa\xea\xb5\x00\x3c\xf3\x4c\x07\x56\xad\x6a\ +\xc3\xbd\xf7\xae\x20\x3b\x7b\x07\x00\x6b\xd7\x46\x73\xf6\xd9\xfd\ +\x89\x8b\xab\xa8\x37\x96\x5b\x6e\xe9\xc6\x9e\x3d\x0e\x5e\x7e\xf9\ +\x0b\xda\xb4\xb1\x3a\x9a\xbf\xfc\x32\x0e\xc3\x38\x82\xa5\x4b\x93\ +\x99\x3c\x79\xcb\x21\xbf\xbe\xe6\xd6\xb7\x6f\xdf\xaa\x4f\x07\x03\ +\xaf\xd9\x18\x4a\xc8\xd2\x3d\x77\x9a\xa6\x69\x0d\xeb\x0d\xac\x05\ +\x5a\xdd\xd8\xa5\xdb\xed\x1e\xab\xe7\xdb\x59\x13\xf9\xc7\x8f\x1f\ +\x8f\xc3\x71\xe8\x6f\x8b\x2f\xbc\x90\x4c\x5c\x5c\x25\xb9\xb9\xd6\ +\x74\xcc\xde\xbd\x77\xd3\xab\xd7\x6e\x5e\x78\x21\xb9\xd6\xf6\x53\ +\xa7\x6e\xc6\xe9\xb4\xfe\x46\x88\x8d\xad\x24\x2b\x6b\x27\xeb\xd7\ +\x47\xed\x7f\xfe\x9d\x77\x12\x18\x34\x68\xfb\xfe\xc4\x0e\x20\x3d\ +\x7d\x0f\x43\x87\xfe\x5e\x6f\x1c\xdb\xb6\xb9\xf9\xe0\x83\x76\x9c\ +\x7c\xf2\xe6\xfd\x89\x1d\xc0\xc0\x81\x3b\xe8\xd6\x6d\x2f\x1f\x7d\ +\x14\x1a\xab\x6a\x63\x62\x62\xb8\xe4\x92\x4b\xd4\xf0\xe1\xc3\x27\ +\xd9\x1d\x4b\xa8\xd2\x3d\x77\x9a\xa6\x69\x0d\xcb\x02\x2a\x81\x95\ +\x76\x07\x12\x48\x22\x12\x2b\x22\x03\xc2\xbd\xbe\x5d\x53\x94\x97\ +\x3b\x58\xb6\x2c\x91\x63\x8e\xd9\xc6\xde\xbd\xc2\xde\xbd\x4e\x00\ +\xc6\x8c\x29\xe1\xc1\x07\xbb\xb0\x79\x73\x04\x1d\x3a\xec\xdf\xf6\ +\x9a\xe8\x68\x2f\x99\x99\xd5\xe7\xd7\x75\xee\x5c\xc6\xaa\x55\x07\ +\x16\x60\x6c\xda\x14\x45\x4e\xce\xc1\x89\x5c\x5a\xda\x5e\x56\xae\ +\xac\x7b\xa1\xc6\x2f\xbf\x58\xab\x9d\xff\xf3\x9f\x8e\x3c\xf3\x4c\ +\xf5\x85\x21\x3b\x77\x3a\x1b\xec\xf5\x6b\x29\x1c\x0e\x07\x3d\x7b\ +\xf6\x94\x8d\x1b\x37\xea\x1f\xcc\xc3\xa4\x93\x3b\x4d\xd3\xb4\x86\ +\xf5\x07\x7e\x34\x0c\x63\xaf\xdd\x81\x04\xd8\x51\x4a\x29\xa7\x5e\ +\x4c\x71\xf8\x96\x2f\x4f\x60\xfb\x76\x17\x4b\x97\x26\xb1\x74\x69\ +\xd2\x41\xcf\xbf\xfc\x72\x12\x7f\xfa\xd3\xc6\xfd\x8f\x1d\x8e\x86\ +\x47\xf5\x63\x63\x2b\xab\xf5\xe4\x55\xd9\xb5\xcb\x59\xef\x79\x55\ +\xd7\x9e\x31\x63\x03\x7d\xfb\xee\x3a\xe8\xf9\xe8\xe8\xd0\x59\x0f\ +\xb4\x73\xe7\x4e\xda\xb7\x6f\x9f\x6e\x77\x1c\xa1\x4a\x27\x77\x9a\ +\xa6\x69\x0d\x73\x00\xef\xd8\x1d\x44\x10\xe4\x76\xea\xd4\xa9\x2c\ +\x21\x21\x21\xec\x87\x65\x0f\xd7\x0b\x2f\x24\xd3\xb5\xeb\x5e\xf2\ +\xf3\x7f\x3e\xe8\xb9\xc5\x8b\x3b\xf3\xe2\x8b\xc9\xd5\x92\xbb\xc6\ +\xe8\xd1\x63\x37\x6f\xbf\xdd\x9e\x3d\x7b\x1c\x44\x47\x5b\xab\x20\ +\xbc\x5e\xf8\xea\xab\xb8\x7a\xcf\x4b\x4f\xdf\x83\xc3\x01\xa5\xa5\ +\x2e\xb2\xb2\x76\x1e\xd2\x3d\x5b\x9a\xca\xca\x4a\x12\x13\x13\x6b\ +\x1f\xd7\xd6\x1a\xa4\xe7\xdc\x69\x9a\xa6\x35\xc0\x30\x8c\x6b\x0c\ +\xc3\xf8\x8b\xdd\x71\x04\x9a\xcb\xe5\x3a\x76\xe8\xd0\xa1\x61\xbf\ +\x9f\x6c\x69\x69\x29\xff\xfd\x6f\x3b\x2e\xbd\xb4\x2f\x4b\xd0\xe7\ +\x65\xf3\x00\x00\x20\x00\x49\x44\x41\x54\x97\x26\xb1\x67\x4f\xe3\ +\xde\x1a\x3d\x9e\x08\x3e\xfd\x34\x9e\x09\x13\xb6\x32\x68\xd0\xf6\ +\x83\x3e\x4e\x3c\x71\x33\x1b\x36\x44\x35\x98\x94\xd5\x74\xd6\x59\ +\x9b\xa8\xa8\x10\xae\xbd\x36\x83\x35\x6b\x62\xd8\xbd\xdb\xc9\x5d\ +\x77\xa5\xb1\x75\x6b\xfd\xdf\xaa\xb8\xb8\x0a\x4e\x3e\xb9\x88\x7f\ +\xff\xbb\x13\x35\xcb\xc4\xfd\xf4\x53\x34\x2b\x56\x34\xcf\xce\x19\ +\x81\x50\x59\x59\xc9\xa3\x8f\x3e\xea\x14\x09\x95\x02\x2e\x2d\x8b\ +\xee\xb9\xd3\x34\x4d\x0b\x43\x22\x12\xe9\x70\x38\x72\x06\x0e\x1c\ +\x18\xf6\x6f\x9e\x6f\xbe\xf9\x26\x6e\x77\x37\x62\x62\xa6\x31\x7f\ +\x7e\x0f\x16\x2d\xea\xc1\xa8\x51\x25\x1c\x77\xdc\x56\x72\x72\xb6\ +\xd7\x39\x94\xfa\xd2\x4b\xc9\x78\xbd\x30\x71\x62\x71\xad\xcf\x1f\ +\x73\xcc\x36\x62\x62\x2a\x79\xe1\x85\xe4\x6a\x8b\x23\x1a\x92\x99\ +\xb9\x8b\x6b\xae\xf9\x89\x45\x8b\x7a\xf0\xce\x3b\x09\x38\x9d\x8a\ +\x31\x63\x4a\x38\xe1\x84\xcd\xbc\xf3\x4e\x42\xbd\xe7\xce\x9c\xb9\ +\x9e\x1d\x3b\x5c\x5c\x7c\x71\x26\x9d\x3a\x95\x91\x90\x50\xfe\xff\ +\xec\x9d\x77\x78\x94\x55\xf6\xc7\x3f\x67\x5a\x7a\x81\x10\x08\x84\ +\xa6\x74\x95\x2a\xd8\xb1\x60\x5f\x1b\x36\x5c\xd7\xb5\xb1\xa0\xc6\ +\xae\x6b\x61\x16\x5d\x44\x5d\xe3\xcf\xba\xba\x6a\x70\x2d\xa8\xd8\ +\x10\x7b\xc5\xb5\x01\x0a\x36\xaa\x14\x29\xd2\x21\x09\x24\x84\x90\ +\x90\x3a\x99\x39\xbf\x3f\xee\x4c\x32\x24\x93\x4a\x92\x21\xf0\x7e\ +\x9e\x67\x9e\xcc\x7b\xdf\xfb\xde\xf7\x4c\x08\x33\xdf\x39\xf7\x14\ +\x72\x72\x5c\xe4\xe4\xb8\xb8\xeb\xae\xf5\x1c\x72\x48\xdb\xf0\xe8\ +\xa5\xa4\xa4\xb0\x75\xeb\x56\x27\x90\x02\xd4\x5d\xd8\xcf\xa2\x06\ +\xa2\xba\xbf\x65\xf5\x5b\x58\x58\x58\x58\xd4\x87\x88\x8c\x04\xe6\ +\x7c\xf4\xd1\x47\x4d\xee\xca\xb0\x3f\x50\x5e\x5e\xce\xb4\x69\xd3\ +\x18\x35\x6a\x14\x07\x1d\x74\x10\x85\x85\x76\xbe\xf9\x26\x89\x99\ +\x33\x3b\xb0\x64\x49\x1c\x49\x49\x1e\x4e\x3b\x2d\x97\x2b\xaf\xcc\ +\x24\x21\x61\xcf\x84\x84\x3f\xfe\x88\xa6\xa4\xc4\xce\xc0\x81\xb5\ +\x0b\xb7\xd5\xab\xa3\xf1\x78\x6c\x1c\x7a\xe8\x6e\xb2\xb3\x23\xd8\ +\xb6\xcd\xc5\xe0\xc1\x7b\xce\xdf\xb8\x31\x92\xe2\x62\x7b\x8d\x44\ +\x0b\x8f\xc7\xc6\xfa\xf5\x91\x74\xee\x5c\x4e\x5c\x5c\x05\x77\xde\ +\xd9\x97\xa2\x22\x3b\xcf\x3d\xf7\xbb\xdf\x76\x1b\xcb\x96\xc5\xd2\ +\xab\x57\x71\x0d\xdb\xd6\xac\x89\x66\xed\xda\x68\x76\xed\x72\xd0\ +\xbe\xbd\x87\x41\x83\x0a\xe9\xd4\xa9\x9c\xb6\x42\x76\x76\x36\xa3\ +\x47\x8f\x06\x38\x4e\x55\xe7\x86\xdb\x9e\xb6\x86\xe5\xb9\xb3\xb0\ +\xb0\xb0\xa8\x83\x8c\x8c\x8c\x8e\x40\xb7\xb4\xb4\xb4\x05\xe1\xb6\ +\xa5\x99\x39\xbe\x43\x87\x0e\x65\x9d\x3a\x75\x3a\xa0\xe3\xed\xb6\ +\x6d\xdb\x86\xaa\x56\x16\x2f\x8e\x8b\xf3\x32\x7a\xf4\x76\x46\x8f\ +\xde\x4e\x76\x76\x04\x33\x67\x26\x31\x77\x6e\x3b\x1c\x8e\x9a\x8e\ +\x90\xde\xbd\x8b\xeb\x5d\xbf\x6f\xdf\xaa\x39\x29\x29\x65\xa4\xa4\ +\x94\xd5\x98\xd3\xa3\x47\xcd\x3c\x9d\xdc\x5c\x27\x1d\x3a\x78\x2a\ +\xaf\x5f\xba\x34\x96\x79\xf3\x12\xb9\xfe\xfa\xcd\x95\x73\x5c\x2e\ +\x1f\xc3\x86\x15\x84\xbc\x6f\x9f\x3e\xa6\x1c\x4b\x5b\xa5\x63\xc7\ +\x8e\xd8\xed\x76\x9f\xd7\xeb\x3d\x18\xb0\xc4\x5d\x23\xb1\xc4\x9d\ +\x85\x85\x85\x45\xdd\x9c\x0b\x3c\x02\xec\x57\xd5\xf2\xed\x76\xfb\ +\x49\x56\xbc\x9d\x11\x77\x09\x09\x09\x44\x45\x45\xd5\x38\x97\x92\ +\x52\xc6\x55\x57\x65\xee\x91\x10\xf1\xc1\x07\x1d\xe9\xd3\xa7\xb8\ +\xc5\x13\x16\xae\xbb\xee\x10\xe2\xe3\x2b\xe8\xd2\xa5\x8c\x5d\xbb\ +\x9c\x2c\x5c\x18\xc7\xd0\xa1\x85\x8c\x19\xb3\xad\x45\xef\xbb\xaf\ +\x60\xb3\xd9\xb8\xfe\xfa\xeb\xc9\xc9\xc9\xb9\x04\x98\x16\x6e\x7b\ +\xda\x1a\x96\xb8\xb3\xb0\xb0\xb0\xa8\x9b\x2e\x40\xe3\xd2\x1d\xf7\ +\x71\x44\xc4\x61\xb7\xdb\x8f\xb1\xe2\xed\xcc\xf6\x5f\x43\xb7\xa5\ +\x55\x61\xf6\xec\xf6\x3c\xf2\xc8\x41\x9c\x77\xde\x76\x6e\xb8\x61\ +\x73\x8b\xd5\x8e\x7b\xe0\x81\x3f\x58\xb4\x28\x9e\x9d\x3b\x9d\xf4\ +\xe9\x53\xcc\x98\x31\xd9\x1c\x77\xdc\xce\x36\xd3\x1f\xb6\x39\x68\ +\xd7\xae\x9d\x94\x97\x97\xf7\x0a\xb7\x1d\x6d\x11\x4b\xdc\x59\x58\ +\x58\x58\xd4\xcd\x7e\x27\xee\x80\xa1\x5e\xaf\x37\xea\x40\x2f\x5e\ +\xec\xf3\xf9\xc8\xc9\xc9\xa1\x6f\xdf\xbe\x0d\x9a\x2f\x02\xff\xfe\ +\xf7\x4a\xbe\xfc\xb2\x03\x4f\x3d\xd5\x9d\x59\xb3\xda\x71\xcf\x3d\ +\xeb\x38\xee\xb8\xfc\x66\xb7\x6d\xc0\x80\xa2\x1a\x31\x78\x07\x20\ +\x12\x19\x19\x79\xe0\x06\x84\xee\x05\x56\x29\x14\x0b\x0b\x0b\x8b\ +\xba\xc9\x06\x7e\x09\xb7\x11\xcd\xcc\xf1\x09\x09\x09\xe5\x5d\xbb\ +\x76\x0d\xb7\x1d\x61\x25\x37\x37\x17\xaf\xd7\x5b\x19\x6f\xd7\x50\ +\x4e\x3f\x3d\x97\x77\xde\x59\xc2\xb1\xc7\xe6\x73\xf7\xdd\x7d\xf9\ +\xfc\xf3\x9a\xc5\x8b\x2d\xf6\x1e\x97\xcb\x45\x74\x74\x74\xdb\xa9\ +\xdf\xb2\x0f\x61\x79\xee\x2c\x2c\x2c\x2c\xea\x20\x2d\x2d\xed\xbe\ +\x70\xdb\xd0\xdc\xd8\x6c\xb6\x13\x87\x0f\x1f\x7e\xc0\xbf\xff\x67\ +\x67\x67\x13\x1d\x1d\x4d\x7c\x7c\x7c\xfd\x93\xab\x11\x1b\xeb\xe5\ +\xde\x7b\xd7\x91\x9c\xec\xe1\x81\x07\x7a\xb1\x7b\xb7\x83\x31\x63\ +\xb2\x5b\xc0\xca\x03\x17\x97\xcb\xc5\x13\x4f\x3c\xe1\x48\x4f\x4f\ +\x8f\x50\xd5\x9a\x99\x28\x16\xb5\x72\xc0\xff\xe7\xb6\xb0\xb0\xb0\ +\x38\x90\x10\x11\x71\x38\x1c\xc7\x0f\x1b\x36\xac\xc1\x3b\x37\x25\ +\xde\x12\xb6\x97\x6c\x07\x20\xd1\x95\x48\x82\xab\x6d\x34\xa0\xaf\ +\x8f\xc6\xc4\xdb\xd5\xc6\x75\xd7\x99\xb8\xbb\x79\xf3\x12\xb8\xe8\ +\xa2\x6c\x6c\xd6\x7e\x58\xb3\x91\x9a\x9a\x4a\x5e\x5e\x9e\x00\x3d\ +\x81\x55\x61\x36\xa7\x4d\x61\x89\x3b\x0b\x0b\x0b\x8b\x46\x22\x93\ +\xc5\x45\x29\xaf\x05\x0d\xbd\xa7\xe9\x3a\xa3\xf2\xfc\x3f\xe4\x4f\ +\x28\x57\xf8\x0f\x5f\xd1\x74\x9d\xd9\xba\x16\xd6\xc9\x61\x15\x15\ +\x15\xf1\x8d\xe9\x27\xfb\xf3\xf6\x9f\x99\xf0\xf3\x04\x00\xae\x19\ +\x70\x0d\x63\xfb\x8d\x6d\x29\xdb\x5a\x95\x6d\xdb\xb6\x31\x6c\xd8\ +\xb0\xbd\x5e\xe7\xb2\xcb\xb2\xb8\xf4\xd2\xac\x4a\x61\xa7\xca\x01\ +\x95\xf8\xd0\x52\x74\xe9\xd2\x25\xf0\xf4\x60\x2c\x71\xd7\x28\x2c\ +\x71\x67\x61\x61\x61\x51\x0b\x19\x19\x19\x31\xc0\x08\xe0\xe7\xb4\ +\xb4\xb4\x92\xa0\x53\x0e\xe0\x92\xa0\xe3\x13\x64\xb2\x7c\xa6\x93\ +\x34\x50\x58\xac\x7f\xe5\x79\x65\x2e\xb0\x2f\x89\xbb\xe3\x63\x62\ +\x62\x3c\x07\x1f\x7c\xb0\x33\xdc\x86\x84\x9b\x33\xcf\x3c\x93\x98\ +\x98\x98\x66\x59\x2b\x20\xec\xde\x78\xa3\x33\xeb\xd6\x45\x71\xef\ +\xbd\xeb\x9a\x65\xdd\x03\x99\xa8\xa8\x28\xe2\xe2\xe2\x3c\x85\x85\ +\x85\x07\x87\xdb\x96\xb6\x86\xe5\x40\xb6\xb0\xb0\xb0\xa8\x9d\x43\ +\x80\xef\x80\x8e\xf5\xcc\x4b\xa1\x84\x9b\x5b\xc1\x9e\xbd\xc6\x66\ +\xb3\x9d\x30\x74\xe8\x50\xab\x65\x27\xd0\xa1\x43\x87\x90\xf5\xed\ +\xf6\x86\xbe\x7d\x8b\xf8\xe2\x8b\x0e\x7c\xfa\xa9\xd5\xf3\x7e\x6f\ +\x51\x55\xee\xba\xeb\x2e\xc7\xf1\xc7\x1f\x7f\x54\xb8\x6d\x69\x6b\ +\x58\x9e\x3b\x0b\x0b\x0b\x8b\xda\x09\xec\x0b\x35\x24\x52\xfe\x6e\ +\x99\x2c\x53\x74\x92\xd6\x59\x17\x43\xee\x92\x3e\xd8\xb9\x17\x18\ +\x8a\xd0\x05\x65\x3d\xf0\x23\xc2\xfd\xfa\x90\xe6\x54\xce\x9b\x20\ +\x4f\x22\x98\x5a\x25\xc2\xc5\x28\xf7\x01\xa7\x02\xab\x34\x5d\xcf\ +\x11\xb7\xbc\x82\x89\x45\xf2\xe0\xe3\x6a\x84\xa7\x10\x8e\x46\x58\ +\x06\xfc\x4b\x1f\xd2\xd9\xe2\x96\xeb\x11\xae\x46\xe9\x02\x7c\x87\ +\x70\x9b\xc3\xe6\x18\x75\xf8\xe1\x87\x3b\x7c\xea\xe3\x91\x25\x8f\ +\xb0\x7a\xd7\x6a\x72\x4a\x72\x28\xaa\x28\xa2\x7d\x44\x7b\xba\xc5\ +\x76\x63\xcc\xc1\x63\x38\xba\xd3\xd1\x0d\xfa\x05\x6d\xdc\xbd\x91\ +\x97\x57\xbd\xcc\xea\xfc\xd5\xe4\x95\xe5\xd1\x2d\xb6\x1b\x23\x53\ +\x46\x72\x59\xef\xcb\x70\xd8\x0e\xbc\x8f\x98\x11\x23\x0a\x18\x3b\ +\x76\x2b\x8f\x3f\xde\x93\x81\x03\x77\xd3\xa3\x47\x49\xfd\x17\x59\ +\x84\x44\x44\x88\x8d\x8d\x95\x76\xed\xda\x75\xa9\x7f\xb6\x45\x30\ +\x07\xde\xff\x3c\x0b\x0b\x0b\x8b\x86\xd3\x05\xd8\x99\x96\x96\x56\ +\x57\xa6\xde\x4a\x20\x0e\x21\x95\x52\xee\x02\xfe\x51\xdb\x44\x99\ +\x20\x67\x62\xe7\x43\xc0\x74\x86\x30\x1d\xad\xda\x03\x87\x03\x7f\ +\x91\xbb\xe4\x08\x7d\x44\xd7\x9a\xc9\x0c\x01\x4e\xf0\xcf\xfb\x10\ +\x38\xc6\xbf\x4c\xa0\xe6\xde\x11\xc0\x00\xc0\x8b\x30\x07\xe1\x20\ +\xff\xdc\xce\xc0\x11\xe2\x96\x37\x80\xeb\xa9\xea\x9a\x75\x19\xa5\ +\x74\xaf\xa8\xa8\x48\x1a\x3a\x74\x28\x8a\xf2\xe1\x86\x0f\x01\x70\ +\xd9\x5c\x28\xca\x96\xa2\x2d\x6c\x29\xda\xc2\x8f\xdb\x7e\x64\xf2\ +\xe1\x93\x39\xbd\xdb\xe9\x75\xfe\x72\xbe\xcb\xfc\x8e\x7b\xe7\xdf\ +\x4b\x85\xcf\x14\xf2\x75\xd8\x1c\x2c\xcb\x5b\xc6\xb2\xbc\x65\xcc\ +\xcd\x9e\xcb\x94\x91\x53\xb0\xc9\x81\xb7\x41\x34\x76\x6c\x26\x0b\ +\x16\x24\x30\x71\x62\x6f\x5e\x7e\x79\x39\x2e\x97\x2f\xdc\x26\xb5\ +\x59\xca\xca\xca\x88\x8d\x8d\xb5\x6a\xcd\x34\x92\x03\xef\x7f\x9d\ +\x85\x85\x85\x45\xc3\xd9\x01\x7c\x5a\xe7\x0c\xa5\x18\xb8\xdf\x7f\ +\x74\x8b\xdc\x25\x21\x8b\xa6\xc9\x64\x89\x46\x78\x01\x23\xec\x7c\ +\xc0\x3f\x10\x06\x00\xff\xf5\xaf\xd3\x1e\xbb\xff\x79\x4d\x0e\x07\ +\x5e\x07\xfe\x82\x30\xb5\xda\x39\x3b\x36\x76\xa0\x9c\xed\x17\x81\ +\x00\x09\xc0\xf5\x08\xff\x41\x39\x9b\x80\xe7\x31\x82\x91\xae\x44\ +\x57\x45\xdf\xbe\x7d\x11\x84\xdb\x06\xde\xc6\x27\x67\x7c\xc2\x9c\ +\x73\xe7\x30\xeb\x9c\x59\x3c\x77\xdc\x73\x95\x62\xec\xd5\x35\xaf\ +\xd6\xf9\xb2\x0b\xca\x0b\x78\x78\xf1\xc3\x54\xf8\x2a\x88\x73\xc6\ +\xf1\xd2\x09\x2f\xf1\xcd\x59\xdf\x70\x55\xdf\xab\x00\xf8\x2d\xef\ +\x37\xa6\xaf\x9d\x5e\xe7\x1a\xfb\x2b\x36\x9b\x32\x79\xf2\x1f\x6c\ +\xdf\xee\xe2\xa9\xa7\xba\x87\xdb\x9c\x36\x8d\xc7\xe3\x21\x36\x36\ +\x76\xbf\x6a\xfd\xd7\x1a\x58\x9e\x3b\x0b\x0b\x0b\x8b\x5a\x48\x4b\ +\x4b\x7b\x07\x78\xa7\xde\x89\x91\xbc\x4c\x29\x7f\x07\xfa\xe2\xe0\ +\x1e\xa0\x66\x34\x7d\x19\x83\x81\x54\x00\x84\x85\xfa\x90\xa6\x03\ +\xc8\x64\xb9\x89\x52\xfe\x0a\x44\x03\x27\xc9\x64\x89\x0e\x4a\xcc\ +\x30\x28\x0f\xea\xc3\xfa\x60\xad\xf7\x57\xee\xd4\x87\x75\x96\x4c\ +\x90\x18\x60\xb4\x7f\x74\x93\x3e\xa4\x37\x03\x88\x5b\xbe\x01\x2e\ +\x03\xe8\x33\xbc\x0f\x36\x7f\xf4\xff\xf9\x07\x9d\xcf\x9c\xac\x39\ +\x6c\xda\xbd\x89\x9d\x65\x3b\xa9\xd0\x0a\xe2\x9d\xf1\xe4\x97\xe7\ +\xb3\x79\xf7\x66\x54\x95\xda\x62\xf3\x96\xed\x5c\xc6\xae\xf2\x5d\ +\x00\x0c\x4a\x1a\x44\x6e\x69\x2e\xb9\xa5\xb9\xf4\x88\xeb\x81\x88\ +\xa0\xaa\xfc\x90\xfd\x03\x97\xf6\xbe\xb4\xde\x5f\x5f\x6b\xb3\x79\ +\xf3\x66\xb2\xb3\xb3\x19\x31\x62\x44\x8b\xdd\xa3\x63\xc7\x72\xee\ +\xb9\x67\x1d\x77\xdf\xdd\x97\x11\x23\x76\x71\xe2\x89\x3b\x5b\xec\ +\x5e\xfb\x33\xeb\xd6\xad\xe3\x83\x0f\x3e\xc8\x9d\x32\x65\x4a\xb8\ +\x4d\x69\x53\x58\xe2\xce\xc2\xc2\xc2\x62\x2f\xd1\x49\x5a\x21\x13\ +\xe4\x5e\x84\xe9\x28\xd7\x00\xcf\x87\x98\xd6\xbb\xea\x02\xe6\x05\ +\x5d\x5b\x2e\x6e\x59\x00\x8c\x04\x84\x72\x0e\x06\x96\xed\x71\xa5\ +\xf0\x45\x1d\xb7\xf7\x11\xe9\xef\xa0\x61\x63\x73\xd0\x36\xec\x8f\ +\x41\x73\x76\x05\x9e\xf4\x1b\xd0\xcf\x01\xb0\x69\xf7\x26\xae\xfb\ +\xfe\x3a\xf2\xca\xf2\x42\x2e\xea\xf1\x79\x28\xf5\x96\x12\xe5\x08\ +\x9d\x70\xb0\xa5\x68\x4b\xe5\xf3\xb9\xd9\x73\x99\x9b\x3d\xb7\xc6\ +\x9c\x8d\xbb\x37\xd6\x61\x76\xf8\xd8\xb8\x71\x23\x79\x79\xa1\x5f\ +\x77\x73\x72\xfc\xf1\x3b\xb9\xf0\xc2\x6d\xcc\x9c\xd9\xc1\x12\x77\ +\x4d\x24\x22\x22\x82\xe2\xe2\xe2\xfd\xa3\xb0\x62\x2b\x62\x89\x3b\ +\x0b\x0b\x0b\x8b\xe6\xe0\xff\x98\xc1\x04\xee\xc2\x6c\xa1\x8e\xaf\ +\x71\x5e\xc9\x0a\x3a\xea\x5f\xed\x6c\xbf\x5a\xe6\x19\x22\x59\x5b\ +\xc7\x9d\x2b\x2a\x3d\x7d\x5e\xbc\x41\xc1\x36\x95\x82\x0e\x41\x02\ +\xa2\x2f\xd0\x47\x75\xea\xaa\xa9\x95\xc2\xee\xca\xbe\x57\x72\x6e\ +\x8f\x73\x89\x77\xc5\x33\x76\xf6\x58\x36\xef\xde\x5c\xc7\xed\x0c\ +\x1d\xa3\xaa\x12\x88\x8f\xe9\x74\x0c\xc7\xa5\x1c\x57\x63\x4e\x84\ +\x3d\xa2\xde\x75\xc2\x41\x76\x76\x36\xdd\xbb\xb7\xce\x76\xe9\xed\ +\xb7\x6f\xb0\x0a\x1b\xef\x05\xf1\xf1\xf1\xa8\x6a\x62\xb8\xed\x68\ +\x6b\x58\x7f\x72\x16\x16\x16\x16\xb5\x90\x91\x91\x71\x46\x46\x46\ +\x46\xb7\x86\xcc\x55\x55\xa5\x2a\x99\xa2\xa6\xaa\xa9\xe0\x37\x20\ +\x90\x98\x71\x9c\xdc\x2d\xc3\x01\xc4\x2d\x97\x52\x55\x6a\x65\x9d\ +\x3e\xa4\x3b\xf6\xca\xe8\x7a\xe8\xd1\xa3\x07\x00\xdb\x4a\xb6\x55\ +\x8e\x9d\xd9\xed\x4c\x52\x63\x52\xd9\xb4\x7b\x53\x83\x84\x1d\xc0\ +\x80\xc4\x01\xd8\xc5\x0e\xc0\xba\xc2\x75\x9c\xd9\xed\x4c\x2e\x38\ +\xe8\x82\xca\x47\xb7\xd8\x6e\xb4\x8f\xd8\xf7\x42\xa5\xca\xca\xca\ +\xc8\xcf\xcf\x6f\x74\x3f\xd9\xa6\x12\x2c\xec\x54\x6b\x9f\x67\x11\ +\x9a\xb8\xb8\x38\xbc\x5e\x6f\x5c\xb8\xed\x68\x6b\x58\xe2\xce\xc2\ +\xc2\xc2\xa2\x76\xde\x07\x4e\x69\xe8\x64\x4d\xd7\xff\xa1\x7c\x17\ +\xf2\xdc\xa3\xba\x1d\xe1\x9f\xfe\xc3\x68\x6c\xfc\x2a\x6e\xd9\x0a\ +\xbc\x19\x34\x2d\xad\xe9\xa6\x36\x0c\x87\xc3\x6c\xd8\x1c\xd6\xfe\ +\xb0\xca\xb1\x1b\xe7\xde\xc8\x4d\x73\x6f\xe2\x9a\x39\xd7\x10\x69\ +\x8f\x6c\xd0\x3a\x9d\xa2\x3a\x71\x45\x5f\xd3\x84\x23\xbb\x38\x9b\ +\xd3\x3f\x3f\x9d\x5b\x7f\xbc\x95\x5b\xe6\xdd\xc2\x79\x5f\x9e\xc7\ +\x4d\x73\x6f\xe2\xf7\xfc\xdf\x9b\xff\x05\xec\x25\xd9\xd9\x26\xb7\ +\x64\x6f\xdb\x8e\x35\x06\x55\xb8\xf9\xe6\xfe\xbc\xf7\xde\xde\xdf\ +\x33\x3f\xdf\xc9\xc6\x8d\x51\x7b\x3c\xb6\x6d\x73\xe1\xf1\xec\x9f\ +\x75\x0b\x13\x12\x12\x78\xf0\xc1\x07\x1d\xe7\x9e\x7b\xae\x95\x31\ +\xdb\x08\xac\x6d\x59\x0b\x0b\x0b\x8b\xda\x89\x04\x4a\x1b\x75\x85\ +\x32\x01\xe1\xe7\x90\xe7\xd2\x79\x94\x09\xe4\x02\xe9\x18\x6f\x5d\ +\xa0\x7e\xd7\x6a\xe0\x26\x4d\xd7\xff\x35\xdd\xd4\xc6\x71\x75\xbf\ +\xab\x59\xb3\x6b\x0d\x3f\x6e\xfb\x91\xdc\xd2\x5c\x76\x7b\x76\x73\ +\xe7\xe0\x3b\xf9\x7c\xd3\xe7\xfc\x96\xf7\x5b\x83\xd6\x18\xdf\x7f\ +\x3c\xc9\x91\xc9\xbc\xb8\xf2\x45\xf2\xca\xf2\xf8\x69\xdb\x4f\x00\ +\xd8\xc5\xce\xd0\xa4\xa1\x0c\x6c\x3f\xb0\x25\x5f\x42\x93\xd8\xb6\ +\x6d\x1b\xed\xda\xb5\x23\x22\xa2\xf5\xb6\x8c\x45\xa0\x6b\xd7\x32\ +\x5e\x7f\xbd\x33\xe7\x9f\xbf\x1d\xbb\xbd\xe9\x2e\xbc\x37\xde\x48\ +\x61\xda\xb4\xd0\x65\xdf\x0e\x3b\x6c\x37\xd7\x5d\xb7\x99\xe1\xc3\ +\x0b\x9a\xbc\xfe\xbe\x46\x74\x74\x34\x0e\x87\x83\xdd\xbb\x77\xa7\ +\x00\xb9\xe1\xb6\xa7\xad\x20\x6a\xf9\x89\x2d\x2c\x2c\x2c\x6a\x90\ +\x91\x91\xe1\xc2\x6c\xa3\x5e\x90\x96\x96\xf6\x41\x73\xaf\x2f\x13\ +\xa5\x13\xd0\x09\x1f\x9b\x35\x5d\x5b\x34\xda\x5e\x44\x3a\x01\xd9\ +\xff\xf9\xcf\x7f\x6a\x64\x88\xe6\x96\xe6\x52\x54\x51\x44\xb7\x98\ +\x6e\x7b\x55\x93\x2e\xbf\x2c\x9f\xed\xa5\xdb\x89\x73\xc6\xd1\x21\ +\xb2\x03\x4e\xdb\xbe\xd9\xdd\xec\xe3\x8f\x3f\x26\x29\x29\x89\x63\ +\x8f\x3d\xb6\x55\xef\xbb\x75\x6b\x04\x17\x5f\x3c\x98\x7b\xef\x5d\ +\xc7\x99\x67\x36\x5d\xa3\x3c\xfb\x6c\xb7\x5a\xc5\x1d\x40\x64\xa4\ +\x8f\xd7\x5f\x5f\x4a\xd7\xae\x8d\xfb\x4e\xb2\xaf\xb2\x7e\xfd\x7a\ +\x76\xee\xdc\xc9\x5b\x6f\xbd\x75\xf2\x9c\x39\x73\xbe\x0d\xb7\x3d\ +\x6d\x05\xcb\x73\x67\x61\x61\x61\x11\x1a\x3b\xa6\xc6\xdd\x96\xfa\ +\x26\x36\x05\xfd\x97\x6e\x03\xb6\xd5\x3b\xb1\x79\x18\x69\xb7\xdb\ +\x7d\x03\x07\x0e\xac\xa1\xde\x3a\x44\x76\xa0\x03\x7b\xbf\xe3\x95\ +\x18\x91\x48\x62\xc4\xbe\x11\xf7\x9e\x59\x9c\xc9\xca\xfc\x95\xac\ +\xcc\x5f\xc9\xfa\x82\xf5\x74\x8b\xed\x46\xff\xc4\xfe\xf4\x8b\xeb\ +\x47\x6e\x6e\x2e\x87\x1e\x7a\x68\xab\xdb\x94\x9a\x5a\xc6\xa9\xa7\ +\xe6\x31\x6d\x5a\x97\xbd\x12\x77\xc1\x5c\x77\xdd\x16\xfe\xfc\xe7\ +\x2c\xd6\xac\x89\xe6\x9f\xff\xec\x4d\x56\x56\x04\xa5\xa5\x36\x7e\ +\xfe\x39\xa1\x52\xdc\xa9\x42\x66\x66\x24\x6b\xd6\x44\x91\x97\xe7\ +\xa4\xbc\xdc\x46\x72\x72\x39\xbd\x7b\x17\xd3\xa3\x87\x99\x53\x5e\ +\x6e\x63\xd9\xb2\x58\x00\x12\x13\x3d\x1c\x7c\x70\x55\x57\x0d\xaf\ +\x57\x58\xb2\xc4\x84\xbc\xc5\xc5\x55\xd0\xa7\x4f\x55\x95\x9e\xdc\ +\x5c\x27\x2b\x57\xc6\x92\x95\x15\x41\x87\x0e\xe5\xf4\xe9\x53\x5c\ +\x43\x54\x6e\xd9\x12\xc9\xf6\xed\xa6\x66\x77\xdf\xbe\x45\xa8\xc2\ +\xc2\x85\xf1\xe4\xe7\x3b\x19\x3c\xb8\x90\x9e\x3d\xeb\xee\xe0\x11\ +\x1b\x1b\xcb\xce\x9d\x3b\x51\xd5\xfa\x5a\x00\x5a\x04\x61\x89\x3b\ +\x0b\x0b\x0b\x8b\x10\xa4\xa5\xa5\x95\x00\xe7\x84\xdb\x8e\x66\xe2\ +\xf8\x3e\x7d\xfa\x78\x22\x23\x23\x5b\x7c\x2f\x72\xc6\xba\x19\xcc\ +\xdc\x3c\x93\x53\xba\x9e\xc2\x49\x9d\x4f\x22\x25\xba\x75\x12\x17\ +\xd6\x15\xae\xe3\x99\x65\xcf\xb0\x6c\xe7\x32\x0a\xca\x43\x6f\x4b\ +\xa6\x78\x52\x38\xdb\x77\x36\xcf\x6e\x7e\x96\xbf\xb5\xff\x1b\x87\ +\xb6\x6b\x5d\x91\x77\xd1\x45\xd9\x8c\x1f\x7f\x28\x1b\x36\x44\xd5\ +\x2b\x6a\x1a\x82\xdd\xae\x44\x46\xfa\x18\x38\x70\x37\x47\x1f\xbd\ +\x8b\xf7\xdf\x37\xfa\xc7\xe1\xa8\xda\x91\x5b\xb1\x22\x96\xbf\xfd\ +\x2d\xf4\xeb\x1c\x35\x2a\x8f\x07\x1e\xf8\x03\xa7\xd3\x47\x7a\xfa\ +\x41\x6c\xde\x1c\x49\xfb\xf6\x1e\x3e\xfe\x78\x51\xe5\x1a\xf3\xe7\ +\xc7\x73\xcb\x2d\x26\xb9\x7b\xdc\xb8\x2d\xf4\xe9\x53\x8c\xcf\x07\ +\xff\xfd\x6f\x57\xde\x78\xa3\x33\x1e\x4f\xd5\xf7\x05\x11\x38\xfb\ +\xec\x1c\x6e\xbf\x7d\x23\x51\x51\x5e\x00\xa6\x4f\x4f\x61\xc6\x0c\ +\x13\x6b\x78\xe3\x8d\x9b\x78\xf3\xcd\xce\xe4\xe5\x39\x2b\xed\xbf\ +\xe7\x9e\xba\x3d\x99\xed\xdb\xb7\xe7\x8a\x2b\xae\xa0\xa8\xa8\x68\ +\xff\x70\x45\xb6\x12\x56\x42\x85\x85\x85\x85\xc5\x7e\x8e\xd3\xe9\ +\x3c\x65\xc4\x88\x11\xad\x12\x64\xd6\x27\xa1\x0f\x5d\x63\xbb\xf2\ +\xc2\xef\x2f\x70\xfe\x57\xe7\x33\x6e\xce\x38\xde\x5a\xfb\x16\xd9\ +\xc5\x0d\x69\xcf\xdb\x78\x7c\xea\xe3\xb5\xd5\xaf\x71\xe5\x77\x57\ +\x32\x6f\xdb\xbc\x1a\xc2\x4e\xa8\x4a\x34\x48\xf1\xa4\x50\x68\x2f\ +\x64\x5e\xfe\x3c\xc6\xcf\x19\xcf\xb3\xcb\x9f\xc5\xe3\xf3\xb4\x88\ +\x5d\xa1\x38\xf4\xd0\x22\xa2\xa3\xbd\x2c\x58\x10\xdf\x6c\x6b\xfa\ +\x7c\xb0\x7a\x75\x0c\x3f\xff\x5c\x55\x0a\xee\x98\x63\xf6\x6c\x6f\ +\xdc\xb5\x6b\x29\x63\xc6\x64\x73\xf3\xcd\x9b\xb8\xf2\xca\xcc\x4a\ +\xef\xdb\xb7\xdf\xb6\x67\xfa\xf4\x14\x44\x60\xcc\x18\xe3\x44\xce\ +\xcb\x73\xf2\xc3\x0f\xed\x2a\xaf\xfd\xfa\xeb\x24\xc0\x64\xfd\x9e\ +\x7d\xb6\x11\x61\x6f\xbf\xdd\x99\x57\x5e\x49\xc5\xe3\xb1\x11\x11\ +\xe1\xe3\xd4\x53\x77\x10\x17\x57\x81\x2a\x7c\xf2\x49\x72\xad\x5d\ +\x39\x9e\x79\xa6\x3b\x3e\x9f\x89\x0d\x04\xe3\x15\x7c\xfa\xe9\xee\ +\x78\xbd\xb5\x27\x83\xd8\xed\x76\x4a\x4a\x4a\x2a\xca\xcb\xcb\xad\ +\x5a\x77\x8d\xc0\xf2\xdc\x59\x58\x58\x58\xec\xc7\x88\x48\x3b\x11\ +\xe9\x3f\x74\xe8\xd0\x56\xb9\xdf\x90\xa4\x21\x0c\x49\x1a\x42\xb9\ +\xaf\x9c\x1f\xb7\xfd\xc8\xb7\x99\xdf\xf2\xc2\xef\x2f\xf0\xf4\xb2\ +\xa7\x39\x24\xf1\x90\x66\xf5\xe8\x6d\x2c\xdc\xc8\xfd\x0b\xef\x67\ +\xf9\xce\xe5\x95\x63\x7d\x13\xfa\x32\x38\x69\x30\xfd\x13\xfb\xd3\ +\x3f\xb1\x3f\x3d\x62\x7b\xb0\xb5\x68\x2b\x2b\xf3\x57\xb2\x6e\xf9\ +\x3a\x76\xec\x36\x95\x66\x7c\xea\x63\xda\x9a\x69\xfc\x90\xfd\x03\ +\xff\x3c\xfc\x9f\x0c\x48\x1c\xb0\xd7\xf6\xd4\x87\xcd\xa6\x0c\x1e\ +\x5c\xc8\xfc\xf9\xf1\x5c\x78\xe1\xde\xef\xc8\x3f\xfb\x6c\x37\x9e\ +\x7d\xb6\xaa\x52\x4f\xe7\xce\x65\xb8\xdd\xeb\x49\x4e\x2e\xaf\x1c\ +\xeb\xdf\xbf\x88\x77\xdf\x5d\x02\x18\x31\x55\x50\xe0\xe0\xa4\x93\ +\xf2\x18\x3b\xf6\x30\x7c\x3e\xe3\x99\xfb\xcb\x5f\xb2\x38\xeb\xac\ +\x1c\x32\x32\xba\x52\x5c\x6c\xe7\xc3\x0f\x93\x39\xf1\xc4\x3c\x2a\ +\x2a\x84\xd9\xb3\x8d\xd0\x1b\x3e\x7c\x17\x29\x29\x65\xf8\x7c\xf0\ +\xc2\x0b\xa9\x95\xeb\xbf\xf9\xe6\x52\x52\x53\x4b\x29\x2e\xb6\x73\ +\xde\x79\x43\x29\x2c\xb4\xf3\xe1\x87\x1d\x19\x3b\x76\x2b\x1d\x3b\ +\x56\xd9\x01\x30\x74\x68\x01\x4f\x3c\xb1\x8a\xa8\x28\x1f\xd7\x5e\ +\x7b\x08\x4b\x96\xc4\xb1\x73\xa7\x93\xec\xec\x08\x52\x53\x6b\x77\ +\xcc\xc5\xc6\xc6\x7a\x4b\x4b\x4b\xdb\xd5\x3a\xc1\xa2\x06\x96\xb8\ +\xb3\xb0\xb0\xb0\x08\x41\x46\x46\x46\x02\x70\x1c\xf0\x4d\x5a\x5a\ +\x5a\x5b\xde\x12\x3a\x0e\x60\xd0\xa0\x41\xad\x7a\x53\x97\xcd\xc5\ +\x09\x9d\x4f\xe0\x84\xce\x27\xb4\x88\xd0\x5b\x5b\xb0\x96\xb1\xb3\ +\xc7\x52\xe6\x35\xa5\x03\xa3\xec\x51\xdc\x78\xd8\x8d\x5c\x70\xd0\ +\x05\x7b\x78\xeb\x00\x7a\xc4\xf5\xa0\x47\x5c\x0f\xf0\xeb\xa0\x11\ +\x5b\x46\xf0\xd8\x92\xc7\x28\xf4\x14\xb2\xbe\x70\x3d\xe3\x66\x8f\ +\x63\xca\xc8\x29\xad\x92\xdd\x7b\xd2\x49\x79\xfc\xf1\x47\x74\x8b\ +\xac\x1d\x17\xe7\x25\x31\x71\x4f\x4f\xa4\xc7\x23\x3c\xf7\x5c\x37\ +\xbe\xfa\x2a\x89\x9c\x1c\x57\x8d\x5a\x7b\xd9\xd9\xc6\xa1\x1b\x1d\ +\xed\xe5\xec\xb3\x73\x78\xe7\x9d\x14\x7e\xf9\x25\x91\xec\xec\x08\ +\xd6\xaf\x8f\xa2\xa0\xc0\xc8\x84\x73\xcf\xcd\x01\x20\x2b\x2b\x82\ +\x92\x12\x53\xdf\xf0\xa0\x83\x4a\x2a\x45\x59\x74\xb4\x97\xc3\x0f\ +\x2f\x60\xd6\x2c\xa3\xc1\xd6\xad\x8b\xae\x21\xee\x46\x8d\xca\x23\ +\x2a\xca\x07\x40\xf7\xee\xa5\x95\xb1\x7c\x3b\x76\x38\xeb\x14\x77\ +\xf1\xf1\xf1\xe4\xe6\xe6\x5a\xe2\xae\x11\x58\xe2\xce\xc2\xc2\xc2\ +\x22\x34\x03\x30\x09\x15\x5d\x20\x44\xd7\x88\xb6\xc3\xf1\x07\x1d\ +\x74\x50\x79\x6c\x6c\x6c\xd8\xda\x45\x34\xb7\xd0\xf3\xaa\x97\xfb\ +\x17\xde\x5f\x29\xec\x06\x25\x0d\x62\xd2\xb0\x49\xa4\xc6\xa4\xd6\ +\x73\xa5\xe1\xf4\xae\xa7\x73\x78\x87\xc3\x79\x68\xd1\x43\xcc\xdb\ +\x36\x0f\xaf\x7a\x79\x60\xe1\x03\x4c\x3b\x69\x5a\x8b\x77\xd5\x08\ +\x88\xa4\xe6\xe0\xea\xab\xb7\x72\xc6\x19\xb9\x7c\xf2\x49\x47\x5e\ +\x7f\xbd\x33\xab\x57\x47\x33\x61\x42\x5f\xde\x78\xe3\xb7\x4a\x11\ +\x95\x9e\x7e\x10\x5f\x7e\x69\x12\x66\x7a\xf6\x2c\x61\xf0\xe0\x42\ +\x22\x23\x7d\xcc\x98\xd1\x09\x9f\x4f\xf6\xd8\x12\xbd\xf8\xe2\x6d\ +\xcc\x98\x91\x82\xcf\x67\xb6\x57\xb3\xb3\x4d\x22\x44\x7c\x7c\x05\ +\x27\x9c\x60\x12\xba\x4b\x4b\xab\xa2\xb9\xe2\xe2\x2a\xf6\xb0\x27\ +\x36\xb6\xea\x38\x78\x5e\x80\xe0\x64\x8c\x88\x08\x5f\xe5\xf3\xba\ +\x8a\x76\xa8\x2a\x69\x69\x69\xae\xcf\x3e\xfb\x6c\x70\xbd\xbf\x10\ +\x8b\x4a\x0e\xb8\x98\x3b\x11\x69\x2f\x22\xfd\xfd\x8f\xe6\x0b\x7c\ +\xb0\xb0\xb0\xd8\xdf\x08\xb8\x57\xda\xb2\xd7\x0e\xa7\xd3\x79\x72\ +\x6b\xc5\xdb\x35\x84\x80\xd0\x9b\x7c\xf8\x64\x66\xfe\x69\x26\x0f\ +\x1f\xf1\xf0\x1e\x31\x7a\x7f\x9b\xfd\xb7\x7a\x63\xf4\x5e\x5d\xfd\ +\x2a\xab\xf2\x57\x01\x30\xac\xc3\x30\xa6\x1c\x37\xa5\xc1\xc2\x2e\ +\x40\x87\xc8\x0e\x3c\x71\xf4\x13\x9c\x9c\x7a\x32\x60\x7a\xed\x3e\ +\xb3\xfc\x99\xa6\xbf\xb0\x30\x10\x1d\xed\xa3\x47\x8f\x52\x6e\xbc\ +\x71\x13\x47\x1f\x6d\xe2\xec\x32\x33\x23\x78\xf5\xd5\xaa\xdf\xc5\ +\x4f\x3f\x99\x0c\xe6\xb8\x38\x2f\xaf\xbe\xba\x0c\xb7\x7b\x3d\x7f\ +\xfa\x53\x2e\x3e\x5f\xcd\x38\xb7\x6e\xdd\x4a\x2b\xd7\xf9\xf8\xe3\ +\x64\xe6\xcc\x31\x1d\x46\x4e\x3f\x3d\x17\xa7\x33\xe0\x71\x2b\xc3\ +\x66\x33\x6a\x6c\xc5\x8a\x58\x4a\x4a\xaa\x64\x44\x70\x2c\x61\x8f\ +\x1e\x35\x13\x46\x44\x42\x3f\xaf\x0b\x11\x21\x3a\x3a\x5a\xa2\xa3\ +\xa3\x1b\x56\x5d\xdb\x02\x00\x87\x88\x5c\x03\x8c\xaa\x63\xce\xfb\ +\xaa\xfa\x4e\x6b\x19\xd4\x0a\x8c\x05\x1e\xf5\x3f\xff\x2b\xf0\x46\ +\x18\x6d\xb1\xb0\xb0\xd8\x77\x69\xf3\xe2\x4e\x44\x62\x44\x64\x50\ +\x6b\xc5\xdb\x35\x96\xa6\x78\xf4\xd6\xec\x5a\xc3\xcb\xab\x5e\x06\ +\x20\xda\x11\xcd\xbd\xc3\xee\xdd\xab\xfa\x7c\x77\x0d\xbe\x8b\x45\ +\xb9\x8b\xc8\x2b\xcb\xe3\xdd\x75\xef\x72\x62\x97\x13\x39\xbc\xc3\ +\xe1\xcd\xf2\xfa\x6a\xe3\x9d\x77\x52\xd8\xb0\x21\x8a\xbb\xee\x5a\ +\xdf\x6c\x6b\x5e\x7f\xfd\x66\x7e\xfa\x29\x11\x55\x78\xe7\x9d\x4e\ +\x5c\x76\x59\x16\x71\x71\x15\x44\x45\xf9\xd8\xb5\x0b\x76\xef\xb6\ +\xf3\xcd\x37\xed\x49\x4a\xf2\xf0\xe2\x8b\xb5\x0b\xe1\x31\x63\xb2\ +\x99\x37\x2f\x91\x9c\x1c\x57\xe5\x58\xb0\xb7\xd1\xe9\xf4\x71\xc6\ +\x19\x3b\xf8\xfc\xf3\x0e\x54\x54\x08\x37\xdc\x30\x80\x73\xcf\xcd\ +\x61\xf6\xec\x76\x64\x65\x99\xef\x10\x03\x07\x16\x86\x14\x77\x4d\ +\xc5\xeb\xf5\xe2\x74\x3a\xad\x9d\xc6\x46\xe0\x00\x46\x00\x97\xd4\ +\x31\xe7\x0f\x60\x7f\x12\x77\x16\x16\x16\x16\x0d\x21\x0f\xf8\x9c\ +\xaa\x7e\xb0\x6d\x91\x63\x54\xd5\x3e\x64\xc8\x90\x70\xdb\x51\x2f\ +\x0d\x15\x7a\xdf\x6c\xfd\x86\x0a\x9f\xd9\xfe\xbb\xe5\xb0\x5b\xe8\ +\x1c\xdd\xb9\x41\xeb\x7b\x3c\x1e\x9c\xce\x9a\x85\x95\x13\x5c\x09\ +\xb8\x87\xba\xb9\xf3\xa7\x3b\x51\x94\xc7\x96\x3c\xc6\x5b\x27\xbf\ +\xd5\xac\xaf\xad\x3a\x79\x79\x8e\xca\xba\x72\xcd\x45\x9f\x3e\xc5\ +\x1c\x7f\xfc\x4e\x66\xcf\x6e\x47\x71\xb1\x9d\xb7\xdf\x4e\x61\xfc\ +\xf8\x2d\x5c\x7c\x71\x36\xff\xf9\x4f\x77\x54\xe1\xfe\xfb\x7b\x01\ +\x70\xdc\x71\x3b\x71\x3a\x35\x64\xcb\xb2\x23\x8f\xdc\x45\x8f\x1e\ +\xa5\x6c\xdc\x68\x1c\x65\xfd\xfb\x17\xed\xb1\x9d\x0a\x70\xdb\x6d\ +\x1b\xd8\xbc\x39\x82\xa5\x4b\xe3\x58\xb1\x22\x96\x15\x2b\xaa\x5e\ +\x4b\xf7\xee\xa5\x4c\x9a\xb4\x6e\x8f\x9e\xba\xf5\xb1\x7a\x75\x0c\ +\x83\x07\x17\xd6\x7a\xde\x2f\xee\xec\x0d\x5f\xb1\x71\x88\x5b\xee\ +\x45\x98\xa2\x0f\x69\xf3\xed\x99\x87\x99\xea\x4a\x78\x1e\xb0\xa6\ +\xda\xd8\xc2\x56\xb2\xc5\xc2\xc2\xc2\x62\x9f\x21\x2d\x2d\x6d\x1e\ +\x70\x56\xb8\xed\xd8\x4b\x8e\x4f\x4d\x4d\x2d\x4b\x4c\x4c\xdc\x67\ +\xb6\x65\x1b\x42\x5d\x42\x2f\x10\x67\x37\xb0\xfd\x40\xce\xeb\x79\ +\x5e\xad\x6b\xa8\x2a\xab\x0b\x56\xb3\xa1\x70\x03\x1d\x7c\x1d\x58\ +\xfc\xd5\x62\x46\x8f\x1e\x4d\x52\x52\x52\x8d\xb9\x23\x53\x46\x72\ +\x42\xe7\x13\x98\x9d\x35\x9b\xf5\x85\xeb\xd9\x55\xbe\x8b\x04\x57\ +\xcb\x55\xde\x88\x8d\xf5\x52\x54\xd4\x34\x6f\xe3\x11\x47\x14\x10\ +\x11\x61\xb6\x45\xab\x0b\xa2\xeb\xaf\xdf\x5c\x29\xc4\x02\xf1\x70\ +\x97\x5d\x96\x45\xe7\xce\x65\x7c\xff\x7d\x3b\x44\xe0\xd0\x43\x77\ +\x33\x7a\xf4\x76\xa6\x4d\xeb\x42\x45\x85\x90\x90\xb0\x67\x02\x86\ +\x08\x5c\x78\xe1\x36\x9e\x78\xa2\x07\x00\xe7\x9c\x53\x53\xef\xc4\ +\xc5\x79\xf9\xef\x7f\x57\xf0\xd5\x57\x49\x2c\x5b\x16\xcb\xf6\xed\ +\x11\xb4\x6f\xef\xa1\x57\xaf\x62\xce\x3d\x37\xa7\x72\x0b\x17\x4c\ +\x59\x96\x84\x04\x63\x4b\xa7\x4e\x65\x35\xc6\x37\x6c\x88\xe4\xf1\ +\xc7\x7b\xb0\x60\x41\x1c\x37\xdd\xb4\x89\xd4\xd4\x9a\xdf\xa5\xde\ +\x79\xe7\x9d\x8a\xdf\x7e\xfb\xad\x25\x1b\x15\xff\x0d\xe5\xef\xe2\ +\x96\xc9\xe4\xf1\x8c\x3e\xaf\xad\x57\x1f\xa7\x85\xa8\x2e\xee\xa6\ +\xaa\xea\x8b\xa1\x26\x8a\xc8\x18\xe0\xfa\xa0\x79\xaf\xfa\xc7\x2f\ +\x00\x6e\xf6\x8f\xbf\x1e\xb8\x5e\x44\x62\x80\xbb\x81\x53\x81\x3e\ +\xc0\x76\xe0\x57\xe0\x1e\x55\xdd\x1c\xb4\xee\xdd\xc0\x99\xfe\xc3\ +\x1b\x81\x1b\xfc\xc7\xdb\x80\x0c\x55\x7d\x45\x44\xce\x00\xee\x00\ +\x06\x02\x4b\x80\xdb\x55\x75\x59\xd0\x1a\x1f\x03\xf1\xfe\x6b\xee\ +\x00\x1e\x03\x8e\x05\xb2\x81\xff\xaa\xea\x7f\x1b\xf2\xcb\x10\x91\ +\xa3\xfc\x36\x1f\x0a\x24\x02\x2b\x81\xd7\x81\x17\x34\xa8\x4f\x9b\ +\x88\x9c\xe7\xb7\xb3\x3f\x90\x80\xf9\x86\xbf\x0a\xf8\x40\x55\x9f\ +\xaf\xe7\x1e\x37\x02\x17\xf9\x0f\xef\x54\xd5\x5f\x1b\x62\x9b\x85\ +\x85\x85\x45\x63\x71\x38\x1c\xa3\x8e\x38\xe2\x88\x36\x25\xec\xaa\ +\x13\x2c\xf4\x96\xef\x5c\xce\xdf\x66\xff\x0d\xa0\xce\xad\xd3\xdc\ +\xd2\x5c\x26\xcd\x9f\xc4\x82\xdc\x05\x00\xf4\x2b\xed\xc7\xb1\x1c\ +\x4b\x91\xb3\x88\x24\x6a\x8a\x3b\x80\xe1\xc9\xc3\x99\x9d\x35\x1b\ +\x80\x95\xf9\x2b\x39\xb2\xe3\x91\xcd\xfc\x4a\xaa\x88\x8e\xf6\x52\ +\x5c\xdc\x34\x47\xd4\x88\x11\xbb\x18\x31\x62\x57\xc8\x73\x3d\x7a\ +\x94\x30\x6e\x5c\xcd\x86\x2a\xa3\x46\xe5\x31\x6a\x54\xde\x1e\x63\ +\x57\x5d\xb5\x35\xe4\x1a\x5e\xaf\xb0\x72\x65\x0c\x00\xed\xda\x79\ +\x38\xe3\x8c\xd0\x05\x86\x45\xe0\xb4\xd3\x76\x70\xda\x69\x3b\xea\ +\xb4\xf7\xe8\xa3\xf3\x2b\xe3\xf8\x42\x8d\xcf\x9e\xdd\x8e\xaf\xbf\ +\x4e\x62\xd6\xac\xf6\xcc\x9d\x9b\xc8\xa5\x97\x66\x73\xd5\x55\x99\ +\x44\x47\x7b\x2b\xe7\x16\x15\x15\x69\x51\x51\x51\x45\x8d\x45\x9a\ +\x97\x04\xe0\x09\xda\x73\xad\xfc\x43\x6e\xd7\x87\xf4\xf3\x16\xbe\ +\x5f\x8b\x52\x5d\xdc\x1d\xec\x17\x38\xc1\x2c\x55\xd5\x22\xe0\x03\ +\xe0\xef\xc0\x11\xc0\x70\x11\x99\x0b\x94\x00\x2f\x02\xed\x80\x15\ +\xc0\x9b\x00\x22\x92\x0c\xfc\x02\xf4\xf4\xaf\xe1\x01\x92\x30\xd9\ +\x67\xe7\x8b\xc8\x48\x55\x5d\xe2\x3f\xd7\x1f\x38\xc1\xff\xfc\x7d\ +\x8c\x10\x04\xe8\x01\x8c\x10\x91\x81\x18\xd1\x17\x08\x00\x38\x15\ +\xf8\x52\x44\x7a\xa9\x6a\x20\x16\xe6\x58\xa0\x3d\x50\x80\x49\xfb\ +\x0f\x34\xde\x4b\x05\x9e\x17\x91\x04\x55\x0d\xc4\xd9\x85\x44\x44\ +\x6e\x03\x1e\x87\xca\x1c\x7a\x0f\x30\xd2\xff\x38\x11\xf8\x8b\x7f\ +\xde\xa9\xfe\xdf\x45\x60\xde\x2e\xff\xeb\xec\x09\x38\x81\x3a\xc5\ +\x1d\xd0\x3b\xe8\xf5\xb6\xaf\x67\xae\x85\x85\x85\x45\x93\x10\x91\ +\x08\x9b\xcd\x36\xa2\x2d\x6c\xc9\x36\x94\x35\xbb\xaa\x36\x96\xfa\ +\x27\xf6\x0f\x39\xc7\xa7\x3e\xdc\xbf\xb8\x59\x9a\xb7\xb4\x72\xac\ +\x53\x45\x27\xb6\x39\xb6\x31\x61\xfe\x04\x5e\x3d\xf1\xd5\x90\x7d\ +\x6f\x83\xd7\x6b\x69\x71\x17\x13\xd3\x74\x71\xd7\x92\x4c\x98\xd0\ +\x87\x9f\x7f\x4e\xac\x4c\x92\xb8\xfd\xf6\x8d\xc4\xc4\x78\xeb\xb9\ +\xaa\xf9\xf0\x78\x6c\xbc\xf6\x5a\x17\x3e\xfb\x2c\x99\xb4\xb4\xcd\ +\x9c\x75\x56\x4e\x83\x13\x2f\x9a\x91\x7e\x28\x9f\x89\x5b\x66\x22\ +\xdc\xa6\x0f\xe9\xca\x56\xb7\xa0\x19\xa8\x2e\xee\xdc\xfe\x47\x30\ +\x23\x80\xf9\xaa\xea\x11\x91\x3f\x03\x8b\x30\x0a\xf7\x55\xa0\x18\ +\x23\xec\x4a\x80\x31\xaa\x1a\xd8\x98\x7f\x8a\x2a\x61\x77\x37\xf0\ +\x1f\x60\x18\xf0\x0d\x10\x07\xbc\x80\x11\x89\xd5\x89\x02\x2e\x03\ +\x06\xf9\xaf\x13\xe0\x76\x4c\xdc\xcb\xd3\xc0\x64\xe0\x48\x8c\x78\ +\x1b\xe5\x1f\x0f\x26\x1e\xf8\x09\x38\x1f\x38\x0a\x48\xc7\x04\x45\ +\xdf\x2b\x22\x2f\xab\x6a\xc8\xaf\x18\x22\xd2\x0f\x78\xd8\x7f\xbf\ +\x35\xfe\xeb\xb7\x00\xff\x06\xae\x02\x2e\x15\x91\xe9\xaa\xfa\x11\ +\x46\x5c\x0a\x26\xc8\xfa\x60\x55\xcd\x12\x91\x28\xff\xfd\x7a\x87\ +\x5a\xdf\xc2\xc2\xa2\xed\x91\x91\x91\xd1\x07\x48\x4d\x4b\x4b\x9b\ +\x15\x6e\x5b\x9a\xc8\x11\x3e\x9f\xcf\xb9\xaf\x26\x53\x34\x85\x15\ +\x3b\x57\x54\x3e\xaf\x4d\xdc\x2d\xc9\x5b\xb2\x87\xb0\x03\xd3\x99\ +\x62\x6d\xc4\x5a\xd6\x15\xac\xe3\xf3\xb5\xb3\x39\xa2\xc3\xb1\x35\ +\xae\x8b\xd3\x6e\xd8\xc4\x86\x4f\x7d\x2c\xce\x59\xce\x69\xc9\xcd\ +\x97\x10\x50\x9d\x32\x2d\xa1\xac\xcc\xc6\x96\xdc\x52\xec\xf6\x3a\ +\xea\x80\xb4\x32\xf9\x05\x60\xb3\xf9\x38\x6c\x50\x01\x47\x1d\x93\ +\xcb\x61\xc3\xb7\x90\xb5\xb3\x65\xef\xb9\xb3\x28\xa6\xc6\xd8\x8e\ +\x1d\x4e\x1e\x7c\xf0\x60\xa6\xcf\xe8\xc0\xf5\x37\xaf\xc6\xeb\xf4\ +\x42\x1c\x91\x32\x59\x5a\xaa\x79\x71\xa8\x3d\xf2\x33\x50\x4e\x91\ +\x09\xf2\x0c\x51\x4c\xd6\x49\x5a\xd3\xfd\xb8\x0f\xd3\xa8\xec\x13\ +\x55\x5d\x2f\x22\xe3\x31\x09\x16\xc7\x04\x9d\xba\x49\x55\x97\x07\ +\x1d\x07\xe2\x54\xf2\x31\x09\x19\xa7\xfb\x8f\x7f\x07\x86\x60\x3c\ +\x72\x9d\x54\xb5\x7a\x89\xee\xff\xa8\xea\x9b\x7e\xaf\xe0\xdd\x41\ +\xe3\x63\x55\x75\x9b\x5f\x84\x05\xbe\x4e\x85\xee\x6f\x02\xb7\xa9\ +\xea\x0a\xe0\x17\x11\x39\xcd\x6f\x4b\x9c\xdf\xde\x4f\x6a\xb9\xe6\ +\x54\xaa\x3c\x83\xdf\x63\xbc\x87\x7d\x80\x65\x41\x73\xce\x01\x3e\ +\xc2\x88\x47\x80\x48\xe0\x05\x11\x99\x8d\x11\xbc\xbf\xaa\xea\x77\ +\xb5\xac\x1f\xcc\x14\x60\xa6\xff\xf9\x82\x06\xcc\xb7\xb0\xb0\x08\ +\x0f\x7f\x06\x2e\x05\x0e\x09\xb7\x21\x4d\x64\x78\x7c\x7c\x7c\x79\ +\xc7\x8e\x1d\x5d\xf5\x4f\x6d\x1b\xac\x2f\x34\xd9\xa5\x51\xf6\xa8\ +\x5a\xeb\xe1\xad\x2b\x58\xb7\xc7\x71\x94\x2f\x8a\x78\x6f\x3c\xd9\ +\x4e\x53\x5a\x25\xfd\x39\x81\x1f\x4f\x0c\x7d\x83\xeb\x7a\x42\xe2\ +\x3a\x7e\x5c\xb5\x8d\xf3\xff\x5e\xcb\x9c\x66\xe4\xa2\xb3\x4f\xa8\ +\x7f\x52\x18\x58\xf6\x5b\x22\xcb\x7e\x4b\xe4\xc5\x29\xe1\xf5\x57\ +\xac\x59\x15\xcf\x6d\x37\x0c\x67\xf8\xe9\x0f\x39\xcf\xbd\xf8\xa5\ +\xf1\x1f\xe7\x7f\x3c\xbe\x95\x4d\x70\x20\xdc\x4a\x29\x67\x88\x5b\ +\x8e\xd1\x74\x6d\x61\xa9\xdb\x7c\x54\x17\x77\x37\x03\xd3\xaa\x8d\ +\xed\x11\xb1\xa9\xaa\x33\x44\x64\x0e\x70\xbc\x7f\x68\xb9\xaa\xbe\ +\x14\x38\xef\xdf\x92\x0d\x14\xbb\x49\x04\xde\xab\xe5\xde\xfd\x31\ +\x31\x72\xc1\x04\x84\x53\x70\xd0\xc0\x86\x20\x11\x18\x1c\x68\x10\ +\xaa\xe6\x4d\xa1\x5f\xd8\x05\xf8\x85\x2a\xa1\x79\x70\x2d\x76\xc0\ +\x9e\x1e\xb7\xb1\xfe\x47\x28\x7b\xc1\x08\xc4\x15\x98\x37\xfc\xb3\ +\x82\xd6\x2f\x11\x91\x7b\x54\xf5\x89\x3a\xee\x83\xaa\xae\xc4\xc4\ +\xf2\x59\x58\x58\xec\xdb\xf8\xfc\x8f\xb6\xca\xca\x82\x82\x02\x57\ +\x61\x61\x21\x71\x71\x71\xe1\xb6\xa5\x59\xe8\x1c\xdd\x99\xa5\x79\ +\x4b\x29\xf1\x96\x90\x5f\x96\x4f\x62\x44\x4d\x47\x4e\x97\xe8\x2e\ +\x7b\x1c\xa7\x78\x52\x50\x94\xed\x8e\xed\x00\x9c\x7c\xca\x0e\x7a\ +\x9f\xfe\x61\x8d\xeb\x7c\x78\x79\xb9\x74\x33\x5e\xa0\x5b\x87\x68\ +\xfe\x74\x5f\xcd\x39\xcd\x45\x6e\x56\x22\xef\x3d\x7f\x22\x97\xdd\ +\xf6\x25\xb1\x09\x2d\xe7\x21\x6c\x0b\x6c\x58\xd9\x99\x2f\xdf\x0e\ +\xbd\x05\x1e\x1d\x57\xca\x99\x7f\xf9\x89\xbe\x5d\xe6\x6b\x4e\x6e\ +\xc7\x8d\x38\x48\x6b\x21\x33\x5e\x05\x3a\x86\x18\xaf\x00\x9e\x03\ +\xee\x6b\x4b\xc2\x0e\x6a\x8a\xbb\x12\xd5\xba\x5d\x8f\x22\x72\x16\ +\x26\x0e\x2d\xc0\xa1\x22\x72\xb5\xaa\x4e\xf5\x1f\xef\xc0\x6c\xd3\ +\x46\x01\x39\xc0\x3f\x6b\x59\x6a\x6d\x88\xb1\x02\x00\x55\xf5\x4a\ +\xd5\x46\x7b\xe8\xc8\xd1\xd0\xc4\x89\x48\x67\x55\x0d\x54\x93\xef\ +\x1b\x74\xae\xae\xae\xd5\xc1\x62\xf2\x35\xe0\xc7\x10\x73\xb6\xfb\ +\x6d\xf3\x88\xc8\x60\xe0\x34\x8c\x17\x71\x08\x70\x12\xc6\x3b\xf8\ +\x4f\x11\xc9\x50\xd5\x5a\xff\xb7\x8a\x88\x83\xaa\xdf\x7b\xb9\xaa\ +\xb6\xe5\x0f\x0f\x0b\x8b\xfd\x99\xc0\xfb\x58\x5b\x65\xae\x88\xe8\ +\x92\x25\x4b\xe4\xb8\xe3\x8e\x0b\xb7\x2d\xcd\xc2\x80\x76\x03\xf8\ +\xdf\x96\xff\x01\x26\x2e\xee\xa8\x4e\xd5\x43\xc4\x21\x29\x22\x09\ +\x87\xcd\x51\x59\x2e\xa5\x53\x45\x27\x76\x38\x76\xe0\x11\x0f\xed\ +\x22\xda\x71\xf7\xc9\x67\x10\xef\xaa\x59\xbf\x7e\xf5\xae\xd5\xbc\ +\xf0\x9d\x49\x92\x3c\xb9\xcf\x60\xae\x1e\xd0\xb0\x12\x2b\x4d\xa1\ +\xa4\xc4\xc6\xc9\x83\x7f\xe7\xb0\xc3\xda\xe3\x72\x1d\xd8\x1f\x01\ +\xb3\xa3\xda\xf1\xe5\xdb\x7b\x8e\xd9\x6c\xca\x05\x17\x6c\xe7\x9a\ +\x6b\xb6\x10\x1f\x1f\xc5\x97\x5f\x3a\xb0\x15\xd8\xf2\xf5\x79\x9d\ +\x19\x7a\x95\xbd\x43\xdc\x12\xa2\xe2\x32\x5f\x01\xb7\xea\x43\x7b\ +\x38\x8c\xda\x0c\xd5\xc5\xdd\xa1\xfe\xcc\xd4\x60\xb2\x55\x75\x31\ +\x80\x88\xa4\x62\x14\xae\x00\xbf\x61\xde\xfc\x8e\x04\x9e\x11\x91\ +\x9f\x54\xf5\x77\x55\xf5\x89\xc8\x2f\x98\xa4\x81\x64\x60\xad\xaa\ +\x7e\x15\x58\x4c\x44\x7a\x02\xe7\xa8\x6a\xcd\x94\x9e\xe6\xe1\x46\ +\x11\x99\x8c\x49\xde\x38\xc5\x3f\xa6\xd4\xbd\x05\x3a\x2f\xe8\x79\ +\x6f\x60\x9c\xaa\x49\x85\x16\x11\x3b\x70\x1e\x90\xe9\x3f\x3e\x14\ +\xc8\x57\xd5\xcf\xf1\xc7\xfc\x89\x88\x1b\x78\x08\x13\x8b\x78\x34\ +\xf0\x6d\x1d\xf7\x7a\x0c\xb8\xc5\xff\xfc\x0c\xe0\xcb\x06\xbf\x32\ +\x0b\x0b\x8b\xd6\x64\x35\x30\x27\xdc\x46\x34\x15\x55\x2d\x70\xb9\ +\x5c\xcb\x17\x2d\x5a\x74\xd8\xfe\x22\xee\x0e\x49\xac\xda\x21\x5f\ +\xb9\xab\xa6\xb8\x9b\x95\x39\x8b\xfb\x17\xde\x4f\x6a\x74\x2a\x85\ +\x9e\x42\xf2\xca\xf2\x48\xf1\xa4\x90\xed\xcc\x26\xc1\x95\xc0\xe4\ +\xc3\x27\x87\x14\x76\x40\x65\xc7\x0b\x80\x01\x89\x03\x5a\xc4\xfe\ +\x00\x51\x51\x3e\x86\x0d\x2b\x68\xd1\x7b\xb4\x55\x46\x8c\x28\xe0\ +\xd6\x5b\x37\xd0\xab\x57\x95\xde\xb2\xdb\xed\x78\x3c\x9e\xd6\xc9\ +\xec\x10\xd6\x02\xb7\xeb\x43\xfa\x71\xab\xdc\xaf\x85\xa8\x2e\xee\ +\x6e\xf5\x3f\x82\x79\x0f\xb8\xc8\x2f\x72\xde\xc2\x64\xbd\x96\x62\ +\x12\x1f\x8a\x81\xc5\x18\xaf\xd5\x74\x11\x39\xc2\x9f\xc1\x7a\x2b\ +\x66\x4b\xd4\x09\xfc\x4f\x44\x96\x60\x3c\x75\xbd\x30\xe5\x4c\x56\ +\x61\x92\x2c\x9a\x1b\x0f\x26\x56\x2f\x0d\x93\xe8\x11\xe0\x2d\x55\ +\xfd\xa3\xb6\x8b\x54\x75\x9e\x88\xbc\x89\xc9\x88\x3d\x06\xc8\xf5\ +\xc7\xd2\xc5\x00\x87\x61\xdc\xb5\x97\x63\xb6\x8d\xcf\x03\x1e\x14\ +\x91\xa5\xc0\x7a\x4c\xac\x5e\xc0\x93\x59\x0a\x2c\xc5\xc2\xc2\xa2\ +\xcd\x93\x96\x96\xf6\x29\xa6\xb7\x6c\x9b\xc5\xe3\xf1\x7c\x33\x7f\ +\xfe\xfc\x3e\x40\x9b\x2e\x87\x12\xa0\x5f\x62\xbf\xca\xa4\x87\xe5\ +\x79\x55\x61\xde\x3e\xf5\x91\xb1\x22\x83\x69\x6b\xa6\x71\x76\xf7\ +\xb3\xb9\x6b\xf0\x5d\x94\xfb\xca\xf9\x70\xd9\x1c\x4a\x72\x33\x49\ +\x4c\xe9\xcb\xa4\x93\x26\xd1\x2e\xa2\xf6\xde\xf3\xcb\x77\x56\xad\ +\x57\x5b\xb2\x46\x73\x91\x9b\xeb\x24\x22\x42\x6b\xf4\x66\x3d\x90\ +\x49\x4d\x2d\xe5\xe6\x9b\x37\x55\xf6\xb0\x0d\xe6\xe3\x8f\x3f\xf6\ +\xae\x5c\xb9\x72\xd1\xcb\x2f\xbf\xdc\x92\x26\x14\x02\xff\x22\x82\ +\x27\x75\x92\x96\xb7\xe4\x8d\x5a\x83\xc6\x54\x51\xbc\x8f\x2a\x11\ +\x33\x41\x55\x97\xa9\xea\x3a\x4c\x99\x12\x30\xa2\xed\x49\x00\xbf\ +\xa7\x6f\x24\x30\x17\xe3\x35\x1b\x0c\x5c\xe0\xff\xf9\x07\x50\xcd\ +\x09\xdb\x6c\x64\x63\x32\x5d\x83\xf9\x00\xb8\xb6\x01\xd7\xfe\x0d\ +\xb8\x07\xb3\x35\x1c\x8f\x49\xa0\x18\x85\x11\xae\x5f\x50\x25\xda\ +\x36\x60\x9a\x88\x0f\xc2\x08\xbd\x33\x81\x58\x4c\x96\xed\xc5\xaa\ +\xfb\x4f\x85\x6b\x0b\x0b\x8b\x36\xcf\xf7\x6b\xd6\xac\x71\x95\x94\ +\xec\x1f\x71\x5d\x91\xf6\x48\x7a\xc5\x9b\x2e\x0b\x3f\x64\xff\xc0\ +\xa2\xdc\x45\xe4\x97\xe5\x73\xd3\xdc\x9b\x78\x7b\xed\xdb\x4c\x18\ +\x32\x81\x7b\x86\xdd\x83\xcb\xee\x22\xd6\x19\xcb\x60\xc7\x70\x04\ +\x38\xb2\xd3\x45\x75\x0a\xbb\xb5\x05\x6b\xf9\x6c\xd3\x67\x80\xe9\ +\x39\xdb\x29\xaa\x53\x8b\xbe\x8e\x67\x9e\xe9\xce\xe4\xc9\xbd\x5a\ +\xf4\x1e\x6d\x85\xe8\x68\x2f\x37\xdc\xb0\x99\xb7\xdf\x5e\x1a\x52\ +\xd8\x01\x94\x95\x95\x51\x50\x50\xd0\x2c\x85\x85\xc5\x2d\x09\xe2\ +\x96\xeb\xc4\x2d\xdd\x82\x86\x5f\xc7\x46\x3f\x4d\xd7\xff\x6b\x6d\ +\x61\x27\x6e\x19\x21\x6e\xb9\xaa\xd9\xd7\x0d\xaa\xcd\xdb\x22\xf8\ +\xcb\x84\x1c\x84\x09\x4c\xce\xae\x2f\xa6\xaf\x89\xf7\xd8\x81\xa9\ +\x19\xb7\x59\x55\xbb\x8b\x09\xd8\xeb\x03\xe4\xa8\x36\x3e\x08\x52\ +\x44\x3a\x03\x9d\x30\xf1\x83\xd9\x81\x2d\xda\x6a\x73\x92\x31\x1e\ +\x3d\x27\x26\xb6\x30\x53\x5b\xfa\x97\x69\x61\x61\x61\xd1\x08\x44\ +\xa4\x23\xb0\xed\x3f\xff\xf9\x0f\x23\x46\xbd\x2b\xb9\xcb\x00\x00\ +\x20\x00\x49\x44\x41\x54\x8c\x08\xb7\x39\xcd\xc2\x9c\xac\x39\xdc\ +\xf5\xf3\x5d\x00\x24\x47\x25\x83\x82\x4d\x6c\xa4\x1f\x91\xce\x21\ +\xed\xf6\x4c\x6c\x5e\xb7\xce\xc3\xfd\xf7\x2b\x77\xdc\xd1\x9e\xc3\ +\x0e\xdb\x1d\x72\x3d\xaf\x7a\x19\x37\x7b\x1c\xbf\xe7\x9b\x06\x08\ +\x13\x86\x4c\x60\x74\xcf\xd1\x2d\xfa\x1a\xc6\x8e\x3d\x8c\xc1\x83\ +\x0b\xb8\xe5\x96\x4d\x2d\x7a\x9f\xfd\x85\x6b\xaf\xbd\xb6\x62\xc9\ +\x92\x25\x2f\xa8\xea\xf5\xd5\xcf\x89\x5b\xae\x00\x1e\xf1\x1f\x2a\ +\xe6\x73\x7b\x13\x66\x67\xed\x05\x4d\x37\x61\x65\x41\xf3\xfb\x61\ +\x92\x1a\xcf\xd4\xf4\x96\x89\xe1\x0b\x85\xb8\xe5\x4a\x20\x4f\xd3\ +\xf5\x93\x6a\xe3\xf7\x03\x37\x68\xba\x86\xae\xae\xdd\x44\x1c\x22\ +\x2d\x56\x37\x26\x98\xcc\xc0\x93\x16\xba\x5f\x20\xfb\xc2\x16\xb4\ +\xfe\xf6\xbd\xb8\x5f\x09\xc6\x43\x07\x10\x23\xa1\xab\x28\x7a\x80\ +\xe0\x12\xdf\x09\xb5\xcc\xb3\xb0\xb0\xd8\xf7\x28\xa8\x2f\x99\x29\ +\x23\x23\xa3\x03\xa6\x7e\xe5\x97\x69\x69\x69\x6d\xb2\x1d\x91\xaa\ +\x6e\x77\xb9\x5c\xeb\x16\x2f\x5e\x7c\xf0\xfe\x22\xee\x8e\xef\x7c\ +\x3c\x67\x74\x3b\x83\x99\x9b\x67\x92\x53\x92\x43\xc7\xa8\x8e\xbc\ +\x7a\xd2\xab\x24\xba\x6a\xbe\xd5\x47\x45\xc5\xb2\x72\xe5\x10\x60\ +\x79\xcd\x85\xfc\x4c\x5b\x33\xad\x52\xd8\x1d\xd5\xe9\xa8\x16\x17\ +\x76\x00\x1b\x37\x46\x72\xce\x39\xdb\x5b\xfc\x3e\xfb\x19\xb5\x7d\ +\xc0\x46\x63\x9c\x31\xff\x04\x36\x63\x76\xde\x0e\xc6\xc4\xdc\xa7\ +\x89\x5b\xde\x04\xae\xd4\x74\x0d\xc4\xec\x65\x63\x42\xb7\x6a\xff\ +\xa3\x68\x19\x6e\xc4\x84\xa4\x55\x2f\xc9\xf6\x09\xb0\xae\xe6\xf4\ +\xbd\xc3\x01\xb4\xa9\xf4\xde\x7a\x48\x65\xff\x7a\x3d\x16\x16\x16\ +\x2d\xc3\x00\xea\x2f\x49\x34\x10\xf3\xc6\xdb\x09\xff\x97\xc5\xb6\ +\x88\x3f\xee\xae\xeb\xf8\xf1\xe3\xf7\x8b\x7a\x77\x65\xde\x32\x7c\ +\x41\xba\x3c\xa7\x24\x87\x69\xab\xa7\x71\xed\x80\x6b\x71\xd9\x1b\ +\xfe\x12\xbd\xea\xe5\xb5\xd5\xaf\xf1\xd2\x2a\x53\xc9\x2b\xce\x19\ +\xc7\xc4\xa1\x13\x9b\xdd\xde\xea\xec\xd8\xe1\xa4\xa8\xc8\x4e\xf7\ +\xee\xa5\xf5\x4f\xb6\x00\xe0\xf2\xcb\x2f\x77\xc4\xc7\xc7\xd7\x56\ +\xdb\x36\xc0\xc7\x9a\x5e\xd9\xf9\x0a\x71\x8b\x1d\xb8\x0b\x93\xec\ +\xb8\x14\xf8\x3f\x00\x4d\xd7\x5d\x98\x7a\xb3\x21\x11\xb7\xd8\x30\ +\xa5\xcf\x36\x6b\xba\x16\x06\x8d\x77\xc0\xe4\x1c\xac\xd1\xf4\xda\ +\xbf\x18\x8a\x5b\xba\x60\x76\x12\x37\x68\xba\x86\x76\x17\x07\xa1\ +\xe9\xfa\x2b\xa6\x35\x6b\xa8\xb5\x12\x31\x4d\x1b\xd6\x68\x7a\xdd\ +\xfd\x6e\xc5\x2d\xa9\x80\x4d\xd3\x4d\x7b\x57\x07\xa6\x8c\x47\x5b\ +\xe7\x48\xcc\xf6\x68\x29\x30\x3f\xcc\xb6\x58\x58\x58\xec\xbb\xf4\ +\xc6\x74\xc8\x69\x08\x81\x4f\xdf\x50\x35\x35\xdb\x12\x73\x56\xac\ +\x58\x31\xd6\xe3\xf1\xe0\x74\xd6\x6c\xbb\xd5\x96\xc8\x2c\xce\x64\ +\xc2\xcf\x13\xd8\x5a\xb4\x95\xab\xfb\x5e\xcd\xd4\xd5\x53\x51\x94\ +\x37\xfe\x78\x83\x79\xdb\xe6\xf1\xcf\xc3\xff\xd9\xa0\x4c\xd7\xb5\ +\x05\x6b\x79\x60\xe1\x03\xac\xcc\xaf\xd2\xf7\x77\x0c\xba\x83\xe4\ +\xc8\xe4\x96\x34\x1f\x80\x75\xeb\x4c\x75\x1d\x4b\xdc\x35\x0c\x55\ +\x25\x3a\x3a\x1a\x87\xc3\xd1\xa8\x6c\x59\xbf\xa7\x2e\x5d\xdc\x72\ +\x26\x70\x9f\xb8\xe5\x69\x4d\xd7\x92\x50\xdb\xb2\xe2\x96\x6f\x31\ +\x09\x15\x5f\x03\x0f\x62\xbc\x7f\x97\x03\xaf\x8b\x5b\x46\x62\xda\ +\x8a\x06\xfe\xb0\x0a\xc4\x2d\x6e\x4d\xd7\xe7\x82\xef\x27\x6e\xb9\ +\x04\xd3\x9d\x2b\x10\xb0\x59\x21\x6e\x79\x52\xd3\xf5\x2e\x71\xcb\ +\x1a\xcc\x7b\xcf\x70\x71\xcb\x65\xfe\xf3\x2f\x69\xba\x8e\x0b\xb5\ +\x2d\x2b\x6e\xe9\x0d\xbc\x82\x69\xad\x0a\x50\x2e\x6e\x79\x1a\x98\ +\xa8\xe9\x26\x26\x50\xdc\x72\x3e\xa6\x65\xeb\xf1\x98\x0e\x5e\x43\ +\xfc\xe3\x3f\x03\xa3\x1d\xaa\x3a\xab\x31\xbf\xb0\x7d\x94\x59\xe1\ +\x36\xc0\xc2\xc2\x62\xdf\x47\x44\x1a\x13\xf3\xbb\xdf\x88\x3b\x8f\ +\xc7\x63\x5f\xb9\x72\x25\x03\x07\x0e\x0c\xb7\x2d\x4d\x66\xde\xb6\ +\x79\x4c\x9a\x3f\x89\xe4\xc8\x64\xa6\x9e\x38\x95\xee\xb1\xdd\x19\ +\xd0\x6e\x00\x0f\x2f\x7e\x98\xbc\xb2\x3c\xd6\x17\xae\x67\xdc\xec\ +\x71\x9c\xdd\xe3\x6c\x06\xb5\x1f\x44\xff\xc4\xfe\x44\x68\x3f\x00\ +\x7c\xf8\x58\x5b\xb0\x96\xdf\xf3\x7f\x67\x59\xde\x32\x3e\xdb\xf4\ +\x19\x1e\x9f\x71\x84\xc4\x3a\x63\xb9\x6d\xe0\x6d\x9c\xde\xed\xf4\ +\xba\x6e\xdf\x6c\xcc\x9d\xdb\x8e\x1e\x3d\x4a\x49\x4e\x6e\xf3\x09\ +\x99\xad\x82\xcf\x67\x9c\x64\x7b\x11\xaf\xff\x21\x26\xc1\xb3\x0f\ +\xa6\x84\x5b\x6d\x8c\xc4\xe4\x07\xdc\x82\x29\x67\x56\x21\x6e\x19\ +\x82\xd1\x17\xef\x61\xb6\x55\x37\x60\x12\x34\x9f\x15\xb7\xe4\x68\ +\xba\xce\x00\x10\xb7\x5c\x8c\x49\x14\xcd\xc0\xc4\xff\xe5\x62\x3c\ +\xff\x81\xb4\xeb\x13\x31\x89\x99\x6b\x81\xdb\xfc\x63\x7b\x34\x88\ +\x08\x20\x6e\x71\x01\x5f\x01\x65\x18\x71\xf7\x3b\xa6\x5b\xce\x53\ +\x98\xad\xe9\x3b\xaa\x5d\x32\x15\x23\x04\x2f\xc2\x6c\x45\x3f\x06\ +\x3c\xd8\xa8\xf6\x63\x16\x16\x16\x16\x07\x10\x3b\x30\x2d\x07\xdb\ +\x74\xaa\xa9\xaa\x6e\x72\xb9\x5c\xd9\x8b\x16\x2d\x4a\x69\x8b\xe2\ +\x4e\x51\x5e\x5a\xf9\x12\x2f\xad\x7c\x89\x93\x53\x4f\x66\xe2\xb0\ +\x89\x44\xd9\x8d\xf7\xeb\xf8\xce\xc7\x33\x38\x69\x30\x8f\x2e\x79\ +\x94\xaf\xb7\x7e\x8d\x57\xbd\x7c\xb4\xe1\x23\x3e\xda\xf0\x11\x4e\ +\x75\x72\x58\xd9\x40\x62\xc6\x29\x37\xae\x5d\x41\xf9\x1f\x65\x35\ +\xd6\x3e\xaa\xd3\x51\xfc\x63\xc8\x3f\xe8\x18\x15\xaa\x39\x41\xcb\ +\x30\x6b\x56\x3b\xce\x38\x23\xb7\xd5\xee\xd7\xd6\x09\x12\x77\x4d\ +\x0d\xb9\x0a\x34\x4c\xe8\x4f\xdd\xe2\xae\x1d\x30\x52\xd3\xab\x5a\ +\xa9\x8a\x5b\x5e\xc0\xbc\x0f\x5c\xae\xe9\x1a\xf8\x03\xba\x5b\xdc\ +\x72\x3c\x30\x01\x98\xe1\x1f\x7b\x0c\xf8\x4e\xd3\xf7\x48\xf8\xf8\ +\xd1\xff\x40\xd3\x75\xab\xb8\xa5\x0c\x28\xd2\x74\xdd\x50\x8f\xbd\ +\x7f\x01\x7a\x02\x47\x6a\xba\xfe\xe2\x1f\xcb\x10\xb7\x0c\x04\x6e\ +\x14\xb7\xfc\xab\x5a\xb7\x8c\x0f\x34\x5d\x1f\x0c\xbc\x56\x71\xcb\ +\xd9\xc0\xa9\x96\xb8\xb3\xb0\xb0\xb0\x08\x41\x5a\x5a\xda\x26\xa0\ +\xe5\xa3\xeb\x5b\x81\x8a\x8a\x8a\x6f\x16\x2c\x58\x30\xe6\x8a\x2b\ +\xae\x68\x53\xfb\xb2\x85\x9e\x42\x26\xcd\x9f\xc4\xcf\xdb\x7f\xe6\ +\x96\x81\xb7\xf0\xe7\x5e\x7f\xae\x31\x27\xc1\x95\xc0\x83\x23\x1e\ +\x64\x54\xea\x28\x1e\x5b\xf2\x18\x79\x65\x79\x00\x78\xc5\xcb\xe0\ +\xa2\x41\x14\xc7\xfe\xc8\x2a\xdd\x53\xd8\xc5\x39\xe3\xb8\xe9\xb0\ +\x9b\x38\xb7\xc7\xb9\xad\xf2\x3a\x02\x14\x15\xd9\xe9\xd3\xa7\x98\ +\x53\x4e\xc9\x6b\xd5\xfb\xb6\x65\x9c\x4e\x27\x13\x27\x4e\xf4\x95\ +\x96\x96\x2e\xa9\x7f\x76\x48\x02\x81\x98\x35\xd5\xfd\x9e\x6c\x0a\ +\x16\x76\x7e\x8e\xc2\xb4\x1b\xbd\x5a\xdc\x7b\xe4\x73\xec\x00\x4e\ +\x12\xb7\x08\xa6\x6a\x46\x77\xe0\xe1\x26\xda\x57\x9d\xa1\xc0\xce\ +\x20\x61\x17\xe0\x63\x4c\x22\x48\x3f\xaa\x5a\xb5\x82\x29\xf7\x16\ +\xcc\x8f\xc0\x19\x96\xb8\xb3\xb0\xb0\xb0\xd8\xcf\x51\xd5\xd9\x4b\ +\x96\x2c\xb9\xc4\xe7\xf3\x61\xb3\x35\xa6\xbc\x69\xf8\x58\xbd\x6b\ +\x35\x13\x7e\x9e\x40\x99\xaf\x8c\x67\x8f\x7b\x96\x21\x49\x43\xea\ +\x9c\x3f\xaa\xcb\x28\x4e\xea\x72\x12\x9b\x77\x6f\x66\x65\xfe\x4a\ +\x56\xe6\xaf\xa4\xa8\xa8\x84\x2e\x25\x07\xe3\x4d\x8c\x66\x58\x6a\ +\x1f\x06\x24\x0e\x60\x40\xe2\x00\xba\xc7\x76\xc7\x26\xad\xff\x7b\ +\x88\x89\xf1\xf2\xe8\xa3\xab\x5b\xfd\xbe\x6d\x99\xf2\xf2\x72\x76\ +\xee\xdc\x69\xc3\x94\x1c\x6b\x0a\x81\xde\xf1\xab\xea\x9c\x05\x7b\ +\x88\x47\x71\x4b\x0c\x26\x31\x22\x99\xd0\x5f\xf2\xbe\xc7\x08\xc7\ +\x40\x33\xe3\xe6\xaa\x71\xdb\x89\xd0\x89\xa1\x81\xf5\x3b\x54\x1b\ +\xaf\xde\xed\xab\x04\xb0\x5b\xe2\xce\xc2\xc2\xc2\x62\xff\xe7\xfb\ +\xd2\xd2\x52\xc7\x1f\x7f\xfc\x41\xdf\xbe\x7d\xeb\x9f\x1d\x66\x3e\ +\xdb\xf4\x19\x8f\x2c\x79\x84\x7e\x89\xfd\x78\x68\xc4\x43\x74\x88\ +\xac\xfe\x79\x16\x1a\x41\xe8\x1e\xdb\x9d\xee\xb1\xdd\x39\xad\xeb\ +\x69\xfc\x90\xbf\x9c\x45\x8b\x96\x71\x59\xd7\x47\x6b\xad\x73\xd7\ +\x5a\xf8\x7c\x82\x88\x62\x55\xcc\x6a\x1c\x05\x05\x95\x6d\xda\x1a\ +\x1d\x73\x27\x6e\x71\x02\x57\x00\x79\x84\xee\x67\x1f\xcc\x1e\x75\ +\x6a\x35\x5d\x8b\xc4\x2d\xdb\x81\x6f\x34\x5d\x6f\xa8\xe3\x1e\x81\ +\x75\xeb\xcb\xe6\x6d\x28\x1b\x80\x73\xc4\x2d\xb6\x6a\x59\xb9\x3d\ +\xfc\x3f\x1b\xd4\xba\xb5\x45\xbf\xba\x88\x88\x53\x44\xf6\x8b\xf4\ +\x7b\x0b\x0b\x8b\x03\x8b\x8c\x8c\x0c\xc9\xc8\xc8\x38\x37\x23\x23\ +\x23\x35\xdc\xb6\xec\x2d\xaa\xba\xd2\xe1\x70\xec\x5c\xb4\x68\x51\ +\xb8\x4d\xa9\x13\x8f\xcf\xc3\x23\x4b\x1e\xe1\x81\x85\x0f\x70\x5e\ +\xcf\xf3\x78\xee\xd8\xe7\x1a\x2c\xec\x42\xd1\xa1\x43\x37\xa2\xa2\ +\x0a\x29\x2e\x0e\x7f\x8c\xdb\x27\x9f\x24\x73\xe5\x95\x03\xa9\xa8\ +\xb0\xd4\x5d\x63\xd8\xbd\xbb\x52\x94\x37\x2a\xe6\xce\x5f\x46\x64\ +\x0a\x26\xd6\xee\x96\xfa\x4a\x89\xd4\xc2\x4c\x60\x8c\xbf\x0c\x4a\ +\xf5\xf5\x05\x40\xd3\xb5\x00\xb3\x15\x7a\x8d\x3f\x19\xa2\x36\xf2\ +\x30\x09\x1b\xf5\xf1\x3d\xa6\x76\x5f\xf5\x6e\x5b\x57\x61\x12\x35\ +\x1a\xe4\xfa\x6d\x16\xcf\x9d\x88\x24\x00\x67\x03\x27\xe0\x70\x74\ +\xc7\xe1\xec\x8e\xd7\xdb\x19\x48\x00\x10\x97\xab\x00\xbb\x3d\x8b\ +\x0a\xef\x26\x2a\x3c\x9b\x30\xcd\xb8\x3f\xdd\x8b\x00\x49\x0b\x0b\ +\x0b\x8b\xd6\xe0\x23\x4c\xa6\xda\xf4\x70\x1b\xb2\xb7\xf8\x7c\xbe\ +\x59\x0b\x17\x2e\x3c\xf7\x92\x4b\x2e\xb1\x87\xdb\x96\x50\x6c\x2f\ +\xd9\x8e\xfb\x17\x37\x6b\x0b\xd6\x32\x79\xf8\x64\x4e\xef\xba\xf7\ +\xd9\xab\xf1\xf1\x1d\x28\x2b\x8b\x66\xd7\xae\x4d\x40\xf8\x3c\x96\ +\x3e\x9f\xf0\xda\x6b\x5d\x18\x3a\xb4\x00\x87\xc3\x6a\x64\xd4\x18\ +\x0a\x0a\x0a\x78\xf8\xe1\x87\xf9\xf4\xd3\x4f\xeb\x2c\x3a\x0e\xdc\ +\xe2\xf7\xb4\x05\x8a\x18\x1f\x81\xd1\x38\xf7\x6a\xba\xbe\xde\xc4\ +\xdb\xdf\x05\x9c\x06\xfc\x2c\x6e\x79\x12\xd3\x3e\x35\x50\xdc\x3c\ +\x1e\xe3\x15\x04\xb8\x19\x23\xca\xe6\x8a\x5b\x9e\xc5\xd4\xc5\xec\ +\x0f\x74\xd4\x74\x9d\xe0\x9f\xf3\x03\x70\x8f\xb8\xe5\x79\x4c\x06\ +\xec\x32\x4d\xd7\xaf\xab\xdf\x50\xd3\xf5\x33\x71\xcb\x77\xc0\x54\ +\x71\x4b\x0f\xff\x3d\x2f\xc4\xb4\x44\x1d\xa7\xe9\x5a\xdc\x10\xc3\ +\x9b\x2c\xee\x44\x24\x09\xb8\x18\xa7\xf3\x62\x6c\xb6\x13\xb0\xd9\ +\x84\x11\x47\x79\xe9\xd5\xd7\x49\x97\x54\xe8\x9c\x0a\x5d\xba\x9a\ +\xc9\x59\x5b\x13\xc8\xda\x9a\xc0\xd6\x2d\xfd\x59\xf7\x47\x05\xbf\ +\xcc\x1b\x8b\xd7\xab\xe2\x72\x7d\x8f\xc7\x33\x03\x98\x61\xf5\x64\ +\xb5\xb0\xb0\xd8\x97\x48\x4b\x4b\xd3\x8c\x8c\x8c\x32\x20\x2a\xdc\ +\xb6\x34\x07\x3e\x9f\x6f\xf6\xc2\x85\x0b\xcf\x02\xf6\x39\x71\xb7\ +\x20\x77\x01\x13\x7f\x9d\x48\x9c\x33\x8e\x97\x4e\x78\xa9\xb2\x7f\ +\xec\xde\x22\x22\x64\x65\xf5\xa3\x53\xa7\xcd\x84\x53\xdc\xfd\xef\ +\x7f\x49\x64\x65\xb9\x78\xea\xa9\xcc\xfa\x27\x5b\xec\x41\x71\x71\ +\x31\xf1\xf1\xf1\x44\x45\x45\xd5\x56\x48\x3c\x13\x98\x8d\x11\x74\ +\x07\x61\x92\x1d\x56\x00\x9f\x01\x6f\x69\xba\x56\x77\xdb\x16\xfb\ +\xe7\x07\x67\xb5\x2c\x26\x44\x56\xbc\xa6\xeb\x36\x71\xcb\x61\xc0\ +\xbf\x30\x25\x50\xba\xf9\xaf\x5b\x02\xbc\x18\x34\x6f\xbe\xbf\x6c\ +\xca\x83\x98\x4e\x19\x09\x98\xf6\x67\x4f\x07\x2d\xf7\x28\x50\x8e\ +\xa9\xcb\xdb\x17\x53\x9b\xf7\x6b\xcc\x36\xec\x0f\xd5\x6e\x7d\xa6\ +\x7f\xad\xb1\x98\x18\xbc\xd5\xc0\x05\x9a\xae\xc1\xc9\x13\x39\xfe\ +\xd7\x51\x3d\x51\x64\x33\x30\xbb\xd1\xbd\x65\x45\x24\x1a\xb8\x05\ +\x87\x63\x22\x2e\x57\x04\xa7\x9f\x6d\xe3\xec\xf3\x6d\x9c\xf6\x27\ +\x88\x8b\x6f\xd8\x22\xbb\x0b\xe1\xab\x2f\xe0\xd3\x0f\x7c\x7c\xf1\ +\x89\x8f\xb2\xb2\x72\xbc\x15\xe9\xc0\x13\xaa\x0d\x53\xa5\x16\x16\ +\x16\x16\x8d\x45\x44\x86\x00\x8b\x80\x01\xaa\x5a\x5f\x87\x0a\x32\ +\x32\x32\x72\x81\xfb\xd2\xd2\xd2\x9e\x69\x71\xe3\x5a\x18\x11\x19\ +\x0a\x2c\x9c\x3e\x7d\x3a\x3d\x7a\xf4\xa8\x77\x7e\x6b\xf1\xfa\x9a\ +\xd7\x79\x6e\xc5\x73\x1c\xdb\xe9\x58\x26\x1d\x3e\x89\x58\x67\x6c\ +\xb3\xad\x9d\x95\x15\xc1\xc4\x89\x3b\x19\x39\x72\x06\x57\x5e\x79\ +\x79\x58\x92\x49\x2a\x2a\x84\xcb\x2e\x1b\xc8\x21\x87\x14\x31\x69\ +\x52\x7d\x61\x5f\x16\xd5\x99\x35\x6b\x16\xb1\xb1\xb1\xdc\x70\xc3\ +\x0d\xd6\x7e\x76\x23\x68\xf0\x5f\xba\x88\xd8\x44\x64\x3c\x4e\xe7\ +\x7a\x22\x22\x1e\xe0\xb6\x09\x31\xac\xce\x76\x30\x75\xba\x8d\x0b\ +\xff\xdc\x70\x61\x07\x10\x1b\x07\xe7\x8f\x81\x97\xde\xb2\xf1\xc7\ +\x36\x07\x77\xde\x13\x4d\x64\xd4\x7d\x38\x9d\x1b\x45\x64\xbc\x88\ +\xec\x73\xdf\x2c\x2d\x2c\x2c\x0e\x48\x66\x00\x59\xe1\x36\xa2\x99\ +\x58\x62\xb7\xdb\x8b\xf6\x95\xb8\xbb\xe2\x8a\x62\xdc\xbf\xb8\x79\ +\x6e\xc5\x73\x5c\x33\xe0\x1a\x1e\x39\xea\x91\x66\x15\x76\x01\x32\ +\x33\x07\xe0\xf5\x7a\xd8\xbe\x3d\x3c\x1d\xe4\x5e\x7b\xad\x0b\x99\ +\x99\x11\x8c\x1d\xbb\xb5\xfe\xc9\x16\x35\xa8\xa8\xa8\xa0\xa8\xa8\ +\xa8\xbe\x2d\x59\x8b\x6a\x34\x48\xdc\x89\x48\x3c\x76\xc7\x17\xd8\ +\x6c\xcf\xf3\x97\xab\x92\x59\xb2\xde\xce\xc4\x07\x8c\x48\xdb\x5b\ +\xa2\x63\x60\xc2\x24\xf8\x6d\xbd\x9d\x2b\xc6\x27\x61\xb3\x4d\xc1\ +\xe1\xf8\x4a\x44\xda\xed\xfd\xe2\x16\x16\xe1\x41\x44\x4e\x10\x91\ +\x31\x41\xc7\xed\x44\xe4\x3a\x11\xe9\x1a\x34\x76\x96\x88\x9c\x19\ +\x1e\x0b\x2d\x1a\x42\x9a\xe1\xbd\xd6\xba\x9f\xb8\xa5\xa3\xb8\x25\ +\xa2\x25\xd6\x56\x55\x1f\xf0\xc3\xa2\x45\x8b\xc2\xfe\x41\xb9\xa1\ +\x70\x03\x57\xcf\xba\x9a\x85\xb9\x0b\xf9\xf7\xd1\xff\xe6\xaa\xbe\ +\x57\x21\xb5\xf6\x85\xdf\x3b\xf2\xf3\x53\x70\xb9\x62\xc8\xcc\x6c\ +\xfd\x2d\xd1\xb5\x6b\xa3\x98\x3a\x35\x95\xf1\xe3\xb7\xd2\xad\x9b\ +\xd5\x6e\xac\x29\x6c\xdd\xba\x95\xc7\x1e\x7b\xcc\xda\xcf\x6e\x24\ +\xf5\xc6\xdc\x89\x48\x2f\x9c\xae\x2f\x88\x8f\xef\xc9\xdb\x9f\x08\ +\x23\x8e\x6a\x19\x4b\x3a\x76\x82\xc7\x9f\x15\xfe\x7a\xb5\x30\xe6\ +\xec\xe3\xc8\xcf\x5b\x20\x22\x67\xa8\xaa\x55\x14\xc8\x62\x9f\x41\ +\x44\x5e\xc4\x24\x0f\x85\xe2\x7f\xaa\x1a\x08\xb0\xfd\x2b\x70\x34\ +\xf0\x8e\xff\xb8\x33\xa6\x35\xcd\x5a\xaa\x52\xd9\x6f\x01\x3c\x98\ +\xb6\x34\x16\x07\x20\xfe\x26\xe5\xd7\x01\x57\x63\x8a\x93\xc6\x01\ +\x2a\x6e\xd9\x08\xbc\x05\x3c\xa2\xe9\x4d\x6e\xbb\x54\x03\xaf\xd7\ +\x3b\x6b\xfe\xfc\xf9\x27\x02\x95\x02\xf2\xbd\xf5\xef\x51\xe4\x29\ +\x22\xd2\x1e\xc9\x98\x5e\x63\x6a\xbf\xb8\x99\xf8\x66\xeb\x37\x3c\ +\xb8\xe8\x41\x7a\xc6\xf6\xe4\xa9\x63\x9f\x22\x25\x2a\xa5\xc5\xef\ +\x99\x90\xd0\x93\xd2\xd2\xd6\x17\x57\xff\xfe\x77\x4f\x7a\xf5\x2a\ +\xe6\xaf\x7f\xdd\x5f\x9c\xbf\xad\x4f\x41\x41\x01\xbb\x76\xed\x0a\ +\x7f\xba\x73\x1b\xa3\x4e\x71\x27\x22\x23\x71\x38\x3f\xa1\xff\x80\ +\x18\xde\xf9\xcc\x41\xe7\x56\xa8\x08\x30\x74\x38\xfc\xb0\xd8\xc9\ +\x9f\xcf\xe9\xca\xd2\xc5\x0b\x44\xe4\x3c\x55\xfd\xb6\xe5\x6f\x6c\ +\x61\xd1\x20\x12\x81\x18\xe0\xce\x10\xe7\x36\x34\x72\xad\xa7\x80\ +\xb0\x7b\x51\x2c\xc2\x83\xb8\x25\x19\xf8\x1c\x18\x5e\xfd\x14\xa6\ +\xfd\x90\x1b\x93\xad\xfb\x73\x33\xde\x76\xce\x8e\x1d\x3b\x22\xb2\ +\xb3\xb3\x49\x49\x31\xa2\xea\x95\x55\xaf\x90\x53\x9a\x43\xa2\x2b\ +\xb1\x45\xc5\x9d\x57\xbd\x3c\xbb\xfc\x59\xde\xfc\xe3\x4d\xce\xed\ +\x71\x2e\x77\x0e\xbe\x13\xa7\xad\x75\x1a\x66\xf4\xea\x75\x6a\x58\ +\xea\xdc\x4d\x9c\xb8\x96\xf2\x72\x1b\x36\x9b\x95\x21\xdb\x54\x0a\ +\x0b\x0b\xf1\xf9\x7c\x96\xb8\x6b\x24\xb5\x8a\x3b\x11\x19\x80\xc3\ +\xf1\x05\x67\x9e\x13\xc5\x0b\xaf\xdb\x88\x6c\xc5\x84\xb1\x4e\x29\ +\x30\xf3\x07\x27\xd7\x5f\x65\xe7\xc3\x19\x9f\x8a\xc8\x51\xaa\x5a\ +\x57\x4f\x38\x0b\x8b\xd6\xa4\x54\x55\xa7\xec\xed\x22\xaa\xfa\x59\ +\x5d\xe7\x45\xa4\x3b\x50\xac\x5a\x23\xdb\x2b\x70\x3e\x01\x23\x02\ +\x8a\x81\xcd\xaa\x5a\xc3\x35\x21\x22\x82\xc9\x22\x2b\x56\x55\xcb\ +\x7d\xd0\x48\xfc\x35\xee\x46\xa6\xa5\xa5\xbd\xdd\x02\xcb\x3f\x43\ +\x95\xb0\xcb\xc2\x34\x04\xff\x11\x53\xf5\x7e\x30\xf0\xf7\x50\x17\ +\xf9\xb7\x6d\x7b\x61\x5a\x14\x35\xe8\xdf\x54\xdc\xd2\x0e\x48\xa6\ +\x3b\x0b\x6d\x5b\x6c\xe5\x8b\x17\x2f\x76\x9d\x71\xc6\x19\x4d\x32\ +\xba\xb8\xa2\x98\xad\x45\x5b\xe9\x93\xd0\x67\x8f\xf1\x92\x8a\x12\ +\x32\x8b\x33\x49\x8e\x4c\x26\xde\xb5\x67\x0c\x76\x5e\x59\x1e\x13\ +\x7f\x9d\xc8\xb2\xbc\x65\xfc\x63\xe8\x3f\x5a\xbd\xed\x57\x6b\x53\ +\x52\x62\x27\x2a\xca\x4b\x4a\x4a\x79\xb8\x4d\x69\xf3\x14\x16\x16\ +\x6a\x45\x45\x85\x25\xee\x1a\x49\x48\x71\x27\x22\xed\x71\xba\x66\ +\x32\x74\x78\x04\x2f\xbd\x65\xc3\x15\x86\x3a\xc4\x11\x11\xf0\xfc\ +\x34\x1b\xd9\x59\x4e\x7e\x99\xf7\x85\x88\x0c\x55\xd5\xf0\x44\xc4\ +\x5a\x58\xb4\x00\x22\xf2\x3f\xc0\xa3\xaa\x67\xf9\x8f\xcf\x07\xde\ +\xc7\xd4\x55\x7a\x16\xe8\x13\x34\xef\x52\x55\xcd\xf3\x1f\x47\x01\ +\xaf\x02\x17\x41\x65\xa0\x52\x99\x88\x5c\xa7\xaa\xaf\xf8\xe7\xd8\ +\x80\x5b\xa9\x4a\xcb\x47\x44\x96\x03\x57\xab\xea\xaf\xad\xf2\x02\ +\xf7\x0f\x86\x00\x6f\x65\x64\x64\x7c\x98\x96\x96\xd6\x6c\xfb\x7a\ +\xfe\xc6\xe3\x01\x37\x59\x19\xa6\x61\x79\x70\x2a\xe5\x2a\xe0\x1d\ +\x7f\x85\xfd\xc0\x35\xfd\x31\xde\xde\x53\xf0\xc7\x4b\x8b\x5b\xb2\ +\x81\x3b\x34\x5d\xdf\x08\x9a\xf7\x38\x70\xbb\xff\xf0\x62\xcc\x96\ +\xef\x99\x80\xf0\x17\xb6\xca\x0c\xf9\x7d\xd1\xa2\x45\x83\x92\x0e\ +\x4f\x92\x9b\xe6\xde\x54\x79\xc3\xfc\xf2\x7c\x8e\xfa\xd0\x84\xdd\ +\x0c\x48\x1c\xc0\xd4\x13\xa7\xf2\xca\xaa\x57\x98\xf2\xbb\xf9\x1e\ +\x73\xdf\xe1\xf7\x31\x2b\x73\x16\x73\xb2\xe7\xe0\x53\x1f\x73\xcf\ +\x9b\x8b\x5d\xec\x2c\xde\xb1\x98\x27\x97\x3e\xc9\xaa\xfc\xaa\xee\ +\x4e\x3d\xe2\x7a\x70\xf7\xe0\xbb\x19\xd6\x61\x18\x00\x5b\x76\x6f\ +\x21\xa7\x24\x87\x17\x8e\x7f\x81\xfe\x89\xfd\xf7\xee\x97\xb7\x8f\ +\xb3\x7c\x79\x2c\xb7\xdf\xde\x8f\xa7\x9e\x5a\x49\xff\xfe\x45\xe1\ +\x36\xa7\xcd\x73\xce\x39\xe7\x48\x44\x44\x44\xd3\x2b\x59\x1f\xa0\ +\xd4\x48\xa8\x10\x11\x27\x0e\xc7\x87\x74\xec\xd8\x99\xb7\x3e\x72\ +\x84\x45\xd8\x05\x70\x38\xe0\xf5\xf7\x1d\x74\xea\x9c\x8c\xc3\xf9\ +\x89\x48\xcb\x04\x1a\x5b\x58\x34\x12\x9b\x88\xf4\x0c\xf1\x48\x68\ +\xa6\xf5\x5f\x01\x26\x60\x8a\x64\x9e\x8c\x69\x24\xfd\x46\xd0\xf9\ +\x3b\x30\xbd\x0e\xcf\xc5\xf4\x3e\xec\xe0\x7f\xbe\x21\x68\xce\xbd\ +\xc0\x43\xc0\x93\x98\x9a\x4a\x27\x62\xea\x41\xfd\x4f\xa4\x66\xb5\ +\x75\x8b\x5a\x09\x04\x72\x77\x6e\xe6\x75\x8f\x08\x7a\xfe\x56\x35\ +\x61\x57\x49\xa0\xaa\xbe\xb8\xa5\x17\x30\x1f\x23\xfc\x05\xe3\xe1\ +\xcb\x05\x52\x80\xd7\xc5\x2d\xe3\x6b\xb9\xcf\x54\xe0\x4f\x98\xd8\ +\x4e\x80\x54\xef\x9f\xbc\xa9\xbf\xce\xff\xb5\xd1\x2e\xa5\xa7\x97\ +\x3d\xcd\xac\xac\x59\xf8\x82\x3a\x22\xfd\x9a\xf3\x2b\x69\xdf\xa7\ +\xb1\x2a\x7f\x15\x0e\x9b\x83\xa1\x49\x43\x89\xb4\x47\xb2\xb1\x70\ +\x23\x37\xfc\x70\x03\x4b\x76\x98\x76\x9d\x83\x92\x06\x31\xfd\x94\ +\xe9\xfb\xbd\xb0\xcb\xca\x8a\xe0\x8e\x3b\xfa\x72\xc8\x21\xbb\xe9\ +\xd3\xc7\xaa\xea\xb5\xb7\x78\xbd\x5e\x22\x23\x23\xf1\x78\x3c\x79\ +\xf5\xcf\xb6\x08\x26\x54\xb6\xec\x44\x1c\xce\xa3\x79\xf7\x0b\x27\ +\x49\xfb\xc0\x67\x40\xbb\xf6\xf0\xee\xe7\x4e\x9c\x8e\x61\xc0\xe4\ +\x70\x9b\x63\x11\x1e\x44\xc4\x2e\x22\x9d\x45\x64\x98\x88\xfc\x49\ +\x44\xae\x16\x91\x4b\x44\xe4\x78\x11\xe9\x2b\x22\xcd\x90\xba\xdd\ +\x60\xda\x63\x0a\x54\x56\x7f\xdc\xd8\x4c\xeb\x3f\xaf\xaa\xef\xab\ +\x6a\xa1\x3f\xde\x74\x02\x70\x86\x88\x0c\xf6\x9f\xef\x06\xac\x51\ +\xd5\x4f\x55\x75\xa7\xaa\xee\x50\xd5\xff\xa9\xea\x2c\x30\x99\xb9\ +\x98\xca\xea\x6f\xa9\xea\x64\x55\x5d\xa3\xaa\xb3\x31\x1e\x9c\x78\ +\x4c\x31\x4e\x8b\x86\x11\x10\x77\xcd\x1d\x70\x3c\x20\xe8\x79\xbd\ +\xf5\xf6\x80\x27\x30\xb1\x9e\x00\xe7\x69\xba\x1e\x03\x74\x05\xd6\ +\xf9\xc7\x1e\x11\xb7\x44\x87\xb8\x6e\x3b\x70\x0c\x90\x84\xa9\x8a\ +\x0f\x31\x74\xc8\xdc\x9d\x19\xd1\xdb\xd1\x9b\x9f\x46\xff\x44\x72\ +\x64\x32\x00\x89\xae\x44\x7e\x1a\xfd\x13\x3f\x8d\xfe\x89\xa9\x27\ +\x4e\xad\xb1\x50\x51\x45\x11\xe3\xfa\x8f\xe3\xbd\x53\xdf\x63\xea\ +\x89\x53\xb1\x89\x8d\x87\x17\x3f\x8c\xa2\xd8\xc5\xce\x9b\xa3\xde\ +\x24\x63\x64\x06\xef\x9f\xf6\x3e\x4e\x9b\x13\x45\x79\xfc\xb7\xc7\ +\x2b\xaf\xb7\xef\x03\x15\xae\x7c\x3e\x1f\x3e\x5f\xcb\x84\xb9\x66\ +\x65\x45\x70\xcb\x2d\xfd\x49\x4e\x2e\xe7\xa1\x87\xfe\xc0\x6e\xb7\ +\xe2\xec\xf6\x16\x8f\xc7\x7c\x27\xd9\xbd\x7b\xf7\xba\x7a\xa6\x5a\ +\x54\x63\x8f\x6d\x59\x11\x49\xc1\x6e\xbf\x9b\x7b\x1f\x74\x30\xe0\ +\xb0\x70\xd9\x54\x93\xfe\x87\x82\x7b\xb2\x83\xfb\xdc\xb7\x89\xc8\ +\xb3\xaa\xba\x39\xdc\x26\x59\xb4\x0c\x22\xd2\x07\xe3\x95\x3a\x04\ +\xa7\xb3\x2b\x76\x7b\x57\x7c\xbe\x4e\x88\x24\xa2\x5a\x55\x2b\x21\ +\x36\xd6\x43\x59\x99\x1d\x8f\xa7\xf2\x0b\x8a\x38\x1c\x65\x38\x9c\ +\x39\x40\x16\x9e\xf2\x4d\xf8\x7c\x5b\x80\x6f\x80\xaf\x42\xc5\xa3\ +\xed\x05\xf9\xc0\x49\x21\xc6\x9b\x2b\xa6\xed\xcb\x6a\xc7\x33\xfd\ +\x3f\x87\x60\x2a\xa3\xcf\x00\xc6\x8b\xc8\x0f\xc0\xdb\xc0\xfb\xaa\ +\x1a\x5c\x2a\x60\x10\xa6\x37\xe1\x6e\x11\xb9\x2e\x84\x8d\x03\xb0\ +\x68\x28\x39\x98\xd6\x63\x85\xcd\xbc\x6e\x70\x9f\xcb\x86\x74\x0a\ +\x3a\xda\xff\xb3\x14\x38\x59\xdc\x72\xb2\xff\x38\xe0\x1e\x4a\x04\ +\x0e\xc1\x78\xf7\x82\x79\x53\xd3\xf5\x47\x00\x71\xcb\x0f\xf8\xff\ +\xed\x25\x51\x7c\x8b\x17\x2f\xb6\x9d\x74\x52\xa8\x3f\xe3\x5a\x0c\ +\xe8\x78\x34\xe3\xfa\x8f\x03\x20\x95\x54\xf2\xcb\xf2\xd9\x5a\x64\ +\x6a\xb7\xb5\x8f\x68\xcf\x7b\xeb\xab\x2a\xc6\x24\xb8\x12\xc8\x2d\ +\xcd\x65\xcd\xae\x35\x94\x78\x4b\x88\xb2\x87\xbf\xc9\x87\xc7\xe3\ +\xe1\xcd\x37\xdf\xe4\x84\x13\x4e\xa0\x67\xcf\x9e\xcd\xba\xf6\xef\ +\xbf\xc7\xf0\xf7\xbf\xf7\x23\x39\xb9\x9c\x27\x9f\x5c\x45\x54\x94\ +\xb7\x59\xd7\x3f\x50\x09\xf4\x95\xcd\xcf\xcf\xb7\x62\xee\x1b\xc9\ +\x9e\x6f\x2a\x22\x93\x48\xee\x64\x63\xdc\x0d\x61\x32\xa7\x0e\xae\ +\xb9\x09\x9e\xfb\xb7\xb0\x3d\xfb\x01\x4c\x03\x5d\x8b\xfd\x04\x11\ +\x19\x06\x9c\x4f\x44\xc4\x25\x40\x1f\x92\x3a\x94\x33\x6c\x84\x9d\ +\xce\xa9\x76\x52\x3a\x43\xa7\xce\xec\xf1\xb3\x63\x0a\xb8\x5c\x26\ +\x16\x69\x67\x1e\x6c\xcb\x82\xec\x2c\xd8\x96\x1d\xc1\xb6\xac\xae\ +\x64\x67\x75\x25\x3b\x6b\x38\xeb\xd6\x78\xf8\x6d\xd1\xcd\x88\x94\ +\x89\xc3\xf1\x05\x5e\xef\x7b\x98\x9e\xc6\xbb\xf6\xd2\xe4\x0a\x55\ +\x5d\xbc\x97\x6b\xd4\x45\xf5\x2d\x88\x40\x0f\xe6\x8e\x00\xaa\xfa\ +\x95\x88\x8c\xc4\x04\xdc\x3f\x02\x3c\x21\x22\xef\x02\x6e\x55\xdd\ +\x88\xf1\xec\x81\x11\x79\x7d\xaa\xad\xb5\x8c\xc6\x67\xf5\x1e\xb0\ +\xa4\xa5\xa5\xf9\x30\xbd\x65\x9b\x9b\xdf\x83\x9e\x0f\xa9\x6b\xa2\ +\x3f\xee\x2e\xc9\x7f\x18\x89\x29\xa1\x13\x8a\x83\xa9\x29\xee\xe6\ +\x05\x3d\xaf\x0c\x00\xb3\x45\xd9\xd6\x2e\x5a\xb4\xa8\x4f\x63\xc4\ +\xdd\x91\x9d\x8e\xdc\xe3\x38\xb7\xac\x2a\xc6\x3d\xa7\x34\x87\xe9\ +\x6b\x6b\xb6\xdf\x55\x94\xac\xe2\x2c\x0e\x8e\x3b\xb8\xc1\xf7\x69\ +\x29\x9c\x4e\x27\xf1\xf1\xf1\x64\x66\x66\x36\xab\xb8\xfb\xe1\x87\ +\x76\xdc\x7b\x6f\x6f\x06\x0f\x2e\x24\x3d\x7d\x8d\x25\xec\x9a\x91\ +\x9d\x3b\x77\x72\xeb\xad\xb7\x52\x5e\x5e\x5e\xfd\xef\xda\xa2\x1e\ +\x2a\xc5\x9d\x88\xf4\x45\x64\x3c\x93\xff\xcf\x4e\xc4\x3e\x18\xda\ +\x16\x19\x09\xf7\xa5\x3b\x49\xbb\xea\x0a\x11\x79\x4c\x55\x97\x85\ +\xdb\x24\x8b\xa6\x23\x22\x47\x03\x97\xe0\x72\x5d\x02\xa4\x90\xda\ +\xad\x9c\x0b\x2e\x71\x71\xf6\xf9\x70\xc4\xd1\x2e\xa4\x81\x05\x4d\ +\xdb\xb5\x37\x8f\xfe\x87\xd6\xb8\x05\xe0\x62\x47\x2e\x7c\xfe\x51\ +\x24\x1f\xbd\x7b\x0e\xb3\xbe\x39\x0f\x9f\x57\xc5\xe5\x9a\xed\xef\ +\x69\xfc\x56\x33\x08\xbd\x96\xa0\x0b\xb0\x26\xe8\x38\x10\xef\xb5\ +\x29\x30\xa0\xaa\x3f\x00\x3f\x88\x48\x0c\xc6\xd3\xf9\x34\xc6\xbb\ +\x74\x2d\x55\x5b\x75\xf7\xab\xea\x37\x2d\x6f\xae\x45\x13\xf8\x1e\ +\x50\xcc\xdf\xe9\x05\xe2\x96\x23\x34\x5d\x7f\x09\x9e\xe0\xdf\x66\ +\x75\x68\xba\x16\x88\x5b\xd6\x01\xbd\x31\x02\xed\x78\xaa\x3c\x76\ +\xc1\x84\x6a\x81\x10\xdc\x77\xb2\x72\x3f\xd2\x1b\xe1\x5d\x38\x7f\ +\xfe\xfc\xee\x40\x84\x4d\x8c\xf3\xdb\xab\x75\x8b\x92\x04\xd7\x9e\ +\x21\xa5\xdd\x62\xba\x61\x13\x1b\x3e\xf5\xd1\x3d\xb6\x3b\x8f\x1e\ +\xf9\x68\xc8\xeb\xba\xc4\x74\xa9\x73\xdd\xd6\xa4\x4b\x97\x2e\x6c\ +\xde\xdc\x7c\x1b\x3f\xe5\xe5\x36\x1e\x7b\xac\x27\x27\x9f\xbc\x03\ +\xb7\x7b\xbd\xb5\x15\xdb\xcc\x6c\xdd\xba\x15\x8f\xc7\xa3\xc0\xc6\ +\x70\xdb\xd2\xd6\xa8\x8a\xb9\x13\xb9\x8b\x5e\x7d\xbc\x8c\xb9\x2c\ +\x8c\xe6\xd4\xc3\x98\xbf\x42\xdf\xfe\x15\x88\x84\x2c\x11\x60\xb1\ +\xef\x23\x22\x7d\xc4\xe9\xfc\x04\x98\x47\xbf\x01\x69\xdc\xee\x4e\ +\x61\xee\x12\x58\xbe\xc9\xc5\x03\x8f\xc2\x91\xc7\xd0\x60\x61\xd7\ +\x10\x92\x3a\xc0\xe5\x7f\x83\x77\xbf\x70\xb0\x61\x87\x8d\x17\xdf\ +\xb4\x73\xd6\xe8\x13\x89\x8c\x7a\x06\xa7\x73\x83\xbf\x6b\x44\xf8\ +\x83\x81\xf6\xa4\xfa\x7f\xc2\xcb\x80\x0a\xe0\x27\xa8\x2c\x6f\x02\ +\x80\xaa\x16\xa9\xea\x1b\x98\xed\xe7\xc0\x56\xdd\x12\x60\x1b\x70\ +\x7d\xa8\xc5\x83\xaf\xb7\x08\x0f\x9a\xae\x0b\x81\xff\xf8\x0f\x6d\ +\xc0\x77\xe2\x96\xfb\xc4\x2d\x27\x8b\x5b\xfe\x24\x6e\xb9\x17\x23\ +\xd2\x03\x5b\xe8\x9f\xfb\x7f\xc6\x00\x97\x63\xca\xa0\xac\xc4\xc4\ +\x04\x0e\x02\xfe\xa5\xe9\xda\xf0\xad\xe3\x76\x2c\x5d\xbf\x7e\xbd\ +\x6b\xf7\xee\xdd\x24\x45\x1a\xa7\x60\xa1\xa7\x90\xe9\x6b\xa7\xb3\ +\x30\x77\x61\xe5\x76\x6b\x5d\x44\xd8\x23\x38\xbc\xc3\xe1\x00\x6c\ +\xda\xbd\x89\x5f\x72\x7e\xa1\x43\x54\x07\x7a\xc4\xf5\x20\x21\x22\ +\x81\x05\xb9\x0b\x78\x77\xfd\xbb\xad\x56\xcb\xae\x21\x74\xe9\xd2\ +\x85\xfc\xfc\x7c\x8a\x8b\xf7\x2e\xd9\xa1\xb8\xd8\xbc\x65\xb8\x5c\ +\x3e\x5e\x7a\x69\x19\xf7\xdc\xb3\xce\x12\x76\x2d\xc0\xd6\xad\x5b\ +\x71\x38\x1c\xdb\x54\xd5\xaa\x29\xd3\x48\x1c\xe0\x2f\x9b\xe0\x70\ +\x5e\xc0\x25\x97\x37\xdc\x63\x12\x0e\x6c\x36\xf8\xeb\x58\x27\xf7\ +\xff\xe3\x7c\x11\x19\xa7\x5a\xf7\x57\x4d\x11\x39\x18\x93\x5d\x06\ +\xe6\x5b\xf2\x4e\x8c\xf7\x63\x63\xa8\x9a\x5f\x22\x92\x88\x09\x6e\ +\xbe\x51\x55\xdf\x6d\x66\xeb\x0f\x68\xfc\xa5\x39\x1e\xc0\x66\xbb\ +\x9b\x83\xfb\xf8\x78\xe4\x69\x38\xf1\x94\xd6\x4d\xc5\x8e\x8d\x83\ +\x0b\x2e\x81\x0b\x2e\xb1\xb1\x2b\x1f\x1e\x79\x20\x91\xe7\x9f\x7e\ +\x16\xb1\xdd\x2a\x22\x63\x1a\x51\x4b\x31\x46\x44\xfe\x1d\x62\x3c\ +\x47\x55\xff\xd5\x0c\x96\x8e\x14\x91\x47\x80\xaf\x80\x11\x98\x72\ +\x26\x53\xfc\x5b\xae\x00\xef\x89\xc8\x26\xcc\x96\x5b\xbe\x7f\xce\ +\x68\x60\x0a\x18\xc1\x27\x22\x37\x00\xd3\x45\xe4\x33\xe0\x4d\xcc\ +\x56\x6f\x37\x4c\x56\xed\x74\x60\x5a\x33\xd8\x79\x40\x90\x91\x91\ +\x31\x18\xe8\x99\x96\x96\xf6\x51\x33\x2f\xed\x06\x92\x81\x4b\x31\ +\x31\x92\x93\xea\x98\x7b\x0f\xa6\x9c\x49\x1f\x4c\x89\x9b\x5b\xc4\ +\x2d\x79\x54\x6d\xd7\x36\xae\x4c\x54\x1f\x96\xe9\x2c\xe5\xb7\xdf\ +\x7e\xe3\x98\x4e\xc7\xb0\x62\xe7\x0a\x00\x9e\x5c\xfa\x24\x00\x97\ +\xf5\xbe\x8c\x9b\x0e\xbb\xa9\xae\x15\x00\x98\x30\x64\x02\x57\xcd\ +\xba\x8a\x42\x4f\x21\x8f\xff\xf6\x38\x4f\x2d\x7b\x8a\x48\x7b\x24\ +\xbb\x3d\x26\x56\x6a\x78\x72\xf5\xfa\xcc\xe1\xa5\x73\xe7\xce\xd8\ +\x6c\x36\x32\x33\x33\xe9\xdd\xbb\x77\xa3\xaf\x57\x85\xf7\xdf\xef\ +\xc4\x94\x29\xdd\xc8\xc8\x58\x41\xef\xde\xc5\x24\x25\x79\xea\xbf\ +\xd0\xa2\x49\xf8\x5b\xc6\xfd\x11\x6e\x3b\xda\x22\x81\x6d\xd9\xa3\ +\xa9\xf0\xb4\xe3\xec\xd1\x61\x35\xa6\x41\x9c\x35\x1a\xee\xbd\x33\ +\x01\x38\x0e\x98\x5d\xcf\xec\x61\x98\x96\x4f\xdb\x30\x81\xc8\x31\ +\x98\xb2\x11\x88\xc8\x57\xc0\x44\xab\xe6\x57\xcb\x23\x22\xd1\xd8\ +\xed\x6f\x21\x72\x36\x0f\x3f\x65\xe3\xea\x6b\xed\xd8\xc3\xec\x2c\ +\x4b\x48\x84\x7f\x3d\x0e\xe3\xae\xb7\x71\xed\x15\xbd\x58\xf0\xf3\ +\x8f\x22\x72\x81\xaa\x56\x4f\x66\xa8\xce\x72\xcc\xdf\x50\xa8\x38\ +\xa9\x2d\x41\xcf\x57\xb1\x67\x4c\x6b\x31\xe6\xef\x35\x38\x9e\x6e\ +\x09\x10\xea\x0b\xca\xc5\x98\x72\x27\x2f\x00\x25\x98\x92\x26\xc1\ +\x99\xe2\x33\x31\xde\xbc\x31\x18\x51\x90\x09\x3c\x08\x3c\x1c\x98\ +\xa0\xaa\xef\xf9\xb7\xbe\xef\xf3\x9f\x4b\xc0\x24\x53\xcc\x66\xcf\ +\x38\x2c\x8b\xfa\x39\x07\xd3\x4e\xae\x59\xc5\x9d\xa6\x6b\x31\xf0\ +\x17\x71\xcb\x8b\x98\x4c\xe6\xfe\xf8\x8b\x13\x63\xb6\xe5\xdf\x01\ +\x7e\xf3\xcf\x2d\x14\xb7\x0c\xc6\xd4\xaf\x3b\x0b\x13\x5f\x67\x03\ +\x96\x02\x0b\x80\x8f\x83\x96\x5e\x4b\xd5\x7b\xe3\xce\x90\xe3\x49\ +\x6c\x72\x3a\x9d\xab\x16\x2f\x5e\xdc\x7f\xfc\x75\xe3\x89\x71\xc6\ +\xb0\x64\xc7\x12\x0a\xca\x0b\x00\x48\x8d\x31\xc9\xc1\x29\xd1\x29\ +\x0c\xed\x30\x14\x80\x76\xae\x9a\xed\xbe\x53\x63\x52\x99\x71\xea\ +\x0c\xa6\xae\x9a\xca\x92\x1d\x4b\xc8\x2c\xce\xc4\x65\x73\x91\x1a\ +\x93\xca\xa0\xf6\x83\x38\x39\xf5\xe4\x1a\xd7\x84\x13\x87\xc3\x41\ +\xc7\x8e\x1d\x9b\x24\xee\x7e\xfc\x31\x91\x17\x5f\x4c\x65\xe5\xca\ +\x18\xae\xbc\x32\x93\x9e\x3d\x4b\x5a\xc8\x4a\x8b\x00\x03\x07\x0e\ +\xd4\xc4\xc4\xc4\xe6\x2a\x31\x75\x40\x21\xaa\x8a\x88\xfc\x1f\x5d\ +\xbb\xdf\xc6\xb2\x8d\xfb\x8e\xff\xbc\x2e\x0e\xef\x57\xce\xda\xd5\ +\xcf\xa9\xea\x6d\x75\x4d\x13\x91\x8b\x30\x99\x85\xa7\x04\x62\x8f\ +\xfc\x25\x33\x4e\x04\xfe\x0f\xd3\xcb\x71\xa4\xaa\x5a\x1f\x76\x2d\ +\x84\x88\x08\x4e\xe7\x77\xb8\x22\x8e\x65\xfa\x27\x0e\x8e\x3b\x31\ +\xdc\x26\xd5\xa4\xac\x0c\xae\xbd\xdc\xc7\x47\xef\x2a\xaa\xa7\xaa\ +\xea\x77\xe1\x30\x23\xa8\x88\x71\x0f\x55\xdd\x54\xdf\x7c\x8b\xc6\ +\x23\x22\x43\x80\x45\xc0\x00\x55\x6d\x48\x09\x12\x32\x32\x32\xc6\ +\x01\x4f\xa6\xa5\xa5\xb5\x66\xb9\x9d\x16\x47\x44\x9e\x19\x30\x60\ +\xc0\xb8\xa9\x53\xa7\xee\x83\x41\xd6\xcd\x43\x56\x56\x04\xe7\x9f\ +\x3f\x84\x17\x5f\x5c\x5e\xd9\x7e\x6c\xe1\xc2\x85\xac\x5e\xbd\x9a\ +\x3f\xff\xb9\x61\x79\x32\xf3\xe6\x19\x51\xb7\x62\x45\x2c\xc7\x1d\ +\xb7\x93\x6b\xae\xd9\x42\xdf\xbe\x56\x0d\xbb\xd6\xe0\xdb\x6f\xbf\ +\xd5\xb5\x6b\xd7\x7e\xfd\xe2\x8b\x2f\x9e\x56\xff\x6c\x8b\x60\x4c\ +\xcc\x5d\x44\xe4\xf9\x9c\x77\x51\xdb\x10\x76\x00\xa3\x2f\x72\xe1\ +\x72\x9d\xdf\x94\x4b\xfd\xb5\xc3\x3e\xc1\xd4\x7e\xca\x05\x5e\x12\ +\x31\x55\xe0\x45\x24\x4a\x44\xee\x13\x91\x41\x81\xf9\x22\x12\x29\ +\x22\xd7\x8a\xc8\xab\x22\xf2\x81\x88\x4c\x11\x91\xbf\x06\xaf\x29\ +\x22\x0e\x11\xb9\x41\x44\xde\x14\x91\x07\x45\xe4\x50\x11\x39\x51\ +\x44\xee\x0e\x9a\xd3\xc3\xbf\x76\x4a\xb5\x6b\x07\xfb\xc7\x23\xab\ +\x8d\xf7\x10\x91\x89\x22\x32\x5d\x44\xfe\x2d\x22\xc7\x37\xe5\xf5\ +\xee\x03\xdc\x80\xea\x48\xbe\x98\xb3\x6f\x0a\x3b\x30\xdd\x50\xa6\ +\x4e\xb7\x71\xde\x45\x82\xd3\x35\x4d\x44\x62\xc3\x6d\x92\xc5\x3e\ +\x45\x36\x10\x9b\x91\x91\xb1\x5f\x89\x3b\x60\xce\xea\xd5\xab\x9d\ +\x65\x65\x65\xf5\xcf\xdc\x8f\x48\x4d\x4d\x65\xf7\xee\xdd\x14\x14\ +\x14\xd4\x39\xaf\xa8\xc8\xce\x15\x57\x0c\xe4\xef\x7f\xef\x47\xc7\ +\x8e\x1e\x5e\x7b\x6d\x19\x8f\x3d\xb6\xda\x12\x76\xad\x84\xcf\xe7\ +\x23\x26\x26\x46\x2a\x2a\x2a\xac\x6d\xd9\x26\x60\xc4\x5d\x85\xa7\ +\x07\xfd\xda\x50\xe9\xab\xbe\x03\xc0\xe3\xe9\xba\x37\x81\xe1\xaa\ +\x9a\x8f\x29\x0c\xda\x1f\x53\x1f\x0a\x20\x0a\x13\xf7\x32\x38\x68\ +\xea\x27\x98\x6d\xb1\x48\x60\x35\x10\x47\xd0\xf6\x97\x88\x38\x30\ +\xb1\x51\xff\x87\xd9\x7a\x4b\x06\x3e\xc3\x6c\xab\xdd\x1d\xb4\x4e\ +\x4f\xff\xda\x7b\x88\x3b\xcc\xf6\xde\x24\xff\xfa\x81\x35\xcf\xc5\ +\x6c\xb7\xdc\x02\x14\x00\xa3\x80\x59\xc1\x62\xb1\x2d\x20\x22\xc9\ +\xd8\xed\x8f\x72\xc7\x3d\x36\x06\x0d\x0d\xb7\x39\x75\x23\x02\x8f\ +\x3f\x67\x23\x3a\xba\x23\xa6\xbb\x83\x85\x45\x80\x55\xc0\x8b\x34\ +\xac\x1e\x5d\x5b\xe2\x7b\xaf\xd7\x6b\x5b\xbe\x7c\x79\xb8\xed\x68\ +\x55\x92\x93\x93\x71\x3a\x9d\x81\x78\xae\x4a\x0a\x0b\x1d\xbc\xf3\ +\x4e\x0a\xbf\xfe\x6a\xfa\xe2\xc6\xc4\x78\x39\xe6\x98\x9d\x4c\x9b\ +\xb6\x94\x87\x1f\x5e\x4d\xdf\xbe\x56\x2b\xb1\xd6\x24\x33\x33\x13\ +\x11\xc1\xe7\xf3\x59\x35\xee\x9a\x80\xc3\x5f\xcd\xde\x45\xe7\xe6\ +\x2e\xc0\xde\x82\x74\x49\x05\x55\x3b\x46\x48\xed\x4d\xbf\xd9\xc0\ +\xbb\x5a\x7f\x4c\xfc\xd3\x1e\x88\x48\x37\x4c\x1f\xc7\x2b\x54\x75\ +\x5a\xd0\x78\xb0\x97\xf3\x4a\xcc\x36\xef\xa8\xc0\x76\x9e\x7f\xeb\ +\x67\x01\xd0\xe8\x32\x1b\x22\x12\x8f\x89\xb5\xfa\x0a\xb8\x44\x55\ +\x2b\xfc\xe3\x93\x81\xfb\x45\xe4\x5d\xd5\xd0\xad\x8a\xf6\x41\x8e\ +\xc5\xe7\x8b\xe4\xfa\x5b\xc3\x6d\x47\xc3\x48\xea\x00\x97\x5d\xed\ +\xe4\xa5\xe7\xce\x61\x4f\x61\xde\x2a\xa8\xea\x07\x54\xf5\x8a\xb5\ +\xd8\x47\x48\x4b\x4b\x5b\x03\xd4\xd6\xde\xab\xcd\xa2\xaa\x59\x2e\ +\x97\x6b\xd3\xa2\x45\x8b\xba\x0f\x1b\x36\x2c\xdc\xe6\xb4\x1a\x36\ +\x9b\x8d\x94\x94\x14\xb6\x6e\xdd\x4a\xff\xfe\x55\xed\xd0\x0a\x0a\ +\xec\x3c\xff\x7c\x57\xae\xb9\x66\x0b\x23\x46\x18\xaf\xde\x75\xd7\ +\x6d\xa9\x6d\x19\x8b\x16\x26\x2b\x2b\x8b\x5b\x6f\xbd\x95\xa4\xa4\ +\xa4\xf7\xc3\x6d\x4b\x5b\xc4\x86\xa9\xa9\x05\xa9\x5d\xc3\x6b\x49\ +\x63\xe8\x52\x69\x6b\x75\x2f\x58\x63\xd9\x16\x58\xb1\x96\xf3\xdb\ +\x31\x01\xc9\xa7\x88\x48\x65\x6f\x49\x55\x0d\x4e\x8f\x1a\x03\xfc\ +\x1c\x1c\xa7\xe5\x2f\x70\xfb\x55\x13\x6d\x3a\x0b\x53\xac\xf6\xf1\ +\x80\xb0\xf3\xf3\x22\xe0\xc4\x08\xc9\xb6\xc2\x91\x1c\xd4\xab\x9c\ +\xf8\x36\x14\x0f\x3b\xe2\x28\x28\x2f\xef\x27\x12\xb2\x95\x93\x85\ +\xc5\x7e\x85\xc7\xe3\xf9\x7a\xfe\xfc\xf9\x07\x5c\xba\xe7\xe0\xc1\ +\x83\x39\xe4\x90\x43\xf6\x18\x4b\x4d\x2d\x63\xe6\xcc\x05\x5c\x72\ +\x49\x76\x98\xac\xb2\x08\x66\xeb\xd6\xad\x88\x48\xd1\xf6\xed\xdb\ +\xf7\xc6\x81\x73\xc0\x52\x25\xee\xda\x9a\xe7\xce\xb0\xb7\xcd\xbc\ +\x03\x95\xfc\xd7\x87\x3a\xa9\xaa\x65\x98\x72\x05\x67\x01\x5b\x44\ +\xe4\x07\x11\xb9\x5c\x44\x82\x4b\x78\x1c\x8c\xd9\xae\xad\xce\x8a\ +\x26\xda\x14\x78\xc7\x79\x5f\x44\xb2\x03\x0f\x20\x90\xd5\x7b\x50\ +\x13\xd7\x0d\x07\xed\xe8\x94\x12\xaa\x7f\xf1\xbe\x4b\x72\x47\x50\ +\xb5\x61\x7a\xb0\x5a\x58\xec\xef\xcc\x59\xbe\x7c\xb9\xcd\xeb\x3d\ +\xb0\xba\x2a\xa4\xa4\xa4\xd0\xb9\x73\xcd\x8f\x0f\xa7\xd3\xaa\x55\ +\xb7\xaf\xb0\x75\xeb\x56\xec\x76\xbb\x55\xbc\xb8\x89\x38\x00\x13\ +\x3c\x1e\xd3\x86\x62\xc8\x23\x22\xc1\x66\x53\x7c\xbe\xbd\xf5\xae\ +\x1c\xe1\xff\x59\x6b\xd6\x9c\xaa\x3e\x2f\x22\xd3\x80\x0b\x80\xf3\ +\x31\x1e\xb4\x7b\x45\xa4\xbf\xaa\xfa\x30\x25\x56\x42\xd5\x6b\xab\ +\x2d\x03\xad\xba\xd8\xa9\x1e\xa4\x5d\xe1\x7f\x5c\x48\xe8\x32\x19\ +\x99\x21\xc6\x2c\x2c\x2c\x5a\x90\x8c\x8c\x8c\x43\x81\xd3\xd2\xd2\ +\xd2\x9e\x0c\xb7\x2d\xcd\xcc\xf7\xe5\xe5\xe5\xf6\x95\x2b\x57\x72\ +\xe8\xa1\x35\xba\xbc\x58\x58\x84\x8d\xdc\xdc\x5c\xad\xa8\xa8\x68\ +\x50\x46\xbb\x45\x4d\x6c\x04\x9a\x9d\x67\xb7\x21\xcd\x90\xb3\x1d\ +\x7c\x3e\xa1\x6a\x5b\xb5\xd1\x88\x48\x4f\xe0\x26\xe0\x07\x4c\xc0\ +\x74\xad\xa8\x6a\xb1\xaa\xbe\xae\xaa\x17\x62\x8a\x22\xf7\x01\x4e\ +\xf7\x9f\x5e\x03\x0c\x09\x91\xdc\x31\xa2\xba\xd5\xfe\x9f\x83\xaa\ +\x8d\x9f\x53\xed\x78\x29\xfe\xc0\x6d\x55\xfd\x29\xc4\xc3\x2a\x91\ +\x61\x61\xd1\xfa\xf4\x03\x1e\xcb\xc8\xc8\x88\x0a\xb7\x21\xcd\x89\ +\xaa\xae\x73\x3a\x9d\xdb\x17\x2d\x5a\x14\x6e\x53\x2c\x2c\xf6\xe0\ +\xd4\x53\x4f\x95\x0b\x2f\xbc\x70\x7f\xcb\x50\x6f\x35\x6c\x04\x3c\ +\x41\x99\xf5\xb7\x9b\xd9\x67\xc8\xaa\xb4\xb5\xa1\xc1\x11\x2e\x7f\ +\x49\x93\x24\x11\x19\x21\x22\x77\x62\x6a\x5d\xf9\x80\xbf\xa9\x6a\ +\x48\x5f\xbc\x88\x1c\x24\x22\xa3\xaa\x09\xb7\xee\xfe\x9f\x81\x3e\ +\x8d\x53\x30\x6f\xfc\x37\x06\x5d\x77\x29\x35\xc5\xdd\x7a\x4c\x37\ +\x81\x31\x22\xd2\x4e\x44\x9c\xfe\x3a\x7c\xd5\x3b\x77\x7f\x82\x11\ +\x78\xcf\xf9\x3b\x6c\x04\xd6\x14\x11\x39\x3d\x38\xf6\xcf\xa2\xf5\ +\x11\x91\x3f\xfb\xff\xdd\x2c\x0e\x2c\x96\x62\xde\x2f\xf7\x3b\xf7\ +\x56\x45\x45\xc5\xb7\x0b\x17\x2e\xac\xa8\x7f\xa6\x85\x45\xeb\xe0\ +\xf1\x78\x88\x8c\x8c\x24\x2f\x2f\x6f\x69\xb8\x6d\x69\xab\x04\x3c\ +\x77\x1a\x24\x98\xf6\x7d\xaa\x6c\xad\xd1\x42\xac\x16\x3e\xc7\x54\ +\xfa\xcf\x05\x7e\xc1\xb4\xf2\x99\x06\xf4\x56\xd5\x50\xf1\x72\x01\ +\x7a\x60\x7a\x76\x6e\x13\x91\xb9\x22\xb2\x16\x78\x0d\xd3\xbe\xe9\ +\x2b\x00\x55\xfd\x1f\xf0\x18\xf0\xb4\x88\x2c\x13\x91\x25\xfe\xf5\ +\xff\x1b\xbc\x90\xaa\x96\x00\x13\x30\x1e\xbf\x4c\x4c\x93\xef\xc7\ +\x09\x2a\xab\xe2\x9f\xe7\xc1\x24\x69\x54\x00\x2b\xfd\x6b\x2e\xf0\ +\xdb\xfe\x31\x90\xd8\xc0\xd7\x6c\xd1\x32\x8c\xc3\x64\x48\x5b\x1c\ +\x58\xac\xc5\xbc\x87\x1c\x16\x6e\x43\x9a\x1b\x55\x9d\xb3\x78\xf1\ +\xe2\xda\xbe\xe3\xee\xb7\xf8\x7c\x3e\x96\x2c\x59\xc2\xce\x9d\x3b\ +\xeb\x9f\x6c\xd1\xaa\xe4\xe6\xe6\x02\xb0\x61\xc3\x86\xb9\x61\x36\ +\xa5\xcd\xe2\x50\x55\x8f\xb8\x22\xf2\xd9\xba\xb9\x66\x6f\x99\x7d\ +\x95\x2d\x9b\xc1\xe1\x28\x52\x8f\xa7\xbe\xfe\x2f\xb3\xa9\xf2\x8c\ +\x55\xf6\x96\xf5\xd7\xb8\x0b\x45\x81\x7f\xfe\xef\x00\xaa\x3a\xcb\ +\xef\x3d\x3b\x0a\xe8\x04\x14\x01\x8b\x54\x75\x7e\xf0\x45\xaa\x7a\ +\xa7\x88\xbc\x09\x1c\x09\x6c\xc0\x6c\xf5\xde\x59\x7d\x71\x7f\xfc\ +\xde\xaf\xfe\x79\x5b\xfd\xf6\x45\x02\xdf\x02\xbb\x83\xe6\xad\x14\ +\x91\x23\x31\x2d\xd6\xfa\x62\xb2\x64\x37\x01\xb3\x55\xb5\xee\xca\ +\x9b\x16\xfb\x04\xfe\x6d\xff\x72\x55\xcd\x0c\x1a\xeb\x08\xb4\x03\ +\xfe\x68\x40\x5f\xe4\x83\x80\x22\x55\x0d\x99\x29\xe6\xf7\x26\xf7\ +\x06\x32\x55\xb5\x59\x0a\x70\x89\x88\x1d\x13\x72\xb0\x5d\x55\xf3\ +\xea\x98\xe7\xf2\xdf\x7b\x93\xaa\xee\xae\x6d\xde\xfe\x44\x5a\x5a\ +\x9a\x2f\x23\x23\x63\x22\x55\xe5\x93\xf6\x27\xe6\x14\x17\x17\x3b\ +\xd7\xae\x5d\xdb\xa4\x7e\xab\x6d\x15\x9b\xcd\xc6\xef\xbf\xff\x8e\ +\xcf\xe7\xa3\x5d\xbb\xb6\xf3\xf1\x77\x20\xb0\x65\xcb\x16\x72\x73\ +\x73\x59\xbb\x76\xed\xf7\xe1\xb6\xa5\xad\x62\x82\xfb\xd5\x37\x97\ +\xd9\xdf\xb4\x9d\x74\x29\x63\x6b\xbd\x2d\xc3\x54\x35\x47\x55\x67\ +\xf9\x1f\xb3\x55\xf5\xb7\x3a\x84\x1d\xaa\x5a\xe1\x9f\xbb\x2d\x68\ +\x6c\xbd\xaa\xbe\xa5\xaa\xff\x56\xd5\x17\xaa\x0b\xbb\xa0\x79\x8b\ +\x54\x75\x8a\xaa\xce\xac\xeb\x03\x4f\x55\x17\xaa\x6a\x86\xaa\x7e\ +\xac\xaa\xbb\x54\x75\x9b\xff\x9e\x15\xd5\xe6\x05\x6c\xf9\xaf\xaa\ +\x3e\xab\xaa\x9f\x58\xc2\x3c\xdd\x52\x0d\x00\x00\x20\x00\x49\x44\ +\x41\x54\x2e\xbc\x88\xc8\x7c\xe0\x64\xe0\x6c\x11\x51\xff\x63\x86\ +\xff\xdc\x44\x11\xd9\x2d\x22\x47\x8b\xc8\x66\xcc\x36\xfc\xbf\xfc\ +\xe7\x86\x8b\xc8\x72\x4c\x8c\xe8\x4a\xa0\x40\x44\xee\x08\xde\xee\ +\x17\x91\xdb\x44\xc4\x27\x22\x43\x44\x64\x1d\xb0\x0e\xe3\x31\xfe\ +\xb4\x7a\xc7\x0c\x11\x19\x85\xf9\x72\xb0\x1a\xc8\xf7\x77\x4f\xb9\ +\x57\x44\x4a\x82\xe6\x1c\xe9\xb7\xef\xa8\x6a\xd7\x5e\xe2\x1f\x4f\ +\x09\x1a\x8b\x14\x91\xc7\x80\x42\xcc\x17\x9b\x1d\x22\x32\x3b\x38\ +\x2c\xc0\x3f\xaf\xbd\x88\xbc\x81\xf9\x22\xb2\x1c\xd8\x25\x22\x33\ +\x44\x24\x89\x03\x80\xb4\xb4\xb4\x27\xd3\xd2\xd2\xf6\xc7\x5e\xd4\ +\x2b\x1c\x0e\xc7\xae\xc5\x8b\x17\x87\xdb\x8e\x56\xa7\x4b\x97\x2e\ +\x35\x8a\x19\x5b\x84\x9f\xe5\xcb\x97\xf3\xd0\x43\x0f\x65\xab\x6a\ +\x4e\xfd\xb3\x2d\x42\xe1\xef\x50\x51\xf1\x01\xb3\xbe\x81\xa2\x36\ +\xf0\x25\xbc\xb4\x14\xbe\xfe\x42\xa9\xa8\x78\x2f\xdc\xa6\x58\x1c\ +\x70\x9c\x83\xf9\x52\xf1\x0d\xa6\x24\xcd\x41\xc0\xf5\x41\xe7\x23\ +\x30\xdb\xfd\xff\xc5\x34\x80\x7f\x48\x44\x3a\x60\x3c\xb3\xbb\x30\ +\x9d\x4f\x92\x81\x47\x80\x47\xab\x5d\x0b\xa6\x80\xf1\x6b\xc0\x53\ +\xfe\xeb\xef\x06\xfe\x84\xe9\x54\x62\x26\x88\xf4\x00\xbe\xc0\x94\ +\xc6\xe9\x81\x29\xe7\xb3\x1b\xf8\xfb\x5e\xbc\xae\x97\x81\x2b\x30\ +\xe1\x04\xdd\x81\xd1\x98\x2c\xee\xcf\xa5\xaa\x35\x9f\x00\x5f\x62\ +\x32\xcc\xaf\xc7\x94\x21\x1a\x0b\x0c\xf7\xbf\x66\x8b\x36\x8a\xaa\ +\xaa\xcf\xe7\x9b\xb3\x70\xe1\xc2\xb6\xf3\x05\xbf\x99\xe8\xd2\xa5\ +\x0b\xdb\xb7\x6f\xa7\xa2\xc2\x0a\x39\xdc\x97\x58\xb1\x62\x85\xcf\ +\xeb\xf5\xfe\x18\x6e\x3b\xda\x32\x81\x76\x3a\x9f\x52\xe1\xb1\xf1\ +\xf5\x4c\x38\x6f\x1f\x8f\x15\x9f\xf5\x35\x94\x96\xda\x81\x8f\xc2\ +\x6d\x4a\x3d\xfc\x88\xd9\x4e\x3d\xb0\xc9\xce\xb2\xf1\xf2\x94\x70\ +\x5b\xd1\x70\xfe\xa8\x3d\x04\x53\x55\xb3\xfc\xde\xb1\x12\x55\xdd\ +\x10\x62\x8a\x03\x78\x5a\x55\x9f\x0e\x0c\xf8\x3b\x8b\x44\x00\x17\ +\xab\x6a\x20\x58\x74\xb2\xdf\xa3\xf6\x4f\xe0\xd9\x6a\x6b\x4c\x51\ +\xd5\xe7\xfc\xcf\x1f\x11\x91\xcb\x81\x53\xf1\x7b\x01\x31\x22\xae\ +\x04\xb8\x3c\xe0\xc9\x15\x91\x9b\x30\x59\xdc\x8d\xae\x44\x2e\xa6\ +\x8f\xf2\xa5\xc0\x3f\x54\xf5\x09\xff\xf0\x66\x11\xd9\x05\x7c\x87\ +\x11\x7a\x33\x30\xa5\x79\x86\x03\x17\xaa\x6a\xa0\x62\xfc\xab\xfe\ +\x9e\xc8\x53\x44\x64\x90\xaa\x5a\x6d\x82\xda\x28\x3e\x9f\x6f\xd6\ +\x82\x05\x0b\x4e\x07\xec\xe1\xb6\xa5\x35\xe9\xd2\xa5\x0b\x5e\xaf\ +\x97\x6d\xdb\xb6\x91\x9a\xda\x86\x6a\xbd\xee\xe7\x2c\x5d\xba\xb4\ +\xc2\xe7\xf3\xfd\x12\x6e\x3b\xda\x32\x81\x92\x1b\xdb\xc5\xe5\xfa\ +\x95\x4f\x3f\x18\xc1\x79\x17\xed\xdb\xed\x8f\x3e\xfd\x40\x71\xb9\ +\x16\x68\x59\xd9\x3e\x5d\x46\x5c\x55\x67\x02\x33\xc3\x6d\x47\x98\ +\xd9\xc5\x96\xcd\xf9\x4c\xb8\x65\xdf\xfe\x9b\xaa\x8e\xdd\xee\xa5\ +\xe9\x55\x5d\x3f\xaf\x76\x3c\x14\x58\x16\x24\xec\x02\x7c\x0c\x9c\ +\x21\x22\x9d\x82\xc3\x00\x80\x0f\xaa\xcd\xfb\x09\x38\x21\xe8\x78\ +\x08\xf0\x53\xf0\x16\xbd\xaa\xfa\x44\xe4\x2b\xe0\xea\x26\xd8\x1b\ +\xd8\xb6\xb5\x8b\xc8\x75\x41\xe3\x36\xa0\x1c\x08\x34\x9d\x3e\xda\ +\x7f\xdc\xb9\xda\xbc\xf6\xfe\x9f\x03\x80\xfd\x5a\xdc\x65\x64\x64\ +\x44\x63\x12\xa0\xa6\xa4\xa5\xa5\x35\xb5\x48\xf9\xbe\xca\x9c\x5d\ +\xbb\x76\xb9\xb6\x6c\xd9\x42\xd7\xae\x6d\xa8\x5b\xd1\x5e\x12\x1d\ +\x1d\x4d\x62\x62\x22\x99\x99\x99\x96\xb8\xdb\x47\xc8\xc9\xc9\x21\ +\x32\x32\xd2\xe5\x70\x38\x16\x84\xdb\x96\xb6\x4c\x55\x23\x6c\x8f\ +\xe7\x45\x3e\x78\xe7\x70\x26\xa5\xdb\xe9\xda\xbd\x8e\x4b\xc2\xc8\ +\xe6\x8d\xf0\xf6\x34\xa5\xc2\xf3\x4a\xb8\x4d\xb1\xa8\x1f\x55\xbd\ +\x9b\x30\xf4\x68\x0d\x23\x45\xaa\xfa\x47\xb5\xb1\x4e\x98\x44\x9e\ +\xea\x04\x62\x49\x92\xa9\xaa\xd7\xa8\xaa\x5a\x3d\x03\xbc\x98\x3d\ +\x1b\xd6\x27\x63\xca\xf8\xd4\xb6\x5e\x63\xe9\xc6\xff\xb3\x77\xde\ +\xe1\x51\x95\xd9\x1f\xff\x9c\x69\xa1\x48\x11\x02\x84\x84\x2a\x20\ +\x52\x54\x14\xeb\xcf\x86\xdd\x15\x2c\xa8\xd8\xd7\x5e\x98\x75\x5d\ +\x57\x57\x5d\x7b\x6f\x6b\x59\x0b\xae\xd7\xde\x05\x15\x45\x11\x15\ +\x51\x29\x02\xd2\x02\x24\xa1\x77\x81\x40\x42\x42\x80\x40\x80\x24\ +\xd3\xce\xef\x8f\x77\x22\x21\x04\x92\x90\xc9\xdc\x94\xfb\x79\x9e\ +\xfb\x5c\xe6\xce\x7b\xdf\xf7\x3b\x40\x32\xe7\x9e\xf7\x14\x93\x6c\ +\x74\x62\x39\xef\x4d\x64\x57\xef\xe6\x8e\x18\xe3\xae\x6c\x5d\x46\ +\x30\xdb\xb5\x0d\xa1\xab\x7a\x21\xc6\x80\x9e\xcf\xfe\x77\xa0\xa9\ +\xad\xa4\xb9\xdd\xee\xc2\xb4\xb4\xb4\xc6\x0d\xc9\xb8\x03\x27\xee\ +\xae\xb6\xb1\x62\xc5\x0a\x1e\x7a\xe8\x21\x86\x0f\x1f\xbe\xc0\x6e\ +\x2d\x75\x99\xd2\xdd\x12\x3e\x40\x64\x0d\x4f\x3e\x58\x7b\xe3\x2e\ +\x9e\x78\x20\x82\x90\x05\xbc\x63\xb7\x14\x07\x87\x4a\xb2\x9a\xf2\ +\x7b\x17\x77\x8e\x9e\x33\xab\x38\x5f\xe6\x5e\xe6\x2b\xfb\x44\x56\ +\x1c\x3d\xb7\x2a\x73\xbd\x6c\x11\xed\x55\x98\x58\xbf\x9b\x54\xf5\ +\x9c\x72\x8e\x37\x4b\x8d\x03\x38\x77\x2f\xe3\xbe\xaf\xe2\xe7\xa8\ +\x73\xf8\xfd\x7e\xc5\x24\x92\xd4\xc7\x72\x28\x61\x60\x5a\x5a\x5a\ +\x5a\xc3\xaa\x87\x82\x31\xee\xf2\xf2\xf2\x08\x04\x02\x76\x4b\x71\ +\xc0\x94\x41\xc9\xcf\xcf\x0f\x4d\x9d\x3a\xb5\xb2\xa5\xce\x1c\xca\ +\xe1\x4f\xe3\x4e\x55\x43\x04\x83\xf7\xf0\xe5\x67\x2e\x16\x64\xd8\ +\xa9\xa9\x7c\xe6\xa5\xc1\x57\x23\x5c\x04\x83\xff\x56\x55\xe7\xa7\ +\xd0\xc1\x2e\x36\x53\xb5\xfe\xbe\x53\x80\x5e\x22\x72\x64\xc9\x05\ +\x11\x71\x61\x12\x18\x16\xaa\xea\xd6\x2a\xae\x3f\x05\x38\x21\x5a\ +\x6a\xa5\x64\xbe\xa6\xec\xe9\x51\x2b\xe9\x64\x72\x72\x99\xeb\x97\ +\x96\x79\x3d\x09\x63\x08\xde\x56\xde\x62\xa5\x32\x7a\xc7\x61\x5a\ +\x15\x5e\x53\x45\xbd\xf5\x8d\xf9\xc0\xa1\x76\x8b\xa8\x09\xc2\xe1\ +\xf0\xc4\xd9\xb3\x67\x37\xb8\xdf\xad\x25\x3d\x66\xb3\xb3\x1d\x5b\ +\xa2\x36\x10\x0c\x06\x75\xeb\xd6\xad\xe5\x96\x80\x72\xa8\x3c\xa5\ +\xb7\x7b\x50\xd5\x51\xe2\xf5\xcd\xe1\xdf\x77\xf4\x63\xcc\x04\x0f\ +\xae\x5a\xd2\xf3\x3d\x12\x81\xfb\xff\x19\xc6\xe3\x59\x44\x30\x38\ +\xc2\x6e\x39\x0e\x0d\x9a\xdf\x81\x8b\x45\xe4\x3d\xcc\x17\xfd\x32\ +\x55\x2d\x1b\x67\x57\x9a\xb7\x31\xdd\x4b\xbe\x17\x91\xc7\x30\xc5\ +\xa8\x6f\xc4\x74\x3a\x38\x77\x3f\xd6\x7f\x0d\xf0\x03\x63\x45\xe4\ +\x51\xcc\x56\xe9\xdd\x98\x6d\xd9\xa6\x25\x83\x54\x75\xb3\x88\xfc\ +\x08\x0c\x15\x11\x0f\xb0\x26\xba\xee\xce\xd2\x93\xa9\xea\x1f\xd1\ +\x79\x9e\x15\x91\x64\xe0\x7b\xcc\xf6\x63\x57\xe0\x32\x4c\xbd\xc6\ +\xe9\xaa\x3a\x51\x44\x3e\x00\xde\x12\x91\xc3\x31\x35\x1a\x05\x53\ +\x17\xef\xaf\xc0\x29\xfb\xaa\x8d\x57\x8f\x78\x1b\x53\xab\xb0\x3e\ +\x32\x25\x37\x37\x37\x61\xe3\xc6\x8d\xb4\x69\xd3\xc6\x6e\x2d\x71\ +\x23\x21\x21\x81\xd6\xad\x5b\x93\x95\x95\x45\xe7\xce\x9d\x2b\xbe\ +\xc1\xa1\x46\xc9\xcc\xcc\xd4\x26\x4d\x9a\x38\xfd\xf0\xaa\x89\x67\ +\x8f\x2b\xa1\xe0\x50\xa6\x4f\x9d\xc6\x13\x0f\xc0\x63\xcf\x95\x73\ +\x8b\x0d\x3c\xf5\x10\x4c\x9f\xaa\x44\x22\xb7\x36\xb8\x32\xea\x0e\ +\xb5\x8d\x37\x30\x46\xcd\x89\xc0\x05\x18\x23\xe7\x47\x8c\xf1\xb4\ +\x47\xc1\x4d\x55\x0d\x44\x33\x63\x5f\xc0\x64\xba\xb6\xc4\x6c\xed\ +\x0d\x50\xd5\xa9\xa5\x86\xae\xc3\x78\xd1\xca\xb2\x02\x93\x54\x51\ +\x32\xdf\xd6\x68\x81\xeb\x57\xa3\x47\x26\xf0\x01\xd0\x02\x78\xb4\ +\xcc\xbd\xd7\x47\xf5\x5e\x8d\x69\xd5\x37\x1c\x53\x42\xa5\xc4\x28\ +\x2c\x99\xf3\x3f\x22\xb2\x20\xaa\xef\x65\x4c\x76\xef\x3a\x4c\x17\ +\x96\xe5\xa5\xc6\xdd\x20\x22\xd3\x80\xeb\x80\x2b\x31\xb1\x7a\x7f\ +\x60\xb2\x69\xeb\x40\x1d\xa5\xea\x53\x4f\xeb\xdc\x95\x30\xd3\xe5\ +\x72\x05\xd3\xd2\xd2\xbc\x67\x9d\x75\x96\xdd\x5a\xe2\x4a\xc7\x8e\ +\x1d\xd9\xb1\xa3\x21\x84\x8d\xd6\x6e\xb2\xb3\xb3\x19\x31\x62\x84\ +\x0b\x78\xfe\xdd\x77\xdf\xb5\x5b\x4e\x9d\x46\xca\xb3\x95\x44\xe4\ +\x4a\xe0\x53\xde\xfc\x48\xb8\xdc\xe6\x5d\x98\xaf\x46\xc0\x4d\x57\ +\x02\xdc\xa0\xaa\x1f\xd8\x2b\xc6\xc1\xa1\x76\x22\x22\xf7\x01\x8f\ +\xaa\x6a\xbd\x6a\x6c\x1f\x6b\x44\xa4\x1f\x26\x21\xa5\x97\xaa\x2e\ +\xb1\x5b\x4f\x6d\xc3\xeb\xf5\x4e\x3b\xff\xfc\xf3\x8f\xbf\xf7\xde\ +\x7b\xed\x96\x12\x13\xb2\xb3\x13\x18\x3c\xb8\x1f\xef\xbe\xbb\x90\ +\xbe\x7d\x1b\xc4\xf3\x47\x9d\x66\xc2\x84\x09\x3c\xf8\xe0\x83\xaa\ +\xaa\xcd\x1b\x4a\xf7\x9b\x9a\xa2\xdc\x7d\x57\x55\x1d\x0e\x3c\xc3\ +\xdf\x6f\x8a\x30\x63\x6a\x79\x43\xe2\xc3\x9c\x59\xf0\xb7\xeb\xc2\ +\x88\xbc\xe4\x18\x76\x0e\x0e\x0e\x0e\x35\x4b\x28\x14\x9a\x98\x9a\ +\x9a\x5a\x5c\xf1\xc8\xf8\x12\x0c\x0a\x13\x26\xb4\x62\xf8\xf0\xf6\ +\x4c\x9b\xd6\x92\x48\x64\xcf\x31\x8b\x16\x35\xe5\xb5\xd7\x6a\x69\ +\xa5\x07\x87\x4a\xb1\x78\xf1\x62\xbc\x5e\xef\x4a\xc7\xb0\xab\x3e\ +\xfb\x0a\xaa\x7b\x18\x61\x34\x17\x9c\x11\xe6\x9b\x2f\xe3\x26\xe8\ +\x4f\x7e\xf8\x16\x06\x0e\x08\x13\x89\x8c\x43\xb5\x7e\x3c\x46\x3a\ +\x38\x38\xd4\x79\x2c\xcb\x3a\xc7\xb2\xac\x5f\xed\xd6\x51\x43\x4c\ +\xce\xcc\xcc\x4c\xd8\xba\xb5\xaa\x79\x3e\x35\x47\x61\xa1\x9b\x5b\ +\x6f\xed\xc3\x03\x0f\xf4\xe0\xb5\xd7\x3a\x71\xd7\x5d\x3d\xb9\xf5\ +\xd6\x3e\x64\x66\x36\xda\x6d\xdc\xea\xd5\x8d\x19\x39\x32\x69\x2f\ +\xb3\x38\xd4\x05\x8a\x8a\x8a\xc2\x89\x89\x89\xb5\x30\xa3\xb3\xee\ +\xb1\x57\xe3\x4e\x55\x95\x60\x70\x08\x81\xe0\xeb\x5c\x7f\x19\x3c\ +\xfd\x30\xc4\x2b\xdc\xed\x85\xa7\xe0\xea\x8b\xa0\xb8\xe8\x1d\x42\ +\xa1\x0b\x54\xb5\x9c\xe7\x34\x07\x07\x87\x12\x54\xf5\x39\x67\x4b\ +\x36\x6e\x6c\x07\x4e\xb7\x2c\xab\x2a\x59\xd3\x75\x85\x69\x22\x12\ +\xc9\xc8\xa8\x3d\xdf\xaf\x9f\x7d\xd6\x9e\x25\x4b\x9a\x70\xe3\x8d\ +\xeb\xf9\xe2\x8b\x0c\x9e\x7c\x72\x05\x1b\x36\xf8\xb8\xf9\xe6\x3e\ +\x2c\x5e\xdc\xb4\xe2\x09\x1c\xea\x04\xa1\x50\x88\x01\x03\x06\xb8\ +\x8f\x3d\xf6\xd8\xda\xf3\x64\x51\x87\xd9\x67\x3a\xac\xaa\x86\x35\ +\x12\xfe\x27\x70\x33\x2f\x3d\x13\xe6\xb2\x41\x61\xd6\xfc\x51\x73\ +\x6a\xd6\xad\x85\xab\x2e\x8c\xf0\xcc\x23\x61\x54\xff\xae\x91\x88\ +\x5f\x55\x9d\xa6\x7f\x0e\x0e\x0e\xb5\x89\x54\xa0\x88\xdd\x3b\x87\ +\xd4\x0b\x54\xb5\xc0\xe3\xf1\x2c\x48\x4b\xab\x3d\xc9\x8a\x33\x67\ +\x36\xa7\x7f\xff\x02\x6e\xbe\x79\x1d\x9d\x3b\x17\x71\xe6\x99\x9b\ +\xf8\xe4\x93\xf9\x74\xed\x5a\xc8\xdf\xff\xde\x8b\xf9\xf3\x0f\x88\ +\xd9\x5a\xe1\x70\xd8\xe9\x33\x6b\x13\x7f\xfc\xf1\x07\x22\xc2\xaa\ +\x55\xab\x9c\xbe\xf1\x31\xa0\x52\xb5\x4e\x54\xf5\x5d\x22\x91\xd3\ +\x98\xf8\x4b\x36\xfd\x0f\x8e\xf0\xc0\x5d\xb0\x79\x53\xec\x54\x6c\ +\xcd\x87\x47\xee\x85\x23\xba\x87\xf9\x79\x6c\x16\xaa\x67\xab\x6a\ +\xd9\x9e\x9b\x0e\x0e\x0e\x0e\xb6\xe3\xf7\xfb\x8b\x81\x59\xc0\x00\ +\x9b\xa5\xd4\x08\xc1\x60\x70\x7c\x6d\x8a\xbb\xdb\xb4\xc9\xc7\x51\ +\x47\xed\xee\xcc\x69\xd9\x32\xc4\x2b\xaf\x2c\xe1\xd0\x43\x0b\xb8\ +\xe3\x8e\x43\x98\x37\xaf\x59\xb5\xd7\x51\x55\x46\x8c\x18\xc1\xd2\ +\xa5\x4b\xab\x3d\x97\x43\xd5\xc9\xc9\xc9\x21\x37\x37\x97\x8c\x8c\ +\x8c\x09\x76\x6b\xa9\x0f\x54\xba\x90\x9d\xaa\x4e\x26\x18\xec\x46\ +\x28\x74\x17\x6f\x0f\xcb\xe7\xd0\xce\x21\x9e\x7b\x1c\x96\x55\x23\ +\xe1\x6c\xc5\x32\xb3\x05\xdb\xa7\x53\x88\x37\x5e\xd9\x4a\x30\x78\ +\x0f\xc1\x40\x37\x55\x1d\xbf\xff\x93\x3a\x38\x38\x38\xd4\x38\x37\ +\x03\x77\xda\x2d\xa2\x86\x98\xbc\x72\xe5\x4a\x5f\x61\x61\xa1\xdd\ +\x3a\x00\x68\xdd\x3a\x40\x56\x56\xc2\x1e\xd7\x13\x12\x22\xbc\xf0\ +\xc2\x32\x8e\x3a\x6a\x1b\x77\xdc\xd1\x93\x8c\x8c\xea\x19\x78\x22\ +\x42\x9b\x36\x6d\x9c\x56\x64\x36\xb1\x62\xc5\x0a\xa6\x4f\x9f\xbe\ +\x5e\x55\x8b\xec\xd6\x52\x1f\xd8\xb3\xce\xdd\x3e\x88\x76\x86\x78\ +\x55\x44\x3e\x20\x14\xba\x87\x97\x9e\x19\xca\x73\x8f\x25\xd2\xe5\ +\xa0\x00\x17\x0e\xf1\x71\xe6\x5f\xa0\xcb\x41\xd0\xae\x3d\x78\xca\ +\x4c\x1d\x0a\x41\x4e\x36\xac\xf9\x03\x7e\x19\x0b\xa3\xbf\x0a\xb0\ +\x6a\x85\x0f\xaf\x6f\x33\xc1\xc0\xdb\xc0\x73\xfb\x51\xad\xdf\xc1\ +\xc1\xa1\x1c\x44\xe4\x12\x20\x4f\x55\x27\xd9\xad\xa5\x3e\xe2\xf7\ +\xfb\x97\xd9\xad\xa1\x06\x99\xaa\xaa\xcc\x9b\x37\x8f\x63\x8f\x3d\ +\xd6\x6e\x2d\xf4\xeb\xb7\x9d\xb1\x63\x5b\x13\x0a\x09\x1e\xcf\xee\ +\x71\xdf\x5e\xaf\xf2\xcc\x33\xcb\x79\xe0\x81\x1e\x8c\x1e\xdd\x16\ +\xaf\xb7\x7a\x71\xe1\x29\x29\x29\xcc\x9d\x3b\x17\x55\x65\x57\x73\ +\x16\x87\x78\xf0\xd5\x57\x5f\x05\xf3\xf2\xf2\x3e\xb2\x5b\x47\x7d\ +\x61\xbf\x5a\x50\xa8\xea\x36\x55\x7d\x98\x60\xa0\x2d\xf0\x7f\xac\ +\x5e\xf5\x2a\x6f\xbc\xbc\x86\x81\x03\xa0\x4f\x27\x68\xe3\x53\xba\ +\x26\x06\x38\xe1\xf0\x22\x4e\x38\xbc\x88\x83\x12\x03\xb4\xf1\x29\ +\x7d\x3a\xc1\xb9\xa7\xc0\xff\xfe\x9b\xc9\xaa\x15\xc3\x80\x13\x09\ +\x06\xda\xa8\xea\xfd\x8e\x61\xe7\x50\x9f\x10\x91\xbf\x89\xc8\xa9\ +\x36\x4a\x78\x08\xb8\xd6\xc6\xf5\x1d\xea\x28\xaa\x9a\xe7\xf5\x7a\ +\x57\xd6\x96\xb8\xbb\xb3\xcf\xce\xa3\x63\xc7\x22\x16\x2d\x2a\x3f\ +\xb6\xce\xe3\x31\x06\xde\xd9\x67\x6f\xa2\x53\xa7\xea\x79\x1b\x93\ +\x93\x93\x09\x04\x02\xe4\xe5\xe5\x55\x6b\x1e\x87\xaa\xf1\xc7\x1f\ +\x7f\x90\x97\x97\xe7\x05\xc6\xda\xad\xa5\xbe\x50\x25\xcf\x5d\x59\ +\xa2\xdd\x22\xa6\x47\x8f\x7b\xa3\xed\x8b\x52\x50\x4d\x66\xcb\xa6\ +\x14\xb6\x6c\x4a\xc6\x54\xf3\xcf\x02\xd6\x97\x9c\xb5\xb8\x78\x7d\ +\x35\x75\x3b\x38\xd4\x76\xee\x07\xbe\x00\x26\xda\x2d\xc4\xa1\xe6\ +\xb0\x2c\xab\x91\xdf\xef\xaf\x77\xdb\x48\xc1\x60\xf0\xd7\xd9\xb3\ +\x67\x77\x02\x7c\x76\x6b\xe9\xde\x7d\x27\x96\xb5\x78\x9f\x63\x3c\ +\x1e\xe5\xf1\xc7\x57\x54\x7b\xad\x56\xad\x5a\xd1\xb8\x71\x63\xb2\ +\xb2\xb2\x1a\x54\x0b\x36\xbb\x99\x3e\x7d\x3a\x6e\xb7\x7b\x7b\x38\ +\x1c\x9e\x6e\xb7\x96\xfa\x42\xb5\x8c\xbb\xb2\xa8\x6a\x16\xc6\x80\ +\x73\x70\xa8\xf7\x88\x48\x57\x20\xa0\xaa\xfb\xf5\xb0\x22\x22\x29\ +\x40\x82\xaa\xae\xaa\x60\x9c\x17\xd3\xc3\xf5\x0f\x55\x2d\xd7\x35\ +\x21\x22\x8d\x80\xce\xc0\xf2\x58\x95\x0e\x12\x91\x03\x80\x4e\xc0\ +\x8a\x68\x48\x86\x43\x29\x2c\xcb\xba\x8b\x5d\x7d\x82\xeb\x1b\x53\ +\x96\x2c\x59\x72\x4b\x30\x18\xc4\xeb\xf5\xda\xad\x25\xae\x24\x27\ +\x27\x93\x95\x95\xc5\xe1\x87\x1f\x6e\xb7\x94\x06\x43\x20\x10\xd0\ +\xa3\x8f\x3e\x3a\x6d\xfa\xf4\xe9\x61\xbb\xb5\xd4\x17\xf6\x6b\x5b\ +\xd6\xc1\xa1\xa1\x22\x86\xdb\x44\x64\x13\xb0\x0a\x58\x27\x22\x4b\ +\x45\xe4\x84\x52\x63\x0a\x80\x0e\xc0\xbf\x44\x44\xa3\xc7\x53\xa5\ +\xde\xbf\x44\x44\xd6\x61\xfa\xb7\xae\x14\x91\x2c\x11\xb9\xb0\xcc\ +\x3a\x33\x45\x64\xb8\x88\xdc\x05\x6c\xc1\xf4\xa3\xdd\x2a\x22\xff\ +\x28\x33\xce\x25\x22\x4f\x03\x5b\x81\x25\xc0\xa6\x68\xfb\xc0\xb2\ +\xba\x5f\x16\x91\xd5\xe5\x5c\xff\x46\x44\x26\x95\xb9\xd6\x3d\x7a\ +\x6d\x5b\x74\xdd\x02\x11\x79\x41\x44\x6c\xf7\xe2\xd4\x32\x16\x00\ +\xbd\x2d\xcb\xaa\x8f\x2e\x9e\xc9\xa1\x50\xc8\xb5\x70\xe1\x42\xbb\ +\x75\xc4\x9d\xe4\xe4\x64\x72\x72\x72\x88\x94\xd7\x06\xc3\x21\xe6\ +\xec\xdc\xb9\x93\x5e\xbd\x7a\x49\xb7\x6e\xdd\x9c\x76\x80\x31\xc4\ +\x31\xee\x1c\x1c\xaa\xc6\xbf\x80\x57\x80\x37\x80\xde\xc0\x09\xc0\ +\x72\x60\x5c\x34\x2c\x01\x8c\x27\x67\x03\xf0\x0e\xd0\x35\x7a\xbc\ +\x08\x20\x22\x17\x01\x23\x81\xd1\xc0\xd1\xc0\x61\xc0\xcf\xc0\xd7\ +\x22\xd2\xbf\xcc\x5a\x67\x03\x03\x81\xcb\x80\x23\x80\x1f\x81\xff\ +\x8a\x48\xcf\x52\x63\xee\x00\xee\x8b\xea\x3a\x10\x53\x9e\xe3\x1e\ +\xa0\xfb\xfe\x7c\x38\x11\x39\x10\x98\x81\xf1\xea\x0f\x01\x52\x80\ +\x07\x81\x5b\x80\x47\xf7\x67\xce\x7a\xcc\x34\x20\x0c\x9c\x64\xb7\ +\x90\x58\xa3\xaa\xeb\xbc\x5e\xef\xfa\xf4\xf4\x74\xbb\xa5\xc4\x9d\ +\xe4\xe4\x64\x42\xa1\x10\x39\x39\x39\x76\x4b\x69\x10\xa4\xa7\xa7\ +\xe3\xf5\x7a\x89\x44\x22\x6f\xdb\xad\xa5\x3e\xe1\x18\x77\x0e\x0e\ +\x95\x44\x44\x9a\x02\x0f\x03\xdf\xa8\xea\xc3\xaa\xba\x58\x55\xa7\ +\x61\x12\x17\x7c\xc0\xdf\x01\x54\x75\x2d\x10\x02\xb6\xa9\xea\xea\ +\xe8\x91\x1f\x9d\xe6\x39\x60\x8e\xaa\xde\xa6\xaa\xb3\x55\x75\x3e\ +\x66\x6b\x2f\x0f\x63\x94\x95\xa6\x05\x70\x85\xaa\xfe\xa0\xaa\xe9\ +\x18\x23\xcb\x0d\x9c\x16\xd5\x23\xc0\xbf\x81\x91\xaa\xfa\xba\xaa\ +\xe6\xab\x6a\x06\xc6\x10\xdb\xdf\xd2\xfd\x77\x63\x8c\xc4\x6b\x55\ +\xf5\x6b\x55\xcd\x52\xd5\x17\x81\xe1\x18\x4f\x64\xc3\xda\xa3\xdb\ +\x07\x7e\xbf\x7f\x3b\x30\x13\xe8\x62\xb3\x94\x1a\x21\x18\x0c\x8e\ +\x9f\x33\x67\x4e\xd0\x6e\x1d\xf1\xa6\x59\xb3\x66\x34\x6f\xde\xdc\ +\x29\x89\x12\x27\xb2\xb2\xb2\xd8\xba\x75\x6b\x70\xf8\xf0\xe1\xb3\ +\xed\xd6\x52\x9f\x88\x69\xcc\x9d\x83\x43\x3d\xa7\x17\xd0\x1c\xd8\ +\x22\x22\x43\xcb\xbc\xb7\x2e\xfa\xfe\x5e\x11\x91\x56\x98\xd8\xb9\ +\x51\xe5\xdc\xbf\xa6\x9c\xfb\x7f\x57\xd5\xdc\x52\xaf\x17\x61\xb6\ +\x4a\x4b\x3c\x84\x49\x40\x3b\xe0\xa7\xd2\x37\xa9\x6a\xaa\x88\x6c\ +\xa9\xe0\xb3\xec\x8d\xe3\x80\x4c\xe0\x4c\x11\x39\xb3\xcc\x7b\x09\ +\x18\x2f\x64\x7d\x2e\x03\x52\x55\x4e\xf2\xfb\xfd\xf5\x75\xff\x6e\ +\xf2\xbc\x79\xf3\xae\x8c\x44\x22\xb8\x5c\x0d\xcb\x0f\x50\x12\x77\ +\xd7\xbf\x7f\x59\x67\xba\x43\xac\x19\x3d\x7a\x74\xa8\x43\x87\x0e\ +\x5f\xdf\x77\xdf\x7d\x76\x4b\xa9\x57\x38\xc6\x9d\x83\x43\xe5\xe9\ +\x14\x3d\xf7\xc1\x24\x2f\x94\x66\x19\xb0\xb2\x92\xf7\x77\x01\x2e\ +\x2c\xf3\xde\x66\x8c\xf7\xae\x34\xbb\x25\x6a\xa8\xaa\x8a\x48\x11\ +\xc6\x7b\x07\xd0\x36\x7a\x2e\xcf\x90\xdb\x58\x81\x96\x7d\x69\xf4\ +\x96\xa3\x0f\x60\x5c\xa9\xb5\x1d\x80\x7a\x6c\xd8\x01\x4c\x2e\x2e\ +\x2e\xf6\x2c\x5d\xba\x94\x5e\xbd\xf6\xf9\xdc\x52\xef\xe8\xd3\xa7\ +\x0f\x45\x45\xf5\x2e\x09\xba\xd6\xb1\x7a\xf5\x6a\x96\x2f\x5f\xee\ +\x59\xbe\x7c\xf9\xeb\x76\x6b\xa9\x6f\x38\xc6\x9d\x83\x43\xe5\x29\ +\x31\xde\x9e\x57\xd5\xef\xf6\xe3\xfe\x92\xac\xd8\x4f\x54\xf5\x95\ +\x18\xe8\x59\x1b\x3d\xb7\x2f\x7d\x51\x44\x5c\x98\x84\x8e\xd2\x14\ +\x01\x2d\x45\xc4\x55\x26\x9b\xf6\x50\x8c\xd7\xb1\xb4\xc6\x03\x54\ +\xf5\x9c\x18\xe8\x73\xa8\xc3\xa8\xea\x72\xaf\xd7\xbb\x29\x3d\x3d\ +\xbd\x75\x6d\x32\xee\xf2\xf3\xbd\x4c\x9e\xdc\x92\xdc\xdc\x04\x8a\ +\x8b\x77\x2f\x34\xec\x76\x2b\x43\x87\xae\xdb\xcb\x9d\x95\xe7\xc0\ +\x03\x0f\xac\xf6\x1c\x0e\x15\x33\x7d\xfa\x74\x3c\x1e\x4f\x41\x28\ +\x14\x9a\x61\xb7\x96\xfa\x86\x63\xdc\x39\x38\x54\x9e\xc5\x98\x2d\ +\xcb\xbf\x01\x7b\x18\x77\x22\x22\xd1\xda\x8f\x60\x3c\x71\x5d\x4b\ +\xbf\xaf\xaa\xdb\x44\x64\x3a\x70\x93\x88\xbc\x51\xb6\xbc\x48\x99\ +\xfb\x2b\x44\x55\xb7\x88\xc8\x42\xe0\x2a\xe0\xcd\x52\x6f\x9d\x07\ +\x34\x29\x33\x7c\x2d\x26\x86\xef\x30\x20\x3d\xba\x5e\x7f\xa0\x1b\ +\xbb\x1b\x77\x3f\x01\x2f\x88\x48\x7f\x55\x9d\x53\x1d\x7d\x0d\x05\ +\xcb\xb2\x9a\x03\xa7\xfa\xfd\xfe\xd1\x76\x6b\x89\x35\x91\x48\x64\ +\xe2\xdc\xb9\x73\x07\x5f\x71\xc5\x15\xb5\xc2\x63\x9b\x96\xd6\x9c\ +\xbb\xee\x3a\x98\xc2\x42\x37\x8d\x1a\x45\x68\xd2\x64\xf7\xca\x19\ +\x5e\x6f\x6c\x8c\x3b\x87\xf8\xf0\xfb\xef\xbf\x87\x23\x91\xc8\x4f\ +\xaa\xea\x94\x40\x89\x31\x8e\x71\xe7\xe0\x50\x49\x54\x35\x10\x8d\ +\x95\x1b\x2d\x22\xbf\x02\x1f\x61\xb6\x52\x3b\x00\xe7\x62\x0c\xa3\ +\xb7\xa2\xc3\xa7\x02\x7f\x15\x91\xd7\x30\xde\xb0\x99\xaa\x3a\x1d\ +\xf0\x03\xbf\x03\xd3\x45\xe4\x0d\xcc\xd6\x6b\x12\x26\x49\x62\x2d\ +\xa6\xb3\x44\x55\x78\x10\xf8\x46\x44\x3e\x01\x3e\xc3\x6c\x17\xdf\ +\x03\xe4\x96\x19\x37\x0a\x93\xb1\xfb\xa9\x88\xbc\x89\x31\x3c\x2f\ +\x61\xcf\xad\xe4\x61\xc0\x15\xc0\x2f\x22\xf2\x12\xc6\x10\x6c\x8a\ +\x31\x0a\x4f\x03\xfe\xaf\x8a\xfa\x1a\x02\xfd\x81\x6f\x2d\xcb\xea\ +\xe2\xf7\xfb\xd7\xd8\x2d\x26\x96\x44\x22\x91\xdf\xd2\xd2\xd2\x2e\ +\x50\x55\x77\x6d\x68\xc7\x35\x6c\x58\x27\xda\xb4\x09\xf2\xc0\x03\ +\x4b\x39\xf4\xd0\xed\xb8\xdd\xce\xb3\x46\x5d\x65\xc7\x8e\x1d\x5c\ +\x7e\xf9\xe5\xee\x16\x2d\x5a\x38\x31\xbc\x35\x40\xc3\x8a\x92\x75\ +\x70\xa8\x26\xaa\xfa\x23\xa6\x84\xc9\x4e\xe0\x31\x4c\x16\xe9\x5d\ +\x18\x63\xea\xb7\x52\x43\xef\x07\xfe\x8b\x31\xb6\x2e\xc0\x94\x4d\ +\x21\x9a\xcd\xda\x17\x58\x8a\x31\xc2\x3e\xc7\x18\x68\x2e\xe0\xfb\ +\x52\xf7\xcf\xc5\x24\x50\x94\x65\x1a\xbb\xb6\x77\x51\xd5\xd1\x98\ +\xf8\xb8\xee\xc0\x87\xd1\xb5\x86\x00\x63\x30\x75\xef\x4a\xc6\xe5\ +\x00\x83\x30\xdb\xb3\x8f\x62\x8c\xb5\xab\x81\x11\x44\x3d\x79\xd1\ +\x71\x21\x4c\x69\x8f\x61\xc0\x60\xe0\x13\xe0\x25\x4c\xa2\xc5\x87\ +\x15\xfc\xf5\x34\x54\x26\x03\x9b\x80\x8b\xec\x16\x52\x03\x4c\xd9\ +\xbe\x7d\xbb\x77\xf5\xea\xd5\x76\xeb\x00\x60\xed\xda\x46\x5c\x76\ +\xd9\x06\xfa\xf5\x2b\x70\x0c\xbb\x3a\xce\xfc\xf9\xf3\xf1\xf9\x7c\ +\xec\xd8\xb1\xe3\x03\xbb\xb5\xd4\x47\x1c\xcf\x9d\x83\x43\x15\x89\ +\x96\x25\x39\xbf\x82\x31\xdb\x30\xc6\x5f\x79\xef\xad\x06\xf6\x28\ +\x34\x5c\x66\x8c\x7f\x2f\xd7\x07\x97\x73\xed\x3b\xf6\xdc\x26\xbe\ +\xa9\x9c\x71\x13\x81\xa3\xca\x5c\x9e\x52\xce\xb8\x62\x8c\x01\xe8\ +\xd4\xb5\xab\x04\x7e\xbf\x3f\x6c\x59\xd6\x77\x18\x63\xf8\x65\xbb\ +\xf5\xc4\x98\xf9\x6e\xb7\x7b\x7b\x5a\x5a\xda\x01\x5d\xbb\x76\xad\ +\x78\x74\x0d\xd3\xa3\xc7\x0e\x36\x6e\x8c\x5f\x2d\xed\xf4\xf4\x74\ +\x92\x92\x92\x48\x4a\x4a\x8a\xdb\x9a\x0d\x85\xad\x5b\xb7\x92\x9f\ +\x9f\x5f\x30\x7d\xfa\xf4\x8a\x12\xd1\x1c\xf6\x03\xc7\x73\xe7\xe0\ +\xe0\xe0\x50\x7d\x3e\xa2\x1e\xf6\x11\x8e\x26\xdf\x4c\x4e\x4b\x4b\ +\xab\x15\x59\xc1\xd7\x5f\x9f\xc5\x4f\x3f\x25\xb2\x66\x4d\xa3\xb8\ +\xac\x97\x99\x99\xc9\xca\x95\x8e\xed\x11\x6b\x54\x15\xaf\xd7\xab\ +\x6b\xd7\xae\xfd\xad\xe2\xd1\x0e\xfb\x83\xe3\xb9\x73\x70\x70\x70\ +\xa8\x26\x7e\xbf\xff\x37\x76\xdf\x96\xaf\x37\x84\xc3\xe1\xdf\x66\ +\xcf\x9e\x7d\x06\xa6\x50\xb7\xad\xa4\xa7\x37\xc3\xed\x8e\x70\xd9\ +\x65\x87\x73\xd0\x41\x85\x1c\x74\xd0\xce\xdd\xde\xf7\x78\x94\xc7\ +\x1e\x8b\x9d\x31\x96\x9c\x9c\xcc\xaa\x55\xfb\x6c\xfd\xec\xb0\x1f\ +\xac\x59\xb3\x86\x07\x1f\x7c\x50\x9a\x36\x6d\xfa\x82\xdd\x5a\xea\ +\x2b\x8e\x71\xe7\xe0\xe0\xe0\xe0\xb0\x2f\x26\x6f\xd9\xb2\xc5\x97\ +\x95\x95\x45\x72\x72\x72\xc5\xa3\x6b\x90\x0d\x1b\x12\x68\xd2\x24\ +\x42\x8f\x1e\xc6\xa8\x5b\xb3\xa6\xf1\x6e\xef\x7b\xbd\xb1\x8d\xc3\ +\x4b\x4e\x4e\x26\x2d\x2d\x8d\x1d\x3b\x76\xd0\xb4\xe9\xfe\x36\x7d\ +\x71\x28\xcb\xe4\xc9\x93\x71\xb9\x5c\x05\xdb\xb7\x6f\xff\xdd\x6e\ +\x2d\xf5\x15\xc7\xb8\x73\x70\x70\x70\x70\xd8\x17\x73\x5c\x2e\x57\ +\x71\x5a\x5a\x5a\x82\xdd\xc6\xdd\x23\x8f\xc4\x77\x8b\xb4\x6d\xdb\ +\xb6\x78\x3c\x1e\xb2\xb2\xb2\xe8\xd1\xa3\x47\x5c\xd7\xae\xcf\x7c\ +\xf7\xdd\x77\xc1\x48\x24\x32\xc2\x29\x81\x52\x73\x38\x31\x77\x0e\ +\x0e\x0e\x0e\x31\xc2\xb2\xac\x57\x2d\xcb\xda\x23\xe9\xa5\x2e\xa3\ +\xaa\x41\x97\xcb\x35\x33\x3d\x3d\xbd\xc1\xa5\xa7\xba\xdd\x6e\xda\ +\xb5\x6b\xc7\xfa\xf5\xeb\x2b\x1e\xec\x50\x29\x16\x2c\x58\x80\xdb\ +\xed\xf6\xaa\xaa\x93\x25\x5b\x83\x38\x9e\x3b\x07\x07\x07\x87\xd8\ +\xd1\x15\x53\xfe\xe6\x1b\xbb\x85\xc4\x92\x50\x28\x34\x21\x35\x35\ +\xf5\x58\x4c\x7f\x61\x5b\x29\x28\xf0\xf0\xc9\x27\xed\xc9\xc8\x68\ +\x46\x6e\xae\x8f\x03\x0f\x0c\xd1\xad\xdb\x4e\xae\xbb\x2e\x8b\x94\ +\x94\xd8\xb7\x0c\x4b\x4e\x4e\x66\xd1\xa2\xf2\xaa\x12\x39\xec\x0f\ +\xab\x57\xaf\xe6\xea\xab\xaf\x2e\x7e\xea\xa9\xa7\x9c\xae\x14\x35\ +\x88\xe3\xb9\x73\x70\x70\x70\x88\x1d\x5f\x01\x67\x5b\x96\x75\x80\ +\xdd\x42\x62\xcc\xe4\x0d\x1b\x36\x24\x6c\xda\xb4\xc9\x56\x11\x79\ +\x79\x5e\x2e\xbb\xec\x30\x3e\xfd\xb4\x3d\x22\xd0\xb7\xef\x76\x9a\ +\x35\x0b\x31\x7e\x7c\x2b\x2e\xbf\xfc\x30\xe6\xcd\x6b\x16\xf3\x35\ +\x93\x93\x93\xd9\xb1\x63\x07\x5b\xb7\x6e\x8d\xf9\xdc\x0d\x8d\xe2\ +\xe2\x62\x5a\xb6\x6c\x49\x56\x56\xd6\x04\xbb\xb5\xd4\x77\x1c\xcf\ +\x9d\x83\x83\x83\x43\xec\x18\x03\xbc\x0b\xfc\x05\x18\x69\xb3\x96\ +\x58\x32\x43\x44\xc2\xe9\xe9\xe9\xee\xd3\x4f\x3f\xdd\x36\x11\xc3\ +\x86\x75\xa2\x49\x93\x30\xef\xbc\xb3\x90\x94\x94\xe2\x3f\xaf\x17\ +\x14\xb8\x79\xf8\xe1\x1e\x3c\xfd\x74\x57\xbe\xf8\x62\x5e\x4c\xd7\ +\x4c\x4c\x4c\xc4\xe7\xf3\xb1\x7e\xfd\x7a\x5a\xb4\x68\x11\xd3\xb9\ +\x1b\x1a\x33\x66\xcc\xa0\x59\xb3\x66\x04\x02\x81\x27\xed\xd6\x52\ +\xdf\x71\x3c\x77\x0e\x0e\x0e\x0e\x31\xc2\xef\xf7\x6f\xc1\x74\xf8\ +\x18\x65\xb7\x96\x58\xa2\xaa\x85\x1e\x8f\x27\x2d\x3d\x3d\xbd\xe2\ +\xc1\x35\x48\x46\x46\x73\x6e\xbe\x79\xdd\x6e\x86\x1d\x40\xb3\x66\ +\x61\xee\xbc\x73\x35\x6b\xd6\x34\x26\x3f\xdf\x1b\xd3\x35\x45\x84\ +\xf6\xed\xdb\x93\x9d\x9d\x1d\xd3\x79\x1b\x22\x93\x26\x4d\x8a\xa4\ +\xa6\xa6\xae\xfd\xf4\xd3\x4f\xa7\xdb\xad\xa5\xbe\x13\x17\xcf\x9d\ +\x98\xa6\x84\x07\x02\xdb\xcb\x36\x4b\x77\x70\x70\x70\xa8\x4f\xf8\ +\xfd\xfe\x99\x76\x6b\xa8\x09\x82\xc1\xe0\xf8\x59\xb3\x66\x1d\x8a\ +\x8d\x71\x77\x45\x45\x42\xa3\x46\xe5\xd7\x53\x6e\xdc\xd8\x5c\x2f\ +\x2e\x8e\x7d\x0f\xdc\x0e\x1d\x3a\x38\x49\x15\xd5\x24\x2f\x2f\x8f\ +\x9f\x7e\xfa\x49\x54\xf5\x9e\xf7\xdf\x7f\xdf\x6e\x39\xf5\x9e\x98\ +\x18\x77\x22\x72\x18\xd0\x0d\xd3\x00\xbd\x3d\x90\x84\xc7\xd3\x01\ +\x8f\xa7\x03\x11\x4d\xc2\xe5\x6a\x45\x24\xe2\x06\x10\x9f\xaf\x00\ +\xb7\x3b\x87\x48\x24\x8b\x40\x60\x2d\xb0\x01\xc8\x8e\x9e\xb3\x80\ +\x59\xaa\xba\x73\x2f\x4b\xc5\x14\x11\x69\x06\x5c\x05\xfc\x14\x6d\ +\x09\x85\x88\x9c\x0d\x24\x44\x5b\x3a\x21\x22\xed\x31\xfd\x3a\x47\ +\xaa\xaa\xbd\x01\x27\x0e\x0e\x0e\x0e\xf6\x31\x65\xed\xda\xb5\xf7\ +\x16\x14\x14\xd0\xac\x59\xec\x63\xdb\x2a\xc3\x21\x87\xec\xe4\xcb\ +\x2f\x93\x38\xe1\x84\x7c\x3c\x9e\xdd\x93\x77\x47\x8c\x68\x4f\xcb\ +\x96\x21\xda\xb5\x8b\xbd\xff\xa0\x57\xaf\x5e\xf4\xea\xd5\x2b\xe6\ +\xf3\x36\x24\xc6\x8e\x1d\x8b\xcb\xe5\xda\x1e\x0e\x87\x47\xdb\xad\ +\xa5\x21\xb0\x5f\xc6\x9d\x88\xb8\x80\x13\x80\x8b\xf0\xfa\x2e\x05\ +\x92\x71\xb9\x95\x03\x0f\x0c\xd2\xae\x7d\x84\xe4\x14\x0f\xed\x53\ +\x3c\x24\xb5\x87\xb6\x49\xd0\x2e\x09\xda\xb4\x85\x82\x02\xc8\xc9\ +\x6e\xc6\x86\xec\x66\xe4\x64\x77\x27\x3b\x2b\xc2\xfa\xcc\x20\x1b\ +\xb2\x60\x53\x9e\x97\x60\xd0\x85\xdb\x5d\x2c\x6e\xf7\x58\x22\x91\ +\x91\xc0\x0f\xaa\x5a\xe5\x28\x56\x11\xe9\x0b\xfc\xba\x8f\x21\xa7\ +\xa9\xea\x22\xa0\x35\x60\x61\x1a\xaf\xaf\x8e\xbe\x37\x14\xe3\x65\ +\x2c\xe9\xd5\x79\x70\x74\xcc\x0c\x4c\x73\x70\x07\x07\x07\x87\x0a\ +\xb1\x2c\xeb\x30\x60\x91\xdf\xef\x0f\xd9\xad\x25\x46\x4c\x05\xc8\ +\xc8\xc8\xe0\xc4\x13\x4f\xb4\x45\x80\xdf\x9f\xc9\x8d\x37\xf6\x61\ +\xc8\x90\xc3\x39\xe3\x8c\xcd\x24\x26\x06\xd8\xb6\xcd\xc3\xb4\x69\ +\x2d\x59\xbc\xb8\x29\x0f\x3f\xec\xb4\x0a\xab\xad\x8c\x1e\x3d\x3a\ +\x18\x89\x44\x3e\x89\xf6\xae\x76\xa8\x61\x2a\x6d\xdc\x89\x88\x17\ +\x38\x0d\x91\x8b\xf0\x7a\x2f\x21\x18\x6c\xc5\x41\x3d\x02\x5c\x7c\ +\x99\x8f\xf3\x2e\x82\xbe\x87\x0b\x2e\x57\x55\xdb\xd3\xb8\x28\xed\ +\xe2\xdf\x90\x05\x63\xc7\x24\x30\xfa\xab\x41\x4c\x99\x78\x3e\xaa\ +\x11\xf1\x7a\x27\x10\x0a\x7d\x09\x8c\x56\xd5\xbc\x4a\xce\xeb\x05\ +\xda\x01\x9f\x11\xfd\x85\x54\x86\x0d\x55\xd0\xb8\x0c\xf0\x03\x99\ +\x55\xb8\xc7\xc1\xc1\xa1\x01\x63\x59\x56\x5b\x60\x2e\x70\x19\xf0\ +\xb5\xcd\x72\x62\x82\xaa\x6e\xf5\xf9\x7c\x8b\xd3\xd3\xd3\x7b\xdb\ +\x65\xdc\xf5\xec\xb9\x83\xb7\xdf\x5e\xc8\x5b\x6f\x75\x64\xe4\xc8\ +\x76\x14\x15\xb9\xf0\x78\x94\x83\x0e\xda\xc9\x73\xcf\x2d\x67\xc0\ +\x80\xcd\xb6\xe8\x72\xd8\x37\xf3\xe7\xcf\xe7\xca\x2b\xaf\xf4\x8e\ +\x18\x31\xe2\x0b\xbb\xb5\x34\x14\x2a\x34\xee\xa2\x46\xdd\x6d\x78\ +\x3c\x8f\x13\x0a\x35\xe7\xd0\xc3\x03\x0c\xbe\xcc\xc7\xa0\xc1\xd0\ +\xa3\x67\x6c\x7b\x0d\x26\x25\xc3\xf5\xb7\xc2\xf5\xb7\x7a\xd8\x9a\ +\x0f\x3f\x7d\xef\xe2\xbb\xaf\x4e\xe7\x97\xb1\xa7\x13\x0c\xbe\x2d\ +\x1e\xcf\xe7\x84\xc3\xf7\xaa\x6a\x65\x83\x1f\x26\xab\xea\xdb\xd5\ +\x91\xa4\xaa\xd9\xc0\x9b\x7b\x7b\x5f\x44\x1a\x61\xea\x5a\x2d\x8f\ +\x36\xd9\x2e\xfb\xbe\x3b\xfa\x7e\x33\x60\x83\xaa\xe6\xec\x65\x9e\ +\x66\x40\xc7\xe8\x3c\xc1\xea\x68\x76\x70\x70\xb0\x17\xbf\xdf\x9f\ +\x6b\x59\xd6\xf7\x98\x9d\x80\x7a\x61\xdc\x81\x89\xbb\x9b\x3d\x7b\ +\x76\x37\x6c\x8c\xbb\xeb\xdd\x7b\x07\xaf\xbe\xba\x04\x55\xc8\xcf\ +\xf7\xd2\xa2\x45\x08\x97\xab\xc1\xd5\x57\xae\x53\xac\x5d\xbb\x16\ +\x8f\xc7\x53\xb8\x76\xed\xda\xc9\x76\x6b\x69\x28\xec\x33\x5b\x56\ +\x44\xce\xc4\xeb\x5b\x82\xd7\xfb\x22\xff\xfc\x77\x73\x16\xae\x85\ +\xc9\x69\x3e\xee\xbc\x0f\x7a\xf4\xac\x59\x65\x2d\x5a\xc2\x65\x57\ +\xc3\x67\xdf\xba\x59\xb3\xc5\xcd\x3b\x9f\xb9\x48\x4e\x19\x82\xdb\ +\xbd\x52\x44\x1e\x16\x91\x78\x25\x83\x9c\x22\x22\x2a\x22\xfd\x4a\ +\x5d\x5b\x24\x22\x6f\x89\xc8\x4b\x40\x3e\xb0\x04\xd8\x2c\x22\x97\ +\x96\xb9\x77\x30\xb0\x16\x58\x09\xa4\x03\x1b\x44\x64\x7e\x99\x31\ +\x3d\x45\x64\x0a\xb0\x15\x58\x08\x14\x88\xc8\x33\x51\xa3\xda\xc1\ +\xc1\xa1\xee\xf2\x26\x70\xba\x65\x59\xdd\xed\x16\x12\x43\x26\x2f\ +\x5f\xbe\xdc\x5b\x54\x14\xfb\x62\xc1\x95\x21\x35\xb5\x05\x85\x85\ +\xe6\x6b\x4b\x04\x0e\x3c\x30\x18\x57\xc3\x2e\x1c\x0e\x13\x08\x38\ +\x39\x81\x55\xa1\xb0\xb0\x90\x36\x6d\xda\xb0\x7c\xf9\x72\x27\xd6\ +\x2e\x8e\xec\xd5\xb8\x13\x91\x7f\x22\x32\x8e\xb3\xfe\xd2\x85\x39\ +\xcb\xdc\x3c\xf4\x14\xa4\x74\x8c\xa7\xb6\x5d\x34\x6e\x02\x97\x5c\ +\x01\x73\x96\x7b\x79\xf4\xd9\x04\x12\x1a\x3d\x8a\xc7\x3b\x36\xea\ +\xed\xda\x17\xad\x45\xa4\x4b\x99\xa3\x53\x8c\x54\x5d\x8e\xf1\xc8\ +\xf5\x00\x92\x31\x4f\xe7\x9f\x8b\x48\x7f\x00\x11\x69\x0a\x0c\x07\ +\xa6\x00\xbd\x80\x26\x40\x4f\xe0\x4f\x4f\xa2\x88\x24\x62\x62\xf9\ +\x22\xc0\x45\x40\x0a\xf0\x08\xf0\x0f\xe0\x81\x18\xe9\x74\x70\x70\ +\xb0\x87\x9f\x81\x0f\xa9\x05\x5d\x1d\x62\xc8\x94\x70\x38\xec\x9a\ +\x3f\x7f\x7e\xc5\x23\x6b\x80\xb7\xdf\xee\xc0\xa0\x41\x47\xf2\xc2\ +\x0b\x5d\x58\xbe\xbc\x49\xdc\xd7\xff\xe6\x9b\x6f\xc8\xc8\xc8\x88\ +\xfb\xba\x75\x99\xd4\xd4\x54\x8a\x8a\x8a\x58\xb4\x68\xd1\x7d\x76\ +\x6b\x69\x48\x94\xeb\xfd\x12\xb7\xfb\x45\x44\xee\xe2\x89\xe7\x85\ +\xdb\xef\x8e\x7d\x5e\xf9\xfe\xe2\xf3\xc1\x3f\xee\x81\x01\x67\xb8\ +\xb9\xe8\x9c\x53\xd8\x9a\x3f\x53\x44\x4e\xda\x47\x16\xeb\x33\xd1\ +\xa3\x34\x85\x18\x43\xab\xba\x84\x80\xeb\x54\x75\x3b\x80\x88\x0c\ +\x05\xce\x04\xfe\x0d\x5c\x0a\x24\x02\x8d\x80\xcf\x55\x75\x49\xf4\ +\x9e\x65\xd1\xa3\x84\xfb\x30\xdb\xb5\x7f\x55\xd5\xb5\xd1\x6b\xcf\ +\x8b\xc8\x21\xc0\x3d\x22\xf2\x64\x79\x5b\xbd\x0e\x0e\x0e\xb5\x1f\ +\xbf\xdf\x1f\x01\x6e\xb0\x5b\x47\x2c\x51\xd5\x1c\x9f\xcf\xb7\x3a\ +\x23\x23\xa3\xcb\xd1\x47\x1f\x1d\xf7\xf5\x1f\x79\x64\x25\xdf\x7e\ +\xdb\x96\x1f\x7e\x68\xc3\xd7\x5f\xb7\xa3\x4f\x9f\xed\x0c\x1e\x9c\ +\xcb\x19\x67\x6c\xda\x6b\x89\x94\x58\xd2\xae\x5d\x3b\xb2\xb2\xb2\ +\x6a\x7c\x9d\xfa\xc4\x57\x5f\x7d\x15\x5a\xbc\x78\xf1\xf8\x6d\xdb\ +\xb6\xad\xb1\x5b\x4b\x43\x62\x0f\xcf\x9d\x88\x0c\x24\x12\xf9\x17\ +\xef\x7c\x26\xdc\x7e\xb7\x1d\x9a\x2a\xe6\xb0\x23\xe0\xb7\xd9\x5e\ +\x12\x13\xbb\xe3\xf1\x0c\xdb\xc7\xc8\xa7\x80\x23\xca\x1c\xc7\xc5\ +\x48\xc5\xef\x25\x86\x1d\x98\xe6\xda\xc0\x78\xa0\x5f\xf4\xf5\x1a\ +\x20\x15\x78\x4f\x44\xfe\x27\x22\xa7\x47\xeb\xfd\x95\xe6\x38\x4c\ +\x96\xee\xb9\x22\x32\xb4\xe4\x00\xc2\x40\x53\x20\x56\x5e\x46\x07\ +\x07\x07\x87\x98\x10\x0c\x06\x7f\x9d\x3d\x7b\xb6\x2d\x7b\x93\x1d\ +\x3b\x16\x71\xfb\xed\x6b\x19\x33\x66\x2e\x4f\x3e\xb9\x82\x84\x84\ +\x08\x4f\x3d\x75\x10\x83\x06\x1d\xc9\x4b\x2f\x75\x61\xe5\xca\xc6\ +\x35\xba\x7e\x4a\x4a\x0a\x79\x79\x79\xce\xd6\x6c\x25\xc9\xcb\xcb\ +\x23\x35\x35\xd5\x5d\x50\x50\xf0\x96\xdd\x5a\x1a\x1a\xbb\x19\x77\ +\x22\xd2\x0c\xaf\xf7\x7d\x86\x5c\x19\xe1\x92\x2b\xec\xd2\x54\x39\ +\x52\x3a\x82\xf5\x91\x97\x50\xe8\x0a\x11\x19\xb8\x97\x51\x99\xaa\ +\x9a\x5e\xe6\x88\x55\x6f\x9a\xf2\xd2\xb2\xb6\x00\x6d\x4b\xbd\x3e\ +\x1b\x78\x01\x38\x07\x53\x9a\x65\xa9\x88\x5c\x5f\xea\xfd\x8e\x98\ +\x2d\x9b\x0b\xcb\x1c\x1d\x81\x71\x38\xed\xe1\x1c\x1c\x1c\x6a\x1f\ +\x93\x17\x2e\x5c\xe8\x0e\x85\xec\xab\xf0\xe2\xf5\x2a\x67\x9e\xb9\ +\x89\x37\xde\x58\xcc\x17\x5f\x64\x70\xc6\x19\x9b\x18\x39\xb2\x1d\ +\x57\x5d\x75\x18\xb7\xdc\xd2\x9b\xf4\xf4\x9a\xa9\xc3\x97\x9c\x9c\ +\x8c\xaa\x3a\xdd\x2a\x2a\xc9\xb7\xdf\x7e\x8b\xdb\xed\xde\x06\x7c\ +\x6f\xb7\x96\x86\x46\x59\xcf\xdd\x69\x84\x42\x6d\x79\xfa\xbf\x75\ +\xa3\x2d\xd9\x80\x33\xe0\x8c\xbf\x44\x70\xb9\x6e\xb2\x61\xf5\xe4\ +\x72\xae\xb5\xc7\x24\x50\x00\xa0\xaa\x5b\x54\xf5\x39\x55\xed\x86\ +\xf1\xe8\xa5\x03\x6f\x47\x0b\x23\x03\xac\xc2\x64\xc7\x9e\xb3\x97\ +\x63\x45\x8d\x7f\x0a\x07\x07\x87\x1a\xc5\xb2\xac\x36\x96\x65\x4d\ +\xb3\x2c\xeb\x10\xbb\xb5\xc4\x88\x29\xc1\x60\xd0\xbd\x78\xf1\x62\ +\xbb\x75\xb0\x74\x69\x53\x3e\xff\xbc\x3d\x3f\xff\xdc\x1a\x9f\x2f\ +\xc2\xd9\x67\xe7\xa1\x0a\x43\x87\xf6\xe6\xe9\xa7\x0f\x8a\xf9\x7a\ +\x8d\x1a\x35\xa2\x55\xab\x56\xce\xd6\x6c\x25\x28\x28\x28\x60\xc5\ +\x8a\x15\x11\x97\xcb\xf5\x9a\x53\x01\x22\xfe\x94\x35\xe2\x8e\xa5\ +\xcb\x41\x01\xda\xb6\xb3\x45\xcc\x7e\x71\xe2\x29\x2e\x3c\x9e\x58\ +\x6d\xb5\x56\x85\x53\x44\x24\xa5\xe4\x85\x88\x1c\x08\x9c\x8b\x49\ +\xa0\xa0\xec\x16\xac\xaa\x66\x00\x4f\x63\xbc\x71\x27\x47\x2f\x8f\ +\x03\x4e\x8c\x76\xf8\xd8\x8d\x72\xb6\x70\x1d\x1c\x1c\xea\x26\x79\ +\x40\x1b\xe0\x16\xbb\x85\xc4\x02\x55\x5d\xed\xf5\x7a\x37\xd8\xd5\ +\x67\x76\xe7\x4e\x37\xdf\x7c\xd3\x96\x6b\xaf\xed\xcb\xb5\xd7\xf6\ +\x25\x35\xb5\x39\x37\xdd\xb4\x9e\x31\x63\xd2\x78\xfc\xf1\x95\xbc\ +\xf3\xce\x22\x9e\x7e\x7a\x05\x63\xc6\xb4\x21\x27\x27\xb6\xd5\xba\ +\xc0\x6c\xcd\x3a\xad\xc8\x2a\x66\xda\xb4\x69\x0c\x1c\x38\x50\x7a\ +\xf4\xe8\x61\xd9\xad\xa5\x21\x52\xd6\xb8\x6b\x47\x9b\x76\x75\xc3\ +\x6b\x57\x42\x62\x1b\x08\x87\x0f\xdc\x8b\x31\x74\xa9\x88\xbc\x52\ +\xce\xd1\xaf\x9c\xb1\x55\x65\x2d\xf0\xa3\x88\x0c\x89\x96\x3c\x19\ +\x17\xbd\xfe\x5c\xf4\x7c\xba\x88\x4c\x12\x91\xdb\x44\xe4\x4c\x11\ +\xb9\x06\x18\x06\x6c\x03\x7e\x8f\x8e\xf9\x2f\xa6\xfc\xc9\x04\x11\ +\xb9\x5f\x44\xce\x15\x91\xcb\x44\xe4\x19\x60\x52\x0c\x34\x3a\x38\ +\x38\xd8\x8c\xdf\xef\x57\x4c\x96\xfc\x35\x96\x65\xd5\x6c\x50\x58\ +\x9c\x08\x85\x42\x13\xe6\xcc\x99\x13\xf7\x7d\xd9\x77\xde\xe9\xc0\ +\xc0\x81\x26\x5b\x36\x29\x29\xc0\xab\xaf\x2e\x61\xe4\xc8\x0c\xae\ +\xbc\x32\x9b\x16\x2d\x76\xc9\x39\xfd\xf4\x4d\xb4\x68\x11\xe2\x8f\ +\x3f\x62\xff\xd7\x9d\x9c\x9c\x4c\x7e\x7e\x3e\x85\x85\x85\x31\x9f\ +\xbb\xbe\x10\x08\x04\xf0\xf9\x7c\xba\x72\xe5\xca\x39\x0b\x16\x2c\ +\x70\xf6\xb0\x6d\xa0\x6c\x4c\x57\x2a\xf3\xd2\xae\x25\x1c\x06\xb7\ +\xdb\x16\x41\x55\x66\x6e\x2a\xb8\xdd\x19\x1a\x0a\x95\x2e\x76\xb4\ +\x1d\xf8\x0d\xf3\xf9\xca\x33\xe4\x5a\x46\xcf\x45\xd1\x71\xa5\x3b\ +\x5f\x2c\xc0\x64\xb0\x96\x90\x1f\x1d\xb3\x9d\xdd\x99\x00\x4c\x04\ +\xfe\x09\x74\xc7\x6c\xb9\xfe\x9f\xaa\x96\x74\xb2\x58\x81\x31\x00\ +\xff\x81\xe9\x96\xb1\x03\x53\xb1\xfe\x74\x55\x5d\x07\xa0\xaa\x01\ +\x11\x39\x1e\x78\x08\xb8\x18\xb8\x27\xba\xce\x52\xe0\xa3\xca\x7c\ +\x7c\x07\x07\x87\x3a\xc1\x07\x98\x32\x47\x67\x01\x75\xbe\xde\x97\ +\xaa\xfe\x96\x9e\x9e\x7e\x69\x24\x12\xc1\xe5\x8a\x9f\x3f\x60\xd5\ +\xaa\xc6\x5c\x79\x65\x36\x17\x5c\x90\x4b\xdb\xb6\xfb\x4e\x6a\x78\ +\xf1\xc5\xa5\xf8\x7c\xb1\xaf\x81\xd7\xbe\x7d\x7b\x5c\x2e\x17\x59\ +\x59\x59\x74\xeb\xd6\x2d\xe6\xf3\xd7\x07\x26\x4d\x9a\x44\xab\x56\ +\xad\x64\xe7\xce\x9d\xff\xb0\x5b\x4b\x43\x45\x54\x77\xfd\xe7\x17\ +\x91\xde\xc0\x42\xde\xfa\xc4\x14\x10\xae\xed\x6c\xd9\x0c\x47\xf6\ +\x08\xb2\x65\xf3\x8b\xaa\x1a\xb7\xba\x70\x22\xb2\x08\x98\xa2\xaa\ +\xb7\xc6\x6b\x4d\x87\xaa\x11\xed\x7f\xdc\x28\x7a\x34\x06\x04\x63\ +\xcc\x17\x02\x45\xaa\x1a\xb6\x51\x9e\x83\x4d\x44\xbd\xf6\x69\x40\ +\xaf\x52\x25\x8a\xe2\x82\x65\x59\x89\x7e\xbf\xbf\xb2\x2d\x14\x6b\ +\x35\x22\xd2\x0b\x58\xf4\xf1\xc7\x1f\x73\xf0\xc1\x07\xdb\x2d\x67\ +\xaf\x64\x67\x27\x30\x78\x70\x3f\xde\x7d\x77\x21\x7d\xfb\x96\x7d\ +\x3e\xdf\x7f\xbe\xff\xfe\x7b\x9a\x37\x6f\xce\xc9\x27\x9f\x5c\xf1\ +\xe0\x06\x46\x38\x1c\xe6\xba\xeb\xae\x0b\xf5\xec\xd9\x73\xca\x98\ +\x31\x63\x4e\xb3\x5b\x4f\x43\x65\x37\xcf\x9d\xaa\x2e\x12\x97\xeb\ +\x5d\xee\xf9\xfb\x75\x9c\x7e\xb6\x87\xc4\x36\x76\xe9\xaa\x1c\xff\ +\xbe\x23\xc2\xf6\x82\xcd\xec\xda\x0a\x75\xa8\x87\x44\xe3\x19\x93\ +\x31\x09\x2b\xbb\x0e\x91\x64\x7c\xbe\x4e\x88\xb4\x43\xb5\x31\x11\ +\x4d\x40\x23\x09\x44\x22\x3e\x2a\xc8\x34\x16\x97\x2b\x8c\xdb\x1d\ +\x40\x5c\xc5\xb8\xa4\x18\x91\x22\x94\x8d\x04\x03\x6b\x89\x44\xb2\ +\x80\xec\xb2\x87\xaa\xe6\xd6\xe8\x07\x75\xa8\xd7\xd4\x17\xc3\x0e\ +\x40\x55\x17\x7b\xbd\xde\xfc\xf4\xf4\xf4\x96\x76\x19\x77\xc5\xc5\ +\x2e\xb6\x6f\xdf\x7d\x87\x49\x04\x5a\xb5\xaa\xf9\xd8\xfd\xe4\xe4\ +\x64\x96\x2d\x5b\x56\xf1\xc0\x06\xc8\xcf\x3f\xff\xcc\x8a\x15\x2b\ +\x64\xf9\xf2\xe5\x37\xda\xad\xa5\x21\xb3\xe7\x17\xa0\xea\xbf\x28\ +\xdc\x79\x2e\x03\x07\xb4\x61\xd4\x4f\x5e\xdb\xba\x52\xec\x8b\x48\ +\x04\xfe\x7d\x87\x32\xf2\x33\x41\xf5\x7a\x55\xdd\x66\xb7\x24\x87\ +\xea\x13\xed\x38\xd2\x07\xe8\x0b\x1c\x8a\xd7\xd7\x0f\x38\x14\x38\ +\xf0\xcf\x41\x6e\xb7\xd2\xaa\x75\x88\xa4\x64\x48\xe9\xe0\x21\x29\ +\x59\x68\xdb\xce\x74\x31\x69\xdc\x18\x12\x1a\x95\x7f\x46\xa0\xb8\ +\x08\x0a\x0b\x4b\xce\x6e\x8a\x8b\x1a\x53\x58\xd8\xf8\xcf\xeb\x79\ +\xb9\x9d\xd9\x90\x7d\x14\xeb\x33\x83\x64\x67\x29\x9b\x36\x7a\x08\ +\x06\xff\xdc\x73\x12\xaf\x77\x07\x6e\xf7\x62\x8a\x8b\xe7\x62\xb6\ +\xef\x17\x00\xf3\x55\xb5\xde\x7c\x69\x3b\x38\x54\x96\x48\x24\x32\ +\x69\xee\xdc\xb9\xe7\x5d\x7a\xe9\xa5\x71\x8b\xe1\x51\x85\xcf\x3f\ +\x6f\xcf\x67\x9f\x25\x91\x97\xb7\x67\xb2\x84\xd7\xab\x4c\x99\x32\ +\xab\xc6\x75\xf4\xe8\xd1\x83\xe4\xe4\xf2\x0a\x26\x34\x6c\x54\x95\ +\xf7\xdf\x7f\x3f\x28\x22\x5f\x44\x22\x91\x3f\xec\xd6\xd3\x90\xd9\ +\xc3\xb8\x2e\x95\xa3\xf7\x00\x00\x20\x00\x49\x44\x41\x54\x53\xd5\ +\x6d\x22\x72\x1c\xab\x56\xfc\xcc\xc9\xfd\xbb\xf1\xd1\x97\x5e\x4e\ +\x1c\x60\x83\xb4\xbd\xb0\x31\x17\x6e\xbb\x21\xcc\xf8\x9f\xc2\xa8\ +\x5e\xae\xaa\x63\xe3\x2d\x41\x55\x7b\xc7\x7b\xcd\xfa\x88\x88\xf4\ +\x04\x4e\xc3\xe5\x3a\x0d\x8f\xf7\x04\x8c\x47\x0e\x1a\x37\x09\x71\ +\x48\xef\x08\x87\x1d\xe1\xa3\xf7\xa1\xd0\xfd\x60\x68\x97\x04\xed\ +\xda\x43\xeb\x44\xc1\xe5\xaa\xe9\xbe\xbb\xbb\xe6\xdf\xb2\x19\x72\ +\xb2\x21\x67\x03\xfc\xb1\xb2\x29\x8b\xe6\x1f\xc5\xfc\x8c\xc3\x59\ +\x34\x0f\xb6\x6e\xf5\x02\x88\x2f\x61\x33\x1a\x99\x4d\x28\xf4\x2b\ +\x26\x16\x33\xcd\xe9\x2c\xe2\xb0\x37\x2c\xcb\x1a\x02\x78\xfc\x7e\ +\xff\x08\xbb\xb5\x54\x87\x48\x24\xf2\xdb\x9c\x39\x73\xce\x05\xe2\ +\x66\xdc\x7d\xf3\x4d\x5b\x86\x0d\xeb\xc4\x09\x27\x6c\xa1\xa8\xa8\ +\x10\xb7\x5b\x39\xfe\xf8\xad\x4c\x9f\xde\x82\x45\x8b\x0e\xe0\x8e\ +\x3b\xe2\xd3\x04\xa1\x59\xb3\x66\x34\x6b\x56\x33\xb5\xf4\xea\x32\ +\x53\xa6\x4c\x21\x27\x27\xc7\x13\x89\x44\x9e\xb5\x5b\x4b\x43\xa7\ +\xdc\xad\x2b\x55\xcd\x14\x91\x63\xd9\x96\xff\x39\x83\x4e\xfd\x0b\ +\x17\x0e\x89\xf0\xf4\x4b\x2e\x5b\xbd\x78\xc1\x20\xbc\xf5\x1a\x3c\ +\xfb\x68\x88\x40\x20\x8f\x70\xf8\x02\x55\xad\xf9\x47\x34\x87\x98\ +\x21\x22\xc9\xc0\xd9\x88\x9c\x8e\xc7\x7b\x26\xd0\x96\x26\x4d\x43\ +\x9c\x7c\x2a\x1c\x77\xa2\x87\x43\xfa\x40\xef\xbe\xd0\xb1\xb3\x87\ +\xda\x52\x09\xe6\xc0\x56\xe6\x38\xa4\x0f\x9c\x72\x7a\xc9\x55\x63\ +\xfc\xe5\x6c\x80\xc5\x0b\x60\xd1\xfc\x56\xcc\xf8\xfd\x0c\x7e\x1b\ +\x7f\x2a\x5b\xf3\xbd\x78\x3c\x05\xe2\xf1\x4c\x24\x1c\xfe\x15\x18\ +\xa7\xaa\xce\xfe\x8d\x43\x69\x4e\x02\x86\x58\x96\xf5\xad\xdf\xef\ +\xaf\xcb\x29\x97\x93\x0b\x0a\x0a\x7c\x6b\xd6\xac\xa1\x73\xe7\xce\ +\x71\x59\xf0\x9b\x6f\xda\x71\xce\x39\x79\x3c\xf2\xc8\x4a\x5e\x7d\ +\xb5\x33\xa1\x10\x5c\x76\xd9\x06\x2e\xbb\x6c\x03\x6f\xbe\xd9\x81\ +\xc9\x93\x5b\x31\x70\xa0\xe3\x48\xb7\x8b\x60\x30\xa8\x37\xde\x78\ +\x63\xe6\x1b\x6f\xbc\xb1\xc8\x6e\x2d\x0d\x9d\xbd\xc6\x25\x45\xb7\ +\x3a\xcf\x15\x91\xf3\xf9\xe1\xdb\x57\xf9\x71\x74\x47\xce\x1a\x08\ +\x17\x5c\xe2\xe6\xec\x81\xd0\xbc\x45\xcd\xab\x8b\x44\x60\xc6\x54\ +\xf8\x6e\x14\x8c\xfa\x3c\xc8\xa6\x3c\x25\x1c\x7e\x16\x78\x5e\x55\ +\x77\xd6\xbc\x00\x87\xea\x22\x22\x09\xc0\x05\x78\xbc\x37\x21\x72\ +\x06\x1e\x6f\x84\x63\xff\x4f\x39\xed\x2c\x0f\xa7\x9c\x0e\xfd\xfa\ +\x7b\xea\x4c\x66\x76\x59\xda\x25\x99\x63\xc0\x19\xf0\xb7\x3b\x5d\ +\xa8\xba\x58\x38\x0f\x26\x4f\x68\xc6\xa4\x5f\x07\x32\x75\xd2\xb9\ +\xec\xdc\xe9\x91\x84\x84\x39\x04\x02\x6f\x03\x5f\xa8\xea\x56\xbb\ +\x65\x3b\xd8\xce\xb3\xc0\x4d\xc0\xad\xc0\x2b\x36\x6b\xa9\x0e\x19\ +\x6e\xb7\x7b\x67\x46\x46\x46\x93\x78\x19\x77\xeb\xd6\x25\x70\xfd\ +\xf5\xa6\xc6\x9c\xc7\x13\x61\xfd\xfa\x5d\xa5\x4e\x2e\xbd\x34\x87\ +\xf3\xcf\x3f\x82\x40\xc0\x85\xcf\xe7\x38\xce\xe3\x4d\x6a\x6a\x2a\ +\x2d\x5b\xb6\x94\xa9\x53\xa7\xd6\xd2\xbe\xa5\x0d\x8b\x0a\x73\xd8\ +\x55\xf5\x3b\x82\xc1\x9e\x04\x02\xb7\xf1\xd3\x98\xa9\xdc\x72\x75\ +\x98\x83\x12\x23\x0c\x3e\x2b\xc4\x47\xef\x98\x6d\xd2\x58\x12\x08\ +\xc0\xaf\x3f\xc1\x1d\xb7\x28\x07\x25\x06\x39\xf7\x14\x78\xcf\x5a\ +\x4d\x6e\xce\x7f\x09\x87\xbb\xab\xea\x63\x8e\x61\x57\xfb\x11\x91\ +\xfe\xe2\x72\xbd\x8e\xc7\x9b\x8b\xcb\xf5\x39\xa7\x9c\x7e\x1a\x1f\ +\x7e\x29\x64\x6e\x75\xf3\xfd\x44\x0f\x77\xdd\x0f\xfd\x8f\xa9\x3b\ +\x25\x77\x2a\x83\x08\xf4\x3d\x1c\xfe\x76\x27\x7c\xf9\x83\x9b\xcc\ +\x6d\x1e\xbe\xf9\x19\xce\xbf\xf8\x48\x7c\xbe\x37\x70\xbb\x73\xc5\ +\xe3\x19\x21\x22\x67\xc6\x66\x39\xb9\xb5\x74\x4f\xe2\x32\x47\xcf\ +\x58\xac\x51\x45\x3d\x6f\x89\xc8\x98\x52\xaf\xfb\x8b\xc8\x06\x11\ +\x39\xa2\xd4\xb5\x1f\x44\xa4\x41\x17\x35\xf5\xfb\xfd\xd9\xc0\x9b\ +\xc0\x9d\x96\x65\xd5\xad\xba\xa2\xa5\x88\x66\x9c\xff\x3e\x77\xee\ +\xdc\xb8\x59\x52\x4d\x9a\x44\x70\xbb\x4d\x85\x87\x36\x6d\x82\xac\ +\x5a\xb5\xcb\xb8\xdb\xb2\xc5\x43\x28\x24\x35\x52\xb8\xd8\xa1\x62\ +\xb6\x6d\xdb\xa6\x8b\x17\x2f\xce\xf9\xf1\xc7\x1f\x47\xda\xad\xc5\ +\xa1\x92\xbd\x4b\x55\x35\x00\xbc\x05\xbc\x25\x22\xad\x08\x85\xce\ +\x63\xf2\x84\x8b\xf9\x6d\xc2\xd9\xfc\xf3\x56\x2f\x47\x1f\x1f\xe2\ +\xe8\xe3\xbc\x7f\xc6\x45\x95\x78\x34\xda\xb5\x37\x5b\x5a\x65\xb7\ +\xd8\x76\x6c\x87\x0d\xd9\x26\x96\xa9\xf4\x79\xf5\xaa\x08\xbf\x8c\ +\x8d\xb0\x73\x87\x07\xaf\x77\x01\xc1\xe0\x97\xc0\x37\x1a\x28\x5e\ +\x18\xf3\x4f\xee\x50\x23\x88\xc8\x79\xb8\x5c\xc3\x80\xce\x74\xed\ +\x1e\xe6\xaf\x37\xb8\xb9\xe2\x1a\x48\x4a\xae\x47\x56\x5c\x25\x71\ +\xbb\xe1\xd4\x33\xe1\xd4\x33\x85\x6d\x5b\xdd\x8c\xfa\xc2\xcd\x27\ +\xef\x0d\x61\xce\xac\xcb\xc5\xe7\xdb\x4a\x30\xf8\x28\x30\xac\x1a\ +\xf1\x79\x6f\x00\xc5\x98\xc2\xd8\x65\xc9\xc7\xd4\x4b\xac\x34\x22\ +\x32\x1e\xc8\x55\xd5\x58\x35\x96\xf6\x62\x6a\x3c\x96\xfe\xb6\x6d\ +\x4d\xf9\x7a\x1b\x1a\x4f\x03\xc3\xfc\x7e\x7f\x9d\x76\x31\x85\xc3\ +\xe1\x89\xa9\xa9\xa9\x27\x63\x7a\x64\xd7\x38\x3d\x7a\xec\x64\xd9\ +\xb2\xa6\x9c\x72\xca\x16\xfa\xf7\xdf\xca\x2b\xaf\x74\xe6\xd5\x57\ +\x3b\x73\xdc\x71\xf9\x7c\xfa\x69\x32\x4d\x9b\x86\x49\x4a\xda\x77\ +\xfd\xbb\x58\x32\x7f\xfe\x7c\x0e\x38\xe0\x00\xba\x76\xed\x1a\xb7\ +\x35\x6b\x23\xf3\xe6\xcd\x23\x35\x35\x55\xb6\x6c\xd9\x72\x8f\xdd\ +\x5a\x1c\x0c\x55\x6e\x4c\xaf\xaa\x9b\x31\x05\x76\x3f\x12\x91\x26\ +\xc0\x39\xa4\x4e\xbf\x80\xf4\xd9\x87\x02\xed\x09\x85\x12\x89\x44\ +\x76\xcd\xeb\x76\x47\x68\xd5\x3a\x48\x62\x5b\xd8\xbe\x0d\x36\x6e\ +\x74\x53\x54\x58\x7a\x5d\xc5\xeb\xdd\x8a\xb8\x72\x08\x87\x56\x13\ +\x0e\xff\x04\x7c\xa3\x81\x40\x7c\x22\x63\x1d\x62\x82\x88\x1c\x84\ +\xb8\xc6\xe1\x76\x77\xa7\x7d\x0a\xfc\xe7\x55\x18\x78\x61\xc3\x33\ +\xe8\xf6\x46\xf3\x16\x70\xdd\x2d\x70\xdd\x2d\x6e\xe6\xcc\x82\x7b\ +\xfe\xde\x82\xb4\xd9\xaf\xe0\x72\x3d\x21\x22\x97\xaa\xea\xb8\x8a\ +\x27\x29\x97\x4f\x55\x35\x56\x6d\xad\x7c\x94\x4e\x26\xa9\x22\x4e\ +\xdd\xc7\xca\xe3\xf7\xfb\x37\x01\x9b\xec\xd6\x11\x03\x26\x6f\xda\ +\xb4\x29\x61\xc3\x86\x0d\x24\x25\x25\xd5\xf8\x62\x17\x5f\x9c\xc3\ +\xbc\x79\x26\x91\xa1\x5b\xb7\x42\xae\xb9\x26\x8b\x0f\x3f\x4c\x66\ +\xc4\x88\x24\x3a\x74\x28\xe2\x81\x07\x56\xe1\xf5\xc6\xcf\x5e\xce\ +\xcd\xcd\x25\x3b\x3b\xbb\xc1\x1b\x77\xef\xbd\xf7\x5e\x68\xce\x9c\ +\x39\x73\x83\xc1\xe0\x27\x76\x6b\x71\x30\x54\xd9\xb8\x2b\x4d\x74\ +\x7b\x74\x54\xf4\xf8\x13\x11\x69\x85\xc9\x7c\x4c\x22\x1c\x6e\xcf\ +\xc6\xdc\x24\x36\xe6\xb6\x05\x0a\x80\x0d\x98\xba\x61\x25\xe7\x1c\ +\x0d\x04\xe2\xde\xc6\xc6\x21\x76\x88\xc8\xed\x78\xbd\xaf\xe0\xf1\ +\xb8\xb8\xf7\x11\xb3\x2d\x99\x10\x97\x07\xf9\xba\x49\xff\x63\x60\ +\xfc\x4c\xf8\xe2\x53\x78\xf8\x9e\xe6\x6c\xde\xf4\x93\x88\x7c\x0c\ +\xdc\x50\x13\xc5\x95\x45\xe4\x01\x4c\xcf\xe3\x5c\xe0\xaf\x40\x0f\ +\x60\x36\xf0\x9a\xaa\x16\x47\xc7\xf8\x81\x4e\x40\x6b\x11\x79\x2c\ +\x7a\xeb\x3c\x55\x1d\x25\x22\x2d\x80\xf3\x81\x13\x81\xb6\x40\x16\ +\xf0\x93\xaa\x8e\x29\xb3\xce\x25\x40\x0b\x55\x7d\x6f\x3f\x34\xfe\ +\x05\x38\x13\xe8\x00\xcc\x03\xde\x52\xd5\x8d\x55\x9d\xc7\x21\xee\ +\xa4\xba\x5c\xae\x40\x46\x46\x86\x2f\x1e\xc6\xdd\x49\x27\x6d\xe1\ +\xa4\x93\xb6\xfc\xf9\x7a\xe8\xd0\x4c\x2e\xb9\x64\x03\x9b\x36\xf9\ +\x38\xf8\xe0\x1d\x71\xcf\xc3\x4a\x4e\x4e\x66\xd6\xac\x59\xa8\x2a\ +\x0d\xb5\x1d\xf8\xb2\x65\xcb\x98\x39\x73\xa6\x07\x78\xc2\x6e\x2d\ +\x0e\xbb\xa8\x91\x78\x0f\x55\xdd\xac\xaa\x0b\x55\x75\xbc\xaa\x7e\ +\xaa\xaa\x2f\xaa\xea\xbd\xaa\xfa\xa4\xaa\xbe\xa3\xaa\xdf\xab\xea\ +\x6c\x55\x5d\xaf\xaa\x8e\x61\x57\x87\x11\x91\xfb\xf1\x78\x5f\xe3\ +\xe0\x5e\x2e\xd2\x56\xc2\x9d\xf7\x39\x86\x5d\x65\x10\x81\xcb\xff\ +\x0a\x19\x2b\xe1\xdc\xf3\xc1\xed\xb9\x06\x13\x8f\x56\x13\x3f\x93\ +\x0f\x60\xda\xe4\xfd\x0e\x1c\x83\xd9\x2a\x7d\x1e\xf8\xaa\xd4\x98\ +\x14\x4c\x37\x8f\x26\x40\x97\xe8\x91\x18\x7d\xef\x62\xe0\x71\x8c\ +\x67\x6f\x35\x26\xdb\xf3\x3b\x11\x79\xaa\xcc\x3a\x43\x80\x2a\x17\ +\x2e\x15\x91\x8f\x80\x1f\x81\x93\x31\x5b\xb6\x77\x03\x0b\x44\xa4\ +\x4f\x55\xe7\xaa\x6b\x58\x96\xe5\xb3\x2c\xeb\x46\xcb\xb2\xea\xe4\ +\x0f\x8d\xaa\x06\x5c\x2e\x57\x6a\x5a\x5a\x5a\xec\xfb\x7c\x55\x92\ +\xc4\xc4\x20\x3d\x7b\xee\x20\x14\x72\xf1\xed\xb7\x6d\xe3\xba\x76\ +\x72\x72\x32\xc1\x60\x90\x8d\x1b\x1b\xee\x73\xc8\x07\x1f\x7c\x10\ +\xf6\x78\x3c\x0b\x55\xf5\x07\xbb\xb5\x38\xec\xa2\x5a\x9e\x3b\x87\ +\x86\x8d\x88\xdc\x85\xc7\xf3\x0c\x3d\x7a\xc2\x98\x09\xd0\xaa\xb5\ +\xdd\x92\xea\x1e\x4d\x9a\xc2\xfb\x9f\xc3\xb5\x43\xe0\xe7\x1f\xce\ +\x26\x1c\x1e\x0d\x9c\x57\x85\x19\x4e\x11\x91\x0f\xcb\xb9\xfe\x80\ +\xaa\x66\x95\x7a\x7d\x01\x70\x98\xaa\x2e\x02\x10\x91\x87\x81\x27\ +\x44\xe4\x10\x55\x5d\xa2\xaa\x0f\x89\xc8\x29\x40\x8e\xaa\x5e\x57\ +\x66\xae\xaf\x80\x0f\xb4\x54\xaf\x42\x11\x79\x01\xf8\xb7\x88\x58\ +\xaa\xba\xbe\x0a\x7a\x77\x43\x44\xae\x00\xae\x01\x06\xab\xea\xb7\ +\xd1\x6b\x77\x60\x3c\x8b\xaf\x60\xbc\x79\xf5\x99\x44\xe0\x7f\x98\ +\x16\x79\xaf\xdb\xac\x65\xbf\x08\x85\x42\x13\x66\xcd\x9a\x75\x14\ +\x71\x88\xbb\x2b\x2a\x72\xd1\xa8\xd1\xee\xdb\xae\xc1\xa0\x8b\xd1\ +\xa3\xdb\xf0\xf1\xc7\xc9\x6c\xd9\xe2\xe5\xc2\x0b\xe3\xd7\x48\xa6\ +\x45\x8b\x16\x34\x6d\xda\x94\xac\xac\x2c\xda\xb6\x8d\xaf\x61\x59\ +\x1b\x98\x35\x6b\x16\x83\x06\x0d\x72\x2f\x5f\xbe\xfc\x61\xbb\xb5\ +\x38\xec\x4e\x9d\xcd\xd4\x72\xb0\x17\x11\xe9\x8b\xc8\x0b\xb4\x6a\ +\x0d\xdf\x4f\x74\x0c\xbb\xea\xe0\xf5\xc2\x47\x23\xcd\x76\xad\xcb\ +\x3d\x48\x44\xae\xad\xc2\xdd\x09\x40\xcb\x72\x8e\xb2\xf1\x8e\x93\ +\x4b\x0c\xbb\x28\x25\x31\x7e\x3d\x2a\x5a\x40\x55\xb7\xa9\xaa\x8a\ +\x48\x27\x11\x39\x41\x44\xce\x01\x56\x62\x1e\x0e\xab\x5b\xd0\xfb\ +\x06\x60\x09\x30\xba\xd4\x7a\x3b\x80\xcf\x80\x53\x45\xa4\xa6\x0b\ +\x56\xdb\x8a\xdf\xef\xcf\x02\xde\x06\x1e\xb6\x2c\xab\xa5\xdd\x7a\ +\xf6\x93\x29\x59\x59\x59\x09\xf9\xf9\xf9\x35\xb6\xc0\x8f\x3f\x26\ +\x72\xc1\x05\x47\x30\x60\xc0\xd1\x5c\x7c\x71\x3f\x86\x0f\x37\xf5\ +\xce\x53\x53\x9b\x73\xe5\x95\x87\xf2\xe2\x8b\x5d\x48\x4a\x2a\xe6\ +\xbf\xff\xad\x52\x0e\x51\x4c\x48\x4e\x4e\x26\x2b\x2b\xab\xe2\x81\ +\xf5\x8c\x40\x20\xc0\xb6\x6d\xdb\x74\xf5\xea\xd5\x99\x99\x99\x99\ +\xdf\xd8\xad\xc7\x61\x77\x1c\xcf\x9d\x43\x95\x11\x11\x0f\x5e\xef\ +\x70\x12\x12\x5c\x0c\xb9\x0a\x5a\x27\x56\x7c\x93\xc3\xbe\xf1\x7a\ +\xe1\xfa\xa1\x30\x37\x15\xc4\xf3\xba\x88\xfc\xac\xaa\xd9\x95\xb8\ +\xf3\xe7\x4a\x26\x54\xfc\x56\xe6\xf5\xaa\xe8\xb9\x79\x45\x37\x8a\ +\x48\x57\x8c\xb1\x75\x3c\x10\x06\xd6\x44\xcf\x60\xb6\x78\xab\x43\ +\x2f\xa0\x15\x90\x5d\x26\x66\x29\x01\x63\xa0\x76\xc2\x18\x92\xf5\ +\x99\x47\x80\xcb\x80\x87\x30\x5b\xd2\x75\x8d\x69\x22\x12\x4e\x4f\ +\x4f\x77\x0f\x18\x30\x20\xe6\x93\x2f\x5f\xde\x84\x27\x9f\xec\x46\ +\x42\x42\x84\xd3\x4e\xdb\xcc\xe2\xc5\x4d\x19\x36\xac\x13\xaa\xf0\ +\xc6\x1b\x1d\xe9\xd4\xa9\x88\x61\xc3\x96\x70\xf4\xd1\xf6\x94\x90\ +\x4c\x49\x49\x61\xca\x94\x29\x84\xc3\x61\xdc\xf5\xa9\xb4\x53\x05\ +\x8c\x1f\x3f\x9e\x96\x2d\x5b\xca\xf2\xe5\xcb\x2f\xb2\x5b\x8b\xc3\ +\x9e\x38\x9e\x3b\x87\xfd\xe1\x16\x22\xda\x87\xed\xdb\xe1\x82\x4b\ +\xec\xd6\x52\x7f\x38\xf7\x7c\x73\x6e\xde\xb2\x31\x2e\xd7\x73\x31\ +\x9e\xbd\x3a\xb1\xad\x6f\x61\x3c\x7c\xfd\x80\xa6\xaa\xda\x0d\x28\ +\x69\xd7\x51\xdd\x28\xf2\x10\x30\x1e\xb8\xb0\xcc\xf1\x17\x8c\x31\ +\xb9\xdf\x5b\xbe\x75\x05\xbf\xdf\x9f\x0f\x5c\x04\xfc\xc7\x6e\x2d\ +\xfb\x83\xaa\xee\xf0\x78\x3c\xf3\xd2\xd2\xd2\x6a\x64\xfe\x5f\x7e\ +\x69\x8d\xc7\xa3\x7c\xfb\x6d\x1a\xcf\x3c\xb3\x9c\x51\xa3\xd2\x39\ +\xe9\xa4\x2d\x0c\x1b\xd6\x89\x53\x4f\xdd\xcc\x87\x1f\x2e\xb0\xcd\ +\xb0\x03\x68\xdf\xbe\x3d\xe1\x70\x98\x9c\x9c\x1c\xdb\x34\xc4\x9b\ +\x0d\x1b\x36\x30\x79\xf2\xe4\xc8\xac\x59\xb3\x46\x8f\x1d\x3b\x76\ +\xb6\xdd\x7a\x1c\xf6\xc4\x31\xee\x1c\xaa\x8e\xd7\xf7\x4f\x2e\xbd\ +\x4a\x10\x31\xbd\x57\x1d\x62\x43\xc1\x36\x08\x85\xe0\xf2\xab\xdd\ +\xc0\x15\x22\x12\x6f\x97\x68\x00\x93\x50\x51\x96\x63\x81\x8f\x54\ +\x35\xa3\x24\xbb\x16\x38\xa2\x9c\x71\xfb\xc3\x7c\xa0\x3b\x30\x4b\ +\x55\x67\x94\x73\x14\xc5\x68\x9d\x5a\x8d\xdf\xef\xff\xdd\xef\xf7\ +\xd7\xd9\xa8\xfc\x60\x30\x38\x61\xf6\xec\xd9\xc5\x15\x8f\xac\x3a\ +\xb9\xb9\x3e\xfa\xf7\xdf\x4a\xcb\x96\xe6\xf9\x44\x04\x4e\x3b\xcd\ +\xfc\xde\xf9\xeb\x5f\xb3\x49\x48\xb0\xb7\x54\x60\xd3\xa6\x4d\x69\ +\xd1\xa2\x45\x83\xda\x9a\x7d\xe5\x95\x57\xc2\x53\xa6\x4c\x59\x3b\ +\x62\xc4\x88\x4b\xed\xd6\xe2\x50\x3e\x8e\x71\xe7\x50\x25\x44\x64\ +\x00\xc1\x40\x0f\xfe\x7e\x97\x70\xf4\x71\xf0\xdd\xd7\x76\x4b\xaa\ +\x3f\x8c\xf9\x06\x5a\x1e\x08\xf7\x3f\x0e\x8d\x9b\x08\x26\x1e\xad\ +\x22\x7c\x22\xd2\xb2\x9c\xa3\xd1\x7e\x28\x58\x0b\x1c\x29\x22\x29\ +\x65\xae\x4f\x01\x4e\x8e\xb6\x92\x43\x44\x3a\x00\xb1\xf2\x2c\x3e\ +\x0b\xf4\x04\x9e\x17\x91\x3f\x8b\x1d\x47\x3f\x83\xb3\xdd\x53\x77\ +\x98\xbc\x6a\xd5\x2a\xdf\x8e\x1d\x3b\x62\x3e\x71\x51\x91\x7b\x8f\ +\xc2\xc4\xed\xda\x19\x3b\xb2\x73\xe7\xda\xd1\x9a\x37\x25\x25\xa5\ +\xc1\x18\x77\x33\x67\xce\x64\xd2\xa4\x49\xee\x50\x28\x34\x34\xda\ +\xe0\xc0\xa1\x16\xe2\x18\x77\x0e\x55\xe5\x5c\xba\x1f\x1c\xa0\xcf\ +\x61\x30\x68\x30\x7c\x3b\x12\xe6\xcc\xb2\x5b\x53\xdd\x27\x6b\x1d\ +\x58\xaf\xc0\x5f\xce\x87\x66\xcd\xe1\x82\x4b\x3c\x78\xbd\x83\x2a\ +\x71\xe7\xb5\xc0\x96\x72\x8e\xfd\xa9\x39\x35\x0c\xf3\x3b\x61\x9d\ +\x88\xe4\x8b\xc8\xdb\xa5\xae\x1f\x01\x6c\x14\x91\x19\xc0\x42\x4c\ +\x77\x8c\x6a\xa3\xaa\xd3\x80\x9b\x81\x5b\x80\x0d\x22\x32\x4b\x44\ +\x96\x00\x39\xc0\x1d\xb1\x58\xa3\x2e\x61\x59\x56\x23\xcb\xb2\x1e\ +\xb5\x2c\xab\xae\xa5\x5e\x4e\x55\x55\xe6\xcd\x9b\x57\x23\x93\x17\ +\x14\xb8\x59\xb3\xa6\xf1\x9f\x47\x4e\x8e\x49\xcc\x5d\xbb\xb6\xd1\ +\x6e\xd7\xd7\xae\xdd\x9f\x67\x9a\xea\xd3\xa1\x43\x07\x12\x12\x12\ +\x28\x95\x50\x5e\x2f\x29\x2e\x2e\xe6\xdd\x77\xdf\x0d\xb9\xdd\xee\ +\xef\xaa\x51\x78\xdd\x21\x0e\x38\x09\x15\x0e\x55\xc3\xeb\x3b\x9e\ +\x63\x4f\x30\x1e\x96\x5b\x6e\x87\xdf\xc6\xc3\x45\x67\xc3\xe8\x5f\ +\xa1\x5f\x7f\x9b\xc5\xd5\x51\xb2\xd6\xc1\xa0\x53\xa1\x71\x13\x78\ +\xe2\x79\x73\xad\xff\x31\xf0\xe5\xa7\xfd\x45\x44\x74\xef\xdf\x18\ +\xa7\xb1\xf7\x98\xb7\xb5\xa5\xfe\xfc\x17\x4c\x12\x44\x69\xb6\x02\ +\xa7\x02\x7f\x66\xd0\xaa\xea\x5c\x11\xe9\x8c\xd9\x26\x6d\x85\x29\ +\x7a\x8c\xaa\x8e\x13\x91\xbe\xc0\x29\x98\x42\xe4\xd3\x30\xb1\x70\ +\x0b\x80\xc5\xa5\xe6\x7c\x9c\xdd\xcb\x61\x2c\x2a\xbb\x06\xf0\x37\ +\x60\x37\x77\x8b\xaa\xbe\x27\x22\xdf\x63\xb6\x7f\xbb\x62\x6a\xdd\ +\x2d\x06\x66\xee\xe5\xb3\xd5\x67\x7c\xc0\x50\xcc\xdf\xc3\x75\xf6\ +\x4a\xa9\x3c\xaa\xba\xd9\xe7\xf3\x2d\x4f\x4f\x4f\x3f\xf8\xf8\xe3\ +\x8f\x8f\xf9\xfc\xe3\xc7\xb7\x66\xfc\xf8\x3d\x33\xf2\xaf\xb9\xe6\ +\xd0\xdd\x5e\x7b\xbd\xca\x94\x29\xf1\x7f\xd8\xec\xd4\xa9\x13\x9d\ +\x3a\x75\x8a\xfb\xba\xf1\x66\xd2\xa4\x49\x5c\x7d\xf5\xd5\xee\x61\ +\xc3\x86\xd5\xc5\xc4\x9f\x06\x85\x63\xdc\x39\x54\x8d\x48\xa4\x3f\ +\x47\x1c\x65\xfe\xdc\xa8\x11\x7c\xf6\x2d\x5c\x75\x21\x5c\x78\x26\ +\x7c\xf2\x35\x9c\x74\xaa\xbd\xfa\xea\x1a\x4b\x16\xc2\x95\x17\x9a\ +\x6c\xd9\x31\x13\x20\xb1\x8d\xb9\x7e\xc4\x51\x10\x0a\x35\xc1\x18\ +\x5a\xcb\xcb\xbb\x55\x55\xcb\x66\xc0\x96\x8b\xaa\x4e\x29\xe7\x5a\ +\x10\x98\x54\xce\xf5\x42\x4c\x1c\x5c\xd9\xeb\x4b\xd9\xb3\x57\xed\ +\xa4\x32\x63\x16\x95\x79\xbd\xad\x9c\x31\x73\xf7\xa2\x31\x07\xf8\ +\xae\xbc\xf7\x1a\x12\x7e\xbf\x7f\x9b\x65\x59\xff\x02\x3e\xb5\x2c\ +\xeb\x6d\xbf\xdf\x3f\xcd\x6e\x4d\x95\x25\x18\x0c\xfe\x9a\x9a\x9a\ +\xda\xc5\xef\xf7\xfb\x2a\x1e\x5d\x79\x06\x0d\xca\xa5\x5f\xbf\xca\ +\xb5\x23\x6e\x40\xc9\xaa\x71\x27\x2b\x2b\x8b\x56\xad\x5a\x31\x73\ +\xe6\xcc\x1f\x33\x33\x33\xcb\xfd\x9d\xe4\x50\x7b\x70\x8c\x3b\x87\ +\x4a\x23\xa6\x56\x45\x63\xda\x27\xef\xba\x58\x62\xe0\xf9\xaf\x85\ +\xf3\x4e\x83\xf3\x2f\x86\x27\x5f\x80\xce\x0d\xbb\xd7\x62\x85\x6c\ +\xd9\x0c\xcf\x3e\x0a\xef\x59\xc6\xe3\x39\x7c\x34\xb4\x29\xb5\x13\ +\x57\x62\xe4\x41\x33\x3b\xe4\x39\xd8\x87\xdf\xef\x1f\x6e\x59\xd6\ +\xcd\x98\xd2\x28\xe7\xda\xad\xa7\x0a\x4c\x5e\xba\x74\xe9\xd0\x40\ +\x20\x80\xcf\x17\x3b\xfb\xee\xc4\x13\x6b\xae\x7e\x9e\x43\xe5\x99\ +\x37\x6f\x9e\x46\x22\x91\x60\x46\x46\x86\x93\x44\x51\x07\x70\x62\ +\xee\x1c\xaa\x42\xf9\xcf\xc5\x8d\x1a\xc1\x07\x5f\xc0\xb7\xbf\xc0\ +\xb2\x25\x70\x4c\x2f\x78\xec\x3e\xc8\x6d\x38\xa5\x01\x2a\xcd\x8e\ +\xed\xf0\xe6\x6b\x70\x64\x0f\xf8\x6e\x14\xfc\xef\x7d\xf8\x75\x06\ +\xb4\xdb\x6b\x5f\x4e\xe7\x67\xb4\x61\xf2\x57\xa0\xae\x7d\x89\x4e\ +\x09\x87\xc3\xae\x85\x0b\x17\xda\xad\xc3\x21\xc6\xa4\xa6\xa6\x32\ +\x76\xec\x58\x99\x33\x67\xce\xbf\xe7\xcd\x9b\xb7\xd3\x6e\x3d\x0e\ +\x15\xe3\x78\xee\x1c\xaa\x82\x31\x34\x22\x7b\x29\x3d\x30\xe0\x0c\ +\xf8\x3d\x03\xde\x7f\xd3\x78\xa5\x5e\x7f\x09\xce\x3c\x17\xae\xbe\ +\x1e\xce\x1a\x68\xb6\x1e\x1b\x22\xaa\x30\x6d\x32\x7c\xfa\x01\x8c\ +\xfe\x0a\x22\x61\xb8\xfd\x6e\xd3\x87\xb7\x49\xd3\xf2\xef\x29\xfe\ +\xb3\xaa\x44\xfd\x8e\xd0\x76\x28\x17\xbf\xdf\xbf\xce\x6e\x0d\x55\ +\x45\x55\xb3\x7c\x3e\x5f\x66\x5a\x5a\x5a\xc7\x23\x8e\x88\x55\xa5\ +\x9c\xba\x45\x28\x14\x22\x18\x0c\xd2\xb8\x71\x63\xbb\xa5\xc4\x8c\ +\x50\x28\xc4\xf3\xcf\x3f\x1f\xcc\xca\xca\xfa\x29\x14\x0a\xbd\x62\ +\xb7\x1e\x87\xca\xe1\x78\x05\x1c\x2a\x8d\xaa\x06\xf0\xf9\x72\x59\ +\xb1\x6c\xef\x83\xdc\x6e\xb8\xf9\x36\x58\x94\x09\xff\xfb\xc0\x78\ +\xaa\xae\xbe\x08\x7a\xa5\xc0\x03\x77\xc1\xec\x99\x10\x0e\xef\xfd\ +\xfe\xfa\x82\x2a\x2c\x5e\x00\xcf\x3d\x0e\xfd\xba\xc1\xc0\x01\xb0\ +\x70\x1e\x3c\xfa\x2c\x2c\x5a\x07\x0f\x3e\xb9\x77\xc3\x0e\x60\xd1\ +\x7c\x10\x51\x4c\x6b\x2e\x07\x87\x3a\x41\x30\x18\xfc\x75\xf6\xec\ +\xd9\x41\xbb\x75\xd8\xc5\xb8\x71\xe3\x98\x33\x67\x8e\xdd\x32\x62\ +\xca\xe7\x9f\x7f\xce\xfa\xf5\xeb\x35\x1c\x0e\xdf\x6e\xb7\x16\x87\ +\xca\xe3\x78\xee\x00\x11\x39\x04\xd3\x30\x7d\x4b\xf4\x75\x5b\xe0\ +\x00\x55\x5d\x15\x7d\xed\x05\xba\x01\xeb\x54\x75\xbb\x7d\x4a\x6b\ +\x01\xe1\xf0\x74\x32\xe6\x9e\x47\x45\x0f\x06\x8d\x1a\xc3\x65\x57\ +\x9b\x63\xed\x6a\x18\xfe\x11\x7c\xfe\x31\xbc\xf1\xb2\x29\xf5\xf1\ +\x7f\x27\xc1\xc9\xa7\x99\xa3\xef\xe1\xa6\x32\x69\x5d\x67\xe5\x72\ +\x98\x3c\xc1\x1c\x53\x27\xc1\xc6\x5c\x13\x47\x77\xc9\x95\xc6\x7b\ +\xd9\xe7\xb0\xca\xcf\x95\x36\x1b\x7c\xbe\x95\x5a\x54\x14\xfb\xc2\ +\x61\x0e\x75\x06\xcb\xb2\x5c\xc0\xff\x80\xef\xfd\x7e\xff\x0f\x76\ +\xeb\xa9\x04\x53\x16\x2c\x58\x70\x4d\x43\x6b\xc5\x55\x42\x52\x52\ +\x12\x2b\x56\xac\xb0\x5b\x46\xcc\x58\xb1\x62\x05\x3f\xfc\xf0\x43\ +\x24\x12\x89\x3c\xa9\xaa\x65\x33\xee\x1d\x6a\x31\xf5\xd6\x73\x27\ +\x22\xcd\x44\xe4\xf3\x7d\x1c\x47\x44\xc7\xb9\x30\x65\x17\xae\x2e\ +\x75\xfb\x43\xc0\x2f\xa5\x5e\x77\x88\x8e\x39\x2d\x6e\x1f\xa0\xb6\ +\x12\x0e\xcf\x60\xca\xc4\x10\xa1\x2a\x74\xb3\xea\xd4\x05\xee\x7b\ +\x14\xd2\x57\x9a\xe3\xa9\x17\xa1\xe9\x01\xf0\xf2\x73\x70\xd2\x11\ +\x70\x50\x22\x5c\x7e\x1e\x3c\xf1\x00\x7c\xf9\x19\x2c\xc8\x28\xbd\ +\x2d\x59\xfb\x08\x85\x4c\x6c\xe1\xe8\xaf\xe0\xb9\xc7\xe0\xda\x21\ +\xd0\xbb\x23\xf4\x3f\x18\x1e\xba\xdb\x78\x2b\xff\xf9\x6f\xb3\x45\ +\xbd\x6c\x03\x3c\xfb\x72\xd5\x0c\x3b\x80\x09\x3f\x07\x09\x04\x7e\ +\xaf\x11\xfd\x0e\x75\x06\xbf\xdf\x1f\x01\xbc\xc0\x47\x96\x65\x95\ +\x2d\x2e\x5d\x1b\x99\x1c\x08\x04\xdc\x4b\x97\x96\x4d\xac\x6e\x18\ +\x24\x27\x27\x53\x50\x50\x40\x41\x41\x81\xdd\x52\xaa\xcd\xce\x9d\ +\x3b\x59\xbf\x7e\xbd\x0e\x1c\x38\x30\x9f\xd8\x15\x2d\x77\x88\x13\ +\xf5\xd9\x73\x97\x80\x69\xc6\xbd\x88\x72\x4a\x3b\x54\x91\x1d\xc0\ +\x17\x34\x80\x3e\x97\x95\x60\x04\x9b\x37\x3d\xcd\x98\x51\x30\x78\ +\x3f\xe2\xbd\xbb\x1c\x64\x8e\x6b\x6f\x36\x5b\x97\x0b\xe7\x99\x5a\ +\x79\x73\x66\xc1\xd8\x31\x26\x4e\x2f\x10\x30\xdb\xbb\x07\x75\x87\ +\x5e\x7d\xe1\xe0\x43\xa0\x7d\x0a\xb4\x4f\x86\x76\xed\x21\xa9\x3d\ +\xb4\x4d\xaa\xb9\x18\xbe\x48\xc4\x78\xdd\x36\x64\xc1\x86\x6c\xc8\ +\xc9\x86\xec\x2c\x58\xbe\x04\x16\x2f\x34\xe7\x40\x00\x5c\x2e\xf3\ +\x59\x0e\xe9\x63\x3e\xcf\x29\xa7\x9b\xfa\x74\xd5\xd5\x35\x6d\x32\ +\xcc\x4b\xf3\x62\x7a\xba\xee\x37\x22\x72\x2c\x30\x1a\x38\x4b\x55\ +\x6b\xa6\xba\x6c\xf9\xeb\x3e\x19\x5d\xf3\xd8\x2a\xde\x77\x36\xf0\ +\x11\x70\xb4\xaa\x66\xd6\x88\xb8\xba\xc9\x3f\x30\x7d\x76\x87\x5b\ +\x96\x75\x9a\xdf\xef\xaf\xb5\x71\x0d\xaa\xba\xd2\xe7\xf3\x6d\x4c\ +\x4b\x4b\x6b\xd3\xbb\x77\x6f\xbb\xe5\xc4\x9d\x76\xed\xda\xe1\xf1\ +\x78\x58\xbf\x7e\x3d\x87\x1c\x72\x88\xdd\x72\xaa\xc5\xe4\xc9\x93\ +\xd5\xe7\xf3\x69\x7a\x7a\xfa\x00\x55\xad\x4e\x6f\x6a\x07\x1b\xa8\ +\xcf\xc6\x5d\x09\xa3\x54\xf5\xe1\xea\x4c\xa0\xaa\xb9\xc0\xe5\x31\ +\xd2\x53\xa7\x51\xd5\x35\xe2\xf5\x7e\xc7\xeb\x2f\x0d\x64\xf0\xa5\ +\xd5\xb3\x62\x44\xcc\x96\x6c\xdf\xc3\x77\x5d\x0b\x85\xcc\xf6\xe6\ +\x92\x85\xc6\x90\x5a\xb2\xd0\x18\x7d\x1b\xb2\x60\xf3\x26\x63\x10\ +\x96\xdc\xdb\x3a\xd1\x18\x7b\x6d\xdb\x99\x02\xc0\x09\x09\x90\xd0\ +\xc8\x9c\x1b\x35\x02\x5f\xa9\xb3\x08\x04\x8a\xa1\xa8\x68\xd7\xb9\ +\xb8\x18\x8a\xa3\xe7\xa2\x42\xc8\xdb\x68\x0c\xb9\x8d\xb9\xbb\xc7\ +\x05\xb6\x68\x69\x0c\xca\xae\xdd\xe1\xac\x73\xe1\x1f\xf7\x40\xaf\ +\x3e\x70\x70\x2f\x33\x7f\xac\x79\xe1\xa9\x10\x1e\xef\x0c\x0d\x06\ +\xa6\xc7\x7e\xf2\xb8\xd0\x1c\x68\x53\xe1\x28\x87\x4a\xe1\xf7\xfb\ +\x77\x5a\x96\x75\x29\xf0\x19\xd0\x1e\xa8\xd5\xc9\x16\xa1\x50\x68\ +\xe2\xdc\xb9\x73\x2f\xba\xea\xaa\xab\x1a\xc2\xf7\xcb\x6e\xb8\x5c\ +\x2e\xda\xb5\x6b\x47\x56\x56\x56\x9d\x36\xee\x26\x4e\x9c\x48\x62\ +\x62\xa2\x8c\x1b\x37\xee\x81\x29\x53\xa6\x54\xd7\x39\xe2\x60\x03\ +\x0d\xee\x87\x6f\x7f\x10\x91\xf6\xc0\x08\xe0\x81\x68\xbb\x24\x44\ +\xe4\x79\x4c\x26\xe3\x8f\xc0\x03\xc0\xe1\x18\x0f\xe1\x83\xaa\x3a\ +\xab\xd4\xbd\xc9\xc0\x93\x98\x4a\xfd\xad\x80\x8d\xc0\x2c\xe0\xc6\ +\x92\xa6\xe8\x22\xe2\x06\xee\x04\x2e\x02\x7a\x60\x8a\xc5\xbe\xa1\ +\xaa\xc3\xe3\xf2\x01\xab\x4a\x28\xf4\x5f\xe6\xcc\xba\x90\x5f\x7f\ +\x82\x33\xce\x89\xed\xdc\x1e\x0f\xf4\xec\x65\x8e\x0b\x2e\xd9\xfd\ +\xbd\x60\x10\x72\x37\xec\xf2\xa6\x95\x9c\x37\xe6\x42\x61\xa1\x31\ +\xd0\xb6\xe6\x1b\x83\xad\xb0\xd0\x9c\x8b\x8a\xcc\x75\x55\x63\xf8\ +\x35\x6e\x6c\xce\x8d\x1a\x99\xb8\xc0\x46\x8d\xa0\x59\x33\x13\x1b\ +\xd7\xaf\xff\x2e\xcf\xe0\x9f\xe7\x24\x33\x2e\x5e\xfc\x38\x1a\x26\ +\xfe\xe2\x01\x1e\xad\xee\x54\xaa\x3a\x13\xd8\x6b\x8d\x95\xda\x46\ +\xb4\x9d\x51\x9d\xd1\x1b\x4f\xfc\x7e\xff\x42\xcb\xb2\x8e\xf0\xfb\ +\xfd\xb5\x3e\x7b\x5a\x55\x7f\x4b\x4b\x4b\x1b\xac\xaa\x48\x7d\x88\ +\xa5\xad\x22\xc9\xc9\xc9\xcc\x9f\x5f\x77\xed\xa1\xcc\xcc\x4c\x1e\ +\x7f\xfc\xf1\x50\xd7\xae\x5d\x87\x2f\x5a\xb4\xc8\xd9\x8e\xad\xa3\ +\x38\xc6\x5d\xe5\x68\x84\x69\xbd\x94\x58\xea\xda\xe1\xc0\xc1\xc0\ +\xc5\x98\x78\x84\x77\x30\xad\x95\x7e\x13\x91\xe3\x54\x35\x23\x3a\ +\x6e\x14\xc6\x8b\xf1\x0a\xa6\xd3\x40\x12\xa6\x30\xa9\x17\x28\x8a\ +\x8e\x19\x03\xfc\x1f\x30\x12\x78\x0d\x63\xe4\x7d\x24\x22\xed\x55\ +\xf5\xa5\x1a\xfc\x5c\xfb\x85\xaa\x4e\x11\x8f\xe7\x33\x6e\xbc\xe2\ +\x32\xa6\xcf\xf7\x90\xdc\x21\x3e\x0b\x7b\xbd\x90\xd2\xd1\x1c\xf5\ +\x91\xbc\x8d\x70\xdb\x0d\x41\x5c\xae\x8f\x34\x1c\x9e\x50\x99\x5b\ +\x44\xa4\x0f\x26\xfc\xa0\x17\x26\x7c\x60\x06\xf0\x99\xaa\x16\x88\ +\x48\x27\xe0\x06\xe0\x2d\x55\xcd\x8e\x8e\xff\x1b\x90\x09\x64\x00\ +\x57\x01\xfd\x81\xc7\x54\x75\x41\xf4\x21\xe3\x5a\xe0\x18\xcc\xff\ +\xd9\x55\xc0\x57\x51\x23\x11\x11\xb9\x1d\x58\xa9\xaa\x3f\x96\xd1\ +\xf0\x30\x30\xbe\xe4\xc1\x67\x2f\x3a\x4f\x05\xce\x01\x0e\xc2\xfc\ +\xbf\x4f\xc7\x3c\xc0\x14\x96\x1a\xd3\x13\xb8\x02\x78\x45\x55\xf3\ +\xa3\xd7\xfe\x15\xd5\xba\x1a\xb8\x12\xf3\x73\xf7\x2f\x55\x5d\x1d\ +\x4d\x74\xba\x2e\xaa\xd7\x07\xfc\x0e\xbc\x5f\x5f\xb7\x90\xea\x82\ +\x61\x17\x65\xf2\xce\x9d\x3b\xbd\xab\x56\xad\xa2\x5b\xb7\x6e\x76\ +\x6b\x89\x3b\x29\x29\x29\xa4\xa6\xa6\xb2\x79\xf3\x66\x5a\xb5\x6a\ +\x65\xb7\x9c\x2a\x11\x0c\x06\xb9\xef\xbe\xfb\x82\xa1\x50\x68\xe1\ +\xe2\xc5\x8b\x6f\xb2\x5b\x8f\xc3\xfe\x53\x6f\x13\x2a\x4a\x71\xbb\ +\x88\xac\x2e\xe7\x38\x30\x06\x73\x77\x01\xae\x52\xd5\x77\x55\xf5\ +\x2b\x4c\x0f\xcf\x8d\xc0\x63\x00\x22\xd2\x08\xf3\xc5\xf3\x92\xaa\ +\xbe\xa6\xaa\x63\x55\xf5\x03\x55\x1d\xa2\xaa\x05\xd1\x31\x17\x47\ +\xef\xbb\x51\x55\x6f\x56\xd5\xcf\x55\xf5\x52\xe0\x5d\xe0\x31\x11\ +\x39\x20\x06\x3a\x63\x4f\x38\x7c\x2b\x3b\x77\xae\xe1\x9a\x4b\xc2\ +\x04\x1b\x6c\xe5\x83\xd8\x11\x0a\xc1\xcd\x57\x2a\x3b\xb6\x6f\x25\ +\x12\xb9\xb3\x32\xb7\x88\xc8\xf5\xc0\x1c\xcc\xc3\x42\x26\x10\x04\ +\xee\x05\x8e\x8e\x0e\xe9\x84\xf1\x00\x96\x6a\x29\xc2\xdf\x30\x31\ +\x5c\x53\x31\x85\x72\xb7\x03\xcd\x45\xa4\x05\xc6\x38\x1a\x06\x34\ +\xc5\x18\x76\xbd\xd8\x3d\x90\xfa\x76\x60\x60\x39\x52\x1e\x06\x4e\ +\xd8\x87\xce\x46\xc0\xf7\x18\xaf\xf4\x1a\xa0\x35\xf0\x34\x30\x3b\ +\xfa\x5e\x09\x87\x44\xf5\xb6\x2c\x75\xed\x5f\xc0\x1d\x98\x7e\xb6\ +\x17\x02\x3b\x81\x03\x44\x24\x09\x48\xc5\x64\x92\x26\x61\x3a\x79\ +\xbc\x01\x4c\x11\x91\x98\xb6\xbf\xaa\x8d\x58\x96\x75\x9a\x65\x59\ +\xb5\xd5\x2d\xb6\xd0\xe3\xf1\x6c\x4b\x4f\x4f\xb7\x5b\x87\x2d\xb4\ +\x6e\xdd\x1a\x9f\xcf\xc7\xfa\xf5\x75\x2f\x44\xfb\xb5\xd7\x5e\xd3\ +\xd5\xab\x57\x07\x42\xa1\xd0\x45\xd1\x16\x85\x0e\x75\x94\x86\xe0\ +\xb9\x9b\x85\xd9\x3a\x2d\x4b\x61\x39\xd7\xaa\xca\xd2\x12\xaf\x06\ +\x80\xaa\x16\x8b\xc8\x17\xc0\x4d\xd1\xd7\x45\x22\x32\x0d\xf8\x87\ +\x88\xec\x00\xbe\x2b\x29\xb7\x52\x8a\xbf\x00\x9b\x81\x25\xd1\x92\ +\x2c\x25\xa4\x62\x1a\x88\x1f\x02\xcc\x8e\x81\xd6\x98\xa2\xaa\x3b\ +\x44\x64\x30\xe9\x73\xd2\xb9\xe6\x12\xf8\xf8\xab\x86\x5b\xa4\x38\ +\x16\xfc\xf3\x56\x98\x3c\x51\x08\x87\xef\xa8\x4c\xb9\x1d\x11\xe9\ +\x0c\xbc\x0e\x7c\x09\x5c\xa7\xaa\x91\xe8\x75\x17\xc6\x8b\xb5\x2f\ +\xce\x00\xae\x55\xd5\x8f\x4b\xcd\xf7\x1a\xc6\x2b\x56\xda\xeb\x8c\ +\x88\x34\xa9\xfa\x87\xd9\x83\x62\xa0\x7d\xb4\xd7\x6c\xc9\xbc\x47\ +\x62\x0c\xd3\xa1\x18\xaf\xf6\xbe\x18\x04\x9c\xa7\xaa\xdf\x97\xba\ +\xff\x03\x8c\x17\xb0\x93\xaa\x6e\x88\x5e\xeb\x0d\x2c\xc0\x18\x83\ +\x2f\xc4\x40\x77\xad\xc4\xb2\xac\x1e\xc0\xcf\x18\x43\xfe\xbf\x36\ +\xcb\xd9\x03\x55\x55\xb7\xdb\x3d\x79\xee\xdc\xb9\xe7\x5e\x7c\xf1\ +\xc5\x0d\xc1\x81\xb0\x1b\x22\x42\xfb\xf6\xed\xc9\xca\xca\xe2\xd0\ +\x43\x0f\xb5\x5b\x4e\xa5\x99\x3a\x75\x2a\xbd\x7b\xf7\x96\x89\x13\ +\x27\x0e\xdd\xb8\x71\xe3\x1f\x76\xeb\x71\xa8\x1e\x0d\xe1\x07\x6f\ +\xa6\xaa\xbe\x52\xce\x51\x54\xf1\xad\x15\x92\x55\xce\xb5\xf5\x40\ +\x4b\x11\x29\xe9\x09\x3a\x14\x13\x8b\xf7\x1e\x90\x2b\x22\x5f\x88\ +\xc8\x71\xa5\xc6\x1f\x8c\xf1\x54\xcc\xc1\x6c\x55\x95\x1c\x6f\x60\ +\xbe\x14\x6b\x6d\x0c\x92\xaa\xce\x27\x14\x1a\xca\xcf\x3f\xc0\x75\ +\x43\x60\x7b\xdd\x4f\xff\x8f\x3b\xaa\xf0\xd4\x43\xf0\xd9\x07\x10\ +\x0e\x3f\x56\x85\x38\xcb\x21\x40\x13\xe0\xee\x12\xc3\xce\x4c\xa7\ +\x91\x4a\xfc\xdf\xde\x8c\x09\xce\x2f\xcd\xb5\xc0\x87\xa5\x0d\xbb\ +\xe8\x7c\xd5\x6e\x35\xa4\x86\x6d\x22\xd2\x42\x44\x8e\x14\x91\xb3\ +\x80\xb6\x18\x2f\xde\xe1\x15\xdc\x0e\xf0\x47\x19\xc3\xce\x8b\x29\ +\x5d\xf4\x61\x89\x61\x17\x5d\x67\x11\xc6\xfb\x78\x76\x75\x35\xd7\ +\x66\xfc\x7e\xff\x72\xcc\xee\xc0\xb3\x96\x65\xf5\xb7\x59\x4e\xb9\ +\x44\x22\x91\x49\x73\xe6\xcc\xa9\x97\xdb\xe3\x95\x21\x25\x25\x85\ +\xec\xec\x6c\x22\x7b\xeb\xe6\x53\xcb\xc8\xcc\xcc\xc4\xe5\x72\x91\ +\x9b\x9b\x3b\x7f\xe3\xc6\x8d\x9f\xda\xad\xc7\xa1\xfa\xd4\xa8\xe7\ +\x4e\x44\x9a\x62\x8c\x93\xf6\xa5\xce\x00\xd9\xc0\x86\xe8\x91\xad\ +\xaa\x75\xb5\x50\x6b\x79\x5b\xbb\x07\x62\x62\x8a\xb6\x03\xa8\xea\ +\x02\x60\x88\x88\xb4\x03\xce\x03\x6e\x01\xa6\x8a\x48\x17\x55\x5d\ +\x87\xd9\xc6\xcd\x50\xd5\x23\xe3\xa4\x39\xa6\xa8\xea\x3b\x22\xe2\ +\x63\xdc\x8f\xc3\x38\xaa\xa7\xf0\xc6\x87\x70\xda\x59\x76\xcb\xaa\ +\x1b\x64\xcc\x85\x3b\x6e\x31\x67\xd5\xf7\x54\xf5\xf1\x2a\xdc\xdd\ +\x0b\xd8\x10\xcd\xe4\xae\x2a\x13\x54\xf5\xcf\x74\x60\x11\x49\xc1\ +\x64\xb8\xd6\x48\xb9\x14\x31\x51\xf5\xaf\x01\x37\x63\x4a\x14\xe5\ +\x00\xf9\x98\x18\xd6\x76\x95\x98\xe2\xe7\x32\xaf\x7b\x60\x7e\x77\ +\x5d\x23\x22\x65\xeb\xf1\x34\xc3\xfc\x7e\xa9\xef\x3c\x83\xa9\xbb\ +\xf9\xbe\x65\x59\xfd\x6a\x61\x3c\xde\x94\xfc\xfc\x7c\xdf\xfa\xf5\ +\xeb\x49\x49\xa9\x0b\xe5\xf9\x62\x4b\xd7\xae\x5d\x49\x4c\x4c\xac\ +\x13\x09\x25\xc1\x60\x90\x05\x0b\x16\xa8\xaa\x16\x67\x66\x66\x9e\ +\x68\xb7\x1e\x87\xd8\x10\x13\xe3\x2e\xba\x45\x74\x21\x22\x27\xe0\ +\xf5\x75\x40\x24\x85\x50\xa8\x0d\xd0\xb8\xd4\x20\x68\xde\x22\x00\ +\xc0\xb6\xad\xbe\x3f\x4b\x5a\x00\xe2\xf1\x14\xe2\xf1\x6e\x04\xcd\ +\x26\x10\x58\x8b\xea\x0c\xe0\x1b\x55\xad\xed\xae\xe1\xde\x22\x92\ +\xac\xaa\xa5\x3d\x78\x67\x02\xf3\x55\x75\xb7\x5f\xb6\xaa\x9a\x03\ +\xbc\x2b\x22\xa3\x31\x5f\x6e\x43\x80\x97\x81\x99\xc0\xf9\x22\xd2\ +\x43\x55\x97\xc7\x4b\x78\x2c\x51\xd5\xff\x89\xc8\x8f\x6c\xcc\xfd\ +\x95\x8b\xce\x39\x88\x81\xe7\xc3\x8d\x7f\x33\xbd\x66\x5d\x0d\xc1\ +\x39\x5c\x45\xf2\xb7\xc0\x93\x0f\xc1\xfb\x16\xb8\x3d\x5b\x50\xbd\ +\x5c\x55\xcb\x1a\x30\x15\xb1\x13\x93\xe8\xb3\x5f\x0a\xca\x99\x8b\ +\x4a\xcc\xa7\x94\xf1\xf6\x8b\x48\x63\xa0\xa2\x56\x04\xd7\x01\x7f\ +\x07\x6e\x03\x3e\x57\xd5\xcd\xd1\x7b\xa7\x00\x95\xf9\xf6\xdb\x5a\ +\xe6\x75\x89\x61\xfa\x22\xf0\x6b\x39\xe3\x6b\x71\x05\xec\xd8\xe0\ +\xf7\xfb\x23\x96\x65\x5d\x0d\xb4\xa9\x85\x86\x1d\xc0\x5c\x97\xcb\ +\x55\x94\x96\x96\xd6\xa8\x21\x1a\x77\x8d\x1b\x37\xae\x33\xfd\x65\ +\x2d\xcb\x22\x1c\x0e\x87\x8b\x8b\x8b\xcf\x1f\x33\x66\xcc\xb6\x8a\ +\xef\x70\xa8\x0b\xec\xb7\x71\x17\xcd\xd2\x1b\x8c\x2f\xe1\x52\xe0\ +\x50\x9a\x1e\x10\xe2\x84\x93\xdd\x24\x77\x90\xdd\x4b\x49\x44\xcf\ +\x6d\xda\x81\xd7\x6b\x62\x81\x42\x21\xd8\x98\x03\x39\x1b\xa2\x47\ +\x76\x63\x72\x36\x74\x22\x77\x43\x27\xb2\xd6\x1d\xc3\x6f\x13\x06\ +\xb3\xbd\xe0\x25\x49\x68\xb4\x98\x40\xf1\x17\x18\x43\x6f\x7f\xbd\ +\x0a\x3d\x45\xe4\xc2\x72\xae\x2f\x50\xd5\xea\xf6\x89\x09\x00\x1f\ +\x8b\xc8\x75\x98\x2f\xa0\x3b\x31\xc5\x46\x2f\x81\x3f\x8d\xde\xdb\ +\x31\x5b\x60\x4b\x30\xde\x91\xa1\x98\x2f\xb4\x92\x06\xad\xc3\x80\ +\x5b\x81\x6f\x45\xe4\x0e\x8c\xb1\x97\x80\xf1\xcc\x5c\xa5\xaa\x43\ +\xab\xa9\x31\x2e\x44\x0d\xf1\x6e\x22\x72\x3f\xbf\x8c\xbd\x97\x1f\ +\x46\xb7\x24\x39\x05\xae\xbb\x15\xfe\x7a\x83\x29\x42\xdc\xd0\x99\ +\x3e\x05\x3e\x7a\x07\xbe\xf9\x12\x22\x91\x08\xaa\xc3\x08\x05\xef\ +\x2c\xfb\x20\x50\x49\xe6\x63\xb6\xff\x7b\x47\xb7\x23\xf7\x1b\x55\ +\xdd\x22\x22\xeb\x31\x49\x11\x2f\xef\x63\x68\x1e\x50\xb6\xd5\xc6\ +\xb9\x54\x1c\xde\x71\x2c\x26\x84\xc1\x2a\xf9\xac\xd1\x44\x8a\xfd\ +\x8d\x27\x5d\x81\x89\x99\x4d\x52\xf3\x20\xd8\x20\xf1\xfb\xfd\x59\ +\x94\x1f\x1a\x62\x3b\xaa\x1a\xf2\x78\x3c\xd3\xd2\xd2\xd2\x4e\x1d\ +\x34\x68\x50\xed\x77\x5f\x35\x50\xa6\x4e\x9d\xca\xf0\xe1\xc3\xc1\ +\xc4\xed\xfe\x52\xd1\x78\x87\xba\x43\x95\x8c\xbb\x68\xc0\xf2\x75\ +\xf8\x7c\x43\x80\x2e\x1c\xd8\x2a\xc8\x05\x97\x78\x39\xef\x22\x38\ +\xf9\x34\x4f\xa5\x03\xea\x3d\x9e\x68\xc7\x81\x72\xbf\xf0\x85\x50\ +\xc8\xc3\xd4\x49\x30\x66\x54\x2f\xbe\x1d\xf9\x20\x9b\xf2\x1e\x93\ +\x84\x84\x4c\x02\x81\x2f\x81\x8f\x54\xb5\x2a\x45\x84\x86\x44\x8f\ +\xb2\xdc\x0d\x54\xb7\xcc\xc8\x14\x4c\x16\xdf\x72\x8c\x41\x16\x04\ +\xee\x55\xd5\xaf\xa3\xef\x87\x81\xf3\x31\x19\x7f\x8a\x31\xea\xb6\ +\x03\x8f\xa8\xea\x0f\x00\xaa\x5a\x28\x22\x03\x00\x0b\xb3\xfd\x54\ +\xf2\x8b\xb0\x18\x18\x57\x4d\x7d\x71\x47\x55\x9f\x05\x9e\x15\x91\ +\x53\xc9\x5a\xff\x0c\x2f\x3c\x75\x2c\xcf\x3d\x26\x9c\x7e\x0e\x5c\ +\x7f\x0b\x9c\x35\xd0\xfc\xfb\x37\x14\x36\x64\xc3\xc8\xcf\xe0\x3d\ +\x0b\x56\xaf\x02\xaf\x6f\x07\xc1\xc0\xe7\xc0\x7d\xaa\x9a\x57\x8d\ +\x99\x3f\x03\x1e\xc1\x78\x83\x2f\x2c\xd9\x9e\x15\x91\x0e\x40\x30\ +\xea\x29\xae\x0a\xff\x01\x5e\x15\x91\xeb\x54\xf5\xc3\xe8\x5c\x2e\ +\xe0\x30\x55\x2d\x49\x7b\x9c\x03\x0c\x15\x91\xfe\xaa\x3a\x27\xfa\ +\x80\xf7\xcf\x4a\xcc\x3d\x19\x13\x8e\xd0\x17\x98\x1f\x2d\xb9\xf2\ +\x12\xbb\x97\x16\xaa\x34\xaa\x1a\x16\x91\xff\x00\x0f\x8a\xc8\x78\ +\x55\xfd\xa6\xe4\x3d\x11\xe9\x0e\x24\xab\xea\xe4\xfd\x99\xbb\x2e\ +\x63\x59\x56\x0b\xbf\xdf\x5f\xd6\xcb\x69\x1b\xe1\x70\x78\x52\x6a\ +\x6a\xea\x09\x98\xdf\x8d\x0e\xb5\x8c\x35\x6b\xd6\xf0\xe8\xa3\x8f\ +\x86\x5c\x2e\xd7\xa7\xe1\x70\xb8\x6c\x0c\xae\x43\x1d\xa7\x52\xdf\ +\xb2\x22\xd2\x0e\x91\x27\x11\xb9\x91\xa4\xf6\x61\x2e\xbc\xd4\xcb\ +\xf9\x17\xc1\xb1\x27\x78\x6b\x64\xdb\xcd\xe3\x31\x5b\x7a\x03\xce\ +\x80\x17\xff\xe7\x65\xd6\x74\x18\x33\xaa\x23\xdf\x7c\xf9\x0f\xb2\ +\xd6\xdd\x25\x6e\xf7\x47\x44\x22\x0f\x94\xd4\xee\x2a\x8f\xe8\x17\ +\x67\x85\x4f\x8c\xd1\x60\x74\x29\x73\xed\x1f\x98\x72\x11\x25\xaf\ +\xff\xd8\xdb\x5c\xaa\xfa\x54\xb4\xa0\x71\x37\x60\x95\xaa\x16\x97\ +\x7a\x6f\x1d\x70\xb0\x88\xb4\xc1\xc4\x1b\x06\x80\x35\xa5\x6b\x7b\ +\x45\xc7\x65\x02\x83\xa2\x99\x89\x07\x61\x0c\xbb\x75\x65\xc7\xd5\ +\x25\x54\x75\x22\x70\x7c\x74\xdb\xee\x09\x26\xfd\x72\x23\xbf\x8e\ +\x3d\x90\x56\xad\x8d\x81\x77\xf4\x71\xe6\xe8\x7d\xa8\x69\x35\x56\ +\x5f\xd8\x5e\x00\x53\x7f\x33\x2d\xd5\x7e\x19\x0b\x2b\x96\x82\xc7\ +\xa3\x84\xc3\xe9\xc0\x63\x1a\x28\xfe\x2e\x16\xcb\x44\xb3\x95\x87\ +\x60\x8c\xbc\x35\x22\xb2\x18\xb3\xad\x7a\x30\x26\x16\xab\xaa\xc6\ +\xdd\x1b\xd1\x7b\xdf\x8f\xb6\x0f\xcb\xc2\xfc\x5f\x5c\x84\xa9\xf1\ +\x08\xf0\x3c\x30\x18\x53\xc2\x64\x2d\xd0\x11\xb3\xdd\x5a\x51\x9b\ +\xb1\x51\x98\x52\x2d\xe9\x22\x92\x86\x29\xcd\x32\x15\x98\x58\x45\ +\x8d\xa5\x79\x16\x13\xc7\xfb\xb5\x88\xac\x8b\xea\x6d\x1f\xd5\xf4\ +\x30\xc6\xa0\x6c\x30\x58\x96\xd5\x0b\x98\x66\x59\xd6\x65\x7e\xbf\ +\xbf\xaa\x5b\xfc\x35\xc5\xe4\xdc\xdc\xdc\x27\xf2\xf2\xf2\x48\x4c\ +\xdc\x2f\x3b\xde\xa1\x86\x58\xbb\x76\x2d\x13\x27\x4e\x8c\x00\xa9\ +\x91\x48\xc4\x6f\xb7\x1e\x87\xd8\x23\x15\xed\x08\x89\xc8\x95\xb8\ +\xdd\xef\xd0\x3a\xd1\xcb\x53\x2f\x79\x19\x72\xa5\x89\x9f\xb3\x8b\ +\x51\x5f\xc0\x83\x77\x05\xc9\xcd\x09\x13\x0e\xfb\x4b\xbc\x0c\xf1\ +\x46\x44\xc6\x01\x61\x55\x3d\xd7\x8e\xf5\xeb\x22\x22\x72\x12\xf0\ +\x38\x5e\xef\x91\x44\xb4\x05\xe1\x90\x69\x15\xd6\xef\x28\x38\xee\ +\x04\x63\xec\x1d\x75\x9c\xd9\xc6\xaf\x0b\x84\x42\xc6\x78\x5b\x38\ +\xdf\xf4\xc8\x9d\x3c\x01\xe6\xce\x86\x48\x18\x12\x12\x0a\x29\x2e\ +\x4e\xc3\x94\x2a\x79\xaf\x32\xe5\x4d\xf6\x87\x68\xd2\xd2\xff\x61\ +\xb6\x38\x77\x02\x33\x54\x75\x61\xf4\xbd\x16\xc0\x11\xc0\xec\x92\ +\xf5\x45\xe4\x68\x60\xab\xaa\x2e\xdb\xcb\x7c\x3d\x81\xa3\x30\xb5\ +\xe8\xd6\x02\xbf\x94\x4e\x78\x12\x91\xd6\x98\x6c\xd4\x26\xc0\x14\ +\x55\x5d\x2a\x22\x27\x63\x32\x5a\x33\xa3\x63\xba\x03\xad\x4b\x97\ +\x09\x8a\xd6\x6b\x3c\x0f\x68\x01\xcc\xc5\x6c\xc7\xf6\xc5\x24\xd3\ +\xce\x2f\x35\xf7\xa1\xd1\xcf\x50\xd2\xbd\xe5\x78\x20\x47\x55\x57\ +\xed\x45\x6f\x2f\xa0\x1f\x26\x31\x23\x17\x93\x1d\xbf\x72\x1f\x7f\ +\x5f\xfd\x80\x34\xa0\x97\xaa\x2e\xd9\xdb\xb8\xba\x46\xb4\xe6\xdd\ +\xa7\x98\x9d\x82\x93\xfd\x7e\x7f\x9a\xcd\x92\x10\x91\x46\x2e\x97\ +\xab\xe0\xf1\xc7\x1f\xf7\x9c\x79\xe6\x99\xb6\x68\xc8\xce\x4e\x60\ +\xf0\xe0\x7e\xbc\xfb\xee\x42\xfa\xf6\xad\x91\x1f\xc1\x7d\xb2\x68\ +\x91\x89\x98\xa8\x4d\x7d\x76\x73\x73\x73\x59\xb6\x6c\x19\xeb\xd7\ +\xaf\xdf\x36\x72\xe4\xc8\xce\x99\x99\x99\x65\x63\x70\x1d\xea\x01\ +\xfb\x34\xee\x44\xe4\x21\xe0\x09\x6e\xbb\x4b\x78\xe8\x49\xd3\xbf\ +\xb3\x36\x50\x54\x04\xff\x79\x1c\x5e\x7e\x4e\x81\xa7\x54\xf5\x91\ +\x78\x4b\x70\x8c\xbb\xea\x21\x22\x1e\xe0\x02\x4c\x22\xce\xb1\xf8\ +\x7c\x5d\x28\x2e\x36\xfb\xfa\x49\xed\xe1\xd8\x13\xe0\x90\xde\x90\ +\x94\x1c\xdd\xc2\x8f\x9e\x13\xdb\xc4\x3f\x49\x63\xf3\x26\xc8\x5a\ +\x07\xeb\x32\x61\xf9\x12\x58\x30\x0f\x32\xe6\x98\x1e\xb8\xc1\xa0\ +\xd1\xe3\xf5\x05\x08\x14\xaf\xc2\x74\x6f\x78\x63\x5f\x06\x86\x83\ +\x7d\xd4\x57\xe3\x0e\xc0\xb2\x2c\x2f\xa6\xa6\x67\x5f\xa0\x97\xdf\ +\xef\xb7\xfd\x4b\xdb\xeb\xf5\xce\xb8\xe0\x82\x0b\x8e\xbd\xe7\x9e\ +\x7b\x6c\x59\xdf\x6e\xe3\x6e\xfa\xf4\xe9\xe4\xe4\xe4\x70\xe1\x85\ +\xe5\x85\x7d\xc7\x9f\xad\x5b\xb7\x32\x77\xee\x5c\xdd\xbe\x7d\x7b\ +\xe0\xd7\x5f\x7f\x3d\x78\xc6\x8c\x19\x6b\xed\xd6\xe4\x50\x33\xec\ +\x75\x5b\x56\x44\x9e\xc2\xe5\xba\x9f\x57\xde\x12\xae\xa9\x65\x5d\ +\x48\x1a\x35\x82\x47\x9f\x85\x9e\xbd\x85\xbf\xdf\xf0\xa0\xb8\x5c\ +\x4d\x34\x12\xb9\x3b\xce\x2a\x1e\x8b\xf3\x7a\xf5\x0a\x35\x2d\xa2\ +\xbe\x8e\x1e\x00\x88\x48\x17\xe0\x2a\x36\x64\x9f\xc9\x0f\xa3\x0f\ +\x65\xdc\xf7\xcd\x09\x85\x3c\x84\x4a\x95\xcb\x72\xbb\xa1\x75\xa2\ +\x31\xf4\x3a\x76\x86\xe4\x94\x5d\xc6\x5f\xcb\x03\xc1\xe3\x05\x9f\ +\xcf\x1c\x65\xff\xec\xf5\x9a\x07\x83\xc2\x9d\xb0\x73\x07\xec\x2c\ +\x39\x97\xfa\xf3\xa6\x3c\x58\xbf\x0e\xd6\xae\x86\x75\x6b\x4d\xc2\ +\x4f\x30\xb0\x6b\x7d\x5f\x42\x84\x48\x78\x33\xa1\xd0\x0a\x4c\x0c\ +\xda\xaf\x44\x22\xe3\xb4\xa8\xb0\xce\x6e\xa1\x3b\xd4\x0f\xfc\x7e\ +\x7f\xd0\xb2\xac\x8b\x80\x81\xb5\xc1\xb0\x03\x08\x85\x42\xe2\x2b\ +\x08\x6a\x00\x00\x0e\x74\x49\x44\x41\x54\x13\x52\x53\x53\xfb\xd1\ +\x40\xe3\xee\x92\x93\x93\x59\xb4\x68\x11\xc5\xc5\xc5\x24\x24\xd8\ +\xfb\x57\x50\x5c\x5c\xcc\x23\x8f\x3c\x12\x3a\xfa\xe8\xa3\x43\x4b\ +\x96\x2c\x39\xde\x31\xec\xea\x37\xe5\x7a\xee\x44\xe4\x68\x44\x66\ +\xf0\xd2\x1b\x2e\x6e\xa8\xe5\xc9\x9a\xc3\x3f\x84\xbf\x5d\xaf\xc0\ +\xc9\xaa\x3a\xd5\x6e\x39\x0e\xb1\x27\x5a\x23\xf0\x70\xcc\xd6\x63\ +\x0f\xa0\x33\x90\x0c\x92\x88\xcf\xd7\x0a\x91\x26\x84\x42\x6e\xc2\ +\xfb\x51\x33\x55\xc4\x18\x8c\x2e\x97\x22\xae\x08\x42\x90\x60\x30\ +\x9f\x70\x38\x0f\x13\xc7\xb5\x1a\x93\x30\xb3\x08\x98\xb3\x1f\x89\ +\x0a\x0e\xb5\x88\xfa\xec\xb9\xab\x8d\x88\xc8\x39\xc0\xd8\x9f\x7f\ +\xfe\x99\xe6\xcd\x9b\xc7\x7d\x7d\xbb\x3d\x77\x81\x40\x80\x4f\x3e\ +\xf9\x84\xd3\x4f\x3f\x9d\x2e\x5d\xba\xc4\x7d\xfd\x12\xc2\xe1\x30\ +\x77\xdf\x7d\x77\x38\x35\x35\xb5\x20\x14\x0a\x1d\xa7\xaa\x4b\x6d\ +\x13\xe3\x10\x17\xca\xf7\xdc\x25\x24\xbc\xc5\x31\xc7\x2b\xd7\xdf\ +\x1a\x67\x39\xfb\xc1\x95\xd7\xc1\xd7\x9f\x47\x98\x32\xf1\x4d\xcc\ +\x76\x84\x43\x3d\x23\x6a\x50\xfd\xcc\x9e\xc5\x6c\x77\x43\x44\x12\ +\x31\x1e\x82\x26\x98\x1a\x8b\x09\xd1\x73\xa3\xe8\x9f\x13\x30\xd9\ +\xca\x9b\x30\x5d\x1a\x36\x6a\x24\xe2\xd4\x75\x72\xa8\xb7\x58\x96\ +\xd5\x12\x28\xf0\xfb\xfd\xe1\x0a\x07\xd7\x0c\xd3\x44\x24\x92\x91\ +\x91\xe1\x3a\xe9\xa4\x93\x6c\x92\x60\x1f\x3e\x9f\x8f\xc4\xc4\x44\ +\xb2\xb2\xb2\x6c\x33\xee\x54\x95\xc7\x1f\x7f\x3c\x32\x6b\xd6\xac\ +\xe2\x70\x38\x7c\xba\x63\xd8\x35\x0c\xf6\x30\xee\x44\xa4\x19\x22\ +\xfd\xb8\xed\x2e\xb1\x35\x71\xa2\x2a\xfc\xfd\x5f\x6e\xc6\x8f\xeb\ +\x23\x22\xad\x55\x75\x93\xdd\x72\x1c\xec\xa1\x9a\xa5\x45\x1c\x1c\ +\xea\x15\x96\x65\xb9\x80\x09\x98\xfe\xda\xb6\x6c\xc1\xa8\xea\x36\ +\x9f\xcf\xb7\x30\x2d\x2d\xed\xd0\x86\x68\xdc\x81\xd9\x9a\x5d\xbd\ +\x7a\xb5\x6d\xeb\x8f\x1a\x35\x8a\x48\x24\xa2\xe1\x70\xf8\x5c\x55\ +\x9d\x6b\x9b\x10\x87\xb8\x52\x9e\xe7\xee\x18\x54\x85\xfb\xef\x0c\ +\xf2\xd8\x7d\xb5\xb1\xf2\xf9\x9e\x04\x83\x02\x78\x81\xe3\x80\x1f\ +\x6c\x56\xe3\xe0\xe0\xe0\x60\x3b\xd1\x2e\x16\x4f\x00\x5f\x59\x96\ +\x95\xed\xf7\xfb\xab\xd2\xde\x2e\x66\x04\x83\xc1\xf1\xa9\xa9\xa9\ +\x07\xd3\x40\xe3\xee\x52\x52\x52\xc8\xc8\xc8\x60\xc7\x8e\x1d\x34\ +\x6d\xda\x34\xae\x6b\x8f\x1a\x35\x8a\xae\x5d\xbb\x92\x9f\x9f\xff\ +\x3f\x55\xfd\x2d\xae\x8b\x3b\xd8\x4a\x79\xc6\x5d\x11\xf0\x1f\xfe\ +\xa8\x93\xc9\x7e\x7f\x6e\xb1\x89\x48\x02\xa6\x0c\xc4\x12\x55\xad\ +\x15\xc1\xc5\x0e\x0e\x0e\x0e\xf1\xc4\xef\xf7\x7f\x6b\x59\xd6\xdf\ +\x80\x37\x2d\xcb\x5a\xe9\xf7\xfb\xed\x68\x0a\x3f\x65\xe5\xca\x95\ +\x77\x14\x16\x16\xd6\x99\x96\x5c\xb1\xa4\x5d\xbb\x76\xb8\xdd\x6e\ +\xb2\xb3\xb3\xe9\xde\xbd\x7b\xdc\xd6\xfd\xe9\xa7\x9f\xe8\xdc\xb9\ +\x33\x0b\x17\x2e\x1c\xf9\xf6\xdb\x6f\xdf\x11\xb7\x85\x1d\x6a\x05\ +\x7b\x18\x77\xaa\xfa\x3b\xf0\xbb\x0d\x5a\x62\x4d\x47\x60\x3a\x30\ +\x08\xc7\x9b\xe7\xe0\xe0\xd0\x40\xf1\xfb\xfd\x6f\x5b\x96\x95\x89\ +\xd9\xa2\xb5\x83\x29\x91\x48\x44\xe6\xcf\x9f\xcf\x31\xc7\x1c\x63\ +\x93\x04\xfb\x70\xbb\xdd\xb4\x6d\xdb\x96\xf5\xeb\xd7\xc7\xcd\xb8\ +\xfb\xe1\x87\x1f\xf8\xf2\xcb\x2f\x39\xe6\x98\x63\x46\x7e\xfc\xf1\ +\xc7\x97\xc6\x65\x51\x87\x5a\x45\x03\xea\x03\xe5\xe0\xe0\xe0\xd0\ +\x30\xf1\xfb\xfd\x63\xed\x5a\x5b\x55\x37\xfa\x7c\xbe\x95\x69\x69\ +\x69\xdd\x1a\xa2\x71\x07\x66\x6b\x76\xf1\xe2\xc5\x71\x59\x6b\xc4\ +\x88\x11\xbc\xf6\xda\x6b\xaa\xaa\x4f\x2e\x59\xb2\xe4\xd1\xb8\x2c\ +\xea\x50\xeb\x88\x73\x35\xd8\xf8\x10\xad\xb2\x5f\xd2\x2b\xef\x59\ +\x11\x99\x14\x3d\x8e\x8c\xbe\xff\xa5\x88\xf8\x45\xe4\x42\x11\x19\ +\x2f\x22\x9b\xa2\x25\x12\x10\x91\x13\x44\x64\x9c\x88\x64\x8b\xc8\ +\x22\x11\x79\x4d\x44\x9a\x95\x99\xff\x13\x11\xf9\xa7\x88\x9c\x15\ +\xbd\x3f\x57\x44\x26\x8a\xc8\x11\xe5\x68\xb9\x48\x44\xa6\x89\x48\ +\x96\x88\x7c\x2d\x22\xdd\x45\xe4\x73\x11\xb9\xad\xd4\x98\x7f\x8b\ +\xc8\xbb\xe5\xdc\xfb\xb2\x88\x3c\x55\xe6\x5a\x13\x11\x79\x4e\x44\ +\xe6\x44\xd7\xfd\x55\x44\x4e\x2d\xe7\xde\x36\x22\xf2\xa6\x88\x2c\ +\x8c\xae\x3d\x5a\x44\x9c\x6c\x62\x07\x87\x06\x8e\x65\x59\x62\x59\ +\xd6\x03\x96\x65\xb5\x8e\xd7\x9a\xc1\x60\x70\xfc\x9c\x39\x73\x02\ +\x15\x8f\xac\x9f\xa4\xa4\xa4\xd0\xaa\x55\x2b\x82\xc1\x60\x8d\xad\ +\x11\x0c\x06\x79\xfd\xf5\xd7\xf5\xd5\x57\x5f\x55\x55\xbd\x5f\x55\ +\x1d\xc3\xae\x01\x53\x2f\x8d\x3b\x20\x8f\x5d\xc5\x71\xc7\x03\x1f\ +\x46\x8f\x92\x5e\xb4\xc7\x63\xb2\xc7\xde\x03\xe6\x03\xf7\x00\xf9\ +\xd1\x9a\x4c\x25\x41\xa7\xff\x00\x2c\xe0\x2a\x60\xba\x88\x78\x4b\ +\xcd\x7f\x0c\x70\x23\xf0\x0e\x30\x03\x78\x01\xd3\x87\xf3\xa7\x68\ +\x3b\x28\x00\x44\xe4\x72\xe0\x2b\x4c\x9d\xb4\xa1\xc0\x4c\x4c\x05\ +\xf9\xb3\x81\xd2\xfe\xf9\x9e\xc0\xd1\xe5\x7c\x8e\xc3\x31\xed\x98\ +\x4a\xe6\x6b\x04\xa4\x02\xd7\x00\x93\x80\xbb\xe0\xff\xdb\xbb\xf7\ +\xe0\xa8\xaa\x3b\x80\xe3\xdf\x93\xdd\x20\xa6\x28\x48\x44\xc3\xaa\ +\x40\x4b\x8d\x55\x1c\x6b\x69\x2d\x0c\xb6\x53\x5b\x54\xd4\x76\x5a\ +\xa8\xda\x29\xad\x4a\xb5\x6a\xe7\x38\x53\x95\x5a\xfa\x9c\xd6\xd2\ +\xfa\x88\xaf\xce\x68\xd5\xd3\x82\x28\xd2\x30\x91\x3a\x4a\x9b\xb1\ +\xc2\x84\x50\x2c\x20\xe5\x1d\x22\x1a\x4a\xda\x4a\x06\x08\xa1\x01\ +\x81\x12\x12\x81\xdd\xdc\x5f\xff\x38\x37\xb8\xec\x24\x86\x6c\xb2\ +\x1b\x92\xfd\x7d\x66\xee\x64\xf6\xde\x73\xcf\x39\x19\x20\xf9\x71\ +\x1e\xbf\x43\x00\x54\x1a\x63\xbe\x9a\x54\xee\x1c\xe0\x6d\x60\x22\ +\xfe\xf8\xab\x5f\xe2\xcf\xf3\x5c\x6f\x8c\x39\x56\x9f\x52\x2a\x27\ +\x9d\x0d\x7c\x0f\x58\xee\x9c\x3b\x27\x4b\x6d\x2e\xaf\xa9\xa9\x89\ +\x64\x32\xb8\x39\x99\x0d\x1b\x36\x8c\x49\x93\x26\x91\x9f\x9f\xdf\ +\x79\xe1\x34\x1c\x38\x70\x80\xa5\x4b\x97\xca\xe8\xd1\xa3\x89\x46\ +\xa3\x37\x88\xc8\x23\x19\x69\x48\xf5\x19\xfd\x32\xb8\x0b\xd3\xa1\ +\xbc\x1a\x7e\xac\x14\x91\xb9\xe1\xd5\x90\x54\xec\x12\xe0\x52\x11\ +\xb9\x57\x44\x9e\x17\x91\x3a\xa0\x04\x9f\xe0\xf4\x5a\x11\x79\x59\ +\x44\x7e\x07\x5c\x0f\x8c\x01\xee\x48\x69\x66\x0c\x30\x5e\x44\x7e\ +\x2e\x22\x8f\x01\x77\x01\x67\x01\x57\x03\x18\x63\xf2\x80\x87\x80\ +\x0a\x11\x99\x26\x22\xe5\x22\xf2\x28\xf0\x08\x30\x24\xcd\x6f\x6d\ +\x3a\x70\x11\x30\x49\x44\xee\x13\x91\x52\x11\xb9\x1a\x1f\x90\x3e\ +\x96\x54\xee\x41\x60\x10\x70\x99\x88\xcc\x14\x91\xe7\xf0\x01\xe9\ +\x9e\xf0\x99\x52\x2a\x47\x59\x6b\x77\x03\x97\x87\x1f\xdf\x74\xce\ +\x9d\x9f\x85\x66\x97\x27\x12\x89\x48\xdb\x59\xab\xaa\xe7\x6c\xdf\ +\xbe\x9d\x75\xeb\xd6\xc9\x80\x01\x03\x82\xd5\xab\x57\xdf\x10\x8f\ +\xc7\x5f\xed\xfc\x2d\xd5\xdf\xf5\xcb\xe0\xee\x04\x6d\x6a\x3b\xe8\ +\x1c\xc0\x18\x33\x04\x3f\x52\x56\x2a\x22\x41\xdb\x7d\x11\x79\x03\ +\xf8\x0f\x90\x9a\xa4\xe9\x1f\x29\xc1\xe2\x0a\x40\xf0\x1b\x39\xc0\ +\x9f\xa2\xf0\x51\xe0\xc5\x94\xf7\xca\xc2\x72\xe9\xb8\x0e\xa8\x06\ +\xe2\xc6\x98\x4f\xb4\x5d\xc0\x4a\xa0\x38\x69\xfa\xf8\x3a\x60\x09\ +\x50\x94\x54\xe6\x02\xfc\x68\xdf\x67\xd2\x6c\x5b\x29\xd5\x4f\x58\ +\x6b\x77\xe2\x7f\xa6\x55\x01\x19\x4f\x70\x2c\x22\x3b\xf2\xf3\xf3\ +\x1b\x36\x6d\xda\x94\xe9\xa6\x72\x4a\x75\x75\x35\x73\xe7\xce\x0d\ +\x44\xe4\xe8\x9a\x35\x6b\xc6\x2d\x5e\xbc\x58\x03\x3b\x05\xe4\xf6\ +\x86\x8a\x15\x29\x9f\x47\x85\x5f\xeb\xdb\x29\xbb\x8d\x0f\x82\xb6\ +\x36\xd5\xc9\x1f\x44\xe4\xa0\x31\x26\x8e\x3f\x0d\x01\x60\x44\xf8\ +\x75\x57\x4a\xb9\x16\x63\xcc\x9e\x2e\xf7\xd6\x2b\x06\x0a\x81\xf6\ +\x7e\x42\x1e\x01\x62\xc6\x98\xff\x02\xc3\x80\x2f\x03\xd7\xb4\x53\ +\x4e\x8c\x31\x79\xc9\x01\xac\x52\x2a\xf7\x58\x6b\xf7\x01\x53\xb2\ +\xd5\x5e\x3c\x1e\xaf\xdc\xb0\x61\xc3\x37\xa7\x4d\x9b\x96\x99\xb9\ +\xc9\x1c\xb3\x68\xd1\x22\x1e\x78\xe0\x81\x00\xf8\x6b\x24\x12\xb9\ +\xbd\xbc\xbc\xbc\xb1\xb7\xfb\xa4\x4e\x1e\xb9\x3c\x72\x97\xba\xb8\ +\xb7\xed\x1f\xc6\xd0\x76\xca\x0e\xc3\xaf\xe3\xeb\x8a\xb6\x00\xee\ +\x8c\xe4\x9b\xe1\x74\xed\x19\x29\x65\x03\x3e\x08\x0a\x93\xa5\xae\ +\x87\x69\x04\x5e\x16\x91\x81\x1d\x5c\x5b\x81\x26\x7c\xae\xc2\x07\ +\x3b\x28\x73\xaa\x06\x76\x4a\xa9\xf6\x38\xe7\xc6\x3b\xe7\x32\x75\ +\x34\xd1\xf2\xea\xea\x6a\x13\x04\xb9\xfb\xe3\xe7\xe8\xd1\xa3\x34\ +\x35\x35\x75\xab\x0e\x11\x61\xf6\xec\xd9\xcc\x9c\x39\x93\x20\x08\ +\x7e\xdb\xda\xda\x3a\x59\x03\x3b\x95\xaa\x3f\x07\x77\xcd\xe1\xd7\ +\x33\x4f\xa4\xb0\x88\xec\xc2\x07\x64\x57\x27\xdf\x37\xc6\x8c\xc4\ +\xaf\xaf\x7b\xbb\x8b\xed\xbf\x8b\x3f\xc7\xf4\xca\x94\xfb\x5f\xc0\ +\x9f\xa6\x91\x6c\x17\x70\xbe\x31\xe6\x58\x60\x69\x8c\xb9\x04\x3f\ +\x52\x97\x6c\x2d\x30\x31\x9c\x42\x6e\x97\x88\xb4\x02\xeb\x81\xc9\ +\xc6\x98\x48\x17\xfb\xac\x94\xca\x51\xce\xb9\x61\xf8\x5c\x78\x15\ +\xce\xb9\xa2\x0c\x34\xb1\xe2\xc8\x91\x23\xd1\xda\xda\xda\x0c\x54\ +\xdd\x37\xac\x5c\xb9\x92\x55\xab\x56\xa5\xfd\x7e\x4b\x4b\x0b\xe5\ +\xe5\xe5\x52\x58\x58\x28\xc6\x98\x3b\x83\x20\x98\xa1\xff\x59\x57\ +\xed\xe9\xcf\xc1\xdd\x6e\xfc\x01\xf1\xb7\x18\x63\x26\x1a\x63\x2e\ +\x35\xc6\x0c\xea\xe4\x9d\x87\x80\x29\xc6\x98\xe9\xc6\x98\xa1\xe1\ +\x5a\xb5\x32\x7c\xa0\xf8\x64\x57\x1a\x17\x91\xc3\xc0\x53\xc0\x1d\ +\xc6\x98\xa9\xc6\x98\x81\x61\xc0\xf6\x24\x7e\x0a\x35\x59\x05\x60\ +\x80\x47\xc3\x35\x72\xd7\x03\x7f\x20\xe9\xc4\x8d\xd0\xfd\xf8\x11\ +\xbe\x3f\x1b\x63\x3e\x1b\xa6\x45\x29\x32\xc6\x5c\x6b\x8c\x79\x38\ +\xa9\xdc\x0f\xf1\xbb\x6c\xe7\x1b\x63\x2e\x0a\xdb\x3e\xcf\x18\xf3\ +\x0d\x63\xcc\x7d\x5d\xf9\x3e\x94\x52\xb9\xc1\x5a\xbb\x07\xb8\x02\ +\xbf\xf3\xff\x2d\xe7\xdc\x55\x3d\x59\xbf\x88\x6c\x8d\x46\xa3\xfb\ +\x72\x79\xdd\x5d\x2c\x16\xa3\xa1\xa1\x81\x74\x46\x2f\x1b\x1a\x1a\ +\x58\xbb\x76\xad\x0c\x1e\x3c\x98\xba\xba\xba\x19\x41\x10\xcc\xce\ +\x40\x17\x55\x3f\xd1\x6f\x83\x3b\x11\x11\xe0\x56\xa0\x08\x78\x0d\ +\xbf\x70\x78\x5c\x27\xaf\x3d\x85\x0f\xa0\x4a\xf0\x81\xe1\x16\xfc\ +\x34\xed\x44\x11\x49\x67\x9d\xdc\x4c\x7c\x0a\x96\x52\xa0\x05\x58\ +\x0e\xfc\x1a\x1f\x78\x26\xf7\x75\x25\xf0\x30\x3e\xbd\xca\x16\xfc\ +\x26\x8c\xe7\x81\x0d\x29\xe5\x76\xe2\x77\xb9\x9d\x8a\x4f\xab\xd2\ +\x8c\x4f\xef\xb2\x00\x28\x48\x2a\xb7\x06\xb8\x0a\xf8\x34\xf0\x0e\ +\xf0\x3e\xb0\x1d\x78\x9a\xf4\x37\x73\x28\xa5\xfa\x39\x6b\xed\x5a\ +\xfc\xb1\x8d\x4b\xc8\xc0\xef\x87\x20\x08\xde\xd8\xb8\x71\x63\xc6\ +\x37\x70\x9c\xac\x62\xb1\x18\x89\x44\x82\xc6\xc6\xae\xcd\xa2\x2e\ +\x59\xb2\x84\xca\xca\x4a\xa9\xaf\xaf\x7f\xff\x95\x57\x5e\x19\xbf\ +\x60\xc1\x82\x27\x32\xd4\x45\xd5\x4f\x18\x1f\x03\xa9\x64\x61\x4e\ +\xbb\x8f\x03\x07\x52\x76\xc4\xa6\x5b\xdf\x69\xf8\x3c\x73\xff\x12\ +\x91\xc0\x18\x53\x07\x2c\x14\x91\xe9\x29\xe5\x86\x84\xe5\x6a\x45\ +\x24\xd1\x49\x9d\xa7\xe3\x77\xe3\x1e\x04\x76\x8a\x48\xbb\x09\xa4\ +\x8c\x31\x67\x02\xe7\x02\xfb\xc2\x72\x3a\x84\xaf\x72\x56\x98\xac\ +\xbc\x0a\xb8\x50\x44\xfe\xd9\xdb\xfd\xc9\x35\xc6\x98\xbb\x07\x0d\ +\x1a\xf4\x78\x65\x65\x65\x56\x36\x55\x34\x34\x9c\xc2\x94\x29\x97\ +\xf2\xdc\x73\xef\x70\xf1\xc5\x87\xb2\xd1\x64\xa7\x5e\x7a\xe9\x25\ +\x8a\x8b\x8b\x19\x3b\x76\x6c\xa7\x65\x1b\x1b\x1b\x29\x29\x29\x69\ +\x5d\xb5\x6a\x55\x5e\x41\x41\xc1\x8b\x2d\x2d\x2d\xd3\xf5\xac\x74\ +\x75\x22\xfa\xed\xc8\x5d\x77\x88\x48\x5c\x44\xb6\xf4\x44\x60\x17\ +\xd6\xd7\x24\x22\x5b\x3b\x0b\xac\x44\xe4\x80\x88\xd4\x74\x16\xd8\ +\x85\x65\x0f\x8a\x48\xb5\x88\x6c\xeb\x28\xb0\x0b\xcb\xed\x15\x91\ +\x4d\x22\xb2\x5d\x03\x3b\xa5\x54\x3a\x9c\x73\x9f\x77\xce\xa5\xe6\ +\xfa\x4c\xc7\xf2\x43\x87\x0e\xe5\xd7\xd5\xd5\xf5\x40\x55\x7d\x53\ +\x2c\x16\x63\xd7\xae\x5d\x1f\x5a\x46\x44\x78\xfd\xf5\xd7\x99\x3a\ +\x75\x6a\xeb\xba\x75\xeb\x76\x00\x5f\x6c\x6e\x6e\xbe\x55\x03\x3b\ +\x75\xa2\x34\xb8\x53\x4a\x29\xd5\x99\x71\xc0\xef\x9d\x73\x7f\x72\ +\xce\xa5\x9b\x84\x1d\xe0\xad\x48\x24\xd2\x5c\x55\x55\xd5\x53\xfd\ +\xea\x73\x62\xb1\x18\x8d\x8d\x8d\x1d\x1e\x45\x56\x57\x57\x47\x59\ +\x59\x59\x50\x54\x54\xc4\x84\x09\x13\x16\xc6\xe3\xf1\x0b\x45\xe4\ +\xef\xed\x16\x56\xaa\x03\x1a\xdc\xf5\x8e\x3b\xf1\x47\x9f\x29\xa5\ +\xd4\x49\xcf\x5a\xfb\x38\x7e\x1d\xef\x04\xa0\xca\x39\x57\xd0\xc9\ +\x2b\xed\x0a\x67\x0f\x56\x56\x55\x55\xe5\xec\x2c\x42\x2c\x16\x23\ +\x08\x02\x76\xef\x3e\x6e\xe9\x35\x89\x44\x82\xb2\xb2\x32\x6a\x6b\ +\x6b\x19\x39\x72\x64\xb0\x79\xf3\xe6\x7b\x2a\x2a\x2a\x6e\x0c\x37\ +\xe7\x29\xd5\x25\x1a\xdc\xf5\x02\x11\xa9\x10\x91\xae\xa6\x56\x51\ +\x4a\xa9\x5e\x63\xad\xfd\x1b\xfe\xd8\xc6\xdf\x58\x6b\x5b\xd2\xad\ +\xa7\xb5\xb5\x75\xd9\xfa\xf5\xeb\x73\xf3\x90\x59\xa0\xa0\xa0\x80\ +\x21\x43\x86\x1c\x37\x35\x5b\x53\x53\xc3\x4d\x37\xdd\x14\x9f\x33\ +\x67\xce\x91\xe6\xe6\xe6\xf5\xf1\x78\xfc\x63\xcf\x3e\xfb\xec\x53\ +\xbd\xd8\x4d\xd5\xc7\xe5\xf2\x09\x15\x4a\x29\xa5\xba\x20\x3c\xd5\ +\xe2\xf9\xe4\x7b\xce\xb9\x2f\x01\xbb\xad\xb5\x27\x7a\x70\xec\xf2\ +\x7d\xfb\xf6\x9d\xd2\xd0\xd0\xc0\xf0\xe1\xc3\x7b\xbc\x8f\x7d\x41\ +\x2c\x16\xa3\xbe\xbe\x9e\xa6\xa6\x26\xe6\xcd\x9b\x47\x69\x69\xa9\ +\x44\x22\x91\x15\x89\x44\xe2\xf6\x92\x92\x92\x6d\xbd\xdd\x3f\xd5\ +\xf7\x69\x70\xa7\x94\x52\xaa\x3b\x7e\x00\x5c\xe3\x9c\x7b\x01\xb8\ +\xdf\x5a\xfb\xe1\xbb\x05\x60\x7d\x5e\x5e\xde\xd1\x59\xb3\x66\x0d\ +\x18\x35\x6a\x14\x6d\x19\x1b\x44\xe4\x43\xaf\xd4\x32\x00\x41\x10\ +\x74\xf8\x5c\x44\x68\x6e\x1e\x06\x3c\x43\x69\x69\x29\x43\x87\xd6\ +\x76\x5a\x67\x37\x9e\x4b\xdb\xbd\xb0\x4f\x92\x54\x4e\x52\xdf\x29\ +\x2c\x2c\x64\xc4\x88\x11\x91\xcd\x9b\x37\xb3\x7f\xff\xfe\x23\x22\ +\x72\x67\x3c\x1e\x9f\xd7\x73\x7f\x24\x2a\xd7\x69\x2a\x14\xa5\x54\ +\xce\xd0\x54\x28\x3d\xcf\x39\x97\x07\xdc\x02\x3c\x80\xcf\xc1\x79\ +\x5e\x67\xd3\xb6\xd1\x68\x74\x41\x34\x1a\xbd\x0c\x9f\x77\xb3\x5b\ +\x57\x98\xd3\x34\x00\xa4\xb5\x75\xc6\x59\x41\x70\xdd\x10\x9f\x13\ +\x1e\x60\x60\x9e\xc8\xa7\x4e\x37\xe6\x9d\x26\x38\x98\x00\x23\x00\ +\xc6\xac\x3e\x10\x89\xfc\x68\x5b\xd2\xfb\x6d\x57\x90\xf4\x39\xe8\ +\xe8\x59\xb8\x76\x30\xad\xfe\x8e\x19\x33\xa6\xf0\xb6\xdb\x6e\xbb\ +\xf6\xf0\xe1\xc3\xa6\xaa\xaa\x6a\xc5\xb2\x65\xcb\x6e\xde\xbb\x77\ +\xef\xf1\x0b\xf0\x94\xea\x26\x0d\xee\x94\x52\x39\x43\x83\xbb\xcc\ +\x71\xce\x9d\x0a\x8c\xb7\xd6\x2e\xeb\xad\x3e\x18\xc3\x79\xc0\x56\ +\x7c\x90\xd9\x91\x56\x60\xac\x08\x6f\x65\xa7\x57\xc7\x73\xce\x0d\ +\x04\xee\x05\x9e\xb1\xd6\x76\xef\xa0\x59\xa5\x3a\xa0\xc1\x9d\x52\ +\x2a\x67\x68\x70\x97\x5d\xce\xb9\xbb\x81\x11\xc0\x1c\x6b\xed\x96\ +\x6c\xb4\x69\x0c\xbf\xc2\x9f\x34\xd4\x61\xb7\x44\xb8\x2b\x1b\x7d\ +\x71\xce\x8d\xc4\x9f\x94\x54\x6a\xad\xfd\x77\x36\xda\x54\x0a\x74\ +\xb7\xac\x52\x4a\xa9\xcc\x09\x80\x1b\x81\x1a\xe7\xdc\x2a\xe7\xdc\ +\x05\x59\x68\xf3\x51\x60\x47\x07\xcf\xf6\x03\xbf\xc8\x74\x07\x9c\ +\x73\x57\x38\xe7\x2a\x80\x77\x01\x8b\x3f\xf1\x48\xa9\xac\xd1\xe0\ +\x4e\x29\x95\x4b\x0e\xe3\xa7\xed\x8e\xf4\x76\x47\x72\x81\xb5\xf6\ +\x69\xfc\x31\x89\x93\xf0\x81\x4e\xc6\xd7\x96\x89\xd0\x02\xfc\xb8\ +\x83\xc7\xf7\x8b\xf0\x5e\xa6\xfb\x00\x0c\xc7\xff\x1d\xbb\x01\x38\ +\xd7\x5a\xbb\x38\x0b\x6d\x2a\x75\x8c\x4e\xcb\x2a\xa5\x94\xca\x3a\ +\xe7\xdc\xd9\xc0\x22\x60\x3e\xf0\x47\x6b\x6d\x63\x4f\xd6\x6f\x0c\ +\x6f\xe2\x93\x2e\xb7\xa9\x01\x3e\x29\x42\xa7\xc7\x3b\x9e\x28\xe7\ +\xdc\x19\xc0\xb7\x81\x0b\xac\xb5\xdf\xef\xa9\x7a\x95\xea\x2e\x1d\ +\xb9\x53\x4a\x29\xd5\x1b\xa2\xc0\x1a\xfc\x34\xe9\x4e\xe7\xdc\x13\ +\x3d\x5c\xff\x3d\xf8\x1d\xaa\x6d\xee\xed\xa9\xc0\xce\x39\x97\xef\ +\x9c\x5b\x0a\xec\x02\x1e\x01\x4e\x73\xce\x45\x7a\xa2\x6e\xa5\x7a\ +\x82\x8e\xdc\x29\xa5\x94\xea\x35\xe1\x2e\xdb\xc9\x40\xb3\xb5\xb6\ +\x3c\xe9\xfe\x64\xe0\x6b\xc0\x9b\xc0\x4a\x60\xab\xb5\xb6\x4b\xbf\ +\xb0\x8c\xe1\x05\xe0\x3b\xc0\x5f\x44\x98\x9c\x46\xdf\x46\x03\x97\ +\x03\x9f\x03\x66\x58\x6b\xff\x97\xf4\xac\x04\x3f\x1a\xb8\x50\x77\ +\xbd\xaa\x93\x8d\x26\x31\x56\x4a\x29\xd5\x6b\xac\xb5\xef\x03\x65\ +\xed\x3c\x12\x60\x14\x7e\x43\xc6\x47\x80\x9f\x01\x0f\xb7\x3d\x0c\ +\x03\xaf\x53\x80\xbd\xc0\x7b\xd6\xda\xd6\x76\xea\xf8\x29\xf0\x15\ +\xe0\xbe\xf6\xda\x0e\x73\xf4\x0d\x05\xce\x04\xea\x93\x83\x34\xe7\ +\xdc\x32\xe0\x0a\xfc\xda\xb9\x8d\x40\x11\x70\x2c\xb8\xb3\xd6\xfe\ +\xe4\x04\xbf\x45\xa5\xb2\x4e\x47\xee\x94\x52\x4a\x9d\xb4\x9c\x73\ +\x51\xfc\x99\xb6\x7b\xac\xb5\x3b\x92\xee\xcf\x07\xbe\x15\x7e\x14\ +\xe0\x66\x6b\xed\xfc\xa4\xe7\xdf\x05\xc6\xd4\xd6\x9e\x43\x71\x71\ +\xbd\x00\xf3\xac\xb5\xd5\x49\xcf\x4b\x81\xa9\x7c\xb0\x3c\xe9\xeb\ +\xd6\xda\x85\x49\xcf\xaf\x04\x9a\x81\x8d\xd6\x5a\xdd\x80\xa3\xfa\ +\x14\x1d\xb9\x53\x4a\x29\x75\xd2\xb2\xd6\x26\xf0\x23\x67\xa9\xee\ +\x01\x4a\xf0\x23\x6f\x43\x81\x0d\x29\xcf\xcf\x02\xc6\x15\x17\xd7\ +\x0f\x06\x9a\x80\xd7\x52\x9e\xcf\x02\x16\x02\xfb\xc2\xeb\xdd\x94\ +\x76\x2b\xbb\xdd\x79\xa5\x7a\xc9\xff\x01\xc6\x5e\xaa\x37\xb8\x52\ +\x09\x86\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +" + +qt_resource_name = "\ +\x00\x09\ +\x0c\x78\x54\x88\ +\x00\x6e\ +\x00\x65\x00\x77\x00\x50\x00\x72\x00\x65\x00\x66\x00\x69\x00\x78\ +\x00\x06\ +\x07\x03\x7d\xc3\ +\x00\x69\ +\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\ +\x00\x11\ +\x0b\x8f\x12\x87\ +\x00\x73\ +\x00\x63\x00\x68\x00\x65\x00\x6d\x00\x61\x00\x5f\x00\x73\x00\x68\x00\x70\x00\x65\x00\x72\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x14\ +\x0c\xe5\xe6\xa7\ +\x00\x73\ +\x00\x63\x00\x68\x00\x65\x00\x6d\x00\x61\x00\x5f\x00\x72\x00\x65\x00\x63\x00\x74\x00\x61\x00\x6e\x00\x67\x00\x6c\x00\x65\x00\x2e\ +\x00\x70\x00\x6e\x00\x67\ +\x00\x12\ +\x07\x43\x81\xa7\ +\x00\x73\ +\x00\x63\x00\x68\x00\x65\x00\x6d\x00\x61\x00\x5f\x00\x65\x00\x6c\x00\x6c\x00\x69\x00\x70\x00\x73\x00\x65\x00\x2e\x00\x70\x00\x6e\ +\x00\x67\ +" + +qt_resource_struct = "\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x18\x00\x02\x00\x00\x00\x03\x00\x00\x00\x03\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x01\x06\xa2\ +\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x00\x52\x00\x00\x00\x00\x00\x01\x00\x00\x5a\xc2\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/src/Tools/ZCracksPlug/main.py b/src/Tools/ZCracksPlug/main.py new file mode 100644 index 000000000..e4b3e526d --- /dev/null +++ b/src/Tools/ZCracksPlug/main.py @@ -0,0 +1,514 @@ +import sys, pickle, tempfile, shutil +from os import path, getpid, environ, remove, system + +try: + from PyQt5.QtCore import * + from PyQt5.QtGui import * + from PyQt5.QtWidgets import * +except: + from PyQt4.QtCore import * + from PyQt4.QtGui import * + +import utilityFunctions as uF +import genereCrack, Zset, output, zcracks_ui + +from output import message, init +from zcracks_ui import Ui_Zui + + +# --------------------- +# FONCTIONS ANNEXES +# --------------------- + + +uF.removeFromSessionPath('LD_LIBRARY_PATH', 'Meshgems-2111') + +def stringToFloat(string, typ=float): + if str(string).replace(' ','')=='': + out=[] + else: + out=map(typ, str(string).split()) + return(out) + +def addExtension(string, extension): + cond=True + strLen=len(string) + if strLen<1: + out=None + else: + start=0 + lastPt=0 + while cond: + res=string.find('.',start) + if res==-1: + cond=False + else: + lastPt=res + start=res+1 + if strLen<=(lastPt+1+5) and lastPt!=0: + out=string[:(lastPt+1)]+extension.replace('.','') + else: + out=string+'.'+extension.replace('.','') + return(out) + + +# ---------------------------- +# DEFINITION DE LA CLASSE +# ---------------------------- +class ShipHolderApplication(QGroupBox): + + def __init__(self, parent=None): + super (ShipHolderApplication, self).__init__(parent) + + self.salomeVers=path.normpath(environ['ROOT_SALOME']) + self.salomeVers=path.split(self.salomeVers)[-1].split('V')[-1] + + self.createWidgets() + self.data=dict() + self.GroupToLoad=None + self.ui.widget.setVisible(False) + self.tmpdir=tempfile.mkdtemp() + self.saneGeoName=path.join(self.tmpdir,'salome_sane.geo') + self.crackGeoName=path.join(self.tmpdir,'salome_crack.geo') + self.crackMedName=path.join(self.tmpdir,'salome_crack.med') + self.crackedGeoName=path.join(self.tmpdir,'cracked.geo') + + global log + init(self.tmpdir) + + self.verbose=1 + + #self.connect(self.ui.CBQuad, SIGNAL("toggled(bool)"),self.pressQuad) + #self.connect(self.ui.btReset, SIGNAL("clicked()"),self.pressReset) + #self.connect(self.ui.btCancel, SIGNAL("clicked()"),self.pressCancel) + #self.connect(self.ui.btApply, SIGNAL("clicked()"),self.pressApply) + #self.connect(self.ui.btApplyClose, SIGNAL("clicked()"),self.pressApplyClose) + #self.connect(self.ui.btLoad, SIGNAL("clicked()"),self.pressCharger) + #self.connect(self.ui.btSave, SIGNAL("clicked()"),self.pressSauver) + #self.connect(self.ui.btLoadCracked, SIGNAL("clicked()"),self.pressLoadCracked) + #self.connect(self.ui.btLoadSane, SIGNAL("clicked()"),self.pressLoadSane) + + #self.connect(self.ui.btGrVol, SIGNAL("clicked()"),self.pressLoadGroupVOL) + #self.connect(self.ui.btGrFace, SIGNAL("clicked()"),self.pressLoadGroupFACE) + #self.connect(self.ui.btGrEdge, SIGNAL("clicked()"),self.pressLoadGroupEDGE) + #self.connect(self.ui.btGrNode, SIGNAL("clicked()"),self.pressLoadGroupNODE) + #self.connect(self.ui.btGrAll, SIGNAL("clicked()"),self.pressLoadGroupALL) + #self.connect(self.ui.btVisu, SIGNAL("clicked()"),self.pressVisu) + + #self.connect(self.ui.CBAdvanced, SIGNAL("toggled(bool)"),self.pressAdvanced) + + self.ui.CBQuad.toggled.connect(self.pressQuad) + self.ui.btReset.clicked.connect(self.pressReset) + self.ui.btCancel.clicked.connect(self.pressCancel) + self.ui.btApply.clicked.connect(self.pressApply) + self.ui.btApplyClose.clicked.connect(self.pressApplyClose) + self.ui.btLoad.clicked.connect(self.pressCharger) + self.ui.btSave.clicked.connect(self.pressSauver) + self.ui.btLoadCracked.clicked.connect(self.pressLoadCracked) + self.ui.btLoadSane.clicked.connect(self.pressLoadSane) + + self.ui.btGrVol.clicked.connect(self.pressLoadGroupVOL) + self.ui.btGrFace.clicked.connect(self.pressLoadGroupFACE) + self.ui.btGrEdge.clicked.connect(self.pressLoadGroupEDGE) + self.ui.btGrNode.clicked.connect(self.pressLoadGroupNODE) + self.ui.btGrAll.clicked.connect(self.pressLoadGroupALL) + self.ui.btVisu.clicked.connect(self.pressVisu) + + self.ui.CBAdvanced.toggled.connect(self.pressAdvanced) + self.lineEditTypes=[str, str, float, + float, float, str, + str, str, str, + float, int, int, + str] + + self.lineEditNames=['crackedName','saneName','minSize', + 'maxSize','extractLength','grVol', + 'grFace','grEdge','grNodes', + 'gradation','iterations','layers', + 'surfopt'] + + self.lineEditObjects=[self.ui.valCrackedName,self.ui.valSaneName,self.ui.valMinSize, + self.ui.valMaxSize,self.ui.valExtractLength,self.ui.valGrVol, + self.ui.valGrFace,self.ui.valGrEdge,self.ui.valGrNode, + self.ui.valGradation,self.ui.valIterations,self.ui.valLayers, + self.ui.valSurfopt] + + def createWidgets(self): + self.ui = Ui_Zui() + self.ui.setupUi(self) + +# ----------------------------------- +# FONCTIONS D'ACTIONS DES BOUTONS +# ----------------------------------- + + def pressQuad(self): + if self.ui.CBQuad.isChecked(): + self.ui.CBBarsoum.setEnabled(True) + self.ui.valGradation.setText(QString('2.3')) + else: + self.ui.valGradation.setText(QString('1.3')) + self.ui.CBBarsoum.setChecked(False) + self.ui.CBBarsoum.setEnabled(False) + + + def pressReset(self): + for val in self.lineEditObjects: + val.clear() + self.ui.CBQuad.setChecked(False) + self.ui.CBBarsoum.setChecked(False) + nbOnglet=self.ui.tabWidget.count() + for iongl in range(nbOnglet): + onglet=self.ui.tabWidget.widget(iongl) + tab=onglet.findChildren(QTableWidget)[0] + for irow in range(tab.rowCount()): + if tab.item(irow,0) != None: + tab.item(irow,0).setText(QString('')) + self.ui.valGradation.setText(QString('1.3')) + self.ui.valLayers.setText(QString('5')) + self.ui.valIterations.setText(QString('2')) + self.ui.CBIs2D.setChecked(False) + self.ui.CBRefine.setChecked(False) + + + def pressApply(self): + message('M','\n\n -------------') + message('M',' Nouveau cas ') + message('M',' -------------') + message('M','Getting parameters and checking ...') + self.getParameters() + test=uF.check(self.data) + self.cleanTmpFiles() + + if test: + message('M','Parameters checked and ready to go') + else: + message('E','Parameters checking failled',goOn=True) + return() + + message('M','\nGenerating crack ...') + res=genereCrack.main(self.data, self.crackMedName) + if res: + message('M','Crack generated successfully') + else: + message('E','Crack generation failed',goOn=True) + return() + + if self.ui.CBIs2D.isChecked(): + res=Zset.medToGeo(self.data['saneName'],self.saneGeoName, self.tmpdir, verbose=self.verbose, opt=[' **to_3d']) + else: + res=Zset.medToGeo(self.data['saneName'],self.saneGeoName, self.tmpdir, verbose=self.verbose) + + if res!=0: + message('E','medToGeo sane failed',goOn=True) + return() + + #opt=['**elset crack *function 1.;','**elset elset0 *function 1.;'] + res=Zset.medToGeo(self.crackMedName,self.crackGeoName, self.tmpdir, verbose=self.verbose) + if res!=0: + message('E','medToGeo crack failed',goOn=True) + return() + + names={'saneGeoName':self.saneGeoName, 'crackGeoName':self.crackGeoName, 'crackedGeoName':self.crackedGeoName} + message('M','\nInserting crack ...') + res=Zset.insertCrack(self.data, names, self.tmpdir, verbose=self.verbose) + if res!=0: + message('E','Crack insertion failed',goOn=True) + return() + else: + message('M','Crack inserted successfully') + + if self.ui.CBQuad.isChecked() and self.ui.CBBarsoum.isChecked(): + message('M','\nSaving cracked mesh in quadratic with Barsoum elements...') + opt=[' **lin_to_quad',' **crack_3d_quarter_nodes',' *liset FRONT0'] + res=Zset.geoToMed(self.data['crackedName'], names['crackedGeoName'], self.tmpdir, opt=opt, verbose=self.verbose) + + elif self.ui.CBQuad.isChecked() and not self.ui.CBBarsoum.isChecked(): + message('M','\nSaving cracked mesh in quadratic...') + opt=[' **lin_to_quad'] + res=Zset.geoToMed(self.data['crackedName'], names['crackedGeoName'], self.tmpdir, opt=opt, verbose=self.verbose) + + else: + message('M','\nSaving cracked mesh...') + res=Zset.geoToMed(self.data['crackedName'], names['crackedGeoName'], self.tmpdir, verbose=self.verbose) + + uF.extendElsets(self.data['crackedName']) + + if res==0: + message('M','Cracked mesh ready at : %s' %(self.data['crackedName'])) + message('M','Maximal aspect ratio is %f' %(uF.getMaxAspectRatio(self.tmpdir))) + #message('M','medit %s/_mesh_out_to_ghs3d.mesh' %(self.tmpdir)) + message('M','\n ----------------') + message('M',' Fin cas OK ') + message('M',' ----------------') + + + + def pressApplyClose(self): + self.pressApply() + self.pressCancel() + + + def pressLoadCracked(self): + fileDiag = QFileDialog(self) + fileDiag.setFileMode(QFileDialog.AnyFile) + fileDiag.setNameFilters(["Parametres *.med (*.*med)","All files (*)"]) + fileDiag.setViewMode(QFileDialog.List) + if fileDiag.exec_() : + fileNames = fileDiag.selectedFiles() + filedef = fileNames[0] + filedef = addExtension(str(filedef), 'med') + self.ui.valCrackedName.setText(QString(filedef)) + + + def pressLoadSane(self): + fileDiag = QFileDialog(self) + fileDiag.setFileMode(QFileDialog.AnyFile) + fileDiag.setNameFilters(["Parametres *.med (*.*med)","All files (*)"]) + fileDiag.setViewMode(QFileDialog.List) + if fileDiag.exec_() : + fileNames = fileDiag.selectedFiles() + filedef = fileNames[0] + self.ui.valSaneName.setText(QString(filedef)) + + + def pressCharger(self): + fileDiag = QFileDialog(self) + fileDiag.setFileMode(QFileDialog.AnyFile) + fileDiag.setNameFilters(["Parametres *.dic (*.dic)","All files (*)"]) + fileDiag.setViewMode(QFileDialog.List) + + if fileDiag.exec_() : + fileNames = fileDiag.selectedFiles() + filedef = fileNames[0] + if not path.isfile(str(filedef)): + message('E','Invalid dic file') + self.data=pickle.load(open(str(filedef),'r')) + message('M','\nLoading parameters from %s' %str(filedef)) + + for cont, obj in enumerate(self.lineEditObjects): + if self.lineEditTypes[cont] in [float, int]: + obj.setText(QString(self.data['TXT'+self.lineEditNames[cont]])) + else: + obj.setText(QString(self.data[self.lineEditNames[cont]])) + + self.ui.CBQuad.setChecked(True if 'quad' in self.data.keys() and self.data['quad'] else False) + self.ui.CBBarsoum.setChecked(True if 'barsoum' in self.data.keys() and self.data['barsoum'] else False) + self.ui.CBIs2D.setChecked(True if 'is2D' in self.data.keys() and self.data['is2D'] else False) + self.ui.CBRefine.setChecked(True if 'refine' in self.data.keys() and self.data['refine'] else False) + + + + + + #if self.data['quad']: self.ui.CBQuad.setChecked(True) + #if self.data['barsoum']: self.ui.CBBarsoum.setChecked(True) + #if self.data['is2D']: self.ui.CBIs2D.setChecked(True) + #if self.data['refine']: self.ui.CBRefine.setChecked(True) + self.setTableParameters() + + + def pressSauver(self): + fileDiag = QFileDialog(self) + fileDiag.setFileMode(QFileDialog.AnyFile) + fileDiag.setNameFilters(["Parametres *.dic (*.dic)","All files (*)"]) + fileDiag.setViewMode(QFileDialog.List) + if fileDiag.exec_() : + self.getParameters() + fileNames = fileDiag.selectedFiles() + filedef = fileNames[0] + pickle.dump(self.data, open(addExtension(str(filedef), 'dic'),'w')) + message('M','Saving parameters in %s' %addExtension(str(filedef), 'dic')) + + def pressLoadGroupVOL(self): + try: + self.GroupToLoad='VOL' + self.loadGroups() + except: + message('E','Groups loading impossible',goOn=True) + + def pressLoadGroupFACE(self): + try: + self.GroupToLoad='FACE' + self.loadGroups() + except: + message('E','Groups loading impossible',goOn=True) + + def pressLoadGroupEDGE(self): + try: + self.GroupToLoad='EDGE' + self.loadGroups() + except: + message('E','Groups loading impossible',goOn=True) + + def pressLoadGroupNODE(self): + try: + self.GroupToLoad='NODE' + self.loadGroups() + except: + message('E','Groups loading impossible',goOn=True) + + def pressLoadGroupALL(self): + try: + self.GroupToLoad='ALL' + self.loadGroups() + except: + message('E','Groups loading impossible',goOn=True) + + def pressAdvanced(self): + if self.ui.CBAdvanced.isChecked(): + self.ui.widget.setVisible(True) + else: + self.ui.widget.setVisible(False) + + def pressVisu(self): + meshFile1=path.join(self.tmpdir,'_mesh_out_to_ghs3d.mesh') + meshFile2=path.join(self.tmpdir,'_mesh_out_.mesh') + test1=path.isfile(meshFile1) + test2=path.isfile(meshFile2) + medit=path.join('$Z7PATH/PUBLIC/lib-Linux_64/Zmesh/bin/medit') + if not test1: + if not test2: + message('A','No mesh file to visualize') + else: + print medit+' %s' %meshFile2 + system(medit+' %s' %meshFile2) + else: + print medit+' %s' %meshFile1 + system(medit+' %s' %meshFile1) + return() + + def pressCancel(self): + message('M','exiting Zcracks') + try: + shutil.rmtree(self.tmpdir) + except: + message('E','Impossible to delete %s' %self.tmpdir,goOn=True) + pass + exit() + +# --------------------------------- +# FONCTIONS ANNEXES A LA CLASSE +# --------------------------------- + + + def getParameters(self): + for cont, name in enumerate(self.lineEditNames): + value=str(self.lineEditObjects[cont].text()) + #print name + if self.lineEditTypes[cont] == float: + self.data['TXT'+name]=value + self.data[name]= stringToFloat(value) + elif self.lineEditTypes[cont] == int: + self.data['TXT'+name]=value + self.data[name]= stringToFloat(value, typ=int) + else: + self.data[name]=value + self.data['quad']=self.ui.CBQuad.isChecked() + self.data['barsoum']=self.ui.CBBarsoum.isChecked() + self.data['TXTcrack']=self.getTableParameters() + self.data['crack']=self.getTableParameters(str2float=True) + self.data['is2D']=self.ui.CBIs2D.isChecked() + self.data['refine']=self.ui.CBRefine.isChecked() + + + def getTableParameters(self, str2float=False): + nbOnglet=self.ui.tabWidget.count() + out=dict() + iOngletActif=self.ui.tabWidget.currentIndex() + ongletActif=False + for iongl in range(nbOnglet): + crack=dict() + onglet=self.ui.tabWidget.widget(iongl) + tab=onglet.findChildren(QTableWidget)[0] + for irow in range(tab.rowCount()): + label=tab.verticalHeaderItem(irow).text() + if tab.item(irow,0) is None: + crack[str(label)]='' + elif 'med file' in str(label): + crack[str(label)]=str(tab.item(irow,0).text()) + else: + value=tab.item(irow,0).text() + if str2float: + crack[str(label)]=stringToFloat(value) + else: + crack[str(label)]=str(value) + out[str(self.ui.tabWidget.tabText(iongl))]=crack + if iongl==iOngletActif: + ongletActif=str(self.ui.tabWidget.tabText(iongl)) + + out['actif']=ongletActif + return(out) + + + def setTableParameters(self): + nbOnglet=self.ui.tabWidget.count() + #iOngletActif=self.ui.tabWidget.currentIndex() + for iongl in range(nbOnglet): + onglet=self.ui.tabWidget.widget(iongl) + tab=onglet.findChildren(QTableWidget)[0] + for irow in range(tab.rowCount()): + label=tab.verticalHeaderItem(irow).text() + if tab.item(irow,0) == None: + item = QTableWidgetItem() + tab.setItem(irow, 0, item) + tab.item(irow,0).setText(QString(self.data['TXTcrack'][str(self.ui.tabWidget.tabText(iongl))][str(label)])) + if str(self.ui.tabWidget.tabText(iongl)) == self.data['TXTcrack']['actif']: + self.ui.tabWidget.setCurrentWidget(onglet) + + + def loadGroups(self): + saneFile=str(self.ui.valSaneName.text()) + message('I','Loading Sane mesh...') + if not path.isfile(saneFile): + message('E','Sane mesh med file is not valid') + else: + import SMESH, salome + #salome.salome_init() + theStudy = salome.myStudy + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New(theStudy) + + ([objetSain], status) = smesh.CreateMeshesFromMED(saneFile) + + groupsVOL, groupsFAC, groupsEDG, groupsNOD = '', '', '', '' + nGr=0 + + for group in objetSain.GetGroups(): + if (self.GroupToLoad in ['VOL','ALL']) and (group.GetType()==SMESH.VOLUME): + groupsVOL+=group.GetName().replace(' ','')+" " + nGr+=1 + + if (self.GroupToLoad in ['FACE','ALL']) and (group.GetType()==SMESH.FACE): + groupsFAC+=group.GetName().replace(' ','')+" " + nGr+=1 + + if (self.GroupToLoad in ['EDGE','ALL']) and (group.GetType()==SMESH.EDGE): + groupsEDG+=group.GetName().replace(' ','')+" " + nGr+=1 + + if (self.GroupToLoad in ['NODE','ALL']) and (group.GetType()==SMESH.NODE): + groupsNOD+=group.GetName().replace(' ','')+" " + nGr+=1 + + if groupsVOL!='': self.ui.valGrVol.setText(groupsVOL) + if groupsFAC!='': self.ui.valGrFace.setText(groupsFAC) + if groupsEDG!='': self.ui.valGrEdge.setText(groupsEDG) + if groupsNOD!='': self.ui.valGrNode.setText(groupsNOD) + + message('I','%d group(s) found' %nGr) + + def cleanTmpFiles(self): + for f in [self.saneGeoName, self.crackGeoName, self.crackMedName, self.crackedGeoName]: + try: + remove(f) + except: + pass + + +# --------------------------------- +# LANCEMENT DE LA BOITE DE DIAG +# --------------------------------- + + + + diff --git a/src/Tools/ZCracksPlug/output.py b/src/Tools/ZCracksPlug/output.py new file mode 100644 index 000000000..8a316b0dd --- /dev/null +++ b/src/Tools/ZCracksPlug/output.py @@ -0,0 +1,53 @@ + +from subprocess import Popen +from os import remove, getpid, path + +def init(tmpdir): + global log + log=output(tmpdir) + log.initialise() + +def message(typ, message, goOn=False): + global log + log.message(typ,message,goOn) + +class output(): + def __init__(self, tmpDir, tmpFile='Messages.txt'): + self.tmpFile=path.join(tmpDir,tmpFile) + + def initialise(self): + try: + remove(self.tmpFile) + except: + pass + f = open(self.tmpFile,'w') + f.write('\n ------------------------------\n') + f.write(' | BIENVENU DANS L\'INTERFACE |\n') + f.write(' | ZCRACKS DE SALOME |\n') + f.write(' | VERSION ALPHA |\n') + f.write(' ------------------------------\n\n') + f.close() + + pid=getpid() + fenName='Zcracks message log' + proc = Popen(['xterm -T "%s" -e "tail -s 0.05 -f %s --pid=%d"' %(fenName,self.tmpFile,pid)], shell=True) + return() + + def message(self, typ, message='', goOn=False): + fileName=self.tmpFile + f = open(fileName,'a') + if typ=='E': + f.write('ERROR: '+message+'\n') + #print 'ERROR: '+message + if not goOn: + exit() + + elif typ in ['A','W']: + #print ARNING: '+message + f.write('WARNING: '+message+'\n') + + elif typ in ['M','I']: + #print 'INFO: '+message + f.write(message+'\n') + + f.close() diff --git a/src/Tools/ZCracksPlug/readme.sh b/src/Tools/ZCracksPlug/readme.sh new file mode 100644 index 000000000..3e35a6cd4 --- /dev/null +++ b/src/Tools/ZCracksPlug/readme.sh @@ -0,0 +1,6 @@ +pyuic4 zcracks.ui -o zcracks_ui.py +pyrcc4 images.qrc -o images_rc.py + +#pyuic5 zcracks.ui -o zcracks_ui.py +#pyrcc5 images.qrc -o images_rc.py + diff --git a/src/Tools/ZCracksPlug/rectangle.py b/src/Tools/ZCracksPlug/rectangle.py new file mode 100644 index 000000000..2f6933e25 --- /dev/null +++ b/src/Tools/ZCracksPlug/rectangle.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- + +### +### This file is generated automatically by SALOME v7.7.1 with dump python functionality +### + +import sys, numpy +import salome + +salome.salome_init() +theStudy = salome.myStudy + +import salome_notebook +notebook = salome_notebook.NoteBook(theStudy) + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS +import utilityFunctions as uF +from output import message + +#import GEOM_Gen.ild +#rectangle.generate(data_longueur,data_largeur,data_centre,data_normale,data_direction,data_angle,data_rayon,rayon_entaille,extension,outFile) + +def generate(data_longueur,data_largeur,data_centre, + data_normale,data_direction,data_angle, + data_rayon,rayon_entaille,outFile): + +#data_longueur = 2. +#data_largeur = 1. +#data_centre = [0., 0., 0.] +#data_normale = [1., 2., 0.] +#data_direction = [0., 1., 5.] +#rayon_entaille=0.1 +#data_angle=180. +#data_rayon=0.1 +#extension=0.1 + #epsilon=numpy.max([data_longueur,data_largeur])*1.e-8 + Brayon = data_rayon>1e-12 + Bentaille = rayon_entaille>1e-12 + + A=numpy.pi/(15.) + maxSize=numpy.min([data_longueur,data_largeur])/4. + if Bentaille: + dim=3 + if Brayon: + R=numpy.min([data_rayon,rayon_entaille]) + chordal, minSize = uF.calcElemSize(A, R) + else: + chordal, minSize = uF.calcElemSize(A, rayon_entaille) + else: + dim=2 + if Brayon: + chordal, minSize = uF.calcElemSize(A, data_rayon) + else: + minSize=numpy.min([data_longueur,data_largeur])/10. + maxSize=minSize + chordal=1. + + Vnormale, Vdirection, Vortho = uF.calcCoordVectors(data_normale, data_direction) + Vcentre = numpy.array(data_centre) + + geompy = geomBuilder.New(theStudy) + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + CENTRE = geompy.MakeVertex(Vcentre[0], Vcentre[1], Vcentre[2]) + NORMALE = geompy.MakeVectorDXDYDZ(Vnormale[0], Vnormale[1], Vnormale[2]) + DIRECTION = geompy.MakeVectorDXDYDZ(Vdirection[0], Vdirection[1], Vdirection[2]) + DIRECTION_op = geompy.MakeVectorDXDYDZ(-Vdirection[0], -Vdirection[1], -Vdirection[2]) + V3 = geompy.MakeVectorDXDYDZ(Vortho[0], Vortho[1], Vortho[2]) + V3_op = geompy.MakeVectorDXDYDZ(-Vortho[0], -Vortho[1], -Vortho[2]) + + VP1=Vcentre+Vdirection*data_longueur+Vortho*data_largeur + VP2=Vcentre-Vdirection*data_longueur+Vortho*data_largeur + VP3=Vcentre-Vdirection*data_longueur-Vortho*data_largeur + VP4=Vcentre+Vdirection*data_longueur-Vortho*data_largeur + + Sommet_1 = geompy.MakeVertex(VP1[0], VP1[1], VP1[2]) + Sommet_2 = geompy.MakeVertex(VP2[0], VP2[1], VP2[2]) + Sommet_3 = geompy.MakeVertex(VP3[0], VP3[1], VP3[2]) + Sommet_4 = geompy.MakeVertex(VP4[0], VP4[1], VP4[2]) + + Ligne_1 = geompy.MakeLineTwoPnt(Sommet_1, Sommet_2) + Ligne_2 = geompy.MakeLineTwoPnt(Sommet_2, Sommet_3) + Ligne_3 = geompy.MakeLineTwoPnt(Sommet_3, Sommet_4) + Ligne_4 = geompy.MakeLineTwoPnt(Sommet_4, Sommet_1) + + Contour_1 = geompy.MakeWire([Ligne_1, Ligne_2, Ligne_3, Ligne_4], 1e-07) + + if Brayon or Bentaille: + vertexOfRect=geompy.SubShapeAllIDs(Contour_1, geompy.ShapeType["VERTEX"]) + Contour_1 = geompy.MakeFillet1D(Contour_1, data_rayon + rayon_entaille, vertexOfRect) + + if not Bentaille: + RECTANGLE = geompy.MakeFaceWires([Contour_1], 1) + else: + VP1=Vcentre+Vdirection*(data_longueur-rayon_entaille)+Vnormale*rayon_entaille + VP2=Vcentre+Vdirection*(data_longueur) + VP3=Vcentre+Vdirection*(data_longueur-rayon_entaille)-Vnormale*rayon_entaille + PE1=geompy.MakeVertex(VP1[0], VP1[1], VP1[2]) + PE2=geompy.MakeVertex(VP2[0], VP2[1], VP2[2]) + PE3=geompy.MakeVertex(VP3[0], VP3[1], VP3[2]) + ARC = geompy.MakeArc(PE1, PE2, PE3) + TUYAU = geompy.MakePipe(ARC, Contour_1) + subShapesList=geompy.GetFreeBoundary(TUYAU)[1] + entailleFace1 = geompy.MakeFaceWires([subShapesList[0]], 1) + entailleFace2 = geompy.MakeFaceWires([subShapesList[1]], 1) + RECTANGLE = geompy.MakeShell([TUYAU, entailleFace1, entailleFace2]) + + #edgesIDs = geompy.SubShapeAllIDs(RECTANGLE, geompy.ShapeType["EDGE"]) + #edges = geompy.CreateGroup(RECTANGLE, geompy.ShapeType["EDGE"]) + #geompy.UnionIDs(edges, edgesIDs) + #geompy.addToStudy( RECTANGLE, 'RECTANGLE' ) + #geompy.addToStudyInFather( RECTANGLE , edges, 'edges' ) + + hauteur=data_longueur*1.1 + + eps=1.E-05 + bool_boite=True + extrusion=numpy.max([1.,rayon_entaille])*1.1 + + if ( (data_angle>(eps)) and (data_angle<(180.-eps)) ): + rayon2=hauteur*numpy.tan(data_angle*numpy.pi/180./2.) + + B1=geompy.MakeTranslationVectorDistance(CENTRE,DIRECTION,hauteur) + B2=geompy.MakeTranslationVectorDistance(B1,V3,rayon2) + geompy.TranslateVectorDistance(B1,V3_op,rayon2, False) + LB01 = geompy.MakeLineTwoPnt(CENTRE, B1) + LB02 = geompy.MakeLineTwoPnt(CENTRE, B2) + LB12 = geompy.MakeLineTwoPnt(B1, B2) + plan_BOITE = geompy.MakeFaceWires([LB01, LB02, LB12], True) + extrusion=numpy.max([1.,rayon_entaille])*1.1 + BOITE = geompy.MakePrismVecH2Ways(plan_BOITE, NORMALE, extrusion) + + FACE_FISSURE = geompy.MakeCommonList([RECTANGLE, BOITE]) + + elif ( (data_angle>=(180.-eps)) and (data_angle<=(180.+eps)) ): + VP1=Vcentre+Vortho*data_largeur*1.1 + VP2=Vcentre-Vortho*data_largeur*1.1 + VP3=Vcentre-Vortho*data_largeur*1.1+Vdirection*data_longueur*1.1 + VP4=Vcentre+Vortho*data_largeur*1.1+Vdirection*data_longueur*1.1 + + Sommet_5 = geompy.MakeVertex(VP1[0], VP1[1], VP1[2]) + Sommet_6 = geompy.MakeVertex(VP2[0], VP2[1], VP2[2]) + Sommet_7 = geompy.MakeVertex(VP3[0], VP3[1], VP3[2]) + Sommet_8 = geompy.MakeVertex(VP4[0], VP4[1], VP4[2]) + + Ligne_5 = geompy.MakeLineTwoPnt(Sommet_5, Sommet_6) + Ligne_6 = geompy.MakeLineTwoPnt(Sommet_6, Sommet_7) + Ligne_7 = geompy.MakeLineTwoPnt(Sommet_7, Sommet_8) + Ligne_8 = geompy.MakeLineTwoPnt(Sommet_8, Sommet_5) + + Contour_2 = geompy.MakeWire([Ligne_5, Ligne_6, Ligne_7, Ligne_8], 1e-07) + Face_2 = geompy.MakeFaceWires([Contour_2], 1) + BOITE = geompy.MakePrismVecH2Ways(Face_2, NORMALE, extrusion) + FACE_FISSURE = geompy.MakeCommonList([RECTANGLE, BOITE]) + + #geompy.addToStudy( RECTANGLE, 'RECTANGLE' ) + #geompy.addToStudy( BOITE, 'BOITE' ) + #geompy.addToStudy( FACE_FISSURE, 'FACE_FISSURE' ) + + elif ( (data_angle>(180.+eps)) and (data_angle<(360.-eps)) ): + rayon2=hauteur*numpy.tan((360.-data_angle)*numpy.pi/180./2.) + B1=geompy.MakeTranslationVectorDistance(CENTRE,DIRECTION_op,hauteur) + B2=geompy.MakeTranslationVectorDistance(B1,V3,rayon2) + geompy.TranslateVectorDistance(B1,V3_op,rayon2, False) + LB01 = geompy.MakeLineTwoPnt(CENTRE, B1) + LB02 = geompy.MakeLineTwoPnt(CENTRE, B2) + LB12 = geompy.MakeLineTwoPnt(B1, B2) + plan_BOITE = geompy.MakeFaceWires([LB01, LB02, LB12], True) + extrusion=numpy.max([1.,rayon_entaille])*1.1 + BOITE = geompy.MakePrismVecH2Ways(plan_BOITE, NORMALE, extrusion) + FACE_FISSURE = geompy.MakeCutList(RECTANGLE, [BOITE]) + + elif ( (data_angle<=(eps)) or (data_angle>=(360.-eps)) ): + bool_boite=False + FACE_FISSURE = RECTANGLE + + else: + message('E','Angle non prevu') + + #if bool_boite: + #newEdgesIDs = geompy.SubShapeAllIDs(FACE_FISSURE, geompy.ShapeType["EDGE"]) + #newEdges = geompy.CreateGroup(FACE_FISSURE, geompy.ShapeType["EDGE"]) + #geompy.UnionIDs(newEdges, newEdgesIDs) + + #[oldEdges] = geompy.RestoreGivenSubShapes(FACE_FISSURE, [RECTANGLE, edges], GEOM.FSM_GetInPlace, True, False) + + #toExtrude = geompy.CutListOfGroups([newEdges], [oldEdges]) + + #if extension>1.e-12: + #extrusion = geompy.MakePrismVecH(toExtrude, DIRECTION_op, extension) + #try: + #FACE_FISSURE = geompy.MakeFuseList([FACE_FISSURE, extrusion], False, True) + #except: + #FACE_FISSURE = geompy.MakeFuseList([FACE_FISSURE, extrusion], False, False) + + #geompy.addToStudy( FACE_FISSURE, 'FACE_FISSURE' ) + + # + # SMESH component + # + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New(theStudy) + + Maillage=uF.meshCrack(FACE_FISSURE, minSize, maxSize, chordal, dim) + + try: + Maillage.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + smesh.SetName(Maillage.GetMesh(), 'MAILLAGE_FISSURE') + except: + print 'ExportToMEDX() failed. Invalid file name?' + + + if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) diff --git a/src/Tools/ZCracksPlug/sphere.py b/src/Tools/ZCracksPlug/sphere.py new file mode 100644 index 000000000..79542b2c5 --- /dev/null +++ b/src/Tools/ZCracksPlug/sphere.py @@ -0,0 +1,70 @@ +# -*- coding: utf-8 -*- + +### +### This file is generated automatically by SALOME v7.7.1 with dump python functionality +### + +import sys, numpy +import salome + +salome.salome_init() +theStudy = salome.myStudy + +import salome_notebook +notebook = salome_notebook.NoteBook(theStudy) + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS +import utilityFunctions as uF +from output import message + +#import GEOM_Gen.ild + +def generate(data_rayon,data_centre,outFile): + #data_rayon = 0.1 + #data_centre = [1., 1., 01.] + + geompy = geomBuilder.New(theStudy) + + O = geompy.MakeVertex(0, 0, 0) + OX = geompy.MakeVectorDXDYDZ(1, 0, 0) + OY = geompy.MakeVectorDXDYDZ(0, 1, 0) + OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) + + SPHERE = geompy.MakeSphereR(data_rayon) + geompy.TranslateDXDYDZ(SPHERE, data_centre[0], data_centre[1], data_centre[2]) + [FACE_FISSURE] = geompy.ExtractShapes(SPHERE, geompy.ShapeType["FACE"], True) + + # + # SMESH component + # + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + + smesh = smeshBuilder.New(theStudy) + + A=numpy.pi/(20.) + chordal, minSize = uF.calcElemSize(A, data_rayon) + maxSize=data_rayon/3. + + Maillage=uF.meshCrack(FACE_FISSURE, minSize, maxSize, chordal, dim=3) + + try: + Maillage.ExportMED( outFile, 0, SMESH.MED_V2_2, 1, None ,1) + smesh.SetName(Maillage.GetMesh(), 'MAILLAGE_FISSURE') + except: + print 'ExportToMEDX() failed. Invalid file name?' + + + ## Set names of Mesh objects + + + if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(1) diff --git a/src/Tools/ZCracksPlug/utilityFunctions.py b/src/Tools/ZCracksPlug/utilityFunctions.py new file mode 100644 index 000000000..36db72580 --- /dev/null +++ b/src/Tools/ZCracksPlug/utilityFunctions.py @@ -0,0 +1,485 @@ +#import sys +#sys.path.append('/home/I60976/00_PROJETS/2015_INTEGRATION_ZCRACKS/zcracks_salome/zcracks') + +import numpy, subprocess, sys +from os import remove, getpid, path, environ +from output import message + +def calcCoordVectors(normalIN, directionIN): + V3TEMP=numpy.cross(normalIN,directionIN) + directionTEMP=numpy.cross(V3TEMP,normalIN) + + normalOUT=numpy.array(normalIN)/numpy.linalg.norm(normalIN) + directionOUT=numpy.array(directionTEMP)/numpy.linalg.norm(directionTEMP) + V3OUT=numpy.array(V3TEMP)/numpy.linalg.norm(V3TEMP) + return(normalOUT, directionOUT, V3OUT) + + +def testStrictRange(x, inf=0.0, sup=False): + test=False + c1=(type(x)==list) + if c1: + c2=(len(x)==1) + if c2: + c3=(type(x[0])==type(inf)) + if c3: + c4=(x[0]>inf) + c5=True + if sup!=False: + c5=(x[0]=inf) + c5=True + if sup!=False: + c5=(x[0]<=sup) + if c4 and c5: + test=True + return(test) + +def check(data): + OK=True + + test=False + c1=(data['crackedName']!='') + if c1: + test=True + if not test: + message('E','Invalid Cracked name',goOn=True) + OK=False + + test=False + c1=path.isfile(data['saneName']) + if c1: + c2=(data['saneName']!=data['crackedName']) + if c2: + test=True + else: + message('E','sane mesh and cracked mesh are identical',goOn=True) + OK=False + if not test: + message('E','Bad sane mesh file',goOn=True) + OK=False + + test=testStrictRange(data['minSize']) + if not test: + message('E','invalid min size',goOn=True) + OK=False + + test=testStrictRange(data['maxSize']) + if not test: + message('E','invalid max size',goOn=True) + OK=False + + if OK: + test=(data['maxSize'][0]>=data['minSize'][0]) + if not test: + message('E','min size greater than max size',goOn=True) + OK=False + + test=testStrictRange(data['extractLength']) + if not test: + message('E','invalid extract length',goOn=True) + OK=False + + test=testRange(data['gradation'], inf=1.0) + if not test: + message('E','invalid Gradation',goOn=True) + OK=False + + test=testRange(data['layers'], inf=1) + if not test: + message('E','invalid layers',goOn=True) + OK=False + + test=testRange(data['iterations'], inf=1) + if not test: + message('E','invalid iterations',goOn=True) + OK=False + return(OK) + + +def calcElemSize(A, R): + x=R*(1.-numpy.cos(A/2.)) + h=R*numpy.sin(A/2.) + return(x, h) + +def meshCrack(geomObject, minSize, maxSize, chordal, dim): + import salome + + salome.salome_init() + theStudy = salome.myStudy + + import SMESH, SALOMEDS + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New(theStudy) + Maillage = smesh.Mesh(geomObject) + + if dim==3: + MG_CADSurf = Maillage.Triangle(algo=smeshBuilder.MG_CADSurf) + MG_CADSurf_Parameters = MG_CADSurf.Parameters() + MG_CADSurf_Parameters.SetPhysicalMesh( 0 ) + MG_CADSurf_Parameters.SetGeometricMesh( 1 ) + MG_CADSurf_Parameters.SetMinSize( minSize ) + MG_CADSurf_Parameters.SetMaxSize( maxSize ) + MG_CADSurf_Parameters.SetChordalError( chordal ) + + elif dim==2: + Regular_1D = Maillage.Segment() + Adaptive = Regular_1D.Adaptive(minSize,maxSize,chordal) + NETGEN_2D_ONLY = Maillage.Triangle(algo=smeshBuilder.NETGEN_2D) + else: + message('E',"error in mesh dimension",goOn=True) + + isDone = Maillage.Compute() + + #crack1 = Maillage.CreateEmptyGroup( SMESH.NODE, 'crack' ) + #nbAdd = crack1.AddFrom( Maillage.GetMesh() ) + #crack2 = Maillage.CreateEmptyGroup( SMESH.NODE, 'surface' ) + #nbAdd = crack2.AddFrom( Maillage.GetMesh() ) + + return(Maillage) + +def extendElsets(meshFile, outFile=None): + + if outFile==None: outFile=meshFile + + if not path.isfile(meshFile): + message('E','Mesh med file is not valid') + return('error') + + import SMESH, salome + #salome.salome_init() + theStudy = salome.myStudy + from salome.smesh import smeshBuilder + smesh = smeshBuilder.New(theStudy) + + ([mesh], status) = smesh.CreateMeshesFromMED(meshFile) + + mesh=cleanGroups(mesh) + + # Node color status + nodeList=mesh.GetNodesId() + volElemList=mesh.GetElementsByType(SMESH.VOLUME) + surfElemList=mesh.GetElementsByType(SMESH.FACE) + edgeElemList=mesh.GetElementsByType(SMESH.EDGE) + colorList=[-1]*len(nodeList) + + case2D=True + for group in mesh.GetGroups(): + if group.GetType()==SMESH.VOLUME and group.GetName()[:5]=='sides' : case2D=False + + sides=[] + for group in mesh.GetGroups(): + if case2D: + if group.GetType()==SMESH.FACE and group.GetName()[:5]=='sides': + sides.append(group) + else: + if group.GetType()==SMESH.VOLUME and group.GetName()[:5]=='sides': + sides.append(group) + + sortedSides=[None]*len(sides) + for group in sides: + N=group.GetName().replace('sides','').replace('_bset','').replace(' ','') + N=int(N) + sortedSides[N]=group + + elems=group.GetIDs() + for elemId in elems: + for elemNodeId in mesh.GetElemNodes(elemId) : + colorList[elemNodeId-1]=N + #print colorList + + crackOnly=True + for iN in range(len(sides)/2): + side0=sortedSides[2*iN] + side1=sortedSides[2*iN+1] + elemsOfside0=side0.GetIDs() + elemsOfside1=side1.GetIDs() + NodesOfside0=[] + NodesOfside1=[] + for elem in elemsOfside0: NodesOfside0+=mesh.GetElemNodes(elem) + for elem in elemsOfside1: NodesOfside1+=mesh.GetElemNodes(elem) + front=set(NodesOfside0).intersection(set(NodesOfside1)) + if len(front)==0: crackOnly=False + + if crackOnly: + mesh.ExportMED(outFile, 0, SMESH.MED_V2_2, 1, None ,1) + return('crack') + + # Propagates color using elem connectivity + # Always propagates max color + + #elemToTreat=volElemList + + #while len(elemToTreat)>0 : + #print len(elemToTreat) + #for elemId in elemToTreat: + #minColor=sys.maxint + #maxColor=-sys.maxint + #for elemNodeId in mesh.GetElemNodes(elemId) : + #nodeColor=colorList[elemNodeId-1] + #if nodeColormaxColor : maxColor=nodeColor + #if minColor!=maxColor : + #elemToTreat.remove(elemId) + #for elemNodeId in mesh.GetElemNodes(elemId) : + #colorList[elemNodeId-1]=maxColor + + ifChanged=True + if case2D: + elemList=[surfElemList,edgeElemList] + grElemList=[[],[]] + else: + elemList=[volElemList,surfElemList,edgeElemList] + grElemList=[[],[],[]] + + while ifChanged : + ifChanged=False + for elemId in elemList[0]: + minColor=sys.maxint + maxColor=-sys.maxint + for elemNodeId in mesh.GetElemNodes(elemId) : + nodeColor=colorList[elemNodeId-1] + if nodeColormaxColor : maxColor=nodeColor + if minColor!=maxColor : + ifChanged = True + for elemNodeId in mesh.GetElemNodes(elemId) : + colorList[elemNodeId-1]=maxColor + + for l in grElemList: + for x in range(len(sides)): + l.append([]) + + for N, el in enumerate(elemList): + for elemId in el: + elemNodesId=mesh.GetElemNodes(elemId) + elemColor=colorList[elemNodesId[0]-1] + if elemColor>=0: + grElemList[N][elemColor].append(elemId) + + #for elemId in surfElemList: + #elemNodesId=mesh.GetElemNodes(elemId) + #elemColor=colorList[elemNodesId[0]-1] + #if elemColor>=0: + #selem[elemColor].append(elemId) + + for n in range(len(sides)): + if case2D: + mesh.MakeGroupByIds('Extended_side%d' %n ,SMESH.FACE,grElemList[0][n]) + mesh.MakeGroupByIds('Extended_side%d' %n ,SMESH.EDGE,grElemList[1][n]) + else: + mesh.MakeGroupByIds('Extended_side%d' %n ,SMESH.VOLUME,grElemList[0][n]) + mesh.MakeGroupByIds('Extended_side%d' %n ,SMESH.FACE,grElemList[1][n]) + mesh.MakeGroupByIds('Extended_side%d' %n ,SMESH.EDGE,grElemList[2][n]) + + if outFile==None: outFile=meshFile + mesh.ExportMED(outFile, 0, SMESH.MED_V2_2, 1, None ,1) + return(True) + + +def cleanGroups(mesh): + import SMESH + for group in mesh.GetGroups(): + if '_bset' in group.GetName(): + group.SetName(group.GetName().replace('_bset','')) + + if group.GetType()==SMESH.NODE: + if group.GetName() in ['SURFACE','lip','SFRONT_NODES','FRONT']: mesh.RemoveGroup(group) + + #elif group.GetType()==SMESH.EDGE: + + elif group.GetType()==SMESH.FACE: + if group.GetName() in ['SURFACE','Nlip']: + mesh.RemoveGroup(group) + + elif group.GetType()==SMESH.VOLUME: + if (group.GetName() in ['ELSET0','AUTO']) or (group.GetName()[:4] in ['SIDE']) : + mesh.RemoveGroup(group) + + return(mesh) + + +def getMaxAspectRatio(tmpdir): + logFile=path.join(tmpdir,'MESHING_OUTPUT') + print logFile + if not path.isfile(logFile): return(-1) + + import re + f = open(logFile, "r") + for line in f: + if re.search("WORST ELEMENT QUALITY", line): maxAR=line + + f.close() + for r in [' ','WORSTELEMENTQUALITY','\n']: maxAR=maxAR.replace(r,'') + return(float(maxAR)) + + +#def extendElsets(meshFile): + #if not path.isfile(meshFile): + #message('E','Mesh med file is not valid') + #return(-1) + + #import SMESH, salome + ##salome.salome_init() + #theStudy = salome.myStudy + #from salome.smesh import smeshBuilder + #smesh = smeshBuilder.New(theStudy) + + #([mesh], status) = smesh.CreateMeshesFromMED(meshFile) + + ## Node color status + #nodeList=mesh.GetNodesId() + #colorList=[0]*len(nodeList) + + ## Init using SIDE0 SIDE1 + #for group in mesh.GetGroups(): + #if group.GetType()==SMESH.FACE : + #color=0 + #if group.GetName()[0:4]=='SIDE0' : + #color=1 + #elif group.GetName()[0:4]=='SIDE1' : + #color=2 + #else : continue + ## Get faces + #faces=group.GetIDs() + ## Set faces nodes to given color + #for face_id in faces : + #for face_node_id in mesh.GetElemNodes(face_id) : + #colorList[face_node_id-1]=color + + ## Propagates color using elem connectivity + ## Always propagates max color + #volElemList=mesh.GetElementsByType(SMESH.VOLUME) + #ifChanged=True + #while ifChanged : + #ifChanged=False + #minColor=100 + #maxColor=0 + #for elemId in volElemList: + #for elemNodeId in mesh.GetElemNodes(elemId) : + #nodeColor=colorList[elemNodeId-1] + #if nodeColormaxColor : maxColor=nodeColor + #if minColor!=maxColor : + #ifChanged = True + #for elemNodeId in mesh.GetElemNodes(elemId) : + #colorList[elemNodeId-1]=maxColor + + #velem0 = [] + #velem1 = [] + #for elemId in volElemList: + #elemNodesId=mesh.GetElemNodes(elemId) + #elemColor=colorList[elemNodesId[0]-1] + #if(elemColor==1) : velem0.append(elemId) + #if(elemColor==2) : velem1.append(elemId) + + #mesh.MakeGroupByIds('SIDE_co',SMESH.VOLUME,velem0) + #mesh.MakeGroupByIds('SIDE_ext',SMESH.VOLUME,velem1) + + #surfElemList=mesh.GetElementsByType(SMESH.FACE) + #selem0 = [] + #selem1 = [] + #nbelem0=0 + #nbelem1=0 + + #for elemId in surfElemList: + #elemNodesId=mesh.GetElemNodes(elemId) + #elemColor=colorList[elemNodesId[0]-1] + #if(elemColor==1) : selem0.append(elemId) + #if(elemColor==2) : selem1.append(elemId) + + #mesh.MakeGroupByIds('SIDE_co',SMESH.FACE,selem0) + #mesh.MakeGroupByIds('SIDE_ext',SMESH.FACE,selem1) + + #maxAR=0. + #for elem in volElemList: + #maxAR=max(mesh.GetAspectRatio(elem),maxAR) + #for elem in surfElemList: + #maxAR=max(mesh.GetAspectRatio(elem),maxAR) + + #mesh.ExportMED(meshFile, 0, SMESH.MED_V2_2, 1, None ,1) + #return(maxAR) + + +def removeFromSessionPath(envVar, patern): + if type(patern) is not list: patern=[patern] + if type(envVar) is not list: envVar=[envVar] + + for env in envVar: + path=environ[env] + listPath=path.split(':') + for p in listPath: + for pat in patern: + if pat in p: + path=path.replace(p,'') + path.replace('::',':') + environ[env]=path + + +#def isPlane(geomObject, eps=1.e-9): + #import salome + #salome.salome_init() + #theStudy = salome.myStudy + + #import salome_notebook + #notebook = salome_notebook.NoteBook(theStudy) + + #import GEOM + #from salome.geom import geomBuilder + #geompy = geomBuilder.New(theStudy) + + #Vs=geompy.SubShapeAll(geomObject, geompy.ShapeType["VERTEX"]) + #if len(Vs)<=3: + #return(True) + #elif len(Vs)>3: + #P0=numpy.array(geompy.GetPosition(Vs[0])[:3]) + #P1=numpy.array(geompy.GetPosition(Vs[1])[:3]) + #P2=numpy.array(geompy.GetPosition(Vs[2])[:3]) + #V01=P1-P0 + #V02=P2-P0 + #V12=P2-P1 + #norm01=numpy.linalg.norm(V01) + #norm02=numpy.linalg.norm(V02) + #norm12=numpy.linalg.norm(V12) + #if (norm01 + + + RunConfiguration0-BaseEnvironmentBase + 2 + + + RunConfiguration0-CommandLineArguments + + + + RunConfiguration0-ProFile + zcracks.pro + + + RunConfiguration0-RunConfiguration.name + zcracks + + + RunConfiguration0-UseDyldImageSuffix + false + + + RunConfiguration0-UseTerminal + false + + + RunConfiguration0-UserEnvironmentChanges + + + + RunConfiguration0-UserSetName + false + + + RunConfiguration0-UserSetWorkingDirectory + false + + + RunConfiguration0-UserWorkingDirectory + + + + RunConfiguration0-type + Qt4ProjectManager.Qt4RunConfiguration + + + activeRunConfiguration + 0 + + + activebuildconfiguration + Debug + + + buildConfiguration-Debug + + Debug + 0 + 0 + 2 + + + + buildConfiguration-Release + + Release + 0 + 0 + + + + buildconfiguration-Debug-buildstep0 + + Debug + + + + buildconfiguration-Debug-buildstep1 + + Debug + + + + buildconfiguration-Debug-cleanstep0 + + Debug + true + + clean + + + + + buildconfiguration-Release-buildstep0 + + Release + + + + buildconfiguration-Release-buildstep1 + + Release + + + + buildconfiguration-Release-cleanstep0 + + Release + + + + buildconfigurations + + Debug + Release + + + + buildstep0 + + + + + + + buildstep1 + + + + + + buildsteps + + trolltech.qt4projectmanager.qmake + trolltech.qt4projectmanager.make + + + + cleanstep0 + + + true + + + + cleansteps + + trolltech.qt4projectmanager.make + + + + defaultFileEncoding + System + + + project + + + diff --git a/src/Tools/ZCracksPlug/zcracks.ui b/src/Tools/ZCracksPlug/zcracks.ui new file mode 100644 index 000000000..d464158f1 --- /dev/null +++ b/src/Tools/ZCracksPlug/zcracks.ui @@ -0,0 +1,1726 @@ + + + Zui + + + + 0 + 0 + 709 + 540 + + + + + 709 + 540 + + + + + 709 + 540 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + + + 255 + 255 + 255 + + + + + + + + Zcracks interface - version dev + + + + + + + + 3 + 497 + 301 + 37 + + + + + + + + 85 + 35 + + + + + 85 + 35 + + + + Clear all paramters + + + Reset + + + + + + + + 85 + 35 + + + + + 85 + 35 + + + + Save parameters in a file + + + Save + + + + + + + + 85 + 35 + + + + + 85 + 35 + + + + Load all parameters from a file + + + Load + + + + + + + + + 344 + 490 + 360 + 51 + + + + + + + + 100 + 35 + + + + + 100 + 35 + + + + Exit Zcracks + + + Cancel + + + + + + + + 100 + 35 + + + + + 100 + 35 + + + + Launch crack insertion + + + Apply + + + + + + + + 130 + 35 + + + + + 130 + 35 + + + + Launch crack insertion and quit + + + Apply and close + + + + + + + + + 3 + 6 + 309 + 255 + + + + QFrame::Panel + + + QFrame::Raised + + + 2 + + + 0 + + + + + -2 + 21 + 311 + 81 + + + + + 10 + + + 0 + + + 10 + + + 0 + + + 6 + + + + + + 112 + 0 + + + + + 76 + 16777215 + + + + Name of the resulting cracked mesh + + + + + + + + + + + + + + + Cracked name + + + + + + + + 118 + 0 + + + + file adress (ex: /home/A123456/cracked.med) + + + true + + + + + + + + 100 + 16777215 + + + + Name of the sane mesh + + + Sane mesh + + + + + + + file adress (ex: /home/A123456/cuve.med) + + + true + + + + + + + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + ... + + + + + + + + 28 + 28 + + + + + 28 + 28 + + + + ... + + + + + + + + + 0 + 0 + 311 + 28 + + + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + 255 + 255 + 255 + + + + + + + 0 + 0 + 0 + + + + + + + + + 118 + 118 + 117 + + + + + + + 118 + 118 + 117 + + + + + + + 255 + 255 + 255 + + + + + + + 118 + 118 + 117 + + + + + + + + + 75 + true + + + + General parameters + + + Mesh parameters + + + Qt::AlignCenter + + + + + + -2 + 102 + 311 + 161 + + + + + 10 + + + 0 + + + 10 + + + 0 + + + + + Maximum mesh size + + + Maximum size + + + + + + + Extraction length (optionnal) + + + Extraction length + + + + + + + float (ex: 1.E-04) + + + true + + + + + + + float (ex: 1.E-03) + + + true + + + + + + + float (ex: 1.E-04) + + + true + + + + + + + Quadratic cracked mesh + + + Quadratic + + + + + + + false + + + Use Barsoum (quarter nodes) elements at crack front + + + Barsoum + + + + + + + Minimum mesh size + + + Minimum size + + + + + + + + + + 2 + 265 + 309 + 226 + + + + QFrame::Panel + + + QFrame::Raised + + + 2 + + + 0 + + + + + -1 + 0 + 311 + 28 + + + + + 75 + true + + + + Groups to save (limit list to vital groups) + + + Groups + + + Qt::AlignCenter + + + + + + 0 + 14 + 311 + 220 + + + + + 10 + + + 10 + + + + + Groups of volumes to keep + + + Volumes + + + + + + + groups separated by a space (ex: Gr1 Gr2 Gr3) + + + true + + + + + + + Groups of faces to keep + + + Faces + + + + + + + groups separated by a space (ex: Gr1 Gr2 Gr3) + + + true + + + + + + + + + + + + + Groups of edges to keep + + + Edges + + + + + + + groups separated by a space (ex: Gr1 Gr2 Gr3) + + + true + + + + + + + Groups of nodes to keep + + + Nodes + + + + + + + groups separated by a space (ex: Gr1 Gr2 Gr3) + + + true + + + + + + + + 40 + 28 + + + + Load + + + + + + + + 40 + 28 + + + + Load + + + + + + + + 40 + 28 + + + + Load + + + + + + + + 40 + 28 + + + + Load + + + + + + + + 80 + 28 + + + + Load all + + + + + + + + + + 317 + 6 + 388 + 333 + + + + QFrame::Panel + + + QFrame::Raised + + + 2 + + + 0 + + + + + 4 + 23 + 378 + 306 + + + + + 0 + 270 + + + + + 16777215 + 331 + + + + 2 + + + + Ellipse + + + + + 0 + 0 + 375 + 271 + + + + + 0 + 0 + + + + + 16777215 + 301 + + + + + 0 + 0 + + + + + false + + + + false + + + Qt::DefaultContextMenu + + + false + + + + Centre + + + + 75 + false + true + + + + + + Normale + + + + 75 + true + + + + + + Rayon + + + + 75 + true + + + + + + Direction + + + + + Rayon 2 + + + + + Angle + + + + + Rayon entaille + + + + + Extension + + + + + Valeur + + + + + + + + + 75 + true + + + + + + 0 + 0 + 0 + + + + + + + 0 + 0 + 0 + + + + + + + + + + + 75 + true + + + + + + + + + + 75 + true + + + + + + + + + + + + + + + + + + + + + + + 330 + 0 + 40 + 25 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Fissure de forme elliptique :</span></p><p><img src=":/newPrefix/images/schema_ellipse.png"/><br/></p><p><span style=" font-weight:600; text-decoration: underline;">Centre</span> : Coordonnées du centre de l'ellipse (ex: 0 0 1)</p><p><span style=" font-weight:600; text-decoration: underline;">Normale</span> : Coordonnées du vecteur normal à l'ellipse (ex: 1 0 0)</p><p><span style=" font-weight:600; text-decoration: underline;">Rayon</span> : Rayon de l'ellipse le long du vecteur direction (ex: 1.0e1)</p><p><span style=" text-decoration: underline;">Direction</span> : Coordonnées du vecteur direction de l'ellipse (ex: 0 1 0). Nécessaire pour une ellipse</p><p><span style=" text-decoration: underline;">Rayon 2</span> : Rayon de l'ellipse le long du vecteur orthogonal à normale et direction (ex: 1.0e1). Si vide égal à Rayon</p><p><span style=" text-decoration: underline;">Angle</span> : Angle en degrés pour une ellipse tronquée (ex: 180.). Si vide, l'ellipse n'est pas tronquée</p><p><span style=" text-decoration: underline;">Rayon entaille</span> : Rayon du fond d'entaille. (ex: 1.0e1). Si vide, la fissure est plane sans entaille</p><p><span style=" text-decoration: underline;">Extension</span> : Longueur d'extension de l'ellipse tronquée dans le long de la direction opposée à Direction (ex: 1.0)</p><p><span style=" font-weight:600; font-style:italic;">Gras : Informations obligatoires</span></p></body></html> + + + ? + + + Qt::AlignCenter + + + + + + Rectangle + + + + + 0 + 0 + 375 + 271 + + + + + 16777215 + 301 + + + + + Centre + + + + 75 + true + + + + + + Normale + + + + 75 + true + + + + + + Longueur + + + + 75 + true + + + + + + Direction + + + + 75 + true + + + + + + Largeur + + + + + Rayon + + + + + Angle + + + + + Rayon entaille + + + + + Valeur + + + + + + + + + + + + + + + + + + + + + + + + + + + 330 + 0 + 40 + 25 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Fissure de forme rectangulaire :</span></p><p><img src=":/newPrefix/images/schema_rectangle.png"/><br/></p><p><span style=" font-weight:600; text-decoration: underline;">Centre</span> : Coordonnées du centre du rectangle (ex: 0 0 1)</p><p><span style=" font-weight:600; text-decoration: underline;">Normale</span> : Coordonnées du vecteur normal au rectangle (ex: 1 0 0)</p><p><span style=" font-weight:600; text-decoration: underline;">Longueur</span> : Demie longueur du rectangle le long du vecteur direction (ex: 1.0e1)</p><p><span style=" font-weight:600; text-decoration: underline;">Direction</span> : Coordonnées du vecteur direction du rectangle (ex: 0 1 0)</p><p><span style=" text-decoration: underline;">Largeur</span> : Demie largeur du rectangle le long du vecteur orthogonal à normale et direction (ex: 1.0e1). Si vide, égal à Longueur</p><p><span style=" text-decoration: underline;">Rayon </span>: Rayon du congé aux angles du rectangle (ex: 1.0e1). Si vide, pas de congé</p><p><span style=" text-decoration: underline;">Angle</span> : Angle en degrés pour un rectangle tronqué (ex: 180.). Si vide, le rectangle n'est pas tronquée</p><p><span style=" text-decoration: underline;">Rayon entaille</span> : Rayon du fond d'entaille. (ex: 1.0e1). Si vide, la fissure est plane sans entaille</p><p><span style=" font-weight:600; font-style:italic;">Gras : Informations obligatoires</span></p></body></html> + + + ? + + + Qt::AlignCenter + + + + + + Sphere + + + + + 0 + 0 + 375 + 272 + + + + + 16777215 + 301 + + + + + Centre + + + + 75 + true + + + + + + Rayon + + + + 75 + true + + + + + + Valeur + + + + + + + 330 + 0 + 40 + 25 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Fissure de forme spherique :</span></p><p><img src=":/newPrefix/images/schema_shpere.png"/><br/></p><p><span style=" font-weight:600; text-decoration: underline;">Centre</span> : Coordonnées du centre de la sphere (ex: 0 0 1)</p><p><span style=" font-weight:600; text-decoration: underline;">Rayon</span> : Rayon de la sphere (ex: 1.0e1)</p><p><span style=" font-weight:600; font-style:italic;">Gras : Informations obligatoires</span></p></body></html> + + + ? + + + Qt::AlignCenter + + + + + + Custom + + + + + 0 + 0 + 375 + 271 + + + + + 16777215 + 301 + + + + + med file + + + + 75 + true + + + + + + File + + + + 50 + false + + + + + + + + + + + + + 330 + 0 + 40 + 25 + + + + <html><head/><body><p><span style=" font-weight:600; text-decoration: underline;">Fissure de forme personnalisée :</span></p><p><span style=" font-weight:600; text-decoration: underline;">Med file</span> : Adresse du maillage décrivant la fissure (ex: $HOME/PROJETX/fissure3.med)</p><p><span style=" font-style:italic;">Le maillage de la fissure doit être une surface composée de tétrahèdres linéaires uniquement.</span></p><p><span style=" font-weight:600; font-style:italic;">Gras : Informations obligatoires</span></p></body></html> + + + ? + + + Qt::AlignCenter + + + + + + + + 0 + 0 + 381 + 28 + + + + + 75 + true + + + + Crack automatic generation + + + Crack + + + Qt::AlignCenter + + + + + + true + + + + 317 + 344 + 388 + 147 + + + + QFrame::Panel + + + QFrame::Raised + + + 2 + + + 0 + + + + + 6 + 2 + 171 + 23 + + + + + 75 + true + + + + Advanced options (Use with caution) + + + Advanced options + + + + + + 0 + 24 + 427 + 106 + + + + + + 1 + 35 + 381 + 40 + + + + + 10 + + + 0 + + + 10 + + + 0 + + + + + + 85 + 28 + + + + + 85 + 28 + + + + Load all parameters from a file + + + Quick View + + + + + + + + 67 + 28 + + + + + 16777215 + 28 + + + + SURFOPT options + + + SURFOPT + + + + + + + + 0 + 28 + + + + + 16777215 + 28 + + + + string + + + true + + + + + + + + + + + + 0 + 80 + 81 + 26 + + + + Check if sane mesh is a surface + + + 2D case + + + + + + 90 + 80 + 92 + 26 + + + + Check to refine sane mesh before crack insertion + + + Pre refine + + + + + + 2 + 6 + 381 + 30 + + + + + 10 + + + 0 + + + 10 + + + 0 + + + + + + 0 + 28 + + + + Mesh increase parameter + + + Gradation + + + + + + + + 40 + 28 + + + + float (ex: 1.3) + + + true + + + 1.3 + + + + + + + + 50 + 28 + + + + Constant size layers number + + + Layers + + + + + + + + 69 + 0 + + + + + 16777215 + 28 + + + + Remeshing iterations number + + + Iterations + + + + + + + + 30 + 28 + + + + + 35 + 16777215 + + + + integer (ex: 5) + + + true + + + 5 + + + + + + + + 30 + 28 + + + + + 30 + 28 + + + + integer (ex: 2) + + + true + + + 2 + + + + + + + widget + CBAdvanced + + + + + + + diff --git a/src/Tools/ZCracksPlug/zcracksLaunch.py b/src/Tools/ZCracksPlug/zcracksLaunch.py new file mode 100755 index 000000000..fa7acf20e --- /dev/null +++ b/src/Tools/ZCracksPlug/zcracksLaunch.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import Zcracks +Zcracks.IHM() diff --git a/src/Tools/ZCracksPlug/zcracks_plugin.py b/src/Tools/ZCracksPlug/zcracks_plugin.py index efc45b187..60a09a8e7 100644 --- a/src/Tools/ZCracksPlug/zcracks_plugin.py +++ b/src/Tools/ZCracksPlug/zcracks_plugin.py @@ -18,21 +18,14 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import SalomePyQt -sgPyQt = SalomePyQt.SalomePyQt() -import eficasSalome - -class EficasForZcracks(eficasSalome.MyEficas): - """ - """ - def __init__(self, fichier = None, version = None): - eficasSalome.MyEficas.__init__(self, sgPyQt.getDesktop(), - "ZCRACKS", - fichier, version = version) - #sgPyQt.createView(custom_appli.widgetname, self) - +import os def ZcracksLct(context): - - window=EficasForZcracks() - window.show() + import os,subprocess + command = ". ${ZCRACKSHOME}/salome_do_config.sh ; " + command += 'zcracksLaunch.py &' + if command is not "": + try: + subprocess.check_call(command, executable = '/bin/bash', shell = True, bufsize=-1) + except Exception, e: + print "Error: ",e diff --git a/src/Tools/ZCracksPlug/zcracks_ui.py b/src/Tools/ZCracksPlug/zcracks_ui.py new file mode 100644 index 000000000..9b5d278b3 --- /dev/null +++ b/src/Tools/ZCracksPlug/zcracks_ui.py @@ -0,0 +1,738 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'zcracks.ui' +# +# Created: Wed Oct 19 07:56:41 2016 +# by: PyQt4 UI code generator 4.9.6 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Zui(object): + def setupUi(self, Zui): + Zui.setObjectName(_fromUtf8("Zui")) + Zui.resize(709, 540) + Zui.setMinimumSize(QtCore.QSize(709, 540)) + Zui.setMaximumSize(QtCore.QSize(709, 540)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush) + Zui.setPalette(palette) + Zui.setTitle(_fromUtf8("")) + self.horizontalLayoutWidget = QtGui.QWidget(Zui) + self.horizontalLayoutWidget.setGeometry(QtCore.QRect(3, 497, 301, 37)) + self.horizontalLayoutWidget.setObjectName(_fromUtf8("horizontalLayoutWidget")) + self.horizontalLayout = QtGui.QHBoxLayout(self.horizontalLayoutWidget) + self.horizontalLayout.setMargin(0) + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.btReset = QtGui.QPushButton(self.horizontalLayoutWidget) + self.btReset.setMinimumSize(QtCore.QSize(85, 35)) + self.btReset.setMaximumSize(QtCore.QSize(85, 35)) + self.btReset.setObjectName(_fromUtf8("btReset")) + self.horizontalLayout.addWidget(self.btReset) + self.btSave = QtGui.QPushButton(self.horizontalLayoutWidget) + self.btSave.setMinimumSize(QtCore.QSize(85, 35)) + self.btSave.setMaximumSize(QtCore.QSize(85, 35)) + self.btSave.setObjectName(_fromUtf8("btSave")) + self.horizontalLayout.addWidget(self.btSave) + self.btLoad = QtGui.QPushButton(self.horizontalLayoutWidget) + self.btLoad.setMinimumSize(QtCore.QSize(85, 35)) + self.btLoad.setMaximumSize(QtCore.QSize(85, 35)) + self.btLoad.setObjectName(_fromUtf8("btLoad")) + self.horizontalLayout.addWidget(self.btLoad) + self.horizontalLayoutWidget_2 = QtGui.QWidget(Zui) + self.horizontalLayoutWidget_2.setGeometry(QtCore.QRect(344, 490, 360, 51)) + self.horizontalLayoutWidget_2.setObjectName(_fromUtf8("horizontalLayoutWidget_2")) + self.horizontalLayout_2 = QtGui.QHBoxLayout(self.horizontalLayoutWidget_2) + self.horizontalLayout_2.setMargin(0) + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.btCancel = QtGui.QPushButton(self.horizontalLayoutWidget_2) + self.btCancel.setMinimumSize(QtCore.QSize(100, 35)) + self.btCancel.setMaximumSize(QtCore.QSize(100, 35)) + self.btCancel.setObjectName(_fromUtf8("btCancel")) + self.horizontalLayout_2.addWidget(self.btCancel) + self.btApply = QtGui.QPushButton(self.horizontalLayoutWidget_2) + self.btApply.setMinimumSize(QtCore.QSize(100, 35)) + self.btApply.setMaximumSize(QtCore.QSize(100, 35)) + self.btApply.setObjectName(_fromUtf8("btApply")) + self.horizontalLayout_2.addWidget(self.btApply) + self.btApplyClose = QtGui.QPushButton(self.horizontalLayoutWidget_2) + self.btApplyClose.setMinimumSize(QtCore.QSize(130, 35)) + self.btApplyClose.setMaximumSize(QtCore.QSize(130, 35)) + self.btApplyClose.setObjectName(_fromUtf8("btApplyClose")) + self.horizontalLayout_2.addWidget(self.btApplyClose) + self.frame = QtGui.QFrame(Zui) + self.frame.setGeometry(QtCore.QRect(3, 6, 309, 255)) + self.frame.setFrameShape(QtGui.QFrame.Panel) + self.frame.setFrameShadow(QtGui.QFrame.Raised) + self.frame.setLineWidth(2) + self.frame.setMidLineWidth(0) + self.frame.setObjectName(_fromUtf8("frame")) + self.gridLayoutWidget = QtGui.QWidget(self.frame) + self.gridLayoutWidget.setGeometry(QtCore.QRect(-2, 21, 311, 81)) + self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget")) + self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget) + self.gridLayout.setSpacing(6) + self.gridLayout.setContentsMargins(10, 0, 10, 0) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.txtCrackedName = QtGui.QLabel(self.gridLayoutWidget) + self.txtCrackedName.setMinimumSize(QtCore.QSize(112, 0)) + self.txtCrackedName.setMaximumSize(QtCore.QSize(76, 16777215)) + self.txtCrackedName.setStatusTip(_fromUtf8("")) + self.txtCrackedName.setWhatsThis(_fromUtf8("")) + self.txtCrackedName.setAccessibleName(_fromUtf8("")) + self.txtCrackedName.setAccessibleDescription(_fromUtf8("")) + self.txtCrackedName.setObjectName(_fromUtf8("txtCrackedName")) + self.gridLayout.addWidget(self.txtCrackedName, 0, 0, 1, 1) + self.valCrackedName = QtGui.QLineEdit(self.gridLayoutWidget) + self.valCrackedName.setMinimumSize(QtCore.QSize(118, 0)) + self.valCrackedName.setAutoFillBackground(True) + self.valCrackedName.setObjectName(_fromUtf8("valCrackedName")) + self.gridLayout.addWidget(self.valCrackedName, 0, 1, 1, 1) + self.txtSaneName = QtGui.QLabel(self.gridLayoutWidget) + self.txtSaneName.setMaximumSize(QtCore.QSize(100, 16777215)) + self.txtSaneName.setObjectName(_fromUtf8("txtSaneName")) + self.gridLayout.addWidget(self.txtSaneName, 1, 0, 1, 1) + self.valSaneName = QtGui.QLineEdit(self.gridLayoutWidget) + self.valSaneName.setToolTip(_fromUtf8("file adress (ex: /home/A123456/cuve.med)")) + self.valSaneName.setAutoFillBackground(True) + self.valSaneName.setInputMask(_fromUtf8("")) + self.valSaneName.setText(_fromUtf8("")) + self.valSaneName.setObjectName(_fromUtf8("valSaneName")) + self.gridLayout.addWidget(self.valSaneName, 1, 1, 1, 1) + self.btLoadCracked = QtGui.QPushButton(self.gridLayoutWidget) + self.btLoadCracked.setMinimumSize(QtCore.QSize(28, 28)) + self.btLoadCracked.setMaximumSize(QtCore.QSize(28, 28)) + self.btLoadCracked.setObjectName(_fromUtf8("btLoadCracked")) + self.gridLayout.addWidget(self.btLoadCracked, 0, 2, 1, 1) + self.btLoadSane = QtGui.QPushButton(self.gridLayoutWidget) + self.btLoadSane.setMinimumSize(QtCore.QSize(28, 28)) + self.btLoadSane.setMaximumSize(QtCore.QSize(28, 28)) + self.btLoadSane.setObjectName(_fromUtf8("btLoadSane")) + self.gridLayout.addWidget(self.btLoadSane, 1, 2, 1, 1) + self.cracked_name_2 = QtGui.QLabel(self.frame) + self.cracked_name_2.setGeometry(QtCore.QRect(0, 0, 311, 28)) + palette = QtGui.QPalette() + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.ButtonText, brush) + brush = QtGui.QBrush(QtGui.QColor(118, 118, 117)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.WindowText, brush) + brush = QtGui.QBrush(QtGui.QColor(118, 118, 117)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Text, brush) + brush = QtGui.QBrush(QtGui.QColor(255, 255, 255)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.BrightText, brush) + brush = QtGui.QBrush(QtGui.QColor(118, 118, 117)) + brush.setStyle(QtCore.Qt.SolidPattern) + palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, brush) + self.cracked_name_2.setPalette(palette) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.cracked_name_2.setFont(font) + self.cracked_name_2.setAlignment(QtCore.Qt.AlignCenter) + self.cracked_name_2.setObjectName(_fromUtf8("cracked_name_2")) + self.gridLayoutWidget_3 = QtGui.QWidget(self.frame) + self.gridLayoutWidget_3.setGeometry(QtCore.QRect(-2, 102, 311, 161)) + self.gridLayoutWidget_3.setObjectName(_fromUtf8("gridLayoutWidget_3")) + self.gridLayout_3 = QtGui.QGridLayout(self.gridLayoutWidget_3) + self.gridLayout_3.setContentsMargins(10, 0, 10, 0) + self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) + self.txtMaxSize = QtGui.QLabel(self.gridLayoutWidget_3) + self.txtMaxSize.setObjectName(_fromUtf8("txtMaxSize")) + self.gridLayout_3.addWidget(self.txtMaxSize, 1, 0, 1, 1) + self.txtExtractLength = QtGui.QLabel(self.gridLayoutWidget_3) + self.txtExtractLength.setObjectName(_fromUtf8("txtExtractLength")) + self.gridLayout_3.addWidget(self.txtExtractLength, 2, 0, 1, 1) + self.valMinSize = QtGui.QLineEdit(self.gridLayoutWidget_3) + self.valMinSize.setAutoFillBackground(True) + self.valMinSize.setObjectName(_fromUtf8("valMinSize")) + self.gridLayout_3.addWidget(self.valMinSize, 0, 1, 1, 1) + self.valMaxSize = QtGui.QLineEdit(self.gridLayoutWidget_3) + self.valMaxSize.setAutoFillBackground(True) + self.valMaxSize.setObjectName(_fromUtf8("valMaxSize")) + self.gridLayout_3.addWidget(self.valMaxSize, 1, 1, 1, 1) + self.valExtractLength = QtGui.QLineEdit(self.gridLayoutWidget_3) + self.valExtractLength.setAutoFillBackground(True) + self.valExtractLength.setObjectName(_fromUtf8("valExtractLength")) + self.gridLayout_3.addWidget(self.valExtractLength, 2, 1, 1, 1) + self.CBQuad = QtGui.QCheckBox(self.gridLayoutWidget_3) + self.CBQuad.setObjectName(_fromUtf8("CBQuad")) + self.gridLayout_3.addWidget(self.CBQuad, 3, 0, 1, 1) + self.CBBarsoum = QtGui.QCheckBox(self.gridLayoutWidget_3) + self.CBBarsoum.setEnabled(False) + self.CBBarsoum.setObjectName(_fromUtf8("CBBarsoum")) + self.gridLayout_3.addWidget(self.CBBarsoum, 3, 1, 1, 1) + self.txtMinSize = QtGui.QLabel(self.gridLayoutWidget_3) + self.txtMinSize.setObjectName(_fromUtf8("txtMinSize")) + self.gridLayout_3.addWidget(self.txtMinSize, 0, 0, 1, 1) + self.frame_2 = QtGui.QFrame(Zui) + self.frame_2.setGeometry(QtCore.QRect(2, 265, 309, 226)) + self.frame_2.setFrameShape(QtGui.QFrame.Panel) + self.frame_2.setFrameShadow(QtGui.QFrame.Raised) + self.frame_2.setLineWidth(2) + self.frame_2.setMidLineWidth(0) + self.frame_2.setObjectName(_fromUtf8("frame_2")) + self.labelCrackedName = QtGui.QLabel(self.frame_2) + self.labelCrackedName.setGeometry(QtCore.QRect(-1, 0, 311, 28)) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.labelCrackedName.setFont(font) + self.labelCrackedName.setAlignment(QtCore.Qt.AlignCenter) + self.labelCrackedName.setObjectName(_fromUtf8("labelCrackedName")) + self.gridLayoutWidget_2 = QtGui.QWidget(self.frame_2) + self.gridLayoutWidget_2.setGeometry(QtCore.QRect(0, 14, 311, 220)) + self.gridLayoutWidget_2.setObjectName(_fromUtf8("gridLayoutWidget_2")) + self.gridLayout_2 = QtGui.QGridLayout(self.gridLayoutWidget_2) + self.gridLayout_2.setMargin(10) + self.gridLayout_2.setSpacing(10) + self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) + self.txtGrVol = QtGui.QLabel(self.gridLayoutWidget_2) + self.txtGrVol.setObjectName(_fromUtf8("txtGrVol")) + self.gridLayout_2.addWidget(self.txtGrVol, 0, 0, 1, 1) + self.valGrVol = QtGui.QLineEdit(self.gridLayoutWidget_2) + self.valGrVol.setAutoFillBackground(True) + self.valGrVol.setObjectName(_fromUtf8("valGrVol")) + self.gridLayout_2.addWidget(self.valGrVol, 0, 1, 1, 1) + self.txtGrFace = QtGui.QLabel(self.gridLayoutWidget_2) + self.txtGrFace.setToolTip(_fromUtf8("Groups of faces to keep")) + self.txtGrFace.setObjectName(_fromUtf8("txtGrFace")) + self.gridLayout_2.addWidget(self.txtGrFace, 1, 0, 1, 1) + self.valGrFace = QtGui.QLineEdit(self.gridLayoutWidget_2) + self.valGrFace.setToolTip(_fromUtf8("groups separated by a space (ex: Gr1 Gr2 Gr3)")) + self.valGrFace.setAutoFillBackground(True) + self.valGrFace.setInputMask(_fromUtf8("")) + self.valGrFace.setText(_fromUtf8("")) + self.valGrFace.setObjectName(_fromUtf8("valGrFace")) + self.gridLayout_2.addWidget(self.valGrFace, 1, 1, 1, 1) + self.txtGrEdge = QtGui.QLabel(self.gridLayoutWidget_2) + self.txtGrEdge.setObjectName(_fromUtf8("txtGrEdge")) + self.gridLayout_2.addWidget(self.txtGrEdge, 2, 0, 1, 1) + self.valGrEdge = QtGui.QLineEdit(self.gridLayoutWidget_2) + self.valGrEdge.setAutoFillBackground(True) + self.valGrEdge.setObjectName(_fromUtf8("valGrEdge")) + self.gridLayout_2.addWidget(self.valGrEdge, 2, 1, 1, 1) + self.txtGrNode = QtGui.QLabel(self.gridLayoutWidget_2) + self.txtGrNode.setObjectName(_fromUtf8("txtGrNode")) + self.gridLayout_2.addWidget(self.txtGrNode, 3, 0, 1, 1) + self.valGrNode = QtGui.QLineEdit(self.gridLayoutWidget_2) + self.valGrNode.setAutoFillBackground(True) + self.valGrNode.setObjectName(_fromUtf8("valGrNode")) + self.gridLayout_2.addWidget(self.valGrNode, 3, 1, 1, 1) + self.btGrVol = QtGui.QPushButton(self.gridLayoutWidget_2) + self.btGrVol.setMaximumSize(QtCore.QSize(40, 28)) + self.btGrVol.setObjectName(_fromUtf8("btGrVol")) + self.gridLayout_2.addWidget(self.btGrVol, 0, 2, 1, 1) + self.btGrFace = QtGui.QPushButton(self.gridLayoutWidget_2) + self.btGrFace.setMaximumSize(QtCore.QSize(40, 28)) + self.btGrFace.setObjectName(_fromUtf8("btGrFace")) + self.gridLayout_2.addWidget(self.btGrFace, 1, 2, 1, 1) + self.btGrEdge = QtGui.QPushButton(self.gridLayoutWidget_2) + self.btGrEdge.setMaximumSize(QtCore.QSize(40, 28)) + self.btGrEdge.setObjectName(_fromUtf8("btGrEdge")) + self.gridLayout_2.addWidget(self.btGrEdge, 2, 2, 1, 1) + self.btGrNode = QtGui.QPushButton(self.gridLayoutWidget_2) + self.btGrNode.setMaximumSize(QtCore.QSize(40, 28)) + self.btGrNode.setObjectName(_fromUtf8("btGrNode")) + self.gridLayout_2.addWidget(self.btGrNode, 3, 2, 1, 1) + self.btGrAll = QtGui.QPushButton(self.gridLayoutWidget_2) + self.btGrAll.setMaximumSize(QtCore.QSize(80, 28)) + self.btGrAll.setObjectName(_fromUtf8("btGrAll")) + self.gridLayout_2.addWidget(self.btGrAll, 4, 1, 1, 1) + self.frame_3 = QtGui.QFrame(Zui) + self.frame_3.setGeometry(QtCore.QRect(317, 6, 388, 333)) + self.frame_3.setFrameShape(QtGui.QFrame.Panel) + self.frame_3.setFrameShadow(QtGui.QFrame.Raised) + self.frame_3.setLineWidth(2) + self.frame_3.setMidLineWidth(0) + self.frame_3.setObjectName(_fromUtf8("frame_3")) + self.tabWidget = QtGui.QTabWidget(self.frame_3) + self.tabWidget.setGeometry(QtCore.QRect(4, 23, 378, 306)) + self.tabWidget.setMinimumSize(QtCore.QSize(0, 270)) + self.tabWidget.setMaximumSize(QtCore.QSize(16777215, 331)) + self.tabWidget.setObjectName(_fromUtf8("tabWidget")) + self.ongletEllipse = QtGui.QWidget() + self.ongletEllipse.setObjectName(_fromUtf8("ongletEllipse")) + self.tabEllipse = QtGui.QTableWidget(self.ongletEllipse) + self.tabEllipse.setGeometry(QtCore.QRect(0, 0, 375, 271)) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.tabEllipse.sizePolicy().hasHeightForWidth()) + self.tabEllipse.setSizePolicy(sizePolicy) + self.tabEllipse.setMaximumSize(QtCore.QSize(16777215, 301)) + self.tabEllipse.setBaseSize(QtCore.QSize(0, 0)) + font = QtGui.QFont() + font.setUnderline(False) + self.tabEllipse.setFont(font) + self.tabEllipse.setMouseTracking(False) + self.tabEllipse.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) + self.tabEllipse.setAutoFillBackground(False) + self.tabEllipse.setObjectName(_fromUtf8("tabEllipse")) + self.tabEllipse.setColumnCount(1) + self.tabEllipse.setRowCount(8) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setItalic(False) + font.setWeight(75) + item.setFont(font) + self.tabEllipse.setVerticalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabEllipse.setVerticalHeaderItem(1, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabEllipse.setVerticalHeaderItem(2, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setVerticalHeaderItem(3, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setVerticalHeaderItem(4, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setVerticalHeaderItem(5, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setVerticalHeaderItem(6, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setVerticalHeaderItem(7, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setHorizontalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.NoBrush) + item.setBackground(brush) + brush = QtGui.QBrush(QtGui.QColor(0, 0, 0)) + brush.setStyle(QtCore.Qt.NoBrush) + item.setForeground(brush) + self.tabEllipse.setItem(0, 0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabEllipse.setItem(1, 0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabEllipse.setItem(2, 0, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setItem(3, 0, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setItem(4, 0, item) + item = QtGui.QTableWidgetItem() + self.tabEllipse.setItem(5, 0, item) + self.infoEllipse = QtGui.QLabel(self.ongletEllipse) + self.infoEllipse.setGeometry(QtCore.QRect(330, 0, 40, 25)) + self.infoEllipse.setAlignment(QtCore.Qt.AlignCenter) + self.infoEllipse.setObjectName(_fromUtf8("infoEllipse")) + self.tabWidget.addTab(self.ongletEllipse, _fromUtf8("")) + self.ongletRectangle = QtGui.QWidget() + self.ongletRectangle.setObjectName(_fromUtf8("ongletRectangle")) + self.tabRectangle = QtGui.QTableWidget(self.ongletRectangle) + self.tabRectangle.setGeometry(QtCore.QRect(0, 0, 375, 271)) + self.tabRectangle.setMaximumSize(QtCore.QSize(16777215, 301)) + self.tabRectangle.setObjectName(_fromUtf8("tabRectangle")) + self.tabRectangle.setColumnCount(1) + self.tabRectangle.setRowCount(8) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabRectangle.setVerticalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabRectangle.setVerticalHeaderItem(1, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabRectangle.setVerticalHeaderItem(2, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabRectangle.setVerticalHeaderItem(3, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setVerticalHeaderItem(4, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setVerticalHeaderItem(5, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setVerticalHeaderItem(6, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setVerticalHeaderItem(7, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setHorizontalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setItem(3, 0, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setItem(4, 0, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setItem(5, 0, item) + item = QtGui.QTableWidgetItem() + self.tabRectangle.setItem(6, 0, item) + self.infoRectangle = QtGui.QLabel(self.ongletRectangle) + self.infoRectangle.setGeometry(QtCore.QRect(330, 0, 40, 25)) + self.infoRectangle.setAlignment(QtCore.Qt.AlignCenter) + self.infoRectangle.setObjectName(_fromUtf8("infoRectangle")) + self.tabWidget.addTab(self.ongletRectangle, _fromUtf8("")) + self.ongletSphere = QtGui.QWidget() + self.ongletSphere.setObjectName(_fromUtf8("ongletSphere")) + self.tabSphere = QtGui.QTableWidget(self.ongletSphere) + self.tabSphere.setGeometry(QtCore.QRect(0, 0, 375, 272)) + self.tabSphere.setMaximumSize(QtCore.QSize(16777215, 301)) + self.tabSphere.setObjectName(_fromUtf8("tabSphere")) + self.tabSphere.setColumnCount(1) + self.tabSphere.setRowCount(2) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabSphere.setVerticalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabSphere.setVerticalHeaderItem(1, item) + item = QtGui.QTableWidgetItem() + self.tabSphere.setHorizontalHeaderItem(0, item) + self.infoSphere = QtGui.QLabel(self.ongletSphere) + self.infoSphere.setGeometry(QtCore.QRect(330, 0, 40, 25)) + self.infoSphere.setAlignment(QtCore.Qt.AlignCenter) + self.infoSphere.setObjectName(_fromUtf8("infoSphere")) + self.tabWidget.addTab(self.ongletSphere, _fromUtf8("")) + self.ongletPerso = QtGui.QWidget() + self.ongletPerso.setObjectName(_fromUtf8("ongletPerso")) + self.tabPerso = QtGui.QTableWidget(self.ongletPerso) + self.tabPerso.setGeometry(QtCore.QRect(0, 0, 375, 271)) + self.tabPerso.setMaximumSize(QtCore.QSize(16777215, 301)) + self.tabPerso.setObjectName(_fromUtf8("tabPerso")) + self.tabPerso.setColumnCount(1) + self.tabPerso.setRowCount(1) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + item.setFont(font) + self.tabPerso.setVerticalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + font = QtGui.QFont() + font.setBold(False) + font.setWeight(50) + item.setFont(font) + self.tabPerso.setHorizontalHeaderItem(0, item) + item = QtGui.QTableWidgetItem() + self.tabPerso.setItem(0, 0, item) + self.infoCustom = QtGui.QLabel(self.ongletPerso) + self.infoCustom.setGeometry(QtCore.QRect(330, 0, 40, 25)) + self.infoCustom.setAlignment(QtCore.Qt.AlignCenter) + self.infoCustom.setObjectName(_fromUtf8("infoCustom")) + self.tabWidget.addTab(self.ongletPerso, _fromUtf8("")) + self.labelCrackName = QtGui.QLabel(self.frame_3) + self.labelCrackName.setGeometry(QtCore.QRect(0, 0, 381, 28)) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.labelCrackName.setFont(font) + self.labelCrackName.setAlignment(QtCore.Qt.AlignCenter) + self.labelCrackName.setObjectName(_fromUtf8("labelCrackName")) + self.frame_4 = QtGui.QFrame(Zui) + self.frame_4.setEnabled(True) + self.frame_4.setGeometry(QtCore.QRect(317, 344, 388, 147)) + self.frame_4.setFrameShape(QtGui.QFrame.Panel) + self.frame_4.setFrameShadow(QtGui.QFrame.Raised) + self.frame_4.setLineWidth(2) + self.frame_4.setMidLineWidth(0) + self.frame_4.setObjectName(_fromUtf8("frame_4")) + self.CBAdvanced = QtGui.QCheckBox(self.frame_4) + self.CBAdvanced.setGeometry(QtCore.QRect(6, 2, 171, 23)) + font = QtGui.QFont() + font.setBold(True) + font.setWeight(75) + self.CBAdvanced.setFont(font) + self.CBAdvanced.setObjectName(_fromUtf8("CBAdvanced")) + self.widget = QtGui.QWidget(self.frame_4) + self.widget.setGeometry(QtCore.QRect(0, 24, 427, 106)) + self.widget.setObjectName(_fromUtf8("widget")) + self.gridLayoutWidget_9 = QtGui.QWidget(self.widget) + self.gridLayoutWidget_9.setGeometry(QtCore.QRect(1, 35, 381, 40)) + self.gridLayoutWidget_9.setObjectName(_fromUtf8("gridLayoutWidget_9")) + self.gridLayout_9 = QtGui.QGridLayout(self.gridLayoutWidget_9) + self.gridLayout_9.setContentsMargins(10, 0, 10, 0) + self.gridLayout_9.setObjectName(_fromUtf8("gridLayout_9")) + self.btVisu = QtGui.QPushButton(self.gridLayoutWidget_9) + self.btVisu.setMinimumSize(QtCore.QSize(85, 28)) + self.btVisu.setMaximumSize(QtCore.QSize(85, 28)) + self.btVisu.setObjectName(_fromUtf8("btVisu")) + self.gridLayout_9.addWidget(self.btVisu, 0, 0, 1, 1) + self.txtSurfopt = QtGui.QLabel(self.gridLayoutWidget_9) + self.txtSurfopt.setMinimumSize(QtCore.QSize(67, 28)) + self.txtSurfopt.setMaximumSize(QtCore.QSize(16777215, 28)) + self.txtSurfopt.setObjectName(_fromUtf8("txtSurfopt")) + self.gridLayout_9.addWidget(self.txtSurfopt, 0, 1, 1, 1) + self.valSurfopt = QtGui.QLineEdit(self.gridLayoutWidget_9) + self.valSurfopt.setMinimumSize(QtCore.QSize(0, 28)) + self.valSurfopt.setMaximumSize(QtCore.QSize(16777215, 28)) + self.valSurfopt.setAutoFillBackground(True) + self.valSurfopt.setText(_fromUtf8("")) + self.valSurfopt.setObjectName(_fromUtf8("valSurfopt")) + self.gridLayout_9.addWidget(self.valSurfopt, 0, 2, 1, 1) + self.CBIs2D = QtGui.QCheckBox(self.widget) + self.CBIs2D.setGeometry(QtCore.QRect(0, 80, 81, 26)) + self.CBIs2D.setObjectName(_fromUtf8("CBIs2D")) + self.CBRefine = QtGui.QCheckBox(self.widget) + self.CBRefine.setGeometry(QtCore.QRect(90, 80, 92, 26)) + self.CBRefine.setObjectName(_fromUtf8("CBRefine")) + self.gridLayoutWidget_8 = QtGui.QWidget(self.widget) + self.gridLayoutWidget_8.setGeometry(QtCore.QRect(2, 6, 381, 30)) + self.gridLayoutWidget_8.setObjectName(_fromUtf8("gridLayoutWidget_8")) + self.gridLayout_8 = QtGui.QGridLayout(self.gridLayoutWidget_8) + self.gridLayout_8.setContentsMargins(10, 0, 10, 0) + self.gridLayout_8.setObjectName(_fromUtf8("gridLayout_8")) + self.txtGradation = QtGui.QLabel(self.gridLayoutWidget_8) + self.txtGradation.setMinimumSize(QtCore.QSize(0, 28)) + self.txtGradation.setObjectName(_fromUtf8("txtGradation")) + self.gridLayout_8.addWidget(self.txtGradation, 0, 0, 1, 1) + self.valGradation = QtGui.QLineEdit(self.gridLayoutWidget_8) + self.valGradation.setMinimumSize(QtCore.QSize(40, 28)) + self.valGradation.setAutoFillBackground(True) + self.valGradation.setObjectName(_fromUtf8("valGradation")) + self.gridLayout_8.addWidget(self.valGradation, 0, 1, 1, 1) + self.txtLayers = QtGui.QLabel(self.gridLayoutWidget_8) + self.txtLayers.setMinimumSize(QtCore.QSize(50, 28)) + self.txtLayers.setObjectName(_fromUtf8("txtLayers")) + self.gridLayout_8.addWidget(self.txtLayers, 0, 2, 1, 1) + self.txtIterations = QtGui.QLabel(self.gridLayoutWidget_8) + self.txtIterations.setMinimumSize(QtCore.QSize(69, 0)) + self.txtIterations.setMaximumSize(QtCore.QSize(16777215, 28)) + self.txtIterations.setObjectName(_fromUtf8("txtIterations")) + self.gridLayout_8.addWidget(self.txtIterations, 0, 4, 1, 1) + self.valLayers = QtGui.QLineEdit(self.gridLayoutWidget_8) + self.valLayers.setMinimumSize(QtCore.QSize(30, 28)) + self.valLayers.setMaximumSize(QtCore.QSize(35, 16777215)) + self.valLayers.setAutoFillBackground(True) + self.valLayers.setObjectName(_fromUtf8("valLayers")) + self.gridLayout_8.addWidget(self.valLayers, 0, 3, 1, 1) + self.valIterations = QtGui.QLineEdit(self.gridLayoutWidget_8) + self.valIterations.setMinimumSize(QtCore.QSize(30, 28)) + self.valIterations.setMaximumSize(QtCore.QSize(30, 28)) + self.valIterations.setAutoFillBackground(True) + self.valIterations.setObjectName(_fromUtf8("valIterations")) + self.gridLayout_8.addWidget(self.valIterations, 0, 5, 1, 1) + + self.retranslateUi(Zui) + self.tabWidget.setCurrentIndex(2) + QtCore.QMetaObject.connectSlotsByName(Zui) + + def retranslateUi(self, Zui): + Zui.setWindowTitle(_translate("Zui", "Zcracks interface - version dev", None)) + self.btReset.setToolTip(_translate("Zui", "Clear all paramters", None)) + self.btReset.setText(_translate("Zui", "Reset", None)) + self.btSave.setToolTip(_translate("Zui", "Save parameters in a file", None)) + self.btSave.setText(_translate("Zui", "Save", None)) + self.btLoad.setToolTip(_translate("Zui", "Load all parameters from a file", None)) + self.btLoad.setText(_translate("Zui", "Load", None)) + self.btCancel.setToolTip(_translate("Zui", "Exit Zcracks", None)) + self.btCancel.setText(_translate("Zui", "Cancel", None)) + self.btApply.setToolTip(_translate("Zui", "Launch crack insertion", None)) + self.btApply.setText(_translate("Zui", "Apply", None)) + self.btApplyClose.setToolTip(_translate("Zui", "Launch crack insertion and quit", None)) + self.btApplyClose.setText(_translate("Zui", "Apply and close", None)) + self.txtCrackedName.setToolTip(_translate("Zui", "Name of the resulting cracked mesh", None)) + self.txtCrackedName.setText(_translate("Zui", "Cracked name", None)) + self.valCrackedName.setToolTip(_translate("Zui", "file adress (ex: /home/A123456/cracked.med)", None)) + self.txtSaneName.setToolTip(_translate("Zui", "Name of the sane mesh", None)) + self.txtSaneName.setText(_translate("Zui", "Sane mesh", None)) + self.btLoadCracked.setText(_translate("Zui", "...", None)) + self.btLoadSane.setText(_translate("Zui", "...", None)) + self.cracked_name_2.setToolTip(_translate("Zui", "General parameters", None)) + self.cracked_name_2.setText(_translate("Zui", "Mesh parameters", None)) + self.txtMaxSize.setToolTip(_translate("Zui", "Maximum mesh size", None)) + self.txtMaxSize.setText(_translate("Zui", "Maximum size", None)) + self.txtExtractLength.setToolTip(_translate("Zui", "Extraction length (optionnal)", None)) + self.txtExtractLength.setText(_translate("Zui", "Extraction length", None)) + self.valMinSize.setToolTip(_translate("Zui", "float (ex: 1.E-04)", None)) + self.valMaxSize.setToolTip(_translate("Zui", "float (ex: 1.E-03)", None)) + self.valExtractLength.setToolTip(_translate("Zui", "float (ex: 1.E-04)", None)) + self.CBQuad.setToolTip(_translate("Zui", "Quadratic cracked mesh", None)) + self.CBQuad.setText(_translate("Zui", "Quadratic", None)) + self.CBBarsoum.setToolTip(_translate("Zui", "Use Barsoum (quarter nodes) elements at crack front", None)) + self.CBBarsoum.setText(_translate("Zui", "Barsoum", None)) + self.txtMinSize.setToolTip(_translate("Zui", "Minimum mesh size", None)) + self.txtMinSize.setText(_translate("Zui", "Minimum size", None)) + self.labelCrackedName.setToolTip(_translate("Zui", "Groups to save (limit list to vital groups)", None)) + self.labelCrackedName.setText(_translate("Zui", "Groups", None)) + self.txtGrVol.setToolTip(_translate("Zui", "Groups of volumes to keep", None)) + self.txtGrVol.setText(_translate("Zui", "Volumes", None)) + self.valGrVol.setToolTip(_translate("Zui", "groups separated by a space (ex: Gr1 Gr2 Gr3)", None)) + self.txtGrFace.setText(_translate("Zui", "Faces", None)) + self.txtGrEdge.setToolTip(_translate("Zui", "Groups of edges to keep", None)) + self.txtGrEdge.setText(_translate("Zui", "Edges", None)) + self.valGrEdge.setToolTip(_translate("Zui", "groups separated by a space (ex: Gr1 Gr2 Gr3)", None)) + self.txtGrNode.setToolTip(_translate("Zui", "Groups of nodes to keep", None)) + self.txtGrNode.setText(_translate("Zui", "Nodes", None)) + self.valGrNode.setToolTip(_translate("Zui", "groups separated by a space (ex: Gr1 Gr2 Gr3)", None)) + self.btGrVol.setText(_translate("Zui", "Load", None)) + self.btGrFace.setText(_translate("Zui", "Load", None)) + self.btGrEdge.setText(_translate("Zui", "Load", None)) + self.btGrNode.setText(_translate("Zui", "Load", None)) + self.btGrAll.setText(_translate("Zui", "Load all", None)) + item = self.tabEllipse.verticalHeaderItem(0) + item.setText(_translate("Zui", "Centre", None)) + item = self.tabEllipse.verticalHeaderItem(1) + item.setText(_translate("Zui", "Normale", None)) + item = self.tabEllipse.verticalHeaderItem(2) + item.setText(_translate("Zui", "Rayon", None)) + item = self.tabEllipse.verticalHeaderItem(3) + item.setText(_translate("Zui", "Direction", None)) + item = self.tabEllipse.verticalHeaderItem(4) + item.setText(_translate("Zui", "Rayon 2", None)) + item = self.tabEllipse.verticalHeaderItem(5) + item.setText(_translate("Zui", "Angle", None)) + item = self.tabEllipse.verticalHeaderItem(6) + item.setText(_translate("Zui", "Rayon entaille", None)) + item = self.tabEllipse.verticalHeaderItem(7) + item.setText(_translate("Zui", "Extension", None)) + item = self.tabEllipse.horizontalHeaderItem(0) + item.setText(_translate("Zui", "Valeur", None)) + __sortingEnabled = self.tabEllipse.isSortingEnabled() + self.tabEllipse.setSortingEnabled(False) + self.tabEllipse.setSortingEnabled(__sortingEnabled) + self.infoEllipse.setToolTip(_translate("Zui", "

    Fissure de forme elliptique :


    Centre : Coordonnées du centre de l\'ellipse (ex: 0 0 1)

    Normale : Coordonnées du vecteur normal à l\'ellipse (ex: 1 0 0)

    Rayon : Rayon de l\'ellipse le long du vecteur direction (ex: 1.0e1)

    Direction : Coordonnées du vecteur direction de l\'ellipse (ex: 0 1 0). Nécessaire pour une ellipse

    Rayon 2 : Rayon de l\'ellipse le long du vecteur orthogonal à normale et direction (ex: 1.0e1). Si vide égal à Rayon

    Angle : Angle en degrés pour une ellipse tronquée (ex: 180.). Si vide, l\'ellipse n\'est pas tronquée

    Rayon entaille : Rayon du fond d\'entaille. (ex: 1.0e1). Si vide, la fissure est plane sans entaille

    Extension : Longueur d\'extension de l\'ellipse tronquée dans le long de la direction opposée à Direction (ex: 1.0)

    Gras : Informations obligatoires

    ", None)) + self.infoEllipse.setText(_translate("Zui", "?", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.ongletEllipse), _translate("Zui", "Ellipse", None)) + item = self.tabRectangle.verticalHeaderItem(0) + item.setText(_translate("Zui", "Centre", None)) + item = self.tabRectangle.verticalHeaderItem(1) + item.setText(_translate("Zui", "Normale", None)) + item = self.tabRectangle.verticalHeaderItem(2) + item.setText(_translate("Zui", "Longueur", None)) + item = self.tabRectangle.verticalHeaderItem(3) + item.setText(_translate("Zui", "Direction", None)) + item = self.tabRectangle.verticalHeaderItem(4) + item.setText(_translate("Zui", "Largeur", None)) + item = self.tabRectangle.verticalHeaderItem(5) + item.setText(_translate("Zui", "Rayon", None)) + item = self.tabRectangle.verticalHeaderItem(6) + item.setText(_translate("Zui", "Angle", None)) + item = self.tabRectangle.verticalHeaderItem(7) + item.setText(_translate("Zui", "Rayon entaille", None)) + item = self.tabRectangle.horizontalHeaderItem(0) + item.setText(_translate("Zui", "Valeur", None)) + __sortingEnabled = self.tabRectangle.isSortingEnabled() + self.tabRectangle.setSortingEnabled(False) + self.tabRectangle.setSortingEnabled(__sortingEnabled) + self.infoRectangle.setToolTip(_translate("Zui", "

    Fissure de forme rectangulaire :


    Centre : Coordonnées du centre du rectangle (ex: 0 0 1)

    Normale : Coordonnées du vecteur normal au rectangle (ex: 1 0 0)

    Longueur : Demie longueur du rectangle le long du vecteur direction (ex: 1.0e1)

    Direction : Coordonnées du vecteur direction du rectangle (ex: 0 1 0)

    Largeur : Demie largeur du rectangle le long du vecteur orthogonal à normale et direction (ex: 1.0e1). Si vide, égal à Longueur

    Rayon : Rayon du congé aux angles du rectangle (ex: 1.0e1). Si vide, pas de congé

    Angle : Angle en degrés pour un rectangle tronqué (ex: 180.). Si vide, le rectangle n\'est pas tronquée

    Rayon entaille : Rayon du fond d\'entaille. (ex: 1.0e1). Si vide, la fissure est plane sans entaille

    Gras : Informations obligatoires

    ", None)) + self.infoRectangle.setText(_translate("Zui", "?", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.ongletRectangle), _translate("Zui", "Rectangle", None)) + item = self.tabSphere.verticalHeaderItem(0) + item.setText(_translate("Zui", "Centre", None)) + item = self.tabSphere.verticalHeaderItem(1) + item.setText(_translate("Zui", "Rayon", None)) + item = self.tabSphere.horizontalHeaderItem(0) + item.setText(_translate("Zui", "Valeur", None)) + self.infoSphere.setToolTip(_translate("Zui", "

    Fissure de forme spherique :


    Centre : Coordonnées du centre de la sphere (ex: 0 0 1)

    Rayon : Rayon de la sphere (ex: 1.0e1)

    Gras : Informations obligatoires

    ", None)) + self.infoSphere.setText(_translate("Zui", "?", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.ongletSphere), _translate("Zui", "Sphere", None)) + item = self.tabPerso.verticalHeaderItem(0) + item.setText(_translate("Zui", "med file", None)) + item = self.tabPerso.horizontalHeaderItem(0) + item.setText(_translate("Zui", "File", None)) + __sortingEnabled = self.tabPerso.isSortingEnabled() + self.tabPerso.setSortingEnabled(False) + self.tabPerso.setSortingEnabled(__sortingEnabled) + self.infoCustom.setToolTip(_translate("Zui", "

    Fissure de forme personnalisée :

    Med file : Adresse du maillage décrivant la fissure (ex: $HOME/PROJETX/fissure3.med)

    Le maillage de la fissure doit être une surface composée de tétrahèdres linéaires uniquement.

    Gras : Informations obligatoires

    ", None)) + self.infoCustom.setText(_translate("Zui", "?", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.ongletPerso), _translate("Zui", "Custom", None)) + self.labelCrackName.setToolTip(_translate("Zui", "Crack automatic generation", None)) + self.labelCrackName.setText(_translate("Zui", "Crack", None)) + self.CBAdvanced.setToolTip(_translate("Zui", "Advanced options (Use with caution)", None)) + self.CBAdvanced.setText(_translate("Zui", "Advanced options", None)) + self.btVisu.setToolTip(_translate("Zui", "Load all parameters from a file", None)) + self.btVisu.setText(_translate("Zui", "Quick View", None)) + self.txtSurfopt.setToolTip(_translate("Zui", "SURFOPT options", None)) + self.txtSurfopt.setText(_translate("Zui", "SURFOPT", None)) + self.valSurfopt.setToolTip(_translate("Zui", "string", None)) + self.CBIs2D.setToolTip(_translate("Zui", "Check if sane mesh is a surface", None)) + self.CBIs2D.setText(_translate("Zui", "2D case", None)) + self.CBRefine.setToolTip(_translate("Zui", "Check to refine sane mesh before crack insertion", None)) + self.CBRefine.setText(_translate("Zui", "Pre refine", None)) + self.txtGradation.setToolTip(_translate("Zui", "Mesh increase parameter", None)) + self.txtGradation.setText(_translate("Zui", "Gradation", None)) + self.valGradation.setToolTip(_translate("Zui", "float (ex: 1.3)", None)) + self.valGradation.setText(_translate("Zui", "1.3", None)) + self.txtLayers.setToolTip(_translate("Zui", "Constant size layers number", None)) + self.txtLayers.setText(_translate("Zui", "Layers", None)) + self.txtIterations.setToolTip(_translate("Zui", "Remeshing iterations number", None)) + self.txtIterations.setText(_translate("Zui", "Iterations", None)) + self.valLayers.setToolTip(_translate("Zui", "integer (ex: 5)", None)) + self.valLayers.setText(_translate("Zui", "5", None)) + self.valIterations.setToolTip(_translate("Zui", "integer (ex: 2)", None)) + self.valIterations.setText(_translate("Zui", "2", None)) + +import images_rc diff --git a/src/Tools/blocFissure/AREextradosLauncher.py b/src/Tools/blocFissure/AREextradosLauncher.py index f256b4cc3..40e34cea8 100644 --- a/src/Tools/blocFissure/AREextradosLauncher.py +++ b/src/Tools/blocFissure/AREextradosLauncher.py @@ -33,4 +33,4 @@ dicoParams = dict(nomCas = 'fissTuyau', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/AREintradosLauncher.py b/src/Tools/blocFissure/AREintradosLauncher.py index f95fea280..dc834acd9 100644 --- a/src/Tools/blocFissure/AREintradosLauncher.py +++ b/src/Tools/blocFissure/AREintradosLauncher.py @@ -33,4 +33,4 @@ dicoParams = dict(nomCas = 'fissTuyau', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/CasTests/cubeAngle.py b/src/Tools/blocFissure/CasTests/cubeAngle.py index 38d11ea40..772e465b8 100644 --- a/src/Tools/blocFissure/CasTests/cubeAngle.py +++ b/src/Tools/blocFissure/CasTests/cubeAngle.py @@ -57,7 +57,7 @@ class cubeAngle(fissureGenerique): shellFiss = geompy.ImportFile(os.path.join(gmu.pathBloc, "materielCasTests/CubeAngleFiss.brep"), "BREP") fondFiss = geompy.CreateGroup(shellFiss, geompy.ShapeType["EDGE"]) - geompy.UnionIDs(fondFiss, [4]) + geompy.UnionIDs(fondFiss, [3]) geompy.addToStudy( shellFiss, 'shellFiss' ) geompy.addToStudyInFather( shellFiss, fondFiss, 'fondFiss' ) diff --git a/src/Tools/blocFissure/CasTests/cubeCoin.py b/src/Tools/blocFissure/CasTests/cubeCoin.py index 97d18a45d..c70801eaa 100644 --- a/src/Tools/blocFissure/CasTests/cubeCoin.py +++ b/src/Tools/blocFissure/CasTests/cubeCoin.py @@ -6,7 +6,7 @@ from blocFissure import gmu dicoParams = dict(nomCas = 'cubeCoin', maillageSain = os.path.join(gmu.pathBloc, 'materielCasTests/cubeFin.med'), brepFaceFissure = os.path.join(gmu.pathBloc, "materielCasTests/cubeFin_Coin.brep"), - edgeFissIds = [7], + edgeFissIds = [6], lgInfluence = 50, meshBrep = (5,10), rayonPipe = 10, diff --git a/src/Tools/blocFissure/CasTests/cubeMilieu.py b/src/Tools/blocFissure/CasTests/cubeMilieu.py index 0d93518cd..cd3db8cb2 100644 --- a/src/Tools/blocFissure/CasTests/cubeMilieu.py +++ b/src/Tools/blocFissure/CasTests/cubeMilieu.py @@ -6,7 +6,7 @@ from blocFissure import gmu dicoParams = dict(nomCas = 'cubeMilieu', maillageSain = os.path.join(gmu.pathBloc, 'materielCasTests/cubeFin.med'), brepFaceFissure = os.path.join(gmu.pathBloc, "materielCasTests/cubeFin_Milieu.brep"), - edgeFissIds = [7], + edgeFissIds = [6], lgInfluence = 50, meshBrep = (5,10), rayonPipe = 10, diff --git a/src/Tools/blocFissure/CasTests/cylindre.py b/src/Tools/blocFissure/CasTests/cylindre.py index 9885a96a3..628831869 100644 --- a/src/Tools/blocFissure/CasTests/cylindre.py +++ b/src/Tools/blocFissure/CasTests/cylindre.py @@ -61,7 +61,7 @@ class cylindre(fissureGenerique): shellFiss = geompy.ImportFile(os.path.join(gmu.pathBloc, "materielCasTests/FissInCylindre2.brep"), "BREP") fondFiss = geompy.CreateGroup(shellFiss, geompy.ShapeType["EDGE"]) - geompy.UnionIDs(fondFiss, [7]) + geompy.UnionIDs(fondFiss, [6]) geompy.addToStudy( shellFiss, 'shellFiss' ) geompy.addToStudyInFather( shellFiss, fondFiss, 'fondFiss' ) diff --git a/src/Tools/blocFissure/CasTests/disquePerce.py b/src/Tools/blocFissure/CasTests/disquePerce.py index 5c4b63f3d..0e54cca99 100644 --- a/src/Tools/blocFissure/CasTests/disquePerce.py +++ b/src/Tools/blocFissure/CasTests/disquePerce.py @@ -6,7 +6,7 @@ from blocFissure import gmu dicoParams = dict(nomCas = 'disque', maillageSain = os.path.join(gmu.pathBloc, 'materielCasTests/disque.med'), brepFaceFissure = os.path.join(gmu.pathBloc, "materielCasTests/ellipse_disque.brep"), - edgeFissIds = [4], + edgeFissIds = [3], lgInfluence = 10, meshBrep = (0.5,2.5), rayonPipe = 1.0, diff --git a/src/Tools/blocFissure/CasTests/ellipse_1.py b/src/Tools/blocFissure/CasTests/ellipse_1.py index 2e39357ae..53ac507b8 100644 --- a/src/Tools/blocFissure/CasTests/ellipse_1.py +++ b/src/Tools/blocFissure/CasTests/ellipse_1.py @@ -34,7 +34,7 @@ class ellipse_1(fissureGenerique): # logging.info("genereGeometrieSaine %s", self.nomCas) # box = geompy.MakeBox(0, -500, 0, 400, 500, 800, "boiteSaine") # return [box] - + # --------------------------------------------------------------------------- def genereMaillageSain(self, geometriesSaines, meshParams): logging.info("genereMaillageSain %s", self.nomCas) @@ -65,7 +65,7 @@ class ellipse_1(fissureGenerique): shellFiss = geompy.ImportFile(os.path.join(gmu.pathBloc, "materielCasTests/ellipse1.brep"), "BREP") fondFiss = geompy.CreateGroup(shellFiss, geompy.ShapeType["EDGE"]) - geompy.UnionIDs(fondFiss, [4]) + geompy.UnionIDs(fondFiss, [3]) geompy.addToStudy( shellFiss, 'shellFiss' ) geompy.addToStudyInFather( shellFiss, fondFiss, 'fondFiss' ) diff --git a/src/Tools/blocFissure/CasTests/ellipse_2.py b/src/Tools/blocFissure/CasTests/ellipse_2.py index 69ae3ed95..35c8598d9 100644 --- a/src/Tools/blocFissure/CasTests/ellipse_2.py +++ b/src/Tools/blocFissure/CasTests/ellipse_2.py @@ -37,7 +37,7 @@ class ellipse_2(ellipse_1): shellFiss = geompy.ImportFile(os.path.join(gmu.pathBloc, "materielCasTests/ellipse1_pb.brep"), "BREP") fondFiss = geompy.CreateGroup(shellFiss, geompy.ShapeType["EDGE"]) - geompy.UnionIDs(fondFiss, [4]) + geompy.UnionIDs(fondFiss, [3]) geompy.addToStudy( shellFiss, 'shellFiss' ) geompy.addToStudyInFather( shellFiss, fondFiss, 'fondFiss' ) diff --git a/src/Tools/blocFissure/CasTests/fissure_Coude.py b/src/Tools/blocFissure/CasTests/fissure_Coude.py index 6f87ec6b4..a348ae454 100644 --- a/src/Tools/blocFissure/CasTests/fissure_Coude.py +++ b/src/Tools/blocFissure/CasTests/fissure_Coude.py @@ -140,10 +140,11 @@ class fissure_Coude(fissureGenerique): # --- peau tube exterieur (PEAUEXT) - cercle1 = geompy.MakeCircle(centre, OZ, de/2.) - extru1 = geompy.MakePrismVecH(cercle1, OZ, l_tube_p1) - revol1 = geompy.MakeRevolution(cercle1, axe, angleCoude*math.pi/180.0) - rot1 = geompy.MakeRotation(cercle1, axe, angleCoude*math.pi/180.0) + Disk_3 = geompy.MakeDiskPntVecR(centre, OZ, de/2. +epais) + couronne1 = geompy.MakeCut(Disk_3, Disk_1) + extru1 = geompy.MakePrismVecH(couronne1, OZ, l_tube_p1) + revol1 = geompy.MakeRevolution(couronne1, axe, angleCoude*math.pi/180.0) + rot1 = geompy.MakeRotation(couronne1, axe, angleCoude*math.pi/180.0) extru2 = geompy.MakePrismVecH(rot1, Rotation_2, -l_tube_p2) externe = geompy.MakeFuse(extru1, revol1) externe = geompy.MakeFuse(extru2, externe) @@ -294,7 +295,7 @@ class fissure_Coude(fissureGenerique): azimut = -azimut # axe inverse / ASCOUF axe = geompy.MakeTranslation(OY, -r_cintr, 0, -l_tube_p1) - + if not lgInfluence: lgInfluence = profondeur diff --git a/src/Tools/blocFissure/CasTests/vis_1.py b/src/Tools/blocFissure/CasTests/vis_1.py index cf4400faa..34ab00322 100644 --- a/src/Tools/blocFissure/CasTests/vis_1.py +++ b/src/Tools/blocFissure/CasTests/vis_1.py @@ -59,7 +59,7 @@ class vis_1(fissureGenerique): shellFiss = geompy.ImportFile(os.path.join(gmu.pathBloc, "materielCasTests/visFiss.brep"), "BREP") fondFiss = geompy.CreateGroup(shellFiss, geompy.ShapeType["EDGE"]) - geompy.UnionIDs(fondFiss, [7, 9]) + geompy.UnionIDs(fondFiss, [6, 8]) geompy.addToStudy( shellFiss, 'shellFiss' ) geompy.addToStudyInFather( shellFiss, fondFiss, 'fondFiss' ) diff --git a/src/Tools/blocFissure/exemple2.py b/src/Tools/blocFissure/exemple2.py index e7320f55b..1b0141f65 100644 --- a/src/Tools/blocFissure/exemple2.py +++ b/src/Tools/blocFissure/exemple2.py @@ -91,4 +91,4 @@ dicoParams = dict(nomCas = 'angleCube2', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/fissureLauncher.py b/src/Tools/blocFissure/fissureLauncher.py index 10f7b0ffb..f8b761fab 100644 --- a/src/Tools/blocFissure/fissureLauncher.py +++ b/src/Tools/blocFissure/fissureLauncher.py @@ -33,4 +33,4 @@ dicoParams = dict(nomCas = 'fissTuyau', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) \ No newline at end of file + salome.sg.updateObjBrowser(True) \ No newline at end of file diff --git a/src/Tools/blocFissure/gmu/construitEdgesRadialesDebouchantes.py b/src/Tools/blocFissure/gmu/construitEdgesRadialesDebouchantes.py index d77ccafd6..0dcd41f39 100644 --- a/src/Tools/blocFissure/gmu/construitEdgesRadialesDebouchantes.py +++ b/src/Tools/blocFissure/gmu/construitEdgesRadialesDebouchantes.py @@ -12,12 +12,12 @@ from sortEdges import sortEdges def construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks, facesPipePeau, edgeRadFacePipePeau, nbsegCercle): """ - construction des listes d'edges radiales sur chaque extrémité débouchante + construction des listes d'edges radiales sur chaque extrémité débouchante """ logging.info('start') - + # --- listes de nappes radiales en filling à chaque extrémité débouchante - + facesDebouchantes = [False, False] idFacesDebouchantes = [-1, -1] # contiendra les indices des faces disque débouchantes (facesPipePeau) listNappes =[] @@ -47,7 +47,7 @@ def construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks, geomPublish(initLog.debug, nappe, name) facesDebouchantes[i] = True listNappes.append(nappes) - + # --- mise en correspondance avec les indices des faces disque débouchantes (facesPipePeau) for i, nappes in enumerate(listNappes): if facesDebouchantes[i]: @@ -82,27 +82,48 @@ def construitEdgesRadialesDebouchantes(idisklim, idiskout, gptsdisks, raydisks, else: maxl = geompy.BasicProperties(edge)[0] if maxl < 0.01: # problème MakeSection - logging.debug("problème MakeSection recherche edge radiale %s, longueur trop faible: %s, utilisation partition", k, maxl) + logging.info("problème MakeSection recherche edge radiale %s, longueur trop faible: %s, utilisation partition", k, maxl) partNappeFace = geompy.MakePartition([face, nappes[k]], [] , [], [], geompy.ShapeType["FACE"], 0, [], 0) edps= geompy.ExtractShapes(partNappeFace, geompy.ShapeType["EDGE"], False) ednouv = [] for ii, ed in enumerate(edps): + dmax=100. vxs = geompy.ExtractShapes(ed, geompy.ShapeType["VERTEX"], False) distx = [geompy.MinDistance(vx, face) for vx in vxs] distx += [geompy.MinDistance(vx, nappes[k]) for vx in vxs] dmax = max(distx) - logging.debug(" dmax %s",dmax) - if dmax < 0.01: + lgedge = geompy.BasicProperties(ed)[0] + logging.debug(" dmax %s, longueur edge %s",dmax, lgedge) + if dmax < 0.01 and lgedge > 0.01: ednouv.append(ed) - logging.debug(" edges issues de la partition: %s", ednouv) - for ii, ed in enumerate(ednouv): - geomPublish(initLog.debug, ed, "ednouv%d"%ii) - [edsorted, minl,maxl] = sortEdges(ednouv) - logging.debug(" longueur edge trouvée: %s", maxl) - edge = edsorted[-1] + if (len(ednouv) > 0): + logging.debug(" edges issues de la partition: %s", ednouv) + for ii, ed in enumerate(ednouv): + geomPublish(initLog.debug, ed, "ednouv%d"%ii) + [edsorted, minl,maxl] = sortEdges(ednouv) + logging.debug(" longueur edge trouvée: %s", maxl) + edge = edsorted[-1] + else: + logging.info("problème partition recherche edge radiale %s", k) + vxs = geompy.ExtractShapes(partNappeFace, geompy.ShapeType["VERTEX"], False) + vxnouv=[] + for ii,vx in enumerate(vxs): + distx = geompy.MinDistance(vx, face) + distx += geompy.MinDistance(vx, nappes[k]) + logging.debug("vertex distance: %s", distx) + if distx < 0.005: + vxnouv.append(vx) + logging.debug("nombre vertex candidats %s", len(vxnouv)) + if len(vxnouv) >= 2: + eds = [geompy.MakeEdge(vxnouv[j],vxnouv[(j+1)%len(vxnouv)]) for j in range(len(vxnouv))] + [edsorted2, minl,maxl] = sortEdges(eds) + edge = edsorted2[-1] + logging.debug("lg edge: %s", maxl) + else: + logging.debug("problème recherche edge radiale %s non résolu", k) edges.append(edge) name = 'edgeEndPipe%d'%k geomPublish(initLog.debug, edge, name) listEdges.append(edges) - + return (listEdges, idFacesDebouchantes) \ No newline at end of file diff --git a/src/Tools/blocFissure/gmu/construitFissureGenerale.py b/src/Tools/blocFissure/gmu/construitFissureGenerale.py index c02c09803..8db3cabb0 100644 --- a/src/Tools/blocFissure/gmu/construitFissureGenerale.py +++ b/src/Tools/blocFissure/gmu/construitFissureGenerale.py @@ -333,7 +333,7 @@ def construitFissureGenerale(maillagesSains, logging.info("fichier maillage fissure %s", fichierMaillageFissure) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) logging.info("maillage fissure fini") diff --git a/src/Tools/blocFissure/gmu/fissureCoude.py b/src/Tools/blocFissure/gmu/fissureCoude.py index bf8e0e639..224323567 100644 --- a/src/Tools/blocFissure/gmu/fissureCoude.py +++ b/src/Tools/blocFissure/gmu/fissureCoude.py @@ -178,10 +178,10 @@ class fissureCoude(fissureGenerique): # --- peau tube exterieur (PEAUEXT) - cercle1 = geompy.MakeCircle(centre, OZ, de/2.) - extru1 = geompy.MakePrismVecH(cercle1, OZ, l_tube_p1) - revol1 = geompy.MakeRevolution(cercle1, axe, angleCoude*math.pi/180.0) - rot1 = geompy.MakeRotation(cercle1, axe, angleCoude*math.pi/180.0) + Disk_3 = geompy.MakeDiskPntVecR(centre, OZ, de/2. +epais) + extru1 = geompy.MakePrismVecH(Disk_3, OZ, l_tube_p1) + revol1 = geompy.MakeRevolution(Disk_3, axe, angleCoude*math.pi/180.0) + rot1 = geompy.MakeRotation(Disk_3, axe, angleCoude*math.pi/180.0) extru2 = geompy.MakePrismVecH(rot1, Rotation_2, -l_tube_p2) externe = geompy.MakeFuse(extru1, revol1) externe = geompy.MakeFuse(extru2, externe) @@ -338,13 +338,13 @@ class fissureCoude(fissureGenerique): self.elliptique = False if shapeFissureParams.has_key('elliptique'): self.elliptique = shapeFissureParams['elliptique'] - + azimut = -azimut # axe inverse / ASCOUF axe = geompy.MakeTranslation(OY, -r_cintr, 0, -l_tube_p1) geomPublish(initLog.debug, axe,"axe") - + if not lgInfluence: lgInfluence = profondeur @@ -377,7 +377,7 @@ class fissureCoude(fissureGenerique): lgfond = longueur -2*profondeur angle = lgfond/(2*raybor) pb = geompy.MakeVertex(raybor, 0, 0) - pi = geompy.MakeVertex(rayint, 0, 0) + pi = geompy.MakeVertex(rayint, 0, 0) pbl = geompy.MakeRotation(pb, OZ, angle) pbr = geompy.MakeRotation(pb, OZ, -angle) geomPublish(initLog.debug, pbl,"pbl") @@ -395,7 +395,7 @@ class fissureCoude(fissureGenerique): pt = geompy.MakeRotation(pil, axl, angi) points.append(pt) for i in range(nbp): - angi = angle -2.0*i*angle/nbp + angi = angle -2.0*i*angle/nbp pt = geompy.MakeRotation(pi, OZ, angi) points.append(pt) for i in range(nbp+1): @@ -407,30 +407,30 @@ class fissureCoude(fissureGenerique): pt = geompy.MakeTranslation(pt, 0, 0, -l_tube_p1) pt = geompy.MakeRotation(pt, axe, alpha*math.pi/180.) points[i] = pt - wire0 = geompy.MakeInterpol(points[0:nbp+1]) - wire1 = geompy.MakeInterpol(points[nbp:2*nbp+1]) - wire2 = geompy.MakeInterpol(points[2*nbp:3*nbp+1]) + wire0 = geompy.MakeInterpol(points[0:nbp+1]) + wire1 = geompy.MakeInterpol(points[nbp:2*nbp+1]) + wire2 = geompy.MakeInterpol(points[2*nbp:3*nbp+1]) #wiretube = geompy.MakeInterpol(points) wiretube=geompy.MakeWire([wire0,wire1,wire2]) geomPublish(initLog.debug, wiretube,"wiretube") - + pe = geompy.MakeVertex(rayext, 0, 0) pe = geompy.MakeRotation(pe, OZ, azimut*math.pi/180.) pe = geompy.MakeTranslation(pe, 0, 0, -l_tube_p1) pe = geompy.MakeRotation(pe, axe, alpha*math.pi/180.) - + arce = geompy.MakeArc(points[0], pe, points[-1]) geomPublish(initLog.debug, arce,"arce") - + facefiss = geompy.MakeFaceWires([arce, wiretube], 1) geomPublish(initLog.debug, facefiss, 'facefissPlace' ) - + pc = geompy.MakeVertex((raybor + rayint)/2.0, 0, 0) centre = geompy.MakeRotation(pc, OZ, azimut*math.pi/180.) centre = geompy.MakeTranslation(centre, 0, 0, -l_tube_p1) centre = geompy.MakeRotation(centre, axe, alpha*math.pi/180.) geomPublish(initLog.debug, centre, 'centrefissPlace' ) - + wiretube = geompy.GetInPlace(facefiss, wiretube) geomPublish(initLog.debug, wiretube, 'wiretubePlace' ) try: @@ -449,7 +449,7 @@ class fissureCoude(fissureGenerique): else: raybor = de/2. - epais dp = +1.0 - prof = dp * profondeur + prof = dp * profondeur lgfond = longueur -2*profondeur cosaz = math.cos(azimut*math.pi/180.) sinaz = math.sin(azimut*math.pi/180.) @@ -477,9 +477,9 @@ class fissureCoude(fissureGenerique): for i in range(nbp+2): x = math.sin(i*math.pi/(nbp+1)) # fonction de répartition des points : distance relative x2 = x*x - totx += x2 + totx += x2 xs.append(totx) - logging.debug("x2: %s, totx: %s", x2, totx) + logging.debug("x2: %s, totx: %s", x2, totx) for i in range(nbp+1): #posi = nbp -i # répartition équidistante des points sur la courbe posi = nbp*(1 -xs[i]/totx) # points plus resserrés aux extrémités de la courbe @@ -501,11 +501,11 @@ class fissureCoude(fissureGenerique): x = math.sin(i*math.pi/nbp) #x = 1.0 # répartition équidistante des points sur la courbe x2 = x*x # points plus resserrés aux extrémités de la courbe - totx += x2 + totx += x2 xs.append(totx) - logging.debug("x2: %s, totx: %s", x2, totx) + logging.debug("x2: %s, totx: %s", x2, totx) for i in range(nbp): - angi = alfrd -angle +2.0*angle*xs[i]/totx + angi = alfrd -angle +2.0*angle*xs[i]/totx pt = geompy.MakeRotation(pi, axe, angi) points.append(pt) curves.append(geompy.MakeInterpol(points)) @@ -521,9 +521,9 @@ class fissureCoude(fissureGenerique): for i in range(nbp+2): x = math.sin(i*math.pi/(nbp+1)) x2 = x*x - totx += x2 + totx += x2 xs.append(totx) - logging.debug("x2: %s, totx: %s", x2, totx) + logging.debug("x2: %s, totx: %s", x2, totx) for i in range(nbp+1): #posi = nbp -i # répartition équidistante des points sur la courbe posi = nbp*xs[i]/totx # points plus resserrés aux extrémités de la courbe @@ -536,7 +536,7 @@ class fissureCoude(fissureGenerique): # for i, pt in enumerate(points): # name = "point%d"%i # geomPublishInFather(initLog.debug,curves[-1], pt, name) - + wiretube = geompy.MakeWire(curves) geomPublish(initLog.debug, wiretube,"wiretube") try: @@ -545,26 +545,26 @@ class fissureCoude(fissureGenerique): except: logging.debug("erreur MakeEdgeWire sur fond de fissure, on fait sans") edgetube = None - + pts = [] pts.append(point0) dpr = prof*math.cos(5.0*math.pi/8.0) pe = geompy.MakeTranslation(pb, dpr*cosaz, dpr*sinaz, 0., "pe") for i in range(nbp): - angi = alfrd -angle +2.0*i*angle/nbp + angi = alfrd -angle +2.0*i*angle/nbp pt = geompy.MakeRotation(pe, axe, angi) pts.append(pt) pts.append(point1) arce = geompy.MakeInterpol(pts) geomPublish(initLog.debug, arce,"arce") - + facefiss = geompy.MakeFaceWires([arce, wiretube], 0) geomPublish(initLog.debug, facefiss, 'facefissPlace' ) - + pc = geompy.MakeTranslation(pb, 0.5*prof*cosaz, 0.5*prof*sinaz, 0.) centre = geompy.MakeRotation(pc, axe, alfrd) geomPublish(initLog.debug, centre, 'centrefissPlace' ) - + edges = geompy.ExtractShapes(facefiss, geompy.ShapeType["EDGE"], True) edgesTriees, minl, maxl = sortEdges(edges) edges = edgesTriees[:-1] # la plus grande correspond à arce, on l'elimine @@ -581,7 +581,7 @@ class fissureCoude(fissureGenerique): else: raybor = de/2. - epais dp = +1.0 - prof = dp * profondeur + prof = dp * profondeur cosaz = math.cos(azimut*math.pi/180.) sinaz = math.sin(azimut*math.pi/180.) alfrd = alpha*math.pi/180. @@ -602,7 +602,7 @@ class fissureCoude(fissureGenerique): cox = geompy.VectorCoordinates(ax1) coy = geompy.VectorCoordinates(ay1) localLCS = geompy.MakeMarker(coo[0], coo[1], coo[2], cox[0], cox[1], cox[2], coy[0], coy[1], coy[2], "localLCS") - + pco = geompy.MakeVertex(0, 0, -profondeur, "pco") pao = geompy.MakeRotation(pco, OY, 0.6*math.pi, "pao") pbo = geompy.MakeRotation(pco, OY, -0.6*math.pi, "pbo") @@ -620,7 +620,7 @@ class fissureCoude(fissureGenerique): edgesTriees, minl, maxl = sortEdges(edges) edgetube = edgesTriees[-1] # la plus grande correspond à arci wiretube = edgetube - + pc = geompy.MakeTranslation(pb, 0.5*prof*cosaz, 0.5*prof*sinaz, 0.) centre = geompy.MakeRotation(pc, axe, alfrd) geomPublish(initLog.debug, centre, 'centrefissPlace' ) diff --git a/src/Tools/blocFissure/gmu/identifieEdgesPeau.py b/src/Tools/blocFissure/gmu/identifieEdgesPeau.py index a3abb6208..70595896e 100644 --- a/src/Tools/blocFissure/gmu/identifieEdgesPeau.py +++ b/src/Tools/blocFissure/gmu/identifieEdgesPeau.py @@ -15,16 +15,16 @@ def identifieEdgesPeau(edgesFissExtPipe,verticesPipePeau, facePeau, facesPeauSor identification précise des edges et disques des faces de peau selon index extremité fissure """ logging.info('start') - + facesPipePeau = [None for i in range(len(edgesFissExtPipe))] endsEdgeFond = [None for i in range(len(edgesFissExtPipe))] edgeRadFacePipePeau = [None for i in range(len(edgesFissExtPipe))] - + edgesListees = [] edgesCircPeau = [] verticesCircPeau = [] if len(verticesPipePeau) > 0: # --- au moins une extrémité du pipe sur cette face de peau - + for face in facesPeauSorted[:-1]: # la ou les faces débouchantes, pas la grande face de peau logging.debug("examen face debouchante circulaire") for i,efep in enumerate(edgesFissExtPipe): @@ -52,11 +52,11 @@ def identifieEdgesPeau(edgesFissExtPipe,verticesPipePeau, facePeau, facesPeauSor pass pass pass - + # --- edges circulaires de la face de peau et points de jonction de la face externe de fissure logging.debug("facesPipePeau: %s", facesPipePeau) edgesCircPeau = [None for i in range(len(facesPipePeau))] - verticesCircPeau = [None for i in range(len(facesPipePeau))] + verticesCircPeau = [None for i in range(len(facesPipePeau))] for i,fcirc in enumerate(facesPipePeau): edges = geompy.GetSharedShapesMulti([facePeau, fcirc], geompy.ShapeType["EDGE"]) grpEdgesCirc = geompy.CreateGroup(facePeau, geompy.ShapeType["EDGE"]) @@ -96,8 +96,26 @@ def identifieEdgesPeau(edgesFissExtPipe,verticesPipePeau, facePeau, facesPeauSor geompy.UnionList(groupEdgesBordPeau, edgesBords) bordsVifs = None if aretesVivesC is not None: - logging.debug("identification des bords vifs par GetInPlace (old)") + logging.debug("identification des bords vifs par GetInPlace") bordsVifs = geompy.GetInPlace(facePeau, aretesVivesC) + if bordsVifs is None: + logging.debug("pas d'identification des bords vifs par GetInPlace: test par distance") + edvifs = [] + arvives = geompy.ExtractShapes(aretesVivesC, geompy.ShapeType["EDGE"], False) + edgs = geompy.ExtractShapes(facePeau, geompy.ShapeType["EDGE"], False) + for ed in edgs: + vxs = geompy.ExtractShapes(ed, geompy.ShapeType["VERTEX"], False) + for ar in arvives: + d = geompy.MinDistance(vxs[0], ar) + d += geompy.MinDistance(vxs[1], ar) + logging.debug("test distance bord face peau - arete vive: %s",d) + if d < 0.001: + edvifs.append(ed) + break + if len(edvifs) >0: + bordsVifs = geompy.CreateGroup(facePeau,geompy.ShapeType["EDGE"]) + for ed in edvifs: + geompy.AddObject(bordsVifs, geompy.GetSubShapeID(facePeau, ed)) if bordsVifs is not None: geomPublishInFather(initLog.debug, facePeau, bordsVifs, "bordsVifs") groupEdgesBordPeau = geompy.CutGroups(groupEdgesBordPeau, bordsVifs) @@ -114,9 +132,9 @@ def identifieEdgesPeau(edgesFissExtPipe,verticesPipePeau, facePeau, facesPeauSor aretesVivesCoupees += edv logging.debug("aretesVivesCoupees %s",aretesVivesCoupees) geomPublishInFather(initLog.debug, facePeau, groupEdgesBordPeau , "EdgesBords") - + # --- edges de la face de peau partagées avec la face de fissure - + edgesPeau = geompy.ExtractShapes(facePeau, geompy.ShapeType["EDGE"], False) edges = substractSubShapes(facePeau, edgesPeau, edgesListees) edgesFissurePeau = [] @@ -136,7 +154,7 @@ def identifieEdgesPeau(edgesFissExtPipe,verticesPipePeau, facePeau, facesPeauSor edgesFissurePeau.append(edge) name = "edgeFissurePeau%d"%i geomPublishInFather(initLog.debug, facePeau, edge, name) - + return (endsEdgeFond, facesPipePeau, edgeRadFacePipePeau, edgesCircPeau, verticesCircPeau, groupEdgesBordPeau, bordsVifs, edgesFissurePeau, aretesVivesCoupees) diff --git a/src/Tools/blocFissure/gmu/insereFissureElliptique.py b/src/Tools/blocFissure/gmu/insereFissureElliptique.py index ede20b48c..de8fbeb17 100644 --- a/src/Tools/blocFissure/gmu/insereFissureElliptique.py +++ b/src/Tools/blocFissure/gmu/insereFissureElliptique.py @@ -194,6 +194,6 @@ def insereFissureElliptique(geometriesSaines, maillagesSains, logging.info("fichier maillage fissure : %s", fichierMaillageFissure) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) return maillageComplet diff --git a/src/Tools/blocFissure/gmu/insereFissureGenerale.py b/src/Tools/blocFissure/gmu/insereFissureGenerale.py index 96c733e1e..a8619bdda 100644 --- a/src/Tools/blocFissure/gmu/insereFissureGenerale.py +++ b/src/Tools/blocFissure/gmu/insereFissureGenerale.py @@ -1378,7 +1378,7 @@ def insereFissureGenerale(maillagesSains, logging.info("fichier maillage fissure %s", fichierMaillageFissure) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) logging.info("maillage fissure fini") diff --git a/src/Tools/blocFissure/gmu/insereFissureLongue.py b/src/Tools/blocFissure/gmu/insereFissureLongue.py index bc33172ee..347fb401c 100644 --- a/src/Tools/blocFissure/gmu/insereFissureLongue.py +++ b/src/Tools/blocFissure/gmu/insereFissureLongue.py @@ -654,6 +654,6 @@ def insereFissureLongue(geometriesSaines, maillagesSains, logging.info("fichier maillage fissure %s", fichierMaillageFissure) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) return maillageComplet \ No newline at end of file diff --git a/src/Tools/blocFissure/ihm/fissureCoude.ui b/src/Tools/blocFissure/ihm/fissureCoude.ui index 5687164ed..577556942 100644 --- a/src/Tools/blocFissure/ihm/fissureCoude.ui +++ b/src/Tools/blocFissure/ihm/fissureCoude.ui @@ -6,7 +6,7 @@ 0 0 - 959 + 974 618 diff --git a/src/Tools/blocFissure/ihm/fissureGenerale.ui b/src/Tools/blocFissure/ihm/fissureGenerale.ui index bdf1e36c1..62fad0bbc 100644 --- a/src/Tools/blocFissure/ihm/fissureGenerale.ui +++ b/src/Tools/blocFissure/ihm/fissureGenerale.ui @@ -6,7 +6,7 @@ 0 0 - 663 + 664 624 diff --git a/src/Tools/blocFissure/ihm/fissureGenerale_plugin.py b/src/Tools/blocFissure/ihm/fissureGenerale_plugin.py index 89ac32c6e..48d962653 100644 --- a/src/Tools/blocFissure/ihm/fissureGenerale_plugin.py +++ b/src/Tools/blocFissure/ihm/fissureGenerale_plugin.py @@ -31,60 +31,50 @@ def fissureGeneraleDlg(context): study = context.study studyId = context.studyId sg = context.sg - + import os #import subprocess #import tempfile - from PyQt4 import QtCore - from PyQt4 import QtGui - from PyQt4.QtGui import QFileDialog - from PyQt4.QtGui import QMessageBox - from PyQt4.QtGui import QPalette - from PyQt4.QtGui import QColor - from PyQt4.QtCore import QString + from PyQt5 import QtCore + from PyQt5 import QtWidgets + from PyQt5 import QtGui + from PyQt5.QtWidgets import QFileDialog + from PyQt5.QtWidgets import QMessageBox + from PyQt5.QtGui import QPalette + from PyQt5.QtGui import QColor from fissureGenerale_ui import Ui_Dialog - - class fissureGeneraleDialog(QtGui.QDialog): - + + class fissureGeneraleDialog(QtWidgets.QDialog): + def __init__(self): print "__init__" - QtGui.QDialog.__init__(self) + QtWidgets.QDialog.__init__(self) # Set up the user interface from Designer. self.ui = Ui_Dialog() self.ui.setupUi(self) - + self.blackPalette = self.ui.dsb_influence.palette() self.redPalette = QPalette() self.redPalette.setColor(QPalette.Text, QColor(255,0,0)) self.NOK = False - + self.initDefaut() self.initDialog(self.defaut) self.ui.lb_calcul.hide() - + # Connect up the buttons. - self.connect(self.ui.pb_exemple, QtCore.SIGNAL("clicked()"), - self.genereExemples) - self.connect(self.ui.pb_valPrec, QtCore.SIGNAL("clicked()"), - self.readValPrec) - self.connect(self.ui.pb_reset, QtCore.SIGNAL("clicked()"), - self.resetVal) - self.connect(self.ui.pb_recharger, QtCore.SIGNAL("clicked()"), - self.recharger) - self.connect(self.ui.pb_sauver, QtCore.SIGNAL("clicked()"), - self.sauver) - self.connect(self.ui.pb_maillage, QtCore.SIGNAL("clicked()"), - self.selectMaillage) - self.connect(self.ui.pb_facefiss, QtCore.SIGNAL("clicked()"), - self.selectFacefiss) - self.connect(self.ui.pb_reptrav, QtCore.SIGNAL("clicked()"), - self.selectReptrav) - self.connect(self.ui.pb_nomres, QtCore.SIGNAL("clicked()"), - self.selectNomres) - self.disconnect(self.ui.bb_OkCancel, QtCore.SIGNAL("accepted()"), self.accept) - self.connect(self.ui.bb_OkCancel, QtCore.SIGNAL("accepted()"), - self.execute) - + + self.ui.pb_exemple.clicked.connect(self.genereExemples) + self.ui.pb_valPrec.clicked.connect(self.readValPrec) + self.ui.pb_reset.clicked.connect(self.resetVal) + self.ui.pb_recharger.clicked.connect(self.recharger) + self.ui.pb_sauver.clicked.connect(self.sauver) + self.ui.pb_maillage.clicked.connect(self.selectMaillage) + self.ui.pb_facefiss.clicked.connect(self.selectFacefiss) + self.ui.pb_reptrav.clicked.connect(self.selectReptrav) + self.ui.bb_OkCancel.accepted.disconnect(self.accept) + self.ui.bb_OkCancel.accepted.connect(self.execute) + def initDefaut(self): self.defaut = dict( nomCas = 'angleCube', @@ -103,7 +93,7 @@ def fissureGeneraleDlg(context): nomres = 'casStandard_fissure.med', verbosite = 0) - + def initDialog(self, dico): self.ui.le_maillage.setText(dico['maillageSain']) self.ui.le_facefiss.setText(dico['brepFaceFissure']) @@ -125,7 +115,7 @@ def fissureGeneraleDlg(context): self.ui.cb_log.setCurrentIndex(dico['verbosite']) incomplet = self.testval(dico) pass - + def testval(self, dico): incomplet = False if not os.path.lexists(dico['maillageSain']): @@ -180,21 +170,21 @@ def fissureGeneraleDlg(context): incomplet = True else: self.ui.dsb_areteFaceFissure.setPalette(self.blackPalette) - + print "incomplet: ", incomplet return incomplet - + def fileDefault(self): filedef = os.path.expanduser("~/.config/salome/dialogFissureGenerale.dic") print filedef return filedef - + def writeDefault(self, dico): filedef = self.fileDefault() f = open(filedef, 'w') f.write(str(dico)) f.close() - + def genereExemples(self): maillageSain = os.path.join(gmu.pathBloc, 'materielCasTests/CubeAngle.med') brepFaceFissure = os.path.join(gmu.pathBloc, "materielCasTests/CubeAngleFiss.brep") @@ -206,7 +196,7 @@ def fissureGeneraleDlg(context): from blocFissure.materielCasTests import genereMateriel self.ui.lb_calcul.hide() self.initDialog(self.defaut) - + def readValPrec(self): filedef = self.fileDefault() if os.path.exists(filedef): @@ -219,7 +209,7 @@ def fissureGeneraleDlg(context): def resetVal(self): #self.initDefaut() self.initDialog(self.defaut) - + def setLogVerbosity(self, logfile): from blocFissure.gmu import initLog # le mode de log s'initialise une seule fois print "setLogVerbosity" @@ -231,8 +221,8 @@ def fissureGeneraleDlg(context): initLog.setVerbose(logfile) elif index == 2: initLog.setDebug(logfile) - - + + def sauver(self): print "sauver" fileDiag = QFileDialog(self) @@ -241,6 +231,7 @@ def fissureGeneraleDlg(context): fileDiag.setViewMode(QFileDialog.List) if fileDiag.exec_() : fileNames = fileDiag.selectedFiles() + print fileNames filedef = fileNames[0] if filedef[-4:] not in ['.dic']: filedef += '.dic' @@ -248,7 +239,7 @@ def fissureGeneraleDlg(context): f = open(filedef, 'w') f.write(str(dico)) f.close() - + def recharger(self): print "recharger" fileDiag = QFileDialog(self) @@ -265,7 +256,7 @@ def fissureGeneraleDlg(context): dico = eval(txt) print dico self.initDialog(dico) - + def selectMaillage(self): fileDiag = QFileDialog(self) fileDiag.setFileMode(QFileDialog.ExistingFile) @@ -276,7 +267,7 @@ def fissureGeneraleDlg(context): filedef = fileNames[0] print filedef self.ui.le_maillage.setText(filedef) - + def selectFacefiss(self): fileDiag = QFileDialog(self) fileDiag.setFileMode(QFileDialog.ExistingFile) @@ -287,7 +278,7 @@ def fissureGeneraleDlg(context): filedef = fileNames[0] print filedef self.ui.le_facefiss.setText(filedef) - + def selectReptrav(self): fileDiag = QFileDialog(self) fileDiag.setFileMode(QFileDialog.Directory) @@ -298,8 +289,8 @@ def fissureGeneraleDlg(context): reptrav = str(fileNames[0]) print "reptrav ", reptrav self.ui.le_reptrav.setText(os.path.abspath(reptrav)) - - + + def selectNomres(self): fileDiag = QFileDialog(self) fileDiag.setFileMode(QFileDialog.AnyFile) @@ -316,7 +307,7 @@ def fissureGeneraleDlg(context): self.ui.le_nomres.setText(tempnom) else: self.ui.le_nomres.setText(nomres) - + def creeDico(self): dico = dict( maillageSain = str(self.ui.le_maillage.text()), @@ -336,7 +327,7 @@ def fissureGeneraleDlg(context): ) print dico return dico - + def checkValues(self): return self.NOK @@ -362,7 +353,7 @@ def fissureGeneraleDlg(context): print erreur.msg print '-'*60 for ligne in erreur.pile: - print repr(ligne) + print repr(ligne) print '-'*60 texte = erreur.msg # texte += +"
    " +'-'*60 +"
    " @@ -370,19 +361,19 @@ def fissureGeneraleDlg(context): # texte += repr(ligne) +"
    " mbox = QMessageBox(self) mbox.setWindowTitle("erreur blocFissure") - mbox.setText(QString.fromUtf8(texte)) - mbox.exec_() + mbox.setText(str(texte)) + mbox.exec_() # except Exception as erreur: # print "exception non répertoriée" self.NOK = NOK self.ui.lb_calcul.hide() #self.accept() - - pass + + pass # ---------------------------------------------------------------------------- - - print "main" + + print "main" window = fissureGeneraleDialog() retry = True while(retry): @@ -396,4 +387,4 @@ def fissureGeneraleDlg(context): else: print "dialog rejected, exit" pass - + diff --git a/src/Tools/blocFissure/lanceurSoudureArrondieTest.py b/src/Tools/blocFissure/lanceurSoudureArrondieTest.py index bd91562b6..3b0097aa4 100644 --- a/src/Tools/blocFissure/lanceurSoudureArrondieTest.py +++ b/src/Tools/blocFissure/lanceurSoudureArrondieTest.py @@ -29,4 +29,4 @@ dicoParams = dict(nomCas = 'casTestCoinTriple', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/lanceurSoudureViveTest.py b/src/Tools/blocFissure/lanceurSoudureViveTest.py index aa4d8039a..89ceb14e7 100644 --- a/src/Tools/blocFissure/lanceurSoudureViveTest.py +++ b/src/Tools/blocFissure/lanceurSoudureViveTest.py @@ -29,4 +29,4 @@ dicoParams = dict(nomCas = 'casTestCoinTriple', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/lanceurTestAubry.py b/src/Tools/blocFissure/lanceurTestAubry.py index 6e4311170..49eeed3ae 100644 --- a/src/Tools/blocFissure/lanceurTestAubry.py +++ b/src/Tools/blocFissure/lanceurTestAubry.py @@ -29,4 +29,4 @@ dicoParams = dict(nomCas = 'testAubry', execInstance = casStandard(dicoParams) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/cubeAngle.py b/src/Tools/blocFissure/materielCasTests/cubeAngle.py index cef66f65e..a9c4769aa 100644 --- a/src/Tools/blocFissure/materielCasTests/cubeAngle.py +++ b/src/Tools/blocFissure/materielCasTests/cubeAngle.py @@ -75,4 +75,4 @@ smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D') smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/cubeFin.py b/src/Tools/blocFissure/materielCasTests/cubeFin.py index 02fe24314..3eeb130df 100644 --- a/src/Tools/blocFissure/materielCasTests/cubeFin.py +++ b/src/Tools/blocFissure/materielCasTests/cubeFin.py @@ -127,4 +127,4 @@ smesh.SetName(Nb_Segments_1, 'Nb. Segments_1') cubeFin_1.ExportMED( os.path.join(gmu.pathBloc, "materielCasTests/cubeFin.med"), 0, SMESH.MED_V2_2, 1 ) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py b/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py index 6c55b0e02..c43889c94 100644 --- a/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py +++ b/src/Tools/blocFissure/materielCasTests/decoupeCylindre.py @@ -164,4 +164,4 @@ smesh.SetName(SubMesh_1, 'SubMesh_1') smesh.SetName(SubMesh_2, 'SubMesh_2') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/disque_perce.py b/src/Tools/blocFissure/materielCasTests/disque_perce.py index 2f2730d3d..7fc7173dc 100644 --- a/src/Tools/blocFissure/materielCasTests/disque_perce.py +++ b/src/Tools/blocFissure/materielCasTests/disque_perce.py @@ -86,4 +86,4 @@ smesh.SetName(SubMesh_1, 'SubMesh_1') smesh.SetName(SubMesh_2, 'SubMesh_2') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/ellipse.py b/src/Tools/blocFissure/materielCasTests/ellipse.py index ebb4e40fa..e55e913cf 100644 --- a/src/Tools/blocFissure/materielCasTests/ellipse.py +++ b/src/Tools/blocFissure/materielCasTests/ellipse.py @@ -58,4 +58,4 @@ geompy.ExportBREP(ellipse1, os.path.join(gmu.pathBloc, "materielCasTests/ellipse if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/ellipse_disque.py b/src/Tools/blocFissure/materielCasTests/ellipse_disque.py index 1eb504f23..b0b1d37f3 100644 --- a/src/Tools/blocFissure/materielCasTests/ellipse_disque.py +++ b/src/Tools/blocFissure/materielCasTests/ellipse_disque.py @@ -50,4 +50,4 @@ geompy.addToStudy( Ellipse_disque, 'Ellipse_disque' ) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/ellipse_probleme.py b/src/Tools/blocFissure/materielCasTests/ellipse_probleme.py index 4fa377ae4..5b01a500d 100644 --- a/src/Tools/blocFissure/materielCasTests/ellipse_probleme.py +++ b/src/Tools/blocFissure/materielCasTests/ellipse_probleme.py @@ -56,4 +56,4 @@ geompy.ExportBREP(ellipse1, os.path.join(gmu.pathBloc, "materielCasTests/ellipse if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/eprouvetteCourbe.py b/src/Tools/blocFissure/materielCasTests/eprouvetteCourbe.py index 9098f115f..343070352 100644 --- a/src/Tools/blocFissure/materielCasTests/eprouvetteCourbe.py +++ b/src/Tools/blocFissure/materielCasTests/eprouvetteCourbe.py @@ -104,4 +104,4 @@ smesh.SetName(SubMesh_1, 'SubMesh_1') smesh.SetName(SubMesh_2, 'SubMesh_2') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/eprouvetteDroite.py b/src/Tools/blocFissure/materielCasTests/eprouvetteDroite.py index 33199d2e5..1b2ef1c47 100644 --- a/src/Tools/blocFissure/materielCasTests/eprouvetteDroite.py +++ b/src/Tools/blocFissure/materielCasTests/eprouvetteDroite.py @@ -139,4 +139,4 @@ smesh.SetName(SubMesh_1, 'SubMesh_1') smesh.SetName(SubMesh_2, 'SubMesh_2') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/fissureGauche.py b/src/Tools/blocFissure/materielCasTests/fissureGauche.py index b7e8188a5..a6d4e3999 100644 --- a/src/Tools/blocFissure/materielCasTests/fissureGauche.py +++ b/src/Tools/blocFissure/materielCasTests/fissureGauche.py @@ -133,4 +133,4 @@ smesh.SetName(SubMesh_1, 'SubMesh_1') smesh.SetName(SubMesh_2, 'SubMesh_2') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/fissureGauche2.py b/src/Tools/blocFissure/materielCasTests/fissureGauche2.py index 9a508a5f9..0f08fd715 100644 --- a/src/Tools/blocFissure/materielCasTests/fissureGauche2.py +++ b/src/Tools/blocFissure/materielCasTests/fissureGauche2.py @@ -95,4 +95,4 @@ smesh.SetName(Quadrangle_2D.GetAlgorithm(), 'Quadrangle_2D') smesh.SetName(Hexa_3D.GetAlgorithm(), 'Hexa_3D') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/blocFissure/materielCasTests/vis.py b/src/Tools/blocFissure/materielCasTests/vis.py index 59653c93e..ce9aa6805 100644 --- a/src/Tools/blocFissure/materielCasTests/vis.py +++ b/src/Tools/blocFissure/materielCasTests/vis.py @@ -245,4 +245,4 @@ smesh.SetName(tige_haute_2, 'tige_haute') if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(1) + salome.sg.updateObjBrowser(True) diff --git a/src/Tools/padder/spadderpy/gui/plugindialog.py b/src/Tools/padder/spadderpy/gui/plugindialog.py index 056c8d871..8bd4294a4 100644 --- a/src/Tools/padder/spadderpy/gui/plugindialog.py +++ b/src/Tools/padder/spadderpy/gui/plugindialog.py @@ -360,7 +360,7 @@ class PluginDialog(QDialog): meshname = 'padder_'+str(self.__jobid) smesh.SetName(outputMesh.GetMesh(), meshname) if salome.sg.hasDesktop(): - salome.sg.updateObjBrowser(0) + salome.sg.updateObjBrowser(False) self.__ui.lblStatusBar.setText("Publication OK") self.__setGuiState(["CAN_SELECT"]) diff --git a/src/Tools/smesh_plugins.py b/src/Tools/smesh_plugins.py index 3c81d72fa..2b2ad4b60 100644 --- a/src/Tools/smesh_plugins.py +++ b/src/Tools/smesh_plugins.py @@ -17,9 +17,10 @@ # # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -# Author : Guillaume Boulant (EDF) +# Author : Guillaume Boulant (EDF) # import salome_pluginsmanager +import os try: from spadderPlugin import runSpadderPlugin @@ -75,15 +76,16 @@ except: salome_pluginsmanager.logger.info('ERROR: Meshed Pipe with a crack plug-in is unavailable') pass -# ZCracks plugin requires the module EFICAS to be installed -# thus it is first tested if this module is available before -# adding the plugin to salome_pluginsmanager +# ZCracks plugin requires the Zcracks tool try: - import eficasSalome - from zcracks_plugin import ZcracksLct - salome_pluginsmanager.AddFunction('Run Zcrack', - 'Run Zcrack', - ZcracksLct) + zcracksHome=os.environ['ZCRACKSHOME'] + if len(zcracksHome) > 1: + #print 'ZCRACKSHOME ', zcracksHome + from Zcracks.zcracks_plugin import ZcracksLct + salome_pluginsmanager.AddFunction('Run Zcrack', + 'Run Zcrack', + ZcracksLct) except: + #print 'probleme zcracks' salome_pluginsmanager.logger.info('ERROR: Zcrack plug-in is unavailable') pass